Make spring-task-launch-request-function as auto-config

* Also make a `spring-spel-function`, `spring-filter-function` as auto-config
* Fix Checkstyle violations in those module, as well as in the `spring-payload-converter-function`
This commit is contained in:
Artem Bilan
2024-01-10 09:54:03 -05:00
parent 0f9065df78
commit 97c3be83af
17 changed files with 86 additions and 73 deletions

View File

@@ -4,7 +4,7 @@ This module provides a filter function that can be reused and composed in other
## Beans for injection
You can import the `FilterFunctionConfiguration` in a Spring Boot application and then inject the following bean.
The `FilterFunctionConfiguration` auto-configuration provides following bean:
`filterFunction`

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,8 @@ import org.springframework.integration.transformer.ExpressionEvaluatingTransform
import org.springframework.messaging.Message;
/**
* Auto-configuration for Filter function.
*
* @author Artem Bilan
* @author David Turanski
*/
@@ -36,7 +38,7 @@ public class FilterFunctionConfiguration {
public Function<Message<?>, Message<?>> filterFunction(
ExpressionEvaluatingTransformer filterExpressionEvaluatingTransformer) {
return message -> {
return (message) -> {
if ((Boolean) filterExpressionEvaluatingTransformer.transform(message).getPayload()) {
return message;
}

View File

@@ -0,0 +1,4 @@
/**
* The Filter function support classes.
*/
package org.springframework.cloud.fn.filter;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.springframework.cloud.fn.filter;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
@@ -47,9 +46,8 @@ public class FilterFunctionApplicationTests {
@Test
public void testFilter() {
Stream<Message<?>> messages = List.of("hello", "hello world").stream().map(GenericMessage::new);
List<Message<?>> result = messages.filter(message -> this.filter.apply(message) != null)
.collect(Collectors.toList());
Stream<Message<?>> messages = Stream.of("hello", "hello world").map(GenericMessage::new);
List<Message<?>> result = messages.filter((message) -> this.filter.apply(message) != null).toList();
assertThat(result.size()).isEqualTo(1);
assertThat(result.get(0).getPayload()).isNotNull();
assertThat(result.get(0).getPayload()).isEqualTo("hello world");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,8 @@ import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.MimeTypeUtils;
/**
* The function which transforms a byte array to string.
*
* @author Christian Tzolov
*/
public class ByteArrayTextToString implements Function<Message<?>, Message<?>> {

View File

@@ -0,0 +1,4 @@
/**
* The utility functions for common usage.
*/
package functions;

View File

@@ -5,7 +5,7 @@ The function can be used to apply SpEL transformations on data based on a SpEL e
## Beans for injection
You can import the `SpelFunctionConfiguration` in a Spring Boot application and then inject the following bean.
The `SpelFunctionConfiguration` auto-configuration provides the following bean:
`spelFunction`

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,14 +18,18 @@ package org.springframework.cloud.fn.spel;
import java.util.function.Function;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.transformer.ExpressionEvaluatingTransformer;
import org.springframework.messaging.Message;
@Configuration
/**
* Auto-configuration for SpEL function.
*
* @author Soby Chacko
*/
@AutoConfiguration
@EnableConfigurationProperties(SpelFunctionProperties.class)
public class SpelFunctionConfiguration {
@@ -33,15 +37,14 @@ public class SpelFunctionConfiguration {
public Function<Message<?>, Message<?>> spelFunction(
ExpressionEvaluatingTransformer expressionEvaluatingTransformer) {
return message -> expressionEvaluatingTransformer.transform(message);
return expressionEvaluatingTransformer::transform;
}
@Bean
public ExpressionEvaluatingTransformer expressionEvaluatingTransformer(
SpelFunctionProperties spelFunctionProperties) {
return new ExpressionEvaluatingTransformer(
new SpelExpressionParser().parseExpression(spelFunctionProperties.getExpression()));
return new ExpressionEvaluatingTransformer(spelFunctionProperties.getExpression());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,8 @@ package org.springframework.cloud.fn.spel;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.expression.FunctionExpression;
import org.springframework.messaging.Message;
/**
* Configuration properties for the SpEL function.
@@ -29,18 +30,18 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
@ConfigurationProperties("spel.function")
public class SpelFunctionProperties {
private static final Expression DEFAULT_EXPRESSION = new SpelExpressionParser().parseExpression("payload");
private static final Expression DEFAULT_EXPRESSION = new FunctionExpression<Message<?>>(Message::getPayload);
/**
* A SpEL expression to apply.
*/
private String expression = DEFAULT_EXPRESSION.getExpressionString();
private Expression expression = DEFAULT_EXPRESSION;
public String getExpression() {
public Expression getExpression() {
return this.expression;
}
public void setExpression(String expression) {
public void setExpression(Expression expression) {
this.expression = expression;
}

View File

@@ -0,0 +1,4 @@
/**
* The SpEL function auto-configuration support.
*/
package org.springframework.cloud.fn.spel;

View File

@@ -1,11 +1,11 @@
# Task Launch Request Function
This module provides a function that can be reused and composed in other applications to transform the output to a link:src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequest.java[TaskLaunchRequest]
that can be used as input to the Tasklauncher function to launch a task.
that can be used as input to the TaskLauncher function to launch a task.
## Beans for injection
You can import the `TaskLaunchRequestFunctionConfiguration` in a Spring Boot application and then inject the following bean.
The `TaskLaunchRequestFunctionConfiguration` auto-configuration provides the following bean:
`taskLaunchRequestFunction` as a link:src/main/java/org/springframework/cloud/fn/task/launch/request/TaskLaunchRequestFunction.java[TaskLaunchRequestFunction].

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,14 +23,14 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.util.StringUtils;
@@ -40,11 +40,11 @@ import org.springframework.util.StringUtils;
* that can be composed with other Suppliers or Functions to transform any {@link Message}
* to a {@link TaskLaunchRequest} which may be used as input to the
* {@code TaskLauncherFunction} to launch a task.
*
* <p>
* Command line arguments used by the task, as well as the task name itself may be
* statically configured or extracted from the message contents, using SpEL. See
* {@link TaskLaunchRequestFunctionProperties} for details.
*
* <p>
* It is also possible to provide your own implementations of
* {@link CommandLineArgumentsMessageMapper} and {@link TaskNameMessageMapper}.
*
@@ -57,7 +57,7 @@ public class TaskLaunchRequestFunctionConfiguration {
/**
* The function name.
*/
public final static String TASK_LAUNCH_REQUEST_FUNCTION_NAME = "taskLaunchRequestFunction";
public static final String TASK_LAUNCH_REQUEST_FUNCTION_NAME = "taskLaunchRequestFunction";
/**
* A {@link java.util.function.Function} to transform a {@link Message} payload to a
@@ -67,22 +67,24 @@ public class TaskLaunchRequestFunctionConfiguration {
* @return a {@code TaskLaunchRequest} Message.
*/
@Bean(name = TASK_LAUNCH_REQUEST_FUNCTION_NAME)
public TaskLaunchRequestFunction taskLaunchRequest(
TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor) {
return message -> taskLaunchRequestMessageProcessor.postProcessMessage(message);
TaskLaunchRequestFunction taskLaunchRequest(TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor) {
return taskLaunchRequestMessageProcessor::postProcessMessage;
}
@Bean
public TaskLaunchRequestSupplier taskLaunchRequestInitializer(
TaskLaunchRequestSupplier taskLaunchRequestInitializer(
TaskLaunchRequestFunctionProperties taskLaunchRequestProperties) {
return new TaskLaunchRequestPropertiesInitializer(taskLaunchRequestProperties);
}
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Bean
public TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor(
TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor(
TaskLaunchRequestSupplier taskLaunchRequestInitializer, TaskLaunchRequestFunctionProperties properties,
EvaluationContext evaluationContext, @Nullable TaskNameMessageMapper taskNameMessageMapper,
@Qualifier(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME) EvaluationContext evaluationContext,
@Nullable TaskNameMessageMapper taskNameMessageMapper,
@Nullable CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper) {
if (taskNameMessageMapper == null) {
@@ -97,13 +99,9 @@ public class TaskLaunchRequestFunctionConfiguration {
commandLineArgumentsMessageMapper);
}
@Bean
public EvaluationContext evaluationContext(BeanFactory beanFactory) {
return ExpressionUtils.createStandardEvaluationContext(beanFactory);
}
private TaskNameMessageMapper taskNameMessageMapper(TaskLaunchRequestFunctionProperties taskLaunchRequestProperties,
EvaluationContext evaluationContext) {
if (StringUtils.hasText(taskLaunchRequestProperties.getTaskNameExpression())) {
SpelExpressionParser expressionParser = new SpelExpressionParser();
Expression taskNameExpression = expressionParser
@@ -111,12 +109,13 @@ public class TaskLaunchRequestFunctionConfiguration {
return new ExpressionEvaluatingTaskNameMessageMapper(taskNameExpression, evaluationContext);
}
return message -> taskLaunchRequestProperties.getTaskName();
return (message) -> taskLaunchRequestProperties.getTaskName();
}
private CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper(
TaskLaunchRequestFunctionProperties taskLaunchRequestFunctionProperties,
EvaluationContext evaluationContext) {
return new ExpressionEvaluatingCommandLineArgsMapper(taskLaunchRequestFunctionProperties.getArgExpressions(),
evaluationContext);
}
@@ -130,25 +129,17 @@ public class TaskLaunchRequestFunctionConfiguration {
this.deploymentPropertiesSupplier(() -> KeyValueListParser
.parseCommaDelimitedKeyValuePairs(taskLaunchRequestProperties.getDeploymentProperties()));
this.taskNameSupplier(() -> taskLaunchRequestProperties.getTaskName());
this.taskNameSupplier(taskLaunchRequestProperties::getTaskName);
}
}
private static class ExpressionEvaluatingTaskNameMessageMapper implements TaskNameMessageMapper {
private final Expression expression;
private final EvaluationContext evaluationContext;
ExpressionEvaluatingTaskNameMessageMapper(Expression expression, EvaluationContext evaluationContext) {
this.evaluationContext = evaluationContext;
this.expression = expression;
}
private record ExpressionEvaluatingTaskNameMessageMapper(Expression expression,
EvaluationContext evaluationContext) implements TaskNameMessageMapper {
@Override
public String processMessage(Message<?> message) {
return expression.getValue(evaluationContext, message).toString();
return this.expression.getValue(this.evaluationContext, message).toString();
}
}
@@ -166,7 +157,7 @@ public class TaskLaunchRequestFunctionConfiguration {
SpelExpressionParser expressionParser = new SpelExpressionParser();
KeyValueListParser.parseCommaDelimitedKeyValuePairs(argExpressions)
.forEach((k, v) -> argExpressionsMap.put(k, expressionParser.parseExpression(v)));
.forEach((k, v) -> this.argExpressionsMap.put(k, expressionParser.parseExpression(v)));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -82,7 +82,7 @@ public class TaskLaunchRequestFunctionProperties {
}
public String getTaskName() {
return taskName;
return this.taskName;
}
public void setTaskName(String taskName) {
@@ -90,7 +90,7 @@ public class TaskLaunchRequestFunctionProperties {
}
public String getTaskNameExpression() {
return taskNameExpression;
return this.taskNameExpression;
}
public void setTaskNameExpression(String taskNameExpression) {
@@ -98,7 +98,7 @@ public class TaskLaunchRequestFunctionProperties {
}
public String getArgExpressions() {
return argExpressions;
return this.argExpressions;
}
public void setArgExpressions(String argExpressions) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,22 +46,22 @@ class TaskLaunchRequestMessageProcessor implements MessagePostProcessor {
@Override
public Message<TaskLaunchRequest> postProcessMessage(Message<?> message) {
TaskLaunchRequest taskLaunchRequest = taskLaunchRequestInitializer.get();
TaskLaunchRequest taskLaunchRequest = this.taskLaunchRequestInitializer.get();
if (!StringUtils.hasText(taskLaunchRequest.getTaskName())) {
taskLaunchRequest.setTaskName(taskNameMessageMapper.processMessage(message));
taskLaunchRequest.setTaskName(this.taskNameMessageMapper.processMessage(message));
Assert.hasText(taskLaunchRequest.getTaskName(),
() -> "'taskName' is required in " + TaskLaunchRequest.class.getName());
}
taskLaunchRequest.addCommmandLineArguments(commandLineArgumentsMessageMapper.processMessage(message));
taskLaunchRequest.addCommmandLineArguments(this.commandLineArgumentsMessageMapper.processMessage(message));
MessageBuilder<TaskLaunchRequest> builder = MessageBuilder.withPayload(taskLaunchRequest)
.copyHeaders(message.getHeaders());
return adjustHeaders(builder).build();
}
private MessageBuilder<TaskLaunchRequest> adjustHeaders(MessageBuilder<TaskLaunchRequest> builder) {
private static MessageBuilder<TaskLaunchRequest> adjustHeaders(MessageBuilder<TaskLaunchRequest> builder) {
builder.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON);
return builder;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,18 +30,18 @@ class TaskLaunchRequestSupplier implements Supplier<TaskLaunchRequest> {
private Supplier<Map<String, String>> deploymentPropertiesSupplier;
public TaskLaunchRequestSupplier taskNameSupplier(Supplier<String> taskNameSupplier) {
TaskLaunchRequestSupplier taskNameSupplier(Supplier<String> taskNameSupplier) {
this.taskNameSupplier = taskNameSupplier;
return this;
}
public TaskLaunchRequestSupplier commandLineArgumentSupplier(Supplier<List<String>> commandLineArgumentsSupplier) {
TaskLaunchRequestSupplier commandLineArgumentSupplier(Supplier<List<String>> commandLineArgumentsSupplier) {
this.commandLineArgumentsSupplier = commandLineArgumentsSupplier;
return this;
}
public TaskLaunchRequestSupplier deploymentPropertiesSupplier(
Supplier<Map<String, String>> deploymentPropertiesSupplier) {
TaskLaunchRequestSupplier deploymentPropertiesSupplier(Supplier<Map<String, String>> deploymentPropertiesSupplier) {
this.deploymentPropertiesSupplier = deploymentPropertiesSupplier;
return this;
}

View File

@@ -0,0 +1,4 @@
/**
* The Task Launcher function auto-configuration support.
*/
package org.springframework.cloud.fn.task.launch.request;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2020 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -194,13 +194,13 @@ public class TaskLaunchRequestFunctionApplicationTests {
@Bean
@ConditionalOnProperty("customTaskNameExtractor")
TaskNameMessageMapper taskNameExtractor() {
return message -> ((String) (message.getPayload())).equalsIgnoreCase("foo") ? "fooTask" : "defaultTask";
return (message) -> ((String) (message.getPayload())).equalsIgnoreCase("foo") ? "fooTask" : "defaultTask";
}
@Bean
@ConditionalOnProperty("enhanceTLRArgs")
CommandLineArgumentsMessageMapper commandLineArgumentsProvider() {
return message -> Collections.singletonList("runtimeArg");
return (message) -> Collections.singletonList("runtimeArg");
}
}