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:
Janne Valkealahti
2017-05-12 10:43:01 +01:00
committed by Soby Chacko
parent e2c214b34e
commit 4f72a10bc6
39 changed files with 244 additions and 418 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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)

View File

@@ -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));
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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();

View File

@@ -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>

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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<?>>> {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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.

View File

@@ -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;

View File

@@ -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(

View File

@@ -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()) {

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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());

View File

@@ -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());

View File

@@ -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;

View File

@@ -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());

View File

@@ -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());

View File

@@ -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());

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}
}