Skip to content

Commit

Permalink
Merge pull request #1 from timonback/feat/lazy-asyncapi-creation
Browse files Browse the repository at this point in the history
feat(core): Ensure initMode=lazy stops application start
  • Loading branch information
tvahrst authored Jul 28, 2023
2 parents 0e49359 + 9de97cb commit 74a38de
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.github.stavshamir.springwolf.configuration.properties.SpringWolfConfigProperties.InitMode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.task.TaskExecutor;
Expand All @@ -17,20 +18,25 @@
@Slf4j
@RequiredArgsConstructor
@Service
public class AsyncApiInitApplicationListener implements ApplicationListener<ApplicationReadyEvent> {
public class SpringWolfInitApplicationListener implements ApplicationListener<ApplicationReadyEvent>, InitializingBean {

private final TaskExecutor taskExecutor;
private final AsyncApiService asyncApiService;
private final SpringWolfConfigProperties configProperties;

@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
if (configProperties.getInitMode() == InitMode.BACKGROUND) {
log.debug("triggering background asyncapi creation..");
taskExecutor.execute(this.asyncApiService::getAsyncAPI);
}
}

@Override
public void afterPropertiesSet() {
if (configProperties.getInitMode() == InitMode.FAIL_FAST) {
log.debug("triggering asyncapi creation..");
this.asyncApiService.getAsyncAPI();
} else {
log.debug("triggering background asyncapi creation..");
taskExecutor.execute(this.asyncApiService::getAsyncAPI);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Optional;

Expand Down Expand Up @@ -63,7 +64,7 @@ private AsyncApiDocket parseApplicationConfigProperties(SpringWolfConfigProperti
}

private static Info buildInfo(@Nullable SpringWolfConfigProperties.ConfigDocket.Info info) {
if (info == null || info.getVersion() == null || info.getTitle() == null) {
if (info == null || !StringUtils.hasText(info.getVersion()) || !StringUtils.hasText(info.getTitle())) {
throw new IllegalArgumentException("One or more required fields of the info object (title, version) "
+ "in application.properties with path prefix " + SpringWolfConfigConstants.SPRINGWOLF_CONFIG_PREFIX
+ " is not set.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

import com.asyncapi.v2._6_0.model.info.Info;
import io.github.stavshamir.springwolf.configuration.AsyncApiDocket;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;

@TestConfiguration
@ConditionalOnProperty(name = "test.springwolf.asyncapidocket", havingValue = "true", matchIfMissing = true)
class CustomBeanAsyncApiDocketConfiguration {
@Bean
public AsyncApiDocket docket() {
return AsyncApiDocket.builder()
.info(Info.builder()
.title("AsyncApiDocketConfiguration-title")
.version("AsyncApiDocketConfiguration-version")
.title("CustomBeanAsyncApiDocketConfiguration-title")
.version("CustomBeanAsyncApiDocketConfiguration-version")
.build())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ void testContextWithAsyncApiDocketBean() {
assertNotNull(context);

assertThat(asyncApiService.getAsyncAPI()).isNotNull();
assertThat(asyncApiService.getAsyncAPI().getInfo().getTitle())
.isEqualTo("CustomBeanAsyncApiDocketConfiguration-title");
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package io.github.stavshamir.springwolf.integrationtests;

import io.github.stavshamir.springwolf.asyncapi.AsyncApiInitApplicationListener;
import io.github.stavshamir.springwolf.asyncapi.DefaultAsyncApiService;
import io.github.stavshamir.springwolf.asyncapi.controller.AsyncApiController;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.core.task.TaskExecutor;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;

Expand All @@ -25,9 +27,6 @@ public class InitModeTest {
@TestPropertySource(properties = {"springwolf.init-mode=fail_fast"})
class TestInitModeFailFast {

@Autowired(required = false)
private AsyncApiInitApplicationListener asyncApiInitApplicationListener;

@Autowired
private DefaultAsyncApiService defaultAsyncApiService;

Expand All @@ -45,9 +44,6 @@ void asyncApiShouldHaveBeenInitializedDuringStartup() {
@TestPropertySource(properties = {"springwolf.init-mode=background"})
class TestInitModeBackground {

@Autowired
private AsyncApiInitApplicationListener asyncApiInitApplicationListener;

@MockBean
private TaskExecutor taskExecutor;

Expand All @@ -60,6 +56,23 @@ void asyncApiApplicationListenerShouldNotBeLoaded() {
}
}

@Nested
class TestThrowExceptionWhenConfigurationError {

@Test
void applicationShouldNotStart() {
// using title=empty to trigger a validation exception during startup
String[] args = new String[] {"--test.springwolf.asyncapidocket=false", "--springwolf.docket.info.title="};

try {
SpringApplication.run(TestApplication.class, args);
fail("Exception expected, but not raised.");
} catch (BeanCreationException ex) {
assertThat(ex.getMessage()).contains("Error occured during creation of AsyncAPI");
}
}
}

@Nested
@SpringBootTest(classes = TestApplication.class)
@TestPropertySource(properties = {"springwolf.enabled=false"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@
import com.asyncapi.v2._6_0.model.info.Info;
import io.github.stavshamir.springwolf.configuration.AsyncApiDocket;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class TestApplication {
@Bean
public AsyncApiDocket docket() {
return AsyncApiDocket.builder()
.info(Info.builder()
.title("AsyncApiDocketConfiguration-title")
.version("AsyncApiDocketConfiguration-version")
.build())
.build();
@TestConfiguration
@ConditionalOnProperty(name = "test.springwolf.asyncapidocket", havingValue = "true", matchIfMissing = true)
public static class TestApplicationConfiguration {
@Bean
public AsyncApiDocket docket() {
return AsyncApiDocket.builder()
.info(Info.builder()
.title("AsyncApiDocketConfiguration-title")
.version("AsyncApiDocketConfiguration-version")
.build())
.build();
}
}
}

0 comments on commit 74a38de

Please sign in to comment.