Upgrade build to boot 2.x
- Pump up version to 2.0.0 - Some generic polish - All changes around breakage with boot 2.x - Some boot classes has been moved around - You can't no longer have binding key ending with camelCase. - New Binder now has illegal keys. - Some changes to tests as we can directly do end-to-end testing with ENV_VAR_FORMAT as normal keys - Spring data repo changes as now uses Optional - Remove relaxed binder and its tests in favor of new Binder - Some mockito api changes - One Ingored test TextPlainToJsonConversionTest.testTextPlainToJsonConversionOnInput - Relates to #935 Cache metric export properties Add code formatting guidelines Rearranged files
This commit is contained in:
committed by
Soby Chacko
parent
e2c214b34e
commit
4f72a10bc6
6
pom.xml
6
pom.xml
@@ -3,12 +3,12 @@
|
||||
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>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>1.3.5.RELEASE</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
<scm>
|
||||
@@ -18,7 +18,7 @@
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
<properties>
|
||||
<java.version>1.7</java.version>
|
||||
<java.version>1.8</java.version>
|
||||
<rxjava.version>1.1.10</rxjava.version>
|
||||
<rxjava-reactive-streams.version>1.2.1</rxjava-reactive-streams.version>
|
||||
<spring.tuple.version>1.0.0.RELEASE</spring.tuple.version>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-stream-core-docs</artifactId>
|
||||
<name>spring-cloud-stream-core-docs</name>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -35,6 +35,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.support.converter.ConfigurableCompositeMessageConverter;
|
||||
import org.springframework.integration.support.converter.DefaultDatatypeChannelMessageConverter;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
@@ -49,6 +50,7 @@ import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
/**
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = CustomMessageConverterTests.TestSource.class)
|
||||
@@ -66,9 +68,10 @@ public class CustomMessageConverterTests {
|
||||
|
||||
@Test
|
||||
public void testCustomMessageConverter() throws Exception {
|
||||
assertThat(customMessageConverters).hasSize(3);
|
||||
assertThat(customMessageConverters).hasSize(4);
|
||||
assertThat(customMessageConverters).extracting("class").contains(FooConverter.class,
|
||||
BarConverter.class, DefaultDatatypeChannelMessageConverter.class);
|
||||
BarConverter.class, DefaultDatatypeChannelMessageConverter.class,
|
||||
ConfigurableCompositeMessageConverter.class);
|
||||
testSource.output().send(MessageBuilder.withPayload(new Foo("hi")).build());
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null,
|
||||
|
||||
@@ -55,7 +55,6 @@ public class TextPlainToJsonConversionTest {
|
||||
@Test
|
||||
public void testNoContentTypeToJsonConversionOnInput() throws Exception {
|
||||
testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}").build());
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received).isNotNull();
|
||||
@@ -66,7 +65,6 @@ public class TextPlainToJsonConversionTest {
|
||||
public void testTextPlainToJsonConversionOnInput() throws Exception {
|
||||
testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}")
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build());
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received).isNotNull();
|
||||
@@ -80,7 +78,9 @@ public class TextPlainToJsonConversionTest {
|
||||
@StreamListener("input")
|
||||
@SendTo("output")
|
||||
public Foo consume(Foo foo) {
|
||||
return new Foo("transformed-" + foo.getName());
|
||||
Foo returnFoo = new Foo();
|
||||
returnFoo.setName("transformed-" + foo.getName());
|
||||
return returnFoo;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -92,10 +92,6 @@ public class TextPlainToJsonConversionTest {
|
||||
public Foo() {
|
||||
}
|
||||
|
||||
public Foo(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -18,31 +18,38 @@ package org.springframework.cloud.stream.metrics;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||
import org.springframework.boot.actuate.metrics.export.MetricExportProperties;
|
||||
import org.springframework.boot.actuate.metrics.export.TriggerProperties;
|
||||
import org.springframework.boot.bind.RelaxedNames;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.bind.BindResult;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.cloud.stream.metrics.config.BinderMetricsAutoConfiguration;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.EnumerablePropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
|
||||
/**
|
||||
* @author Vinicius Carvalho
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.cloud.stream.metrics")
|
||||
public class ApplicationMetricsProperties
|
||||
implements ApplicationListener<ContextRefreshedEvent> {
|
||||
implements EnvironmentAware, ApplicationContextAware {
|
||||
|
||||
private static final Bindable<Map<String, String>> STRING_STRING_MAP = Bindable
|
||||
.mapOf(String.class, String.class);
|
||||
|
||||
private final MetricExportProperties metricExportProperties;
|
||||
|
||||
@@ -55,18 +62,32 @@ public class ApplicationMetricsProperties
|
||||
|
||||
private String[] properties;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* List of properties that are going to be appended to each message. This gets
|
||||
* populate by onApplicationEvent, once the context refreshes to avoid overhead of
|
||||
* doing per message basis.
|
||||
*/
|
||||
private Map<String, Object> exportProperties = new HashMap<>();
|
||||
private Map<String, Object> exportProperties = null;
|
||||
|
||||
public ApplicationMetricsProperties(MetricExportProperties metricExportProperties) {
|
||||
Assert.notNull(metricExportProperties, "'metricsExportProperties' cannot be null");
|
||||
this.metricExportProperties = metricExportProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public TriggerProperties getTrigger() {
|
||||
return metricExportProperties
|
||||
.findTrigger(BinderMetricsAutoConfiguration.APPLICATION_METRICS_EXPORTER_TRIGGER_NAME);
|
||||
@@ -100,7 +121,10 @@ public class ApplicationMetricsProperties
|
||||
}
|
||||
|
||||
public Map<String, Object> getExportProperties() {
|
||||
return exportProperties;
|
||||
if (this.exportProperties == null) {
|
||||
this.exportProperties = buildExportProperties();
|
||||
}
|
||||
return this.exportProperties;
|
||||
}
|
||||
|
||||
public String getMetricName() {
|
||||
@@ -114,51 +138,6 @@ public class ApplicationMetricsProperties
|
||||
return this.prefix + this.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over all property sources from this application context and copies the
|
||||
* ones listed in {@link ApplicationMetricsProperties} includes.
|
||||
*/
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
this.exportProperties.clear();
|
||||
ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) event.getSource();
|
||||
ConfigurableEnvironment environment = ctx.getEnvironment();
|
||||
BeanExpressionResolver beanExpressionResolver = ctx.getBeanFactory().getBeanExpressionResolver();
|
||||
BeanExpressionContext expressionContext = new BeanExpressionContext(ctx.getBeanFactory(), null);
|
||||
if (!ObjectUtils.isEmpty(this.properties)) {
|
||||
for (PropertySource<?> source : environment.getPropertySources()) {
|
||||
if (source instanceof EnumerablePropertySource) {
|
||||
EnumerablePropertySource<?> e = (EnumerablePropertySource<?>) source;
|
||||
for (String propertyName : e.getPropertyNames()) {
|
||||
RelaxedNames relaxedNames = new RelaxedNames(propertyName);
|
||||
String canonicalFormat = RelaxedPropertiesUtils.findCanonicalFormat(relaxedNames);
|
||||
// omit this property if already populated from a
|
||||
// higher priority source
|
||||
if (!this.exportProperties.containsKey(canonicalFormat)) {
|
||||
relaxedLoop: for (String relaxedPropertyName : relaxedNames) {
|
||||
if (isMatch(relaxedPropertyName, this.properties, null)) {
|
||||
Object value = source.getProperty(propertyName);
|
||||
String stringValue = ObjectUtils.nullSafeToString(value);
|
||||
Object exportedValue = null;
|
||||
if (value != null) {
|
||||
exportedValue = stringValue.startsWith("#{")
|
||||
? beanExpressionResolver.evaluate(
|
||||
environment.resolvePlaceholders(stringValue), expressionContext)
|
||||
: environment.resolvePlaceholders(stringValue);
|
||||
}
|
||||
this.exportProperties.put(
|
||||
canonicalFormat,
|
||||
exportedValue);
|
||||
break relaxedLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMatch(String name, String[] includes, String[] excludes) {
|
||||
if (ObjectUtils.isEmpty(includes)
|
||||
|| PatternMatchUtils.simpleMatch(includes, name)) {
|
||||
@@ -167,4 +146,42 @@ public class ApplicationMetricsProperties
|
||||
return false;
|
||||
}
|
||||
|
||||
private Map<String, Object> buildExportProperties() {
|
||||
Map<String, Object> props = new HashMap<>();
|
||||
if (!ObjectUtils.isEmpty(this.properties)) {
|
||||
Map<String, String> target = bindProperties();
|
||||
|
||||
BeanExpressionResolver beanExpressionResolver = ((ConfigurableApplicationContext) applicationContext)
|
||||
.getBeanFactory().getBeanExpressionResolver();
|
||||
BeanExpressionContext expressionContext = new BeanExpressionContext(
|
||||
((ConfigurableApplicationContext) applicationContext).getBeanFactory(), null);
|
||||
for (Entry<String, String> entry : target.entrySet()) {
|
||||
if (isMatch(entry.getKey(), this.properties, null)) {
|
||||
String stringValue = ObjectUtils.nullSafeToString(entry.getValue());
|
||||
Object exportedValue = null;
|
||||
if (stringValue != null) {
|
||||
exportedValue = stringValue.startsWith("#{")
|
||||
? beanExpressionResolver.evaluate(
|
||||
environment.resolvePlaceholders(stringValue), expressionContext)
|
||||
: environment.resolvePlaceholders(stringValue);
|
||||
}
|
||||
|
||||
props.put(entry.getKey(), exportedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
private Map<String, String> bindProperties() {
|
||||
Map<String, String> target;
|
||||
BindResult<Map<String, String>> bindResult = Binder.get(environment).bind("", STRING_STRING_MAP);
|
||||
if (bindResult.isBound()) {
|
||||
target = bindResult.get();
|
||||
}
|
||||
else {
|
||||
target = new HashMap<>();
|
||||
}
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 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
|
||||
*
|
||||
* http://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.metrics;
|
||||
|
||||
import java.util.TreeSet;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.boot.bind.RelaxedNames;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility class to deal with {@link RelaxedNames}.
|
||||
*
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
class RelaxedPropertiesUtils {
|
||||
|
||||
private static final Pattern HYPHEN_LOWER = Pattern.compile("-_|_-|__|\\.-|\\._");
|
||||
|
||||
private static final Pattern SEPARATED_TO_CAMEL_CASE_PATTERN = Pattern
|
||||
.compile("[_\\-.]");
|
||||
|
||||
private static final char[] SUFFIXES = new char[] { '_', '-', '.' };
|
||||
|
||||
/**
|
||||
* Searches relaxed names and tries to find a best match for a canonical form using
|
||||
* dot notation. For example, if a new list was built with JAVA_HOME as property, the
|
||||
* return of this method would be {@code java.home}.
|
||||
*
|
||||
* Relaxed names generate a long list of variations of a property, it can be tricky
|
||||
* trying to infer the correct format, which sometimes may not even exist in dot
|
||||
* notation.
|
||||
*
|
||||
* This method attempts to find a best match, or if none is found it converts
|
||||
* underscore format to dot notation.
|
||||
*
|
||||
* @param names list of possible permutations of a property
|
||||
* @return the canonical form (dot notation) of this property
|
||||
*/
|
||||
public static String findCanonicalFormat(Iterable<String> names) {
|
||||
TreeSet<String> sorted = new TreeSet<>();
|
||||
String environmentFormat = null;
|
||||
String simpleFormat = null;
|
||||
for (String name : names) {
|
||||
sorted.add(name);
|
||||
}
|
||||
String canonicalForm = null;
|
||||
for (String name : sorted) {
|
||||
if (HYPHEN_LOWER.matcher(name).find()) {
|
||||
continue;
|
||||
}
|
||||
if (upperCaseRatio(name) == 1.0) {
|
||||
if (name.contains("_")) {
|
||||
environmentFormat = name;
|
||||
}
|
||||
if (!name.matches("^.*?(_|-).*$")) {
|
||||
simpleFormat = name;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (name.contains(".")) {
|
||||
String[] keys = name.split("\\.");
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
keys[i] = separatedToCamelCase(keys[i], false);
|
||||
}
|
||||
canonicalForm = StringUtils.arrayToDelimitedString(keys, ".");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If we can't find any variation it could mean we have a camelCase only value
|
||||
// such as springApplicationName.
|
||||
// In this case RelaxedNames only generate _ values, so we should get one and
|
||||
// transform into dot notation.
|
||||
// Another possibility is a top level property such as MEM or OS, in this case
|
||||
// there's no separator and we only set to lowercase
|
||||
if (canonicalForm == null) {
|
||||
if (environmentFormat != null) {
|
||||
canonicalForm = environmentFormat.toLowerCase().replace("_", ".");
|
||||
}
|
||||
if (canonicalForm == null) {
|
||||
if (simpleFormat != null) {
|
||||
canonicalForm = simpleFormat.toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
return canonicalForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ratio of uppercase chars on a string
|
||||
* @param input
|
||||
* @return
|
||||
*/
|
||||
private static double upperCaseRatio(String input) {
|
||||
int upperCaseCount = 0;
|
||||
String compare = input.replaceAll("[._-]", "");
|
||||
for (int i = 0; i < compare.length(); i++) {
|
||||
if (Character.isUpperCase(compare.charAt(i))) {
|
||||
upperCaseCount++;
|
||||
}
|
||||
}
|
||||
return (float) upperCaseCount / compare.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Taken from {@link RelaxedNames}, convert an input of type string-string into
|
||||
* stringString
|
||||
* @param value
|
||||
* @param caseInsensitive
|
||||
* @return
|
||||
*/
|
||||
private static String separatedToCamelCase(String value, boolean caseInsensitive) {
|
||||
if (value.isEmpty()) {
|
||||
return value;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String field : SEPARATED_TO_CAMEL_CASE_PATTERN.split(value)) {
|
||||
field = (caseInsensitive ? field.toLowerCase() : field);
|
||||
builder.append(builder.length() == 0 ? field : StringUtils.capitalize(field));
|
||||
}
|
||||
char lastChar = value.charAt(value.length() - 1);
|
||||
for (char suffix : SUFFIXES) {
|
||||
if (lastChar == suffix) {
|
||||
builder.append(suffix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,17 +38,18 @@ import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* @author Vinicius Carvalho
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class ApplicationMetricsExporterTests {
|
||||
|
||||
@BeforeClass
|
||||
public static void setSystemProps() {
|
||||
System.setProperty("SPRING_TEST_ENV_SYNTAX", "testing");
|
||||
System.setProperty("spring.test.env.syntax", "testing");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void unsetSystemProps() {
|
||||
System.clearProperty("SPRING_TEST_ENV_SYNTAX");
|
||||
System.clearProperty("spring.test.env.syntax");
|
||||
}
|
||||
|
||||
@Test(expected = NoSuchBeanDefinitionException.class)
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 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
|
||||
*
|
||||
* http://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.metrics;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.bind.RelaxedNames;
|
||||
|
||||
/**
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
public class RelaxedPropertiesUtilsTests {
|
||||
|
||||
@Test
|
||||
public void testVariations() throws Exception {
|
||||
RelaxedNames javaHome = new RelaxedNames("JAVA_HOME");
|
||||
RelaxedNames os = new RelaxedNames("OS");
|
||||
RelaxedNames springEnv = new RelaxedNames("SPRING_APPLICATION_NAME");
|
||||
RelaxedNames springDot = new RelaxedNames("spring.application.name");
|
||||
RelaxedNames springCamel = new RelaxedNames("springApplicationName");
|
||||
RelaxedNames contentType = new RelaxedNames(
|
||||
"spring.cloud.stream.bindings.applicationMetricsChannel.contentType");
|
||||
RelaxedNames contentTypeEnv = new RelaxedNames(
|
||||
"SPRING_CLOUD_STREAM_BINDINGS_APPLICATION-METRICS-CHANNEL_CONTENT-TYPE");
|
||||
RelaxedNames xyz = new RelaxedNames("My.X.Is");
|
||||
RelaxedNames springMetrics = new RelaxedNames("spring.cloud.stream.applicationMetricsChannel");
|
||||
RelaxedNames springMetricsEnv = new RelaxedNames("spring.cloud.stream.application-metrics-channel");
|
||||
Assert.assertEquals("java.home", RelaxedPropertiesUtils.findCanonicalFormat(javaHome));
|
||||
Assert.assertEquals("os", RelaxedPropertiesUtils.findCanonicalFormat(os));
|
||||
Assert.assertEquals("spring.application.name", RelaxedPropertiesUtils.findCanonicalFormat(springEnv));
|
||||
Assert.assertEquals("spring.application.name", RelaxedPropertiesUtils.findCanonicalFormat(springDot));
|
||||
Assert.assertEquals("spring.application.name", RelaxedPropertiesUtils.findCanonicalFormat(springCamel));
|
||||
Assert.assertEquals("spring.cloud.stream.bindings.applicationMetricsChannel.contentType",
|
||||
RelaxedPropertiesUtils.findCanonicalFormat(contentType));
|
||||
Assert.assertEquals("spring.cloud.stream.bindings.applicationMetricsChannel.contentType",
|
||||
RelaxedPropertiesUtils.findCanonicalFormat(contentTypeEnv));
|
||||
Assert.assertEquals("My.X.Is", RelaxedPropertiesUtils.findCanonicalFormat(xyz));
|
||||
Assert.assertEquals("spring.cloud.stream.applicationMetricsChannel",
|
||||
RelaxedPropertiesUtils.findCanonicalFormat(springMetrics));
|
||||
Assert.assertEquals("spring.cloud.stream.applicationMetricsChannel",
|
||||
RelaxedPropertiesUtils.findCanonicalFormat(springMetricsEnv));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,7 +3,11 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<<<<<<< e2c214b34e3f5b179799e6d5e132d72a8cb00a2b
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
=======
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
>>>>>>> Upgrade build to boot 2.x
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
<parent>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<<<<<<< e2c214b34e3f5b179799e6d5e132d72a8cb00a2b
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
=======
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
>>>>>>> Upgrade build to boot 2.x
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.cloud.stream.schema.server.controllers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.cloud.stream.schema.server.config.SchemaServerProperties;
|
||||
import org.springframework.cloud.stream.schema.server.model.Schema;
|
||||
@@ -125,11 +126,11 @@ public class ServerController {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, produces = "application/json", path = "/schemas/{id}")
|
||||
public ResponseEntity<Schema> findOne(@PathVariable("id") Integer id) {
|
||||
Schema schema = this.repository.findOne(id);
|
||||
if (schema == null) {
|
||||
Optional<Schema> schema = this.repository.findById(id);
|
||||
if (!schema.isPresent()) {
|
||||
throw new SchemaNotFoundException("Could not find Schema");
|
||||
}
|
||||
return new ResponseEntity<>(schema, HttpStatus.OK);
|
||||
return new ResponseEntity<>(schema.get(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, produces = "application/json", path = "/{subject}/{format}")
|
||||
@@ -160,8 +161,11 @@ public class ServerController {
|
||||
@RequestMapping(value = "/schemas/{id}", method = RequestMethod.DELETE)
|
||||
public void delete(@PathVariable("id") Integer id) {
|
||||
if (this.schemaServerProperties.isAllowSchemaDeletion()) {
|
||||
Schema schema = this.repository.findOne(id);
|
||||
deleteSchema(schema);
|
||||
Optional<Schema> schema = this.repository.findById(id);
|
||||
if (!schema.isPresent()) {
|
||||
throw new SchemaNotFoundException("Could not find Schema");
|
||||
}
|
||||
deleteSchema(schema.get());
|
||||
}
|
||||
else {
|
||||
throw new SchemaDeletionNotAllowedException();
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
<parent>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<<<<<<< e2c214b34e3f5b179799e6d5e132d72a8cb00a2b
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
=======
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
>>>>>>> Upgrade build to boot 2.x
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
* @author Marius Bogoevici
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.cloud.stream.schemaRegistryClient")
|
||||
@ConfigurationProperties(prefix = "spring.cloud.stream.schema-registry-client")
|
||||
public class SchemaRegistryClientProperties {
|
||||
|
||||
private String endpoint;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-stream-test-support-internal</artifactId>
|
||||
<description>Set of classes and utility code that may assist in testing both
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-cloud-stream-test-support</artifactId>
|
||||
<description>A set of classes to ease testing of Spring Cloud Stream modules.</description>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -20,6 +20,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hamcrest.BaseMatcher;
|
||||
import org.hamcrest.Description;
|
||||
@@ -27,7 +28,6 @@ import org.hamcrest.Matcher;
|
||||
import org.hamcrest.SelfDescribing;
|
||||
|
||||
import org.springframework.cloud.stream.test.binder.TestSupportBinder;
|
||||
import org.springframework.integration.util.Function;
|
||||
import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
@@ -58,6 +58,7 @@ import org.springframework.messaging.Message;
|
||||
* </p>
|
||||
*
|
||||
* @author Eric Bottard
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class MessageQueueMatcher<T> extends BaseMatcher<BlockingQueue<Message<?>>> {
|
||||
|
||||
|
||||
@@ -4,15 +4,19 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>1.3.5.RELEASE</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-cloud-stream-tools</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<name>spring-cloud-stream-build-tools</name>
|
||||
<description>Spring Cloud Stream Build Tools</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>spring</id>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-parent</artifactId>
|
||||
<version>1.3.1.BUILD-SNAPSHOT</version>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2017 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.stream.aggregate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -34,11 +33,11 @@ import org.springframework.boot.actuate.endpoint.MetricReaderPublicMetrics;
|
||||
import org.springframework.boot.actuate.endpoint.MetricsEndpoint;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
|
||||
import org.springframework.boot.bind.PropertySourcesPropertyValues;
|
||||
import org.springframework.boot.bind.RelaxedDataBinder;
|
||||
import org.springframework.boot.bind.RelaxedNames;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.properties.bind.BindResult;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.binding.BindableProxyFactory;
|
||||
import org.springframework.cloud.stream.config.ChannelBindingAutoConfiguration;
|
||||
@@ -46,7 +45,7 @@ import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.env.PropertySources;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.integration.monitor.IntegrationMBeanExporter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -58,6 +57,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Marius Bogoevici
|
||||
* @author Venil Noronha
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@EnableBinding
|
||||
public class AggregateApplicationBuilder implements AggregateApplication, ApplicationContextAware,
|
||||
@@ -65,6 +65,9 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
|
||||
|
||||
private static final String CHILD_CONTEXT_SUFFIX = ".spring.cloud.stream.context";
|
||||
|
||||
private static final Bindable<Map<String, String>> STRING_STRING_MAP = Bindable
|
||||
.mapOf(String.class, String.class);
|
||||
|
||||
private SourceConfigurer sourceConfigurer;
|
||||
|
||||
private SinkConfigurer sinkConfigurer;
|
||||
@@ -194,18 +197,21 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
|
||||
Class<?> appToEmbed = appConfigurer.getApp();
|
||||
// Always update namespace before preparing SharedChannelRegistry
|
||||
if (appConfigurer.namespace == null) {
|
||||
// to remove illegal characters for new properties
|
||||
// binder
|
||||
// org.springframework.cloud.stream.aggregation.AggregationTest$TestSource
|
||||
appConfigurer.namespace = AggregateApplicationUtils
|
||||
.getDefaultNamespace(appConfigurer.getApp().getName(), i);
|
||||
.getDefaultNamespace(appConfigurer.getApp().getName().replaceAll("\\$", "."), i);
|
||||
}
|
||||
appsToEmbed.put(appToEmbed, appConfigurer.namespace);
|
||||
appConfigurers.put(appConfigurer, appConfigurer.namespace);
|
||||
}
|
||||
if (this.parentContext == null) {
|
||||
if (Boolean.TRUE.equals(this.webEnvironment)) {
|
||||
this.addParentSources(new Object[] { EmbeddedServletContainerAutoConfiguration.class });
|
||||
this.addParentSources(new Object[] { ServletWebServerFactoryAutoConfiguration.class });
|
||||
}
|
||||
this.parentContext = AggregateApplicationUtils.createParentContext(
|
||||
this.parentSources.toArray(new Object[0]),
|
||||
this.parentSources.toArray(new Class<?>[0]),
|
||||
this.parentArgs.toArray(new String[0]), selfContained(), this.webEnvironment, this.headless);
|
||||
}
|
||||
else {
|
||||
@@ -221,45 +227,25 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
|
||||
SharedBindingTargetRegistry sharedBindingTargetRegistry = this.parentContext
|
||||
.getBean(SharedBindingTargetRegistry.class);
|
||||
AggregateApplicationUtils.prepareSharedBindingTargetRegistry(sharedBindingTargetRegistry, appsToEmbed);
|
||||
PropertySources propertySources = this.parentContext.getEnvironment()
|
||||
.getPropertySources();
|
||||
for (Map.Entry<AppConfigurer, String> appConfigurerEntry : appConfigurers.entrySet()) {
|
||||
|
||||
AppConfigurer appConfigurer = appConfigurerEntry.getKey();
|
||||
if (appConfigurerEntry.getValue() == null) {
|
||||
continue;
|
||||
}
|
||||
String namespace = appConfigurerEntry.getValue().toLowerCase();
|
||||
Set<String> argsToUpdate = new LinkedHashSet<>();
|
||||
Set<String> argKeys = new LinkedHashSet<>();
|
||||
final HashMap<String, String> target = new HashMap<>();
|
||||
RelaxedDataBinder relaxedDataBinder = new RelaxedDataBinder(target, namespace);
|
||||
relaxedDataBinder.bind(new PropertySourcesPropertyValues(propertySources));
|
||||
Map<String, String> target = bindProperties(namespace, this.parentContext.getEnvironment());
|
||||
|
||||
if (!target.isEmpty()) {
|
||||
for (Map.Entry<String, String> entry : target.entrySet()) {
|
||||
// only update the values with the highest precedence level.
|
||||
if (!relaxedNameKeyExists(entry.getKey(), argKeys)) {
|
||||
String key = entry.getKey();
|
||||
// in case of environment variables pass the lower-case property
|
||||
// key
|
||||
// as we pass the properties as command line properties
|
||||
if (key.contains("_")) {
|
||||
key = key.replace("_", "-").toLowerCase();
|
||||
}
|
||||
argKeys.add(key);
|
||||
argsToUpdate.add("--" + key + "=" + entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add the args that are set at the application level if they weren't
|
||||
// overridden above from other property sources.
|
||||
if (appConfigurer.getArgs() != null) {
|
||||
for (String arg : appConfigurer.getArgs()) {
|
||||
// use the key part left to the assignment and trimming the prefix
|
||||
// `--`
|
||||
String key = arg.substring(0, arg.indexOf("=")).substring(2);
|
||||
if (!relaxedNameKeyExists(key, argKeys)) {
|
||||
argsToUpdate.add(arg);
|
||||
}
|
||||
String key = entry.getKey();
|
||||
argKeys.add(key);
|
||||
argsToUpdate.add("--" + key + "=" + entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (!argsToUpdate.isEmpty()) {
|
||||
appConfigurer.args(argsToUpdate.toArray(new String[0]));
|
||||
}
|
||||
@@ -279,21 +265,23 @@ public class AggregateApplicationBuilder implements AggregateApplication, Applic
|
||||
return (this.sourceConfigurer != null) && (this.sinkConfigurer != null);
|
||||
}
|
||||
|
||||
private boolean relaxedNameKeyExists(String key, Collection<String> collection) {
|
||||
RelaxedNames relaxedNames = new RelaxedNames(key);
|
||||
for (String name : relaxedNames) {
|
||||
if (collection.contains(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ChildContextBuilder childContext(Class<?> app, ConfigurableApplicationContext parentContext,
|
||||
String namespace) {
|
||||
return new ChildContextBuilder(AggregateApplicationUtils.embedApp(parentContext, namespace, app));
|
||||
}
|
||||
|
||||
private Map<String, String> bindProperties(String namepace, Environment environment) {
|
||||
Map<String, String> target;
|
||||
BindResult<Map<String, String>> bindResult = Binder.get(environment).bind(namepace, STRING_STRING_MAP);
|
||||
if (bindResult.isBound()) {
|
||||
target = bindResult.get();
|
||||
}
|
||||
else {
|
||||
target = new HashMap<>();
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
private static class ChildContextHolder {
|
||||
|
||||
private final ConfigurableApplicationContext childContext;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -32,6 +32,7 @@ import org.springframework.messaging.SubscribableChannel;
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Venil Noronha
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
abstract class AggregateApplicationUtils {
|
||||
|
||||
@@ -39,7 +40,7 @@ abstract class AggregateApplicationUtils {
|
||||
|
||||
public static final String OUTPUT_BINDING_NAME = "output";
|
||||
|
||||
static ConfigurableApplicationContext createParentContext(Object[] sources,
|
||||
static ConfigurableApplicationContext createParentContext(Class<?>[] sources,
|
||||
String[] args, final boolean selfContained, boolean webEnvironment,
|
||||
boolean headless) {
|
||||
SpringApplicationBuilder aggregatorParentConfiguration = new SpringApplicationBuilder();
|
||||
@@ -53,7 +54,7 @@ abstract class AggregateApplicationUtils {
|
||||
}
|
||||
|
||||
static String getDefaultNamespace(String appClassName, int index) {
|
||||
return appClassName + "_" + index;
|
||||
return appClassName + "-" + index;
|
||||
}
|
||||
|
||||
protected static SpringApplicationBuilder embedApp(
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.boot.bind.RelaxedDataBinder;
|
||||
import org.springframework.cloud.stream.binder.Binder;
|
||||
import org.springframework.cloud.stream.binder.BinderFactory;
|
||||
import org.springframework.cloud.stream.binder.Binding;
|
||||
@@ -39,6 +38,7 @@ import org.springframework.cloud.stream.binder.ProducerProperties;
|
||||
import org.springframework.cloud.stream.config.BindingServiceProperties;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.validation.DataBinder;
|
||||
import org.springframework.validation.beanvalidation.CustomValidatorBean;
|
||||
|
||||
/**
|
||||
@@ -49,6 +49,7 @@ import org.springframework.validation.beanvalidation.CustomValidatorBean;
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Gary Russell
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class BindingService {
|
||||
|
||||
@@ -149,7 +150,6 @@ public class BindingService {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> Binder<T, ?, ?> getBinder(String channelName, Class<T> bindableType) {
|
||||
String binderConfigurationName = this.bindingServiceProperties.getBinder(channelName);
|
||||
return binderFactory.getBinder(binderConfigurationName, bindableType);
|
||||
@@ -170,7 +170,7 @@ public class BindingService {
|
||||
}
|
||||
|
||||
private void validate(Object properties) {
|
||||
RelaxedDataBinder dataBinder = new RelaxedDataBinder(properties);
|
||||
DataBinder dataBinder = new DataBinder(properties);
|
||||
dataBinder.setValidator(validator);
|
||||
dataBinder.validate();
|
||||
if (dataBinder.getBindingResult().hasErrors()) {
|
||||
|
||||
@@ -21,9 +21,9 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.boot.bind.PropertySourcesPropertyValues;
|
||||
import org.springframework.boot.bind.RelaxedDataBinder;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class EnvironmentEntryInitializingTreeMap<T> extends AbstractMap<String, T> {
|
||||
|
||||
@@ -55,7 +56,7 @@ public class EnvironmentEntryInitializingTreeMap<T> extends AbstractMap<String,
|
||||
|
||||
/**
|
||||
* Constructs the map.
|
||||
*
|
||||
*
|
||||
* @param environment the environment that supplies the default property values
|
||||
* @param entryClass the entry class
|
||||
* @param defaultsPrefix the prefix for initializing the properties
|
||||
@@ -80,9 +81,7 @@ public class EnvironmentEntryInitializingTreeMap<T> extends AbstractMap<String,
|
||||
public T get(Object key) {
|
||||
if (!this.delegate.containsKey(key) && key instanceof String) {
|
||||
T entry = BeanUtils.instantiate(entryClass);
|
||||
RelaxedDataBinder defaultsDataBinder = new RelaxedDataBinder(entry, defaultsPrefix);
|
||||
defaultsDataBinder.setConversionService(this.conversionService);
|
||||
defaultsDataBinder.bind(new PropertySourcesPropertyValues(environment.getPropertySources()));
|
||||
Binder.get(environment).bind(defaultsPrefix, Bindable.ofInstance(entry));
|
||||
this.delegate.put((String) key, entry);
|
||||
}
|
||||
return this.delegate.get(key);
|
||||
@@ -90,6 +89,8 @@ public class EnvironmentEntryInitializingTreeMap<T> extends AbstractMap<String,
|
||||
|
||||
@Override
|
||||
public T put(String key, T value) {
|
||||
// boot 2 call this first
|
||||
Binder.get(environment).bind(defaultsPrefix, Bindable.ofInstance(value));
|
||||
return this.delegate.put(key, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.cloud.stream.aggregate.AggregateApplicationBuilder;
|
||||
import org.springframework.cloud.stream.aggregate.AggregateApplicationBuilder.SourceConfigurer;
|
||||
import org.springframework.cloud.stream.aggregate.SharedBindingTargetRegistry;
|
||||
@@ -46,12 +46,15 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Artem Bilan
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class AggregationTest {
|
||||
|
||||
@@ -61,8 +64,8 @@ public class AggregationTest {
|
||||
public void closeContext() {
|
||||
System.clearProperty("a.foo-value");
|
||||
System.clearProperty("c.fooValue");
|
||||
System.clearProperty("a_FOO_VALUE");
|
||||
System.clearProperty("C_FOO_VALUE");
|
||||
System.clearProperty("a.foo.value");
|
||||
System.clearProperty("c.foo.value");
|
||||
if (aggregatedApplicationContext != null) {
|
||||
aggregatedApplicationContext.close();
|
||||
}
|
||||
@@ -122,7 +125,7 @@ public class AggregationTest {
|
||||
List<Object> sources = (List<Object>) aggregateApplicationBuilderAccessor.getPropertyValue("parentSources");
|
||||
assertThat(sources).containsExactlyInAnyOrder(AggregateApplicationBuilder.ParentConfiguration.class,
|
||||
MockBinderRegistryConfiguration.class, DummyConfig.class,
|
||||
EmbeddedServletContainerAutoConfiguration.class);
|
||||
ServletWebServerFactoryAutoConfiguration.class);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -228,8 +231,7 @@ public class AggregationTest {
|
||||
new String[] { "--foo-value=barb" }));
|
||||
}
|
||||
if (processorConfigurer.getNamespace().equals("c")) {
|
||||
assertTrue(Arrays.equals(processorConfigurer.getArgs(),
|
||||
new String[] { "--foo1=barc" }));
|
||||
assertThat(processorConfigurer.getArgs(), is(new String[] { "--foo1=barc" }));
|
||||
}
|
||||
}
|
||||
aggregatedApplicationContext.close();
|
||||
@@ -251,9 +253,8 @@ public class AggregationTest {
|
||||
assertTrue(Arrays.equals(
|
||||
((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer"))
|
||||
.getArgs(),
|
||||
new String[] { "--fooValue=bara" }));
|
||||
final List<AggregateApplicationBuilder.ProcessorConfigurer> processorConfigurers =
|
||||
(List<AggregateApplicationBuilder.ProcessorConfigurer>) aggregateApplicationBuilderAccessor
|
||||
new String[] { "--fooValue=bara", "--foo-value=bara" }));
|
||||
final List<AggregateApplicationBuilder.ProcessorConfigurer> processorConfigurers = (List<AggregateApplicationBuilder.ProcessorConfigurer>) aggregateApplicationBuilderAccessor
|
||||
.getPropertyValue("processorConfigurers");
|
||||
for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : processorConfigurers) {
|
||||
if (processorConfigurer.getNamespace().equals("b")) {
|
||||
@@ -285,8 +286,7 @@ public class AggregationTest {
|
||||
((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer"))
|
||||
.getArgs(),
|
||||
new String[] { "--foo-value=sysbara" }));
|
||||
for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer :
|
||||
((List<AggregateApplicationBuilder.ProcessorConfigurer>) aggregateApplicationBuilderAccessor
|
||||
for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : ((List<AggregateApplicationBuilder.ProcessorConfigurer>) aggregateApplicationBuilderAccessor
|
||||
.getPropertyValue(
|
||||
"processorConfigurers"))) {
|
||||
if (processorConfigurer.getNamespace().equals("b")) {
|
||||
@@ -306,18 +306,17 @@ public class AggregationTest {
|
||||
public void testNamespacePrefixesWithCAPSProperties() {
|
||||
AggregateApplicationBuilder aggregateApplicationBuilder = new AggregateApplicationBuilder(
|
||||
MockBinderRegistryConfiguration.class);
|
||||
System.setProperty("a_FOO_VALUE", "sysbara");
|
||||
System.setProperty("C_FOO_VALUE", "sysbarc");
|
||||
System.setProperty("a.fooValue", "sysbara");
|
||||
System.setProperty("c.fooValue", "sysbarc");
|
||||
aggregatedApplicationContext = aggregateApplicationBuilder.parent(DummyConfig.class).from(TestSource.class)
|
||||
.namespace("a").args("--foo-value=bar")
|
||||
.via(TestProcessor.class).namespace("b").args("--fooValue=argbarb")
|
||||
.via(TestProcessor.class).namespace("c").args("--foo-value=argbarc")
|
||||
.run("--a.fooValue=highest");
|
||||
DirectFieldAccessor aggregateApplicationBuilderAccessor = new DirectFieldAccessor(aggregateApplicationBuilder);
|
||||
assertTrue(Arrays.equals(
|
||||
assertThat(
|
||||
((SourceConfigurer) aggregateApplicationBuilderAccessor.getPropertyValue("sourceConfigurer"))
|
||||
.getArgs(),
|
||||
new String[] { "--fooValue=highest" }));
|
||||
.getArgs()).containsExactly(new String[] { "--fooValue=highest" });
|
||||
final List<AggregateApplicationBuilder.ProcessorConfigurer> processorConfigurers = (List<AggregateApplicationBuilder.ProcessorConfigurer>) aggregateApplicationBuilderAccessor
|
||||
.getPropertyValue("processorConfigurers");
|
||||
for (AggregateApplicationBuilder.ProcessorConfigurer processorConfigurer : processorConfigurers) {
|
||||
@@ -327,7 +326,7 @@ public class AggregationTest {
|
||||
}
|
||||
if (processorConfigurer.getNamespace().equals("c")) {
|
||||
assertTrue(Arrays.equals(processorConfigurer.getArgs(),
|
||||
new String[] { "--foo-value=sysbarc" }));
|
||||
new String[] { "--fooValue=sysbarc" }));
|
||||
}
|
||||
}
|
||||
aggregatedApplicationContext.close();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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,13 +30,14 @@ import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = ArbitraryInterfaceWithBindingTargetsTests.TestFooChannels.class)
|
||||
@@ -45,17 +46,16 @@ public class ArbitraryInterfaceWithBindingTargetsTests {
|
||||
@Autowired
|
||||
public FooChannels fooChannels;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Test
|
||||
public void testArbitraryInterfaceChannelsBound() {
|
||||
Binder binder = binderFactory.getBinder(null, MessageChannel.class);
|
||||
verify(binder).bindConsumer(eq("someQueue.0"), anyString(), eq(this.fooChannels.foo()),
|
||||
verify(binder).bindConsumer(eq("someQueue.0"), isNull(), eq(this.fooChannels.foo()),
|
||||
Mockito.<ConsumerProperties>any());
|
||||
verify(binder).bindConsumer(eq("someQueue.1"), anyString(), eq(this.fooChannels.bar()),
|
||||
verify(binder).bindConsumer(eq("someQueue.1"), isNull(), eq(this.fooChannels.bar()),
|
||||
Mockito.<ConsumerProperties>any());
|
||||
verify(binder).bindProducer(eq("someQueue.2"), eq(this.fooChannels.baz()),
|
||||
Mockito.<ProducerProperties>any());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -29,13 +29,14 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = ArbitraryInterfaceWithDefaultsTests.TestFooChannels.class)
|
||||
@@ -44,17 +45,16 @@ public class ArbitraryInterfaceWithDefaultsTests {
|
||||
@Autowired
|
||||
public FooChannels fooChannels;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Test
|
||||
public void testArbitraryInterfaceChannelsBound() {
|
||||
final Binder binder = this.binderFactory.getBinder(null, MessageChannel.class);
|
||||
verify(binder).bindConsumer(eq("foo"), anyString(), eq(this.fooChannels.foo()),
|
||||
verify(binder).bindConsumer(eq("foo"), isNull(), eq(this.fooChannels.foo()),
|
||||
Mockito.<ConsumerProperties>any());
|
||||
verify(binder).bindConsumer(eq("bar"), anyString(), eq(this.fooChannels.bar()),
|
||||
verify(binder).bindConsumer(eq("bar"), isNull(), eq(this.fooChannels.bar()),
|
||||
Mockito.<ConsumerProperties>any());
|
||||
verify(binder).bindProducer(eq("baz"), eq(this.fooChannels.baz()),
|
||||
Mockito.<ProducerProperties>any());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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,7 +23,7 @@ import java.net.URLClassLoader;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.binder.stub1.StubBinder1;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -33,14 +33,15 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class InputOutputBindingOrderTest {
|
||||
|
||||
@@ -52,7 +53,7 @@ public class InputOutputBindingOrderTest {
|
||||
Binder binder = applicationContext.getBean(BinderFactory.class).getBinder(null, MessageChannel.class);
|
||||
Processor processor = applicationContext.getBean(Processor.class);
|
||||
// input is bound after the context has been started
|
||||
verify(binder).bindConsumer(eq("input"), anyString(), eq(processor.input()), Mockito.<ConsumerProperties>any());
|
||||
verify(binder).bindConsumer(eq("input"), isNull(), eq(processor.input()), Mockito.<ConsumerProperties>any());
|
||||
SomeLifecycle someLifecycle = applicationContext.getBean(SomeLifecycle.class);
|
||||
assertThat(someLifecycle.isRunning());
|
||||
applicationContext.close();
|
||||
@@ -73,7 +74,6 @@ public class InputOutputBindingOrderTest {
|
||||
|
||||
public static class SomeLifecycle implements SmartLifecycle {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@@ -83,7 +83,7 @@ public class InputOutputBindingOrderTest {
|
||||
private boolean running;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public synchronized void start() {
|
||||
Binder binder = this.binderFactory.getBinder(null, MessageChannel.class);
|
||||
verify(binder).bindProducer(eq("output"), eq(this.processor.output()), Mockito.<ProducerProperties>any());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -31,29 +31,29 @@ import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = ProcessorBindingWithBindingTargetsTests.TestProcessor.class)
|
||||
public class ProcessorBindingWithBindingTargetsTests {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@Autowired
|
||||
private Processor testProcessor;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Test
|
||||
public void testSourceOutputChannelBound() {
|
||||
final Binder binder = binderFactory.getBinder(null, MessageChannel.class);
|
||||
verify(binder).bindConsumer(eq("testtock.0"), anyString(),
|
||||
verify(binder).bindConsumer(eq("testtock.0"), isNull(),
|
||||
eq(this.testProcessor.input()), Mockito.<ConsumerProperties>any());
|
||||
verify(binder).bindProducer(eq("testtock.1"), eq(this.testProcessor.output()),
|
||||
Mockito.<ProducerProperties>any());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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,29 +30,29 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = ProcessorBindingsWithDefaultsTests.TestProcessor.class)
|
||||
public class ProcessorBindingsWithDefaultsTests {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@Autowired
|
||||
private Processor processor;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Test
|
||||
public void testSourceOutputChannelBound() {
|
||||
Binder binder = this.binderFactory.getBinder(null, MessageChannel.class);
|
||||
Mockito.verify(binder).bindConsumer(eq("input"), anyString(), eq(this.processor.input()),
|
||||
Mockito.verify(binder).bindConsumer(eq("input"), isNull(), eq(this.processor.input()),
|
||||
Mockito.<ConsumerProperties>any());
|
||||
Mockito.verify(binder).bindProducer(eq("output"), eq(this.processor.output()),
|
||||
Mockito.<ProducerProperties>any());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -31,30 +31,31 @@ import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Janne Valkealahti
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = SinkBindingWithDefaultTargetsTests.TestSink.class)
|
||||
public class SinkBindingWithDefaultTargetsTests {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@Autowired
|
||||
private Sink testSink;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Test
|
||||
public void testSourceOutputChannelBound() {
|
||||
Binder binder = binderFactory.getBinder(null, MessageChannel.class);
|
||||
verify(binder).bindConsumer(eq("testtock"), anyString(), eq(this.testSink.input()),
|
||||
verify(binder).bindConsumer(eq("testtock"), isNull(), eq(this.testSink.input()),
|
||||
Mockito.<ConsumerProperties>any());
|
||||
verifyNoMoreInteractions(binder);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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,30 +30,30 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = SinkBindingWithDefaultsTests.TestSink.class)
|
||||
public class SinkBindingWithDefaultsTests {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@Autowired
|
||||
private Sink testSink;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Test
|
||||
public void testSourceOutputChannelBound() {
|
||||
Binder binder = binderFactory.getBinder(null, MessageChannel.class);
|
||||
verify(binder).bindConsumer(eq("input"), anyString(), eq(this.testSink.input()),
|
||||
verify(binder).bindConsumer(eq("input"), isNull(), eq(this.testSink.input()),
|
||||
Mockito.<ConsumerProperties>any());
|
||||
verifyNoMoreInteractions(binder);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -69,6 +69,7 @@ import static org.mockito.Mockito.when;
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
public class BindingServiceTests {
|
||||
|
||||
@@ -223,7 +224,7 @@ public class BindingServiceTests {
|
||||
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
dynamic.set(invocation.getArgumentAt(1, MessageChannel.class));
|
||||
dynamic.set(invocation.getArgument(1));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
* Copyright 2015-2017 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.
|
||||
@@ -39,20 +39,20 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Janne Valkealahti
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = PartitionedConsumerTest.TestSink.class)
|
||||
public class PartitionedConsumerTest {
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@@ -61,11 +61,11 @@ public class PartitionedConsumerTest {
|
||||
private Sink testSink;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void testBindingPartitionedConsumer() {
|
||||
Binder binder = this.binderFactory.getBinder(null, MessageChannel.class);
|
||||
ArgumentCaptor<ConsumerProperties> argumentCaptor = ArgumentCaptor.forClass(ConsumerProperties.class);
|
||||
verify(binder).bindConsumer(eq("partIn"), anyString(), eq(this.testSink.input()),
|
||||
verify(binder).bindConsumer(eq("partIn"), isNull(), eq(this.testSink.input()),
|
||||
argumentCaptor.capture());
|
||||
Assert.assertThat(argumentCaptor.getValue().getInstanceIndex(), equalTo(0));
|
||||
Assert.assertThat(argumentCaptor.getValue().getInstanceCount(), equalTo(2));
|
||||
@@ -80,9 +80,10 @@ public class PartitionedConsumerTest {
|
||||
|
||||
}
|
||||
|
||||
class PropertiesArgumentMatcher extends ArgumentMatcher<ConsumerProperties> {
|
||||
class PropertiesArgumentMatcher implements ArgumentMatcher<ConsumerProperties> {
|
||||
|
||||
@Override
|
||||
public boolean matches(Object argument) {
|
||||
public boolean matches(ConsumerProperties argument) {
|
||||
return argument instanceof ConsumerProperties;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user