Various refactoring and improvements

* Remove `MessageChannel` beans whenever their really don't need to be exposed into the target application context.
Use local property definition instead in the configuration class
* Make Twitter `Consumer` configurations conditional on their required properties
to avoid auto-configuration for those bean which are not going to be used in the target application
This commit is contained in:
Artem Bilan
2024-03-07 14:51:36 -05:00
parent d7a80b6487
commit 946b5969da
12 changed files with 69 additions and 106 deletions

View File

@@ -23,7 +23,6 @@ import reactor.core.publisher.Flux;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -46,7 +45,6 @@ import org.springframework.integration.store.MessageGroupStore;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
/**
* The auto-configuration for aggregator function.
@@ -58,6 +56,8 @@ import org.springframework.messaging.MessageChannel;
@EnableConfigurationProperties(AggregatorFunctionProperties.class)
public class AggregatorFunctionConfiguration {
private final FluxMessageChannel outputChannel = new FluxMessageChannel();
@Autowired
private AggregatorFunctionProperties properties;
@@ -65,28 +65,22 @@ public class AggregatorFunctionConfiguration {
private BeanFactory beanFactory;
@Bean
public Function<Flux<Message<?>>, Flux<Message<?>>> aggregatorFunction(FluxMessageChannel inputChannel,
FluxMessageChannel outputChannel) {
return (input) -> Flux.from(outputChannel)
.doOnRequest((request) -> inputChannel.subscribeTo(input.map((
public Function<Flux<Message<?>>, Flux<Message<?>>> aggregatorFunction(FluxMessageChannel aggregatorInputChannel) {
return (input) -> Flux.from(this.outputChannel)
.doOnRequest((request) -> aggregatorInputChannel.subscribeTo(input.map((
inputMessage) -> MessageBuilder.fromMessage(inputMessage).removeHeader("kafka_consumer").build())));
}
@Bean
public FluxMessageChannel inputChannel() {
public FluxMessageChannel aggregatorInputChannel() {
return new FluxMessageChannel();
}
@Bean
public FluxMessageChannel outputChannel() {
return new FluxMessageChannel();
}
@Bean
@ServiceActivator(inputChannel = "inputChannel")
@ServiceActivator(inputChannel = "aggregatorInputChannel")
public AggregatorFactoryBean aggregator(@Nullable CorrelationStrategy correlationStrategy,
@Nullable ReleaseStrategy releaseStrategy, @Nullable MessageGroupProcessor messageGroupProcessor,
@Nullable MessageGroupStore messageStore, @Qualifier("outputChannel") MessageChannel outputChannel,
@Nullable MessageGroupStore messageStore,
@Nullable ComponentCustomizer<AggregatorFactoryBean> aggregatorCustomizer) {
AggregatorFactoryBean aggregator = new AggregatorFactoryBean();
@@ -112,7 +106,7 @@ public class AggregatorFunctionConfiguration {
if (messageStore != null) {
aggregator.setMessageStore(messageStore);
}
aggregator.setOutputChannel(outputChannel);
aggregator.setOutputChannel(this.outputChannel);
if (aggregatorCustomizer != null) {
aggregatorCustomizer.customize(aggregator);

View File

@@ -38,6 +38,7 @@ import org.springframework.messaging.Message;
* Auto-configuration for Twitter Trend function.
*
* @author Christian Tzolov
* @author Artem Bilan
*/
@ConditionalOnProperty(prefix = "twitter.trend", name = "trend-query-type")
@AutoConfiguration(after = TwitterConnectionConfiguration.class)
@@ -47,7 +48,17 @@ public class TwitterTrendFunctionConfiguration {
private static final Log LOGGER = LogFactory.getLog(TwitterTrendFunctionConfiguration.class);
@Bean
public Function<Message<?>, Trends> trend(TwitterTrendFunctionProperties properties, Twitter twitter) {
public Function<Message<?>, Message<byte[]>> twitterTrendFunction(TwitterTrendFunctionProperties properties,
Twitter twitter, Function<Object, Message<byte[]>> managedJson) {
Function<Message<?>, Trends> trendsFunction = trendsFunction(properties, twitter);
Function<Message<?>, List<Location>> closestOrAvailableTrends = closestOrAvailableTrends(properties, twitter);
return (properties.getTrendQueryType() == TwitterTrendFunctionProperties.TrendQueryType.trend)
? trendsFunction.andThen(managedJson) : closestOrAvailableTrends.andThen(managedJson);
}
private Function<Message<?>, Trends> trendsFunction(TwitterTrendFunctionProperties properties, Twitter twitter) {
return (message) -> {
try {
int woeid = properties.getLocationId().getValue(message, int.class);
@@ -60,8 +71,7 @@ public class TwitterTrendFunctionConfiguration {
};
}
@Bean
public Function<Message<?>, List<Location>> closestOrAvailableTrends(TwitterTrendFunctionProperties properties,
private Function<Message<?>, List<Location>> closestOrAvailableTrends(TwitterTrendFunctionProperties properties,
Twitter twitter) {
return (message) -> {
@@ -82,13 +92,4 @@ public class TwitterTrendFunctionConfiguration {
};
}
@Bean
public Function<Message<?>, Message<byte[]>> twitterTrendFunction(Function<Object, Message<byte[]>> managedJson,
Function<Message<?>, Trends> trend, TwitterTrendFunctionProperties properties,
Function<Message<?>, List<Location>> closestOrAvailableTrends) {
return (properties.getTrendQueryType() == TwitterTrendFunctionProperties.TrendQueryType.trend)
? trend.andThen(managedJson) : closestOrAvailableTrends.andThen(managedJson);
}
}

View File

@@ -49,6 +49,7 @@ import static org.mockserver.verify.VerificationTimes.once;
/**
* @author Christian Tzolov
* @author Artem Bilan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "twitter.connection.consumerKey=consumerKey666",
@@ -57,8 +58,6 @@ import static org.mockserver.verify.VerificationTimes.once;
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public abstract class TwitterTrendFunctionTests {
private static final String MOCK_SERVER_IP = "127.0.0.1";
private static ClientAndServer mockServer;
private static MockServerClient mockClient;
@@ -71,7 +70,7 @@ public abstract class TwitterTrendFunctionTests {
@BeforeAll
public static void startServer() {
mockServer = ClientAndServer.startClientAndServer();
mockClient = new MockServerClient(MOCK_SERVER_IP, mockServer.getPort());
mockClient = new MockServerClient("localhost", mockServer.getPort());
trendsRequest = setExpectation(
request().withMethod("GET").withPath("/trends/place.json").withQueryStringParameter("id", "2972"));
@@ -116,7 +115,7 @@ public abstract class TwitterTrendFunctionTests {
Function<TwitterConnectionProperties, ConfigurationBuilder> mockedConfiguration = toConfigurationBuilder
.andThen(new TwitterTestUtils()
.mockTwitterUrls(String.format("http://%s:%s", MOCK_SERVER_IP, mockServer.getPort())));
.mockTwitterUrls(String.format("http://localhost:" + mockServer.getPort())));
return mockedConfiguration.apply(properties).build();
}