Adding rabbit supplier

* Fixing feedback
* Fixing test name
* Migrating existing tests
* New line in the end of RabbitSourceInvalidConfigTests
This commit is contained in:
rstpv
2020-05-28 14:43:59 -05:00
committed by GitHub
parent 1ef16b9b3e
commit 029a95e4f9
12 changed files with 1314 additions and 0 deletions

View File

@@ -18,5 +18,6 @@
<module>load-generator-source</module>
<module>mongodb-source</module>
<module>tcp-source</module>
<module>rabbit-source</module>
</modules>
</project>

View File

@@ -0,0 +1,83 @@
//tag::ref-doc[]
= RabbitMQ Source
The "rabbit" source enables receiving messages from RabbitMQ.
The queue(s) must exist before the stream is deployed; they are not created automatically.
You can easily create a Queue using the RabbitMQ web UI.
== Input
N/A
== Output
=== Payload
* `byte[]`
== Options
The **$$rabbit$$** $$source$$ has the following options:
//tag::configuration-properties[]
$$rabbit.supplier.enable-retry$$:: $$true to enable retry.$$ *($$Boolean$$, default: `$$false$$`)*
$$rabbit.supplier.initial-retry-interval$$:: $$Initial retry interval when retry is enabled.$$ *($$Integer$$, default: `$$1000$$`)*
$$rabbit.supplier.mapped-request-headers$$:: $$Headers that will be mapped.$$ *($$String[]$$, default: `$$[STANDARD_REQUEST_HEADERS]$$`)*
$$rabbit.supplier.max-attempts$$:: $$The maximum delivery attempts when retry is enabled.$$ *($$Integer$$, default: `$$3$$`)*
$$rabbit.supplier.max-retry-interval$$:: $$Max retry interval when retry is enabled.$$ *($$Integer$$, default: `$$30000$$`)*
$$rabbit.supplier.own-connection$$:: $$When true, use a separate connection based on the boot properties.$$ *($$Boolean$$, default: `$$false$$`)*
$$rabbit.supplier.queues$$:: $$The queues to which the source will listen for messages.$$ *($$String[]$$, default: `$$<none>$$`)*
$$rabbit.supplier.requeue$$:: $$Whether rejected messages should be requeued.$$ *($$Boolean$$, default: `$$true$$`)*
$$rabbit.supplier.retry-multiplier$$:: $$Retry backoff multiplier when retry is enabled.$$ *($$Double$$, default: `$$2$$`)*
$$rabbit.supplier.transacted$$:: $$Whether the channel is transacted.$$ *($$Boolean$$, default: `$$false$$`)*
$$spring.rabbitmq.addresses$$:: $$Comma-separated list of addresses to which the client should connect.$$ *($$String$$, default: `$$<none>$$`)*
$$spring.rabbitmq.connection-timeout$$:: $$Connection timeout. Set it to zero to wait forever.$$ *($$Duration$$, default: `$$<none>$$`)*
$$spring.rabbitmq.host$$:: $$RabbitMQ host.$$ *($$String$$, default: `$$localhost$$`)*
$$spring.rabbitmq.password$$:: $$Login to authenticate against the broker.$$ *($$String$$, default: `$$guest$$`)*
$$spring.rabbitmq.port$$:: $$RabbitMQ port.$$ *($$Integer$$, default: `$$5672$$`)*
$$spring.rabbitmq.publisher-confirms$$:: $$Whether to enable publisher confirms.$$ *($$Boolean$$, default: `$$false$$`)*
$$spring.rabbitmq.publisher-returns$$:: $$Whether to enable publisher returns.$$ *($$Boolean$$, default: `$$false$$`)*
$$spring.rabbitmq.requested-heartbeat$$:: $$Requested heartbeat timeout; zero for none. If a duration suffix is not specified, seconds will be used.$$ *($$Duration$$, default: `$$<none>$$`)*
$$spring.rabbitmq.username$$:: $$Login user to authenticate to the broker.$$ *($$String$$, default: `$$guest$$`)*
$$spring.rabbitmq.virtual-host$$:: $$Virtual host to use when connecting to the broker.$$ *($$String$$, default: `$$<none>$$`)*
//end::configuration-properties[]
Also see the https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html[Spring Boot Documentation]
for addition properties for the broker connections and listener properties.
[[rabbitSourceRetry]]
=== A Note About Retry
NOTE: With the default _ackMode_ (*AUTO*) and _requeue_ (*true*) options, failed message deliveries will be retried
indefinitely.
Since there is not much processing in the rabbit source, the risk of failure in the source itself is small, unless
the downstream `Binder` is not connected for some reason.
Setting _requeue_ to *false* will cause messages to be rejected on the first attempt (and possibly sent to a Dead Letter
Exchange/Queue if the broker is so configured).
The _enableRetry_ option allows configuration of retry parameters such that a failed message delivery can be retried and
eventually discarded (or dead-lettered) when retries are exhausted.
The delivery thread is suspended during the retry interval(s).
Retry options are _enableRetry_, _maxAttempts_, _initialRetryInterval_, _retryMultiplier_, and _maxRetryInterval_.
Message deliveries failing with a _MessageConversionException_ are never retried; the assumption being that if a message
could not be converted on the first attempt, subsequent attempts will also fail.
Such messages are discarded (or dead-lettered).
== Build
```
$ ./mvnw clean install -PgenerateApps
$ cd apps
```
You can find the corresponding binder based projects here.
You can then cd into one of the folders and build it:
```
$ ./mvnw clean package
```
== Examples
```
java -jar rabbit-source.jar --rabbit.queues=
```
//end::ref-doc[]

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>rabbit-source</artifactId>
<version>3.0.0-SNAPSHOT</version>
<name>rabbit-source</name>
<description>Rabbit source apps</description>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.cloud.stream.app</groupId>
<artifactId>stream-applications-core</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath/>
</parent>
<properties>
<test-containers-version>1.14.2</test-containers-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud.fn</groupId>
<artifactId>rabbit-supplier</artifactId>
<version>${java-functions.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${test-containers-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>rabbitmq</artifactId>
<version>${test-containers-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-app-starter-doc-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.cloud.stream.app.plugin</groupId>
<artifactId>spring-cloud-stream-app-maven-plugin</artifactId>
<configuration>
<generatedApp>
<name>rabbit</name>
<type>source</type>
<version>${project.version}</version>
<configClass>org.springframework.cloud.fn.supplier.rabbit.RabbitSupplierConfiguration.class</configClass>
</generatedApp>
<dependencies>
<dependency>
<groupId>org.springframework.cloud.fn</groupId>
<artifactId>rabbit-supplier</artifactId>
<version>${java-functions.version}</version>
</dependency>
</dependencies>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
</repository>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
</repository>
</repositories>
</project>

View File

@@ -0,0 +1,2 @@
configuration-properties.classes=org.springframework.cloud.fn.supplier.rabbit.RabbitSupplierProperties, \
org.springframework.boot.autoconfigure.amqp.RabbitProperties

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2016-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.stream.app.source.rabbit;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.bind.validation.BindValidationException;
import org.springframework.boot.context.properties.bind.validation.ValidationErrors;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.cloud.fn.supplier.rabbit.RabbitSupplierProperties;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.FieldError;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.fail;
/**
* Tests for RabbitSource with invalid config.
*
* @author Gary Russell
* @author Chris Schaefer
*/
public class RabbitSourceInvalidConfigTests {
@Test
public void testNoQueues() {
try {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
TestPropertyValues.of("rabbit.supplier.enableRetry:false").applyTo(context);
context.register(Config.class);
context.refresh();
fail("BeanCreationException expected");
} catch (Exception e) {
assertThat(e, instanceOf(BeanCreationException.class));
assertThat(extractedValidationMessage(e), containsString("queue(s) are required"));
}
}
@Test
public void testEmptyQueues() {
try {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
TestPropertyValues.of("rabbit.supplier.enableRetry:false").applyTo(context);
TestPropertyValues.of("rabbit.supplier.queues:").applyTo(context);
context.register(Config.class);
context.refresh();
fail("BeanCreationException expected");
} catch (Exception e) {
assertThat(e, instanceOf(BeanCreationException.class));
assertThat(extractedValidationMessage(e), containsString("At least one queue is required"));
}
}
private String extractedValidationMessage(Exception e) {
BindValidationException bindValidationException = (BindValidationException) e.getCause().getCause();
ValidationErrors validationErrors = bindValidationException.getValidationErrors();
FieldError fieldError = (FieldError) validationErrors.getAllErrors().get(0);
return fieldError.getDefaultMessage();
}
@Configuration
@EnableConfigurationProperties(RabbitSupplierProperties.class)
static class Config {}
}

View File

@@ -0,0 +1,185 @@
/*
* Copyright 2020-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.stream.app.source.rabbit;
import org.aopalliance.aop.Advice;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.amqp.utils.test.TestUtils;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.fn.supplier.rabbit.RabbitSupplierConfiguration;
import org.springframework.cloud.stream.binder.test.OutputDestination;
import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.messaging.Message;
import org.springframework.retry.support.RetryTemplate;
import org.testcontainers.containers.RabbitMQContainer;
import java.util.HashMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
/**
* Tests for RabbitSource.
*
* @author Gary Russell
* @author Chris Schaefer
*/
public class RabbitSourceListenerTests {
static {
RabbitMQContainer rabbitmq = new RabbitMQContainer("rabbitmq:3.7-management-alpine")
.withQueue("scsapp-testq", false, false, new HashMap<>())
.withQueue("scsapp-testq2", false, false, new HashMap<>())
.withQueue("scsapp-testOwnSource", false, false, new HashMap<>())
.withExchange("scsapp-testex", "fanout")
.withBinding("scsapp-testex", "scsapp-testq");
rabbitmq.start();
System.setProperty("spring.rabbitmq.test.port", rabbitmq.getAmqpPort().toString());
}
@Test
public void testRabbitSource() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration
.getCompleteConfiguration(RabbitSourceTestApplication.class))
.web(WebApplicationType.NONE)
.run("--spring.cloud.function.definition=rabbitSupplier",
"--rabbit.supplier.queues=scsapp-testq",
"--rabbit.persistentDeliveryMode=true",
"--spring.rabbitmq.listener.simple.concurrency=2",
"--spring.rabbitmq.listener.simple.maxConcurrency=3",
"--spring.rabbitmq.listener.simple.acknowledgeMode=AUTO",
"--spring.rabbitmq.listener.simple.prefetch=10",
"--spring.rabbitmq.listener.simple.transactionSize=5",
"--spring.rabbitmq.port=" +
"${spring.rabbitmq.test.port}"
)) {
final RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
rabbitTemplate.convertAndSend("scsapp-testex", "", "hello");
OutputDestination target = context.getBean(OutputDestination.class);
Message<byte[]> sourceMessage = target.receive(600000);
final String actual = new String(sourceMessage.getPayload());
assertThat(actual).isEqualTo("hello");
}
}
@Test
public void testOwnConnection() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration
.getCompleteConfiguration(RabbitSourceTestApplication.class))
.web(WebApplicationType.NONE)
.run("--spring.cloud.function.definition=rabbitSupplier",
"--rabbit.supplier.queues=scsapp-testOwnSource",
"--rabbit.supplier.enableRetry=false",
"--rabbit.supplier.own-connection=true",
"--spring.rabbitmq.port=" +
"${spring.rabbitmq.test.port}"
)) {
final RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
final CachingConnectionFactory bootFactory = context.getBean(CachingConnectionFactory.class);
rabbitTemplate.convertAndSend("scsapp-testOwnSource", "foo");
bootFactory.resetConnection();
OutputDestination target = context.getBean(OutputDestination.class);
Message<byte[]> sourceMessage = target.receive(600000);
final String actual = new String(sourceMessage.getPayload());
assertThat(actual).isEqualTo("foo");
assertThat(bootFactory.getCacheProperties().getProperty("localPort")).isEqualTo("0");
}
}
@Test
public void testPropertiesPopulated() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
TestChannelBinderConfiguration
.getCompleteConfiguration(RabbitSourceTestApplication.class))
.web(WebApplicationType.NONE)
.run("--spring.cloud.function.definition=rabbitSupplier",
"--rabbit.supplier.queues = scsapp-testq2",
"--rabbit.supplier.enableRetry = true",
"--rabbit.supplier.initialRetryInterval = 123",
"--rabbit.supplier.maxRetryInterval = 345",
"--rabbit.supplier.retryMultiplier = 1.5",
"--rabbit.supplier.maxAttempts = 5",
"--rabbit.supplier.requeue = false",
"--rabbit.supplier.mappedRequestHeaders = STANDARD_REQUEST_HEADERS,bar",
"--spring.rabbitmq.listener.simple.concurrency = 2",
"--spring.rabbitmq.listener.simple.maxConcurrency = 3 ",
"--spring.rabbitmq.listener.simple.acknowledgeMode = NONE",
"--spring.rabbitmq.listener.simple.prefetch = 10",
"--spring.rabbitmq.listener.simple.batchSize = 5",
"--spring.rabbitmq.port=" +
"${spring.rabbitmq.test.port}"
)) {
final RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);
final SimpleMessageListenerContainer container = context.getBean(SimpleMessageListenerContainer.class);
Advice[] adviceChain = TestUtils.getPropertyValue(container, "adviceChain", Advice[].class);
assertEquals(1, adviceChain.length);
RetryTemplate retryTemplate = TestUtils.getPropertyValue(adviceChain[0], "retryOperations",
RetryTemplate.class);
assertEquals(5, TestUtils.getPropertyValue(retryTemplate, "retryPolicy.maxAttempts"));
assertEquals(123L, TestUtils.getPropertyValue(retryTemplate, "backOffPolicy.initialInterval"));
assertEquals(345L, TestUtils.getPropertyValue(retryTemplate, "backOffPolicy.maxInterval"));
assertEquals(1.5, TestUtils.getPropertyValue(retryTemplate, "backOffPolicy.multiplier"));
assertEquals("scsapp-testq2", container.getQueueNames()[0]);
assertFalse(TestUtils.getPropertyValue(container, "defaultRequeueRejected", Boolean.class));
assertEquals(2, TestUtils.getPropertyValue(container, "concurrentConsumers"));
assertEquals(3, TestUtils.getPropertyValue(container, "maxConcurrentConsumers"));
assertEquals(AcknowledgeMode.NONE, TestUtils.getPropertyValue(container, "acknowledgeMode"));
assertEquals(10, TestUtils.getPropertyValue(container, "prefetchCount"));
assertEquals(5, TestUtils.getPropertyValue(container, "batchSize"));
rabbitTemplate.convertAndSend("", "scsapp-testq2", "foo", message -> {
message.getMessageProperties().getHeaders().put("bar", "baz");
return message;
});
OutputDestination target = context.getBean(OutputDestination.class);
Message<byte[]> sourceMessage = target.receive(600000);
final String actual = new String(sourceMessage.getPayload());
assertEquals("foo", actual);
assertEquals("baz", sourceMessage.getHeaders().get("bar"));
assertNull(sourceMessage.getHeaders().get(AmqpHeaders.DELIVERY_MODE));
}
}
@SpringBootApplication
@Import(RabbitSupplierConfiguration.class)
public static class RabbitSourceTestApplication {
}
}

View File

@@ -73,6 +73,7 @@
<module>supplier/mqtt-supplier</module>
<module>supplier/tcp-supplier</module>
<module>supplier/time-supplier</module>
<module>supplier/rabbit-supplier</module>
<module>spring-functions-parent</module>
</modules>

253
functions/supplier/rabbit-supplier/mvnw vendored Executable file
View File

@@ -0,0 +1,253 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
#
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
# for the new JDKs provided by Oracle.
#
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
#
# Oracle JDKs
#
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
#
# Apple JDKs
#
export JAVA_HOME=`/usr/libexec/java_home`
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Migwn, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
# TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
local basedir=$(pwd)
local wdir=$(pwd)
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
wdir=$(cd "$wdir/.."; pwd)
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
echo "Running version check"
VERSION=$( sed '\!<parent!,\!</parent!d' `dirname $0`/pom.xml | grep '<version' | head -1 | sed -e 's/.*<version>//' -e 's!</version>.*$!!' )
echo "The found version is [${VERSION}]"
if echo $VERSION | egrep -q 'M|RC'; then
echo Activating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
else
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
fi
if echo $VERSION | egrep -q 'RELEASE'; then
echo Activating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
else
echo Deactivating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
fi
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"

View File

@@ -0,0 +1,182 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>rabbit-supplier</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>rabbit-supplier</name>
<description>Rabbit supplier</description>
<parent>
<groupId>org.springframework.cloud.fn</groupId>
<artifactId>spring-functions-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../spring-functions-parent</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,197 @@
/*
* Copyright 2016-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.supplier.rabbit;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Envelope;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionNameStrategy;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer;
import org.springframework.amqp.rabbit.support.DefaultMessagePropertiesConverter;
import org.springframework.amqp.rabbit.support.MessagePropertiesConverter;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.amqp.dsl.Amqp;
import org.springframework.integration.amqp.inbound.AmqpInboundChannelAdapter;
import org.springframework.integration.channel.FluxMessageChannel;
import org.springframework.messaging.Message;
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import java.util.function.Supplier;
/**
* A source module that receives data from RabbitMQ.
*
* @author Gary Russell
* @author Chris Schaefer
* @author Roger Perez
*/
@EnableConfigurationProperties(RabbitSupplierProperties.class)
public class RabbitSupplierConfiguration implements DisposableBean {
private static final MessagePropertiesConverter inboundMessagePropertiesConverter =
new DefaultMessagePropertiesConverter() {
@Override
public MessageProperties toMessageProperties(AMQP.BasicProperties source,
Envelope envelope,
String charset) {
MessageProperties properties = super.toMessageProperties(source, envelope, charset);
properties.setDeliveryMode(null);
return properties;
}
};
@Autowired
private RabbitProperties rabbitProperties;
@Autowired
private ObjectProvider<ConnectionNameStrategy> connectionNameStrategy;
@Autowired
private RabbitSupplierProperties properties;
@Autowired
private ConnectionFactory rabbitConnectionFactory;
private CachingConnectionFactory ownConnectionFactory;
@Bean
public SimpleMessageListenerContainer container() {
ConnectionFactory connectionFactory = this.properties.isOwnConnection()
? buildLocalConnectionFactory()
: this.rabbitConnectionFactory;
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
container.setAutoStartup(false);
RabbitProperties.SimpleContainer simpleContainer = this.rabbitProperties.getListener().getSimple();
AcknowledgeMode acknowledgeMode = simpleContainer.getAcknowledgeMode();
if (acknowledgeMode != null) {
container.setAcknowledgeMode(acknowledgeMode);
}
Integer concurrency = simpleContainer.getConcurrency();
if (concurrency != null) {
container.setConcurrentConsumers(concurrency);
}
Integer maxConcurrency = simpleContainer.getMaxConcurrency();
if (maxConcurrency != null) {
container.setMaxConcurrentConsumers(maxConcurrency);
}
Integer prefetch = simpleContainer.getPrefetch();
if (prefetch != null) {
container.setPrefetchCount(prefetch);
}
Integer transactionSize = simpleContainer.getBatchSize();
if (transactionSize != null) {
container.setBatchSize(transactionSize);
}
container.setDefaultRequeueRejected(this.properties.getRequeue());
container.setChannelTransacted(this.properties.getTransacted());
String[] queues = this.properties.getQueues();
Assert.state(queues.length > 0, "At least one queue is required");
Assert.noNullElements(queues, "queues cannot have null elements");
container.setQueueNames(queues);
if (this.properties.isEnableRetry()) {
container.setAdviceChain(rabbitSourceRetryInterceptor());
}
container.setMessagePropertiesConverter(inboundMessagePropertiesConverter);
return container;
}
@Bean
public AmqpInboundChannelAdapter adapter(SimpleMessageListenerContainer container,
FluxMessageChannel channel) {
return Amqp.inboundAdapter(container)
.autoStartup(false)
.outputChannel(channel)
.mappedRequestHeaders(properties.getMappedRequestHeaders())
.get();
}
@Bean
public Supplier<Flux<Message<?>>> rabbitSupplier(AmqpInboundChannelAdapter adapter,
FluxMessageChannel channel) {
return () -> Flux.from(channel).doOnSubscribe(subscription -> adapter.start());
}
@Bean
public FluxMessageChannel output() {
return new FluxMessageChannel();
}
@Bean
public RetryOperationsInterceptor rabbitSourceRetryInterceptor() {
return RetryInterceptorBuilder.stateless()
.maxAttempts(this.properties.getMaxAttempts())
.backOffOptions(this.properties.getInitialRetryInterval(), this.properties.getRetryMultiplier(),
this.properties.getMaxRetryInterval())
.recoverer(new RejectAndDontRequeueRecoverer())
.build();
}
@Override
public void destroy() throws Exception {
if (this.ownConnectionFactory != null) {
this.ownConnectionFactory.destroy();
}
}
private ConnectionFactory buildLocalConnectionFactory() {
try {
this.ownConnectionFactory = new AutoConfig.Creator().rabbitConnectionFactory(this.rabbitProperties,
this.connectionNameStrategy);
} catch (Exception exception) {
throw new IllegalStateException("Error building connection factory", exception);
}
return this.ownConnectionFactory;
}
}
class AutoConfig extends RabbitAutoConfiguration {
static class Creator extends RabbitConnectionFactoryCreator {
@Override
public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties config,
ObjectProvider<ConnectionNameStrategy> connectionNameStrategy) throws Exception {
CachingConnectionFactory cf = super.rabbitConnectionFactory(config, connectionNameStrategy);
cf.setConnectionNameStrategy(new ConnectionNameStrategy() {
@Override
public String obtainNewConnectionName(ConnectionFactory connectionFactory) {
return "rabbit.supplier.own.connection";
}
});
cf.afterPropertiesSet();
return cf;
}
}
}

View File

@@ -0,0 +1,161 @@
/*
* 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.supplier.rabbit;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@ConfigurationProperties("rabbit.supplier")
@Validated
public class RabbitSupplierProperties {
/**
* Whether rejected messages should be requeued.
*/
private boolean requeue = true;
/**
* Whether the channel is transacted.
*/
private boolean transacted = false;
/**
* The queues to which the source will listen for messages.
*/
private String[] queues;
/**
* Headers that will be mapped.
*/
private String[] mappedRequestHeaders = {"STANDARD_REQUEST_HEADERS"};
/**
* Initial retry interval when retry is enabled.
*/
private int initialRetryInterval = 1000;
/**
* Max retry interval when retry is enabled.
*/
private int maxRetryInterval = 30000;
/**
* Retry backoff multiplier when retry is enabled.
*/
private double retryMultiplier = 2.0;
/**
* The maximum delivery attempts when retry is enabled.
*/
private int maxAttempts = 3;
/**
* true to enable retry.
*/
private boolean enableRetry = false;
/**
* When true, use a separate connection based on the boot properties.
*/
private boolean ownConnection;
public boolean getRequeue() {
return requeue;
}
public void setRequeue(boolean requeue) {
this.requeue = requeue;
}
public boolean getTransacted() {
return transacted;
}
public void setTransacted(boolean transacted) {
this.transacted = transacted;
}
@NotNull(message = "queue(s) are required")
@Size(min = 1, message = "At least one queue is required")
public String[] getQueues() {
return queues;
}
public void setQueues(String[] queues) {
this.queues = queues;
}
@NotNull
public String[] getMappedRequestHeaders() {
return mappedRequestHeaders;
}
public void setMappedRequestHeaders(String[] mappedRequestHeaders) {
this.mappedRequestHeaders = mappedRequestHeaders;
}
public int getInitialRetryInterval() {
return initialRetryInterval;
}
public void setInitialRetryInterval(int initialRetryInterval) {
this.initialRetryInterval = initialRetryInterval;
}
public int getMaxRetryInterval() {
return maxRetryInterval;
}
public void setMaxRetryInterval(int maxRetryInterval) {
this.maxRetryInterval = maxRetryInterval;
}
public double getRetryMultiplier() {
return retryMultiplier;
}
public void setRetryMultiplier(double retryMultiplier) {
this.retryMultiplier = retryMultiplier;
}
public int getMaxAttempts() {
return maxAttempts;
}
public void setMaxAttempts(int maxAttempts) {
this.maxAttempts = maxAttempts;
}
public boolean isEnableRetry() {
return enableRetry;
}
public void setEnableRetry(boolean enableRetry) {
this.enableRetry = enableRetry;
}
public boolean isOwnConnection() {
return this.ownConnection;
}
public void setOwnConnection(boolean ownConnection) {
this.ownConnection = ownConnection;
}
}