Prefix function names with spring-

* Add `spring-` prefix to function names

Fixes: #9

This commit renames each sub-module in the common, consumer, function
and supplier groups with a prefix of `spring-`.

* Update README.adoc links to new prefixed names
This commit is contained in:
Chris Bono
2024-01-02 13:07:00 -06:00
committed by GitHub
parent b9a3e59074
commit 84e732da08
596 changed files with 146 additions and 147 deletions

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2011-2020 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.fn.splitter;
import java.nio.charset.Charset;
import java.util.List;
import java.util.function.Function;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.channel.ReactiveStreamsSubscribableChannel;
import org.springframework.integration.file.splitter.FileSplitter;
import org.springframework.integration.splitter.AbstractMessageSplitter;
import org.springframework.integration.splitter.DefaultMessageSplitter;
import org.springframework.integration.splitter.ExpressionEvaluatingSplitter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
@Configuration
@EnableConfigurationProperties(SplitterFunctionProperties.class)
public class SplitterFunctionConfiguration {
@Bean
public Function<Message<?>, List<Message<?>>> splitterFunction(AbstractMessageSplitter messageSplitter,
SplitterFunctionProperties splitterFunctionProperties) {
messageSplitter.setApplySequence(splitterFunctionProperties.isApplySequence());
ThreadLocalFluxSinkMessageChannel outputChannel = new ThreadLocalFluxSinkMessageChannel();
messageSplitter.setOutputChannel(outputChannel);
return message -> {
messageSplitter.handleMessage(message);
return outputChannel.publisherThreadLocal.get();
};
}
@Bean
@ConditionalOnProperty(prefix = "splitter", name = "expression")
public AbstractMessageSplitter expressionSplitter(SplitterFunctionProperties splitterFunctionProperties) {
return new ExpressionEvaluatingSplitter(
new SpelExpressionParser()
.parseExpression(splitterFunctionProperties.getExpression()));
}
@Bean
@ConditionalOnMissingBean
@Conditional(FileSplitterCondition.class)
public AbstractMessageSplitter fileSplitter(SplitterFunctionProperties splitterFunctionProperties) {
Boolean markers = splitterFunctionProperties.getFileMarkers();
String charset = splitterFunctionProperties.getCharset();
if (markers == null) {
markers = false;
}
FileSplitter fileSplitter = new FileSplitter(true, markers, splitterFunctionProperties.getMarkersJson());
if (charset != null) {
fileSplitter.setCharset(Charset.forName(charset));
}
return fileSplitter;
}
@Bean
@ConditionalOnMissingBean
public AbstractMessageSplitter defaultSplitter(SplitterFunctionProperties splitterFunctionProperties) {
DefaultMessageSplitter defaultMessageSplitter = new DefaultMessageSplitter();
defaultMessageSplitter.setDelimiters(splitterFunctionProperties.getDelimiters());
return defaultMessageSplitter;
}
static class FileSplitterCondition extends AnyNestedCondition {
FileSplitterCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnProperty(prefix = "splitter", name = "charset")
static class Charset {
}
@ConditionalOnProperty(prefix = "splitter", name = "fileMarkers")
static class FileMarkers {
}
}
private static final class ThreadLocalFluxSinkMessageChannel
implements MessageChannel, ReactiveStreamsSubscribableChannel {
private final ThreadLocal<List<Message<?>>> publisherThreadLocal = new ThreadLocal<>();
@Override
@SuppressWarnings("unchecked")
public void subscribeTo(Publisher<? extends Message<?>> publisher) {
this.publisherThreadLocal.set(Flux.from(publisher).collectList().cast(List.class).block());
}
@Override
public boolean send(Message<?> message, long l) {
throw new UnsupportedOperationException("This channel only supports a reactive 'subscribeTo()' ");
}
}
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright 2019-2020 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.fn.splitter;
import jakarta.validation.constraints.AssertTrue;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
/**
* Configuration properties for the Splitter Processor app.
*
* @author Gary Russell
* @author Artem Bilan
*/
@ConfigurationProperties("splitter")
@Validated
public class SplitterFunctionProperties {
/**
* A SpEL expression for splitting payloads.
*/
private String expression;
/**
* When expression is null, delimiters to use when tokenizing
* {@link String} payloads.
*/
private String delimiters;
/**
* Set to true or false to use a {@code FileSplitter} (to split
* text-based files by line) that includes
* (or not) beginning/end of file markers.
*/
private Boolean fileMarkers;
/**
* When 'fileMarkers == true', specify if they should be produced
* as FileSplitter.FileMarker objects or JSON.
*/
private boolean markersJson = true;
/**
* The charset to use when converting bytes in text-based files
* to String.
*/
private String charset;
/**
* Add correlation/sequence information in headers to facilitate later
* aggregation.
*/
private boolean applySequence = true;
public String getExpression() {
return this.expression;
}
public void setExpression(String expression) {
this.expression = expression;
}
public String getDelimiters() {
return this.delimiters;
}
public void setDelimiters(String delimiters) {
this.delimiters = delimiters;
}
public Boolean getFileMarkers() {
return this.fileMarkers;
}
public void setFileMarkers(Boolean fileMarkers) {
this.fileMarkers = fileMarkers;
}
public boolean getMarkersJson() {
return this.markersJson;
}
public void setMarkersJson(boolean markersJson) {
this.markersJson = markersJson;
}
public String getCharset() {
return this.charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public boolean isApplySequence() {
return this.applySequence;
}
public void setApplySequence(boolean applySequence) {
this.applySequence = applySequence;
}
@AssertTrue(message = "'delimiters' is not allowed when an 'expression' is provided")
public boolean isDelimitersAllowed() {
return this.expression == null || this.delimiters == null;
}
@AssertTrue(message = "File properties are not allowed when an 'expression' or 'delimiters' property is provided")
public boolean isFilePropsAllowed() {
return !(this.expression != null || this.delimiters != null) || this.fileMarkers == null && this.charset == null;
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2011-2020 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.fn.splitter;
import java.util.List;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.test.annotation.DirtiesContext;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(properties = "splitter.expression=payload.split(',')")
@DirtiesContext
public class SplitterFunctionApplicationTests {
@Autowired
Function<Message<?>, List<Message<?>>> splitter;
@Test
public void testExpressionSplitter() {
List<Message<?>> messageList = this.splitter.apply(new GenericMessage<>("hello,world"));
assertThat(messageList).extracting(m -> m.getPayload().toString()).contains("hello", "world");
}
@SpringBootApplication
static class SplitterFunctionTestApplication {
}
}