├── README.md ├── .mvn ├── jvm.config ├── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties └── maven.config ├── README.adoc ├── common ├── stream-apps-metadata-store-common │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ └── META-INF │ │ │ │ │ └── spring.factories │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── cloud │ │ │ │ └── stream │ │ │ │ └── app │ │ │ │ └── metadata │ │ │ │ ├── ClientCacheAutoConfiguration.java │ │ │ │ └── MetadataStoreProperties.java │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── stream │ │ │ └── app │ │ │ └── metadata │ │ │ └── MetadataStoreAutoConfigurationTests.java │ ├── pom.xml │ └── README.adoc ├── stream-apps-task-launch-request-common │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ └── META-INF │ │ │ │ │ ├── spring-configuration-metadata-whitelist.properties │ │ │ │ │ └── spring.factories │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── cloud │ │ │ │ └── stream │ │ │ │ └── app │ │ │ │ └── tasklaunchrequest │ │ │ │ ├── support │ │ │ │ ├── TaskNameMessageMapper.java │ │ │ │ ├── CommandLineArgumentsMessageMapper.java │ │ │ │ └── TaskLaunchRequestSupplier.java │ │ │ │ ├── TaskLaunchRequestFunction.java │ │ │ │ ├── ExpressionEvaluatingTaskNameMessageMapper.java │ │ │ │ ├── KeyValueListParser.java │ │ │ │ ├── DataFlowTaskLaunchRequest.java │ │ │ │ ├── TaskLaunchRequestMessageProcessor.java │ │ │ │ ├── DataflowTaskLaunchRequestProperties.java │ │ │ │ └── DataFlowTaskLaunchRequestAutoConfiguration.java │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── stream │ │ │ └── app │ │ │ └── tasklaunchrequest │ │ │ ├── TaskLaunchRequestPropertiesTests.java │ │ │ └── KeyValueListParserTests.java │ ├── pom.xml │ └── README.adoc ├── stream-apps-security-common │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ └── META-INF │ │ │ │ │ └── spring.factories │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── cloud │ │ │ │ └── stream │ │ │ │ └── app │ │ │ │ └── security │ │ │ │ └── common │ │ │ │ ├── OnHttpCsrfOrSecurityDisabled.java │ │ │ │ ├── AppStarterWebSecurityAutoConfigurationProperties.java │ │ │ │ ├── AppStarterWebFluxSecurityAutoConfiguration.java │ │ │ │ └── AppStarterWebSecurityAutoConfiguration.java │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── stream │ │ │ └── app │ │ │ └── security │ │ │ └── common │ │ │ ├── AbstractSecurityCommonTests.java │ │ │ ├── ReactiveSecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java │ │ │ ├── ReactiveSecurityDisabledManagementSecurityEnabledTests.java │ │ │ ├── SecurityDisabledManagementSecurityEnabledTests.java │ │ │ ├── ReactiveSecurityEnabledManagementSecurityEnabledTests.java │ │ │ ├── SecurityEnabledManagementSecurityEnabledTests.java │ │ │ ├── SecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java │ │ │ ├── ReactiveSecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java │ │ │ └── SecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java │ ├── pom.xml │ └── README.adoc ├── stream-apps-micrometer-common │ ├── src │ │ ├── test │ │ │ ├── resources │ │ │ │ └── org │ │ │ │ │ └── springframework │ │ │ │ │ └── cloud │ │ │ │ │ └── stream │ │ │ │ │ └── app │ │ │ │ │ └── micrometer │ │ │ │ │ └── common │ │ │ │ │ └── pcf-scs-info.json │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── cloud │ │ │ │ └── stream │ │ │ │ └── app │ │ │ │ └── micrometer │ │ │ │ └── common │ │ │ │ ├── InfluxReservedKeywordHandlingTest.java │ │ │ │ ├── SpringCloudStreamMicrometerCommonTagsTest.java │ │ │ │ ├── AbstractMicrometerTagTest.java │ │ │ │ ├── CloudFoundryMicrometerCommonTagsTest.java │ │ │ │ └── SpringCloudStreamMicrometerEnvironmentPostProcessorTest.java │ │ └── main │ │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── spring.factories │ │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── stream │ │ │ └── app │ │ │ └── micrometer │ │ │ └── common │ │ │ ├── SpringCloudStreamMicrometerEnvironmentPostProcessor.java │ │ │ ├── CloudFoundryMicrometerCommonTags.java │ │ │ └── SpringCloudStreamMicrometerCommonTags.java │ └── pom.xml ├── stream-apps-file-common │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── springframework │ │ └── cloud │ │ └── stream │ │ └── app │ │ └── file │ │ ├── FileReadingMode.java │ │ ├── remote │ │ ├── AbstractRemoteFileProperties.java │ │ ├── FilePathUtils.java │ │ ├── AbstractRemoteServerProperties.java │ │ ├── RemoteFileDeletingTransactionSynchronizationProcessor.java │ │ ├── AbstractRemoteFileSinkProperties.java │ │ └── AbstractRemoteFileSourceProperties.java │ │ ├── FileConsumerProperties.java │ │ └── FileUtils.java ├── stream-apps-postprocessor-common │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── springframework │ │ └── cloud │ │ └── stream │ │ └── app │ │ └── postprocessor │ │ └── ContentTypeEnvironmentPostProcessor.java ├── stream-apps-ftp-common │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── org │ │ └── springframework │ │ └── cloud │ │ └── stream │ │ └── app │ │ └── ftp │ │ ├── FtpSessionFactoryConfiguration.java │ │ └── FtpSessionFactoryProperties.java ├── pom.xml └── stream-apps-test-support │ ├── pom.xml │ └── src │ └── main │ └── java │ └── org │ └── springframework │ └── cloud │ └── stream │ └── app │ └── test │ ├── PropertiesInitializer.java │ ├── ip │ ├── IpSinkTestConfiguration.java │ └── IpSourceTestConfiguration.java │ ├── script │ └── ScriptableTestConfiguration.java │ ├── redis │ └── RedisTestSupport.java │ ├── BinderTestPropertiesInitializer.java │ └── file │ └── remote │ └── RemoteFileTestSupport.java ├── .gitignore ├── CODE_OF_CONDUCT.adoc ├── .settings.xml ├── mvnw.cmd └── mvnw /README.md: -------------------------------------------------------------------------------- 1 | # core is no longer actively maintained by VMware, Inc. 2 | 3 | -------------------------------------------------------------------------------- /.mvn/jvm.config: -------------------------------------------------------------------------------- 1 | -Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-attic/core/main/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring 2 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip 2 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | #Core components shared by other projects in the app starters organization 2 | This module consists of core dependencies and other common artifacts. 3 | -------------------------------------------------------------------------------- /common/stream-apps-metadata-store-common/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.springframework.cloud.stream.app.metadata.MetadataStoreAutoConfiguration 3 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/resources/META-INF/spring-configuration-metadata-whitelist.properties: -------------------------------------------------------------------------------- 1 | configuration-properties.classes=\ 2 | org.springframework.cloud.stream.app.tasklaunchrequest.DataflowTaskLaunchRequestProperties 3 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.springframework.cloud.stream.app.tasklaunchrequest.DataFlowTaskLaunchRequestAutoConfiguration 3 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.springframework.cloud.stream.app.security.common.AppStarterWebSecurityAutoConfiguration,\ 3 | org.springframework.cloud.stream.app.security.common.AppStarterWebFluxSecurityAutoConfiguration 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | apps/ 2 | /application.yml 3 | /application.properties 4 | asciidoctor.css 5 | *~ 6 | .#* 7 | *# 8 | target/ 9 | build/ 10 | bin/ 11 | _site/ 12 | .classpath 13 | .project 14 | .settings 15 | .springBeans 16 | .DS_Store 17 | *.sw* 18 | *.iml 19 | *.ipr 20 | *.iws 21 | .idea/ 22 | .factorypath 23 | spring-xd-samples/*/xd 24 | dump.rdb 25 | coverage-error.log 26 | .apt_generated 27 | aws.credentials.properties 28 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/test/resources/org/springframework/cloud/stream/app/micrometer/common/pcf-scs-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "sso":[{ 3 | "name": "sso", 4 | "label": "sso", 5 | "plan": "notfree", 6 | "tags": ["configuration"], 7 | "credentials":{ 8 | "uri": "https://pivotal.io", 9 | "client_id": "fakeClientId", 10 | "client_secret": "fakeSecret", 11 | "access_token_uri": "token" 12 | } 13 | }]} 14 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | org.springframework.cloud.stream.app.micrometer.common.SpringCloudStreamMicrometerCommonTags,\ 3 | org.springframework.cloud.stream.app.micrometer.common.CloudFoundryMicrometerCommonTags 4 | org.springframework.boot.env.EnvironmentPostProcessor=\ 5 | org.springframework.cloud.stream.app.micrometer.common.SpringCloudStreamMicrometerEnvironmentPostProcessor 6 | 7 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | stream-apps-common 5 | org.springframework.cloud.stream.app 6 | 3.0.0.BUILD-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | stream-apps-file-common 11 | stream-apps-file-common 12 | 13 | 14 | 15 | org.springframework.integration 16 | spring-integration-file 17 | true 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /common/stream-apps-postprocessor-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | stream-apps-common 6 | org.springframework.cloud.stream.app 7 | 3.0.0.BUILD-SNAPSHOT 8 | 9 | 4.0.0 10 | 11 | stream-apps-postprocessor-common 12 | stream-apps-postprocessor-common 13 | 14 | 15 | 16 | org.springframework.integration 17 | spring-integration-test 18 | test 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /common/stream-apps-ftp-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | stream-apps-common 5 | org.springframework.cloud.stream.app 6 | 3.0.0.BUILD-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | stream-apps-ftp-common 11 | stream-apps-ftp-common 12 | 13 | 14 | 15 | org.springframework.integration 16 | spring-integration-ftp 17 | true 18 | 19 | 20 | org.springframework.cloud.stream.app 21 | stream-apps-file-common 22 | ${project.version} 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | stream-apps-parent 5 | org.springframework.cloud.stream.app 6 | 3.0.0.BUILD-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | stream-apps-common 11 | pom 12 | stream-apps-common 13 | 14 | 15 | stream-apps-file-common 16 | stream-apps-ftp-common 17 | stream-apps-test-support 18 | stream-apps-postprocessor-common 19 | stream-apps-micrometer-common 20 | stream-apps-metadata-store-common 21 | stream-apps-task-launch-request-common 22 | stream-apps-security-common 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/support/TaskNameMessageMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest.support; 18 | 19 | import org.springframework.integration.handler.MessageProcessor; 20 | 21 | @FunctionalInterface 22 | public interface TaskNameMessageMapper extends MessageProcessor { 23 | } 24 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/support/CommandLineArgumentsMessageMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest.support; 18 | 19 | import java.util.Collection; 20 | import org.springframework.integration.handler.MessageProcessor; 21 | 22 | public interface CommandLineArgumentsMessageMapper extends MessageProcessor> { 23 | } 24 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/src/main/java/org/springframework/cloud/stream/app/file/FileReadingMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 the original author or authors. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.springframework.cloud.stream.app.file; 17 | 18 | 19 | /** 20 | * Defines the supported modes of reading and processing files for the 21 | * {@code File}, {@code FTP} and {@code SFTP} sources. 22 | * 23 | * @author Gunnar Hillert 24 | * @author David Turanski 25 | */ 26 | public enum FileReadingMode { 27 | ref, 28 | lines, 29 | contents; 30 | } 31 | -------------------------------------------------------------------------------- /common/stream-apps-test-support/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | stream-apps-common 5 | org.springframework.cloud.stream.app 6 | 3.0.0.BUILD-SNAPSHOT 7 | 8 | 4.0.0 9 | 10 | stream-apps-test-support 11 | 12 | 13 | 14 | org.springframework.integration 15 | spring-integration-test 16 | 17 | 18 | org.springframework.integration 19 | spring-integration-test-support 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-data-redis 24 | true 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestFunction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest; 18 | 19 | import java.util.function.Function; 20 | 21 | import org.springframework.messaging.Message; 22 | 23 | /** 24 | * A marker interface useful for unambiguous dependency injection of this Function. 25 | * 26 | * @author David Turanski 27 | **/ 28 | @FunctionalInterface 29 | public interface TaskLaunchRequestFunction extends Function, Message> { 30 | 31 | } 32 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | stream-apps-common 7 | org.springframework.cloud.stream.app 8 | 3.0.0.BUILD-SNAPSHOT 9 | 10 | 4.0.0 11 | stream-apps-micrometer-common 12 | 13 | 14 | 15 | io.micrometer 16 | micrometer-core 17 | 18 | 19 | io.micrometer 20 | micrometer-registry-influx 21 | test 22 | 23 | 24 | io.pivotal.cfenv 25 | java-cfenv-test-support 26 | test 27 | 2.1.1.RELEASE 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-actuator 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /common/stream-apps-test-support/src/main/java/org/springframework/cloud/stream/app/test/PropertiesInitializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2016 the original author or authors. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.springframework.cloud.stream.app.test; 17 | 18 | import java.util.Properties; 19 | 20 | import org.springframework.context.ApplicationContextInitializer; 21 | import org.springframework.context.ConfigurableApplicationContext; 22 | import org.springframework.core.env.PropertiesPropertySource; 23 | 24 | /** 25 | * @author David Turanski 26 | */ 27 | public class PropertiesInitializer implements ApplicationContextInitializer { 28 | 29 | public static Properties PROPERTIES; 30 | 31 | @Override 32 | public void initialize(ConfigurableApplicationContext configurableApplicationContext) { 33 | configurableApplicationContext.getEnvironment().getPropertySources().addLast(new 34 | PropertiesPropertySource("applicationOptions", PROPERTIES)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/AbstractSecurityCommonTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import org.springframework.beans.factory.annotation.Autowired; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | import org.springframework.boot.test.context.SpringBootTest; 22 | import org.springframework.boot.test.web.client.TestRestTemplate; 23 | import org.springframework.test.annotation.DirtiesContext; 24 | 25 | /** 26 | * @author Christian Tzolov 27 | * @author Artem Bilan 28 | */ 29 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 30 | @DirtiesContext 31 | public abstract class AbstractSecurityCommonTests { 32 | 33 | @Autowired 34 | protected TestRestTemplate restTemplate; 35 | 36 | @SpringBootApplication 37 | public static class AutoConfigurationApplication { 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | stream-apps-common 7 | org.springframework.cloud.stream.app 8 | 3.0.0.BUILD-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | stream-apps-task-launch-request-common 13 | stream-apps-task-launch-request-common 14 | 15 | 16 | 17 | org.springframework.cloud.stream.app 18 | stream-apps-file-common 19 | ${project.version} 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-test 24 | test 25 | 26 | 27 | org.springframework.cloud 28 | spring-cloud-stream 29 | test-jar 30 | test 31 | test-binder 32 | 33 | 34 | org.springframework.cloud 35 | spring-cloud-stream 36 | 37 | 38 | 39 | org.springframework.cloud 40 | spring-cloud-stream-test-support 41 | test 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /common/stream-apps-test-support/src/main/java/org/springframework/cloud/stream/app/test/ip/IpSinkTestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.test.ip; 18 | 19 | import java.util.Properties; 20 | 21 | import org.springframework.cloud.stream.app.test.BinderTestPropertiesInitializer; 22 | import org.springframework.context.ConfigurableApplicationContext; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | /** 27 | * Generated app test configuration for the IP (TCP) sink. 28 | * 29 | * @author Gary Russell 30 | * 31 | */ 32 | @Configuration 33 | public class IpSinkTestConfiguration { 34 | 35 | @Bean 36 | public static BinderTestPropertiesInitializer loadProps(ConfigurableApplicationContext context) { 37 | // minimal properties for the context to load 38 | Properties properties = new Properties(); 39 | properties.put("host", "localhost"); 40 | return new BinderTestPropertiesInitializer(context, properties); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /common/stream-apps-test-support/src/main/java/org/springframework/cloud/stream/app/test/ip/IpSourceTestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.test.ip; 18 | 19 | import java.util.Properties; 20 | 21 | import org.springframework.cloud.stream.app.test.BinderTestPropertiesInitializer; 22 | import org.springframework.context.ConfigurableApplicationContext; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | /** 27 | * Generated app test configuration for IP (TCP, UDP) sources. 28 | * 29 | * @author Gary Russell 30 | * 31 | */ 32 | @Configuration 33 | public class IpSourceTestConfiguration { 34 | 35 | @Bean 36 | public static BinderTestPropertiesInitializer loadProps(ConfigurableApplicationContext context) { 37 | // minimal properties for the context to load 38 | Properties properties = new Properties(); 39 | properties.put("port", 0); 40 | return new BinderTestPropertiesInitializer(context, properties); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /common/stream-apps-test-support/src/main/java/org/springframework/cloud/stream/app/test/script/ScriptableTestConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.test.script; 18 | 19 | import java.util.Properties; 20 | 21 | import org.springframework.cloud.stream.app.test.BinderTestPropertiesInitializer; 22 | import org.springframework.context.ConfigurableApplicationContext; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | 26 | /** 27 | * Test configuration for generated scriptable apps. 28 | * 29 | * @author Gary Russell 30 | * 31 | */ 32 | @Configuration 33 | public class ScriptableTestConfiguration { 34 | 35 | @Bean 36 | public BinderTestPropertiesInitializer loadProps(ConfigurableApplicationContext context) { 37 | // minimal properties for the context to load 38 | Properties properties = new Properties(); 39 | properties.put("script", "foo"); 40 | properties.put("language", "ruby"); 41 | return new BinderTestPropertiesInitializer(context, properties); 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/OnHttpCsrfOrSecurityDisabled.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 21 | 22 | /** 23 | * An {@link AnyNestedCondition} to enable app starters-specific security auto-configuration 24 | * overriding out-of-the-box one in Spring Boot. 25 | * 26 | * @author Artem Bilan 27 | * 28 | * @since 3.0 29 | */ 30 | class OnHttpCsrfOrSecurityDisabled extends AnyNestedCondition { 31 | 32 | OnHttpCsrfOrSecurityDisabled() { 33 | super(ConfigurationPhase.PARSE_CONFIGURATION); 34 | } 35 | 36 | @ConditionalOnProperty(name = "spring.cloud.streamapp.security.enabled", havingValue = "false") 37 | static class SecurityDisabled { 38 | } 39 | 40 | @ConditionalOnProperty(name = "spring.cloud.streamapp.security.csrf-enabled", havingValue = "false") 41 | static class HttpCsrfDisabled { 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/ExpressionEvaluatingTaskNameMessageMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest; 18 | 19 | import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskNameMessageMapper; 20 | import org.springframework.expression.EvaluationContext; 21 | import org.springframework.expression.Expression; 22 | import org.springframework.messaging.Message; 23 | 24 | public class ExpressionEvaluatingTaskNameMessageMapper implements TaskNameMessageMapper { 25 | 26 | private final Expression expression; 27 | private final EvaluationContext evaluationContext; 28 | 29 | public ExpressionEvaluatingTaskNameMessageMapper(Expression expression, EvaluationContext evaluationContext) { 30 | this.evaluationContext = evaluationContext; 31 | this.expression = expression; 32 | } 33 | 34 | @Override 35 | public String processMessage(Message message) { 36 | return expression.getValue(evaluationContext, message).toString(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /common/stream-apps-test-support/src/main/java/org/springframework/cloud/stream/app/test/redis/RedisTestSupport.java: -------------------------------------------------------------------------------- 1 | ///* 2 | // * Copyright 2016 the original author or authors. 3 | // * 4 | // * Licensed under the Apache License, Version 2.0 (the "License"); 5 | // * you may not use this file except in compliance with the License. 6 | // * You may obtain a copy of the License at 7 | // * 8 | // * https://www.apache.org/licenses/LICENSE-2.0 9 | // * 10 | // * Unless required by applicable law or agreed to in writing, software 11 | // * distributed under the License is distributed on an "AS IS" BASIS, 12 | // * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // * See the License for the specific language governing permissions and 14 | // * limitations under the License. 15 | // */ 16 | // 17 | //package org.springframework.cloud.stream.app.test.redis; 18 | // 19 | //import org.springframework.cloud.stream.test.junit.AbstractExternalResourceTestSupport; 20 | //import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; 21 | // 22 | ///** 23 | // * Porting from https://github.com/spring-cloud/spring-cloud-stream/blob/1.0.x/spring-cloud-stream-test-support-internal 24 | // * 25 | // * @author Soby Chacko 26 | // */ 27 | //public class RedisTestSupport extends AbstractExternalResourceTestSupport { 28 | // 29 | // public RedisTestSupport() { 30 | // super("REDIS"); 31 | // } 32 | // @Override 33 | // protected void cleanupResource() throws Exception { 34 | // resource.destroy(); 35 | // } 36 | // 37 | // @Override 38 | // protected void obtainResource() throws Exception { 39 | // resource = new LettuceConnectionFactory(); 40 | // resource.afterPropertiesSet(); 41 | // resource.getConnection().close(); 42 | // } 43 | //} 44 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebSecurityAutoConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.springframework.cloud.stream.app.security.common; 17 | 18 | import org.springframework.boot.context.properties.ConfigurationProperties; 19 | 20 | /** 21 | * {@code AppStarterWebSecurityAutoConfiguration} properties. 22 | * 23 | * @author Christian Tzolov 24 | * @author Artem Bilan 25 | * 26 | * @since 2.1 27 | */ 28 | @ConfigurationProperties("spring.cloud.streamapp.security") 29 | public class AppStarterWebSecurityAutoConfigurationProperties { 30 | 31 | 32 | /** 33 | * The security enabling flag. 34 | */ 35 | private boolean enabled = true; 36 | 37 | /** 38 | * The security CSRF enabling flag. Makes sense only if security 'enabled` is `true'. 39 | */ 40 | private boolean csrfEnabled = true; 41 | 42 | public boolean isEnabled() { 43 | return this.enabled; 44 | } 45 | 46 | public void setEnabled(boolean enabled) { 47 | this.enabled = enabled; 48 | } 49 | 50 | public boolean isCsrfEnabled() { 51 | return this.csrfEnabled; 52 | } 53 | 54 | public void setCsrfEnabled(boolean csrfEnabled) { 55 | this.csrfEnabled = csrfEnabled; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | stream-apps-common 7 | org.springframework.cloud.stream.app 8 | 3.0.0.BUILD-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | stream-apps-security-common 13 | 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-configuration-processor 18 | true 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-autoconfigure-processor 23 | true 24 | 25 | 26 | javax.servlet 27 | javax.servlet-api 28 | provided 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-actuator 33 | true 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-webflux 38 | true 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-web 43 | true 44 | test 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-security 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /common/stream-apps-metadata-store-common/src/main/java/org/springframework/cloud/stream/app/metadata/ClientCacheAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.metadata; 18 | 19 | import org.apache.geode.cache.GemFireCache; 20 | import org.apache.geode.cache.client.ClientCache; 21 | 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 23 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 24 | import org.springframework.context.annotation.Configuration; 25 | import org.springframework.data.gemfire.client.ClientCacheFactoryBean; 26 | import org.springframework.data.gemfire.config.annotation.ClientCacheApplication; 27 | import org.springframework.data.gemfire.config.annotation.EnablePdx; 28 | 29 | /** 30 | * TODO 31 | * 32 | * This is the copy of {@code org.springframework.boot.data.geode.autoconfigure.ClientCacheAutoConfiguration} 33 | * until {@code geode-spring-boot-starter} is released. 34 | * 35 | * @author John Blum 36 | */ 37 | @Configuration 38 | @ConditionalOnClass({ ClientCacheFactoryBean.class, ClientCache.class }) 39 | @ConditionalOnMissingBean(GemFireCache.class) 40 | @ClientCacheApplication 41 | @EnablePdx 42 | public class ClientCacheAutoConfiguration { 43 | 44 | } 45 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/src/main/java/org/springframework/cloud/stream/app/file/remote/AbstractRemoteFileProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.file.remote; 17 | 18 | import org.hibernate.validator.constraints.NotBlank; 19 | 20 | /** 21 | * @deprecated - properties are flattened. 22 | * 23 | * @author Gary Russell 24 | * 25 | */ 26 | @Deprecated 27 | public abstract class AbstractRemoteFileProperties { 28 | 29 | /** 30 | * The remote FTP directory. 31 | */ 32 | private String remoteDir = "/"; 33 | 34 | /** 35 | * The suffix to use while the transfer is in progress. 36 | */ 37 | private String tmpFileSuffix = ".tmp"; 38 | 39 | /** 40 | * The remote file separator. 41 | */ 42 | private String remoteFileSeparator = "/"; 43 | 44 | @NotBlank 45 | public String getRemoteDir() { 46 | return remoteDir; 47 | } 48 | 49 | public final void setRemoteDir(String remoteDir) { 50 | this.remoteDir = remoteDir; 51 | } 52 | 53 | @NotBlank 54 | public String getTmpFileSuffix() { 55 | return tmpFileSuffix; 56 | } 57 | 58 | public void setTmpFileSuffix(String tmpFileSuffix) { 59 | this.tmpFileSuffix = tmpFileSuffix; 60 | } 61 | 62 | @NotBlank 63 | public String getRemoteFileSeparator() { 64 | return remoteFileSeparator; 65 | } 66 | 67 | public void setRemoteFileSeparator(String remoteFileSeparator) { 68 | this.remoteFileSeparator = remoteFileSeparator; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/README.adoc: -------------------------------------------------------------------------------- 1 | === `App Starters Security` Common Module 2 | 3 | Spring Boot auto-configuration to manage the web security of the application starters. 4 | 5 | When the `app-starters-security-common` dependency is on the classpath, the `spring.cloud.streamapp.security.enabled` and `spring.cloud.streamapp.security.csrf-enabled` properties control the application security behavior. 6 | 7 | By default the security is enabled allowing unauthorized access only to the `Info` and `Health` endpoints. 8 | 9 | The `spring.cloud.streamapp.security.enabled = false` completely surpass the application security. 10 | 11 | For secured application setting `spring.cloud.streamapp.security.csrf-enabled = false` disables security for the CSRF access. 12 | 13 | With security enabled (`spring.cloud.streamapp.security.enabled = true`) and `actuator` dependency on the classpath, the `(Reactive)ManagementWebSecurityAutoConfiguration` is activated, providing unauthenticated access to the `HealthEndpoint` and `InfoEndpoint`. 14 | 15 | If the user specifies their own `WebSecurityConfigurerAdapter` (for MVC application), this configuration will back-off completely and the user should specify all the bits that they want to configure as part of the custom security configuration. 16 | For reactive (WebFlux) application the same effect can be achieved with a custom `WebFilterChainProxy` bean. 17 | 18 | === Configuration 19 | To include app starters security management for a stream app, just include a dependency on this module. 20 | 21 | [source,xml] 22 | ---- 23 | 24 | org.springframework.cloud.stream.app 25 | app-starters-security-common 26 | 27 | ---- 28 | 29 | 30 | All Spring Cloud Stream app starters that inherit form the `core` pom have the `app-starters-security-common` dependency included by default. 31 | 32 | * `spring.cloud.streamapp.security.enabled` (default: `true`). If set to `false` it surpasses the boot security. 33 | * `spring.cloud.streamapp.security.csrf-enabled` (default: `true`). If set to `false`, for secured applications it enables CQRS. 34 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/src/main/java/org/springframework/cloud/stream/app/file/remote/FilePathUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.file.remote; 18 | 19 | import java.nio.file.Paths; 20 | 21 | import org.springframework.integration.file.FileHeaders; 22 | import org.springframework.lang.Nullable; 23 | import org.springframework.messaging.Message; 24 | import org.springframework.util.Assert; 25 | 26 | /** 27 | * @author David Turanski 28 | **/ 29 | public abstract class FilePathUtils { 30 | /** 31 | * Returns a remote file path for a message with a file name as payload and {@link FileHeaders#REMOTE_DIRECTORY} 32 | * included as a message header. 33 | * 34 | * @param message the message containing the header. 35 | * @return the file path. 36 | */ 37 | @Nullable 38 | public static String getRemoteFilePath(Message message) { 39 | if (message.getHeaders().containsKey(FileHeaders.REMOTE_DIRECTORY)) { 40 | String filename = (String) message.getPayload(); 41 | String remoteDirectory = (String) message.getHeaders().get(FileHeaders.REMOTE_DIRECTORY); 42 | return getPath(remoteDirectory, filename); 43 | } 44 | return null; 45 | } 46 | 47 | public static String getLocalFilePath(String localDirectory, String filename) { 48 | if (localDirectory != null) { 49 | return getPath(localDirectory, filename); 50 | } 51 | return filename; 52 | } 53 | 54 | private static String getPath(String dirName, String fileName) { 55 | return Paths.get(dirName, fileName).toString(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/KeyValueListParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest; 18 | 19 | import java.util.ArrayList; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | import org.springframework.util.StringUtils; 24 | 25 | /** 26 | * Parses a comma delimited list of key value pairs in which the values can contain commas as well. 27 | * 28 | * @author Chris Schaeffer 29 | * @author David Turanski 30 | **/ 31 | abstract class KeyValueListParser { 32 | 33 | static Map parseCommaDelimitedKeyValuePairs(String value) { 34 | Map keyValuePairs = new HashMap<>(); 35 | 36 | if (StringUtils.isEmpty(value)) { 37 | return keyValuePairs; 38 | } 39 | 40 | ArrayList pairs = new ArrayList<>(); 41 | 42 | String[] candidates = StringUtils.commaDelimitedListToStringArray(value); 43 | 44 | for (int i = 0; i < candidates.length; i++) { 45 | if (i > 0 && !candidates[i].contains("=")) { 46 | pairs.add(pairs.get(pairs.size() - 1) + "," + candidates[i]); 47 | } 48 | else { 49 | pairs.add(candidates[i]); 50 | } 51 | } 52 | 53 | for (String pair : pairs) { 54 | addKeyValuePair(pair, keyValuePairs); 55 | } 56 | 57 | return keyValuePairs; 58 | } 59 | 60 | private static void addKeyValuePair(String pair, Map properties) { 61 | int firstEquals = pair.indexOf('='); 62 | if (firstEquals != -1) { 63 | properties.put(pair.substring(0, firstEquals).trim(), pair.substring(firstEquals + 1).trim()); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/src/main/java/org/springframework/cloud/stream/app/file/remote/AbstractRemoteServerProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.file.remote; 17 | 18 | import org.hibernate.validator.constraints.NotBlank; 19 | 20 | /** 21 | * Common properties for remote servers (e.g. (S)FTP). 22 | * 23 | * @deprecated - properties are flattened. 24 | * 25 | * @author David Turanski 26 | * @author Gary Russell 27 | * 28 | */ 29 | @Deprecated 30 | public abstract class AbstractRemoteServerProperties { 31 | 32 | /** 33 | * The host name of the server. 34 | */ 35 | private String host = "localhost"; 36 | 37 | /** 38 | * The username to use to connect to the server. 39 | */ 40 | 41 | private String username; 42 | /** 43 | * The password to use to connect to the server. 44 | */ 45 | private String password; 46 | 47 | /** 48 | * Cache sessions 49 | */ 50 | private Boolean cacheSessions; 51 | 52 | @NotBlank 53 | public String getHost() { 54 | return this.host; 55 | } 56 | 57 | public void setHost(String host) { 58 | this.host = host; 59 | } 60 | 61 | @NotBlank 62 | public String getUsername() { 63 | return this.username; 64 | } 65 | 66 | public void setUsername(String username) { 67 | this.username = username; 68 | } 69 | 70 | public String getPassword() { 71 | return this.password; 72 | } 73 | 74 | public void setPassword(String password) { 75 | this.password = password; 76 | } 77 | 78 | public Boolean getCacheSessions() { 79 | return this.cacheSessions; 80 | } 81 | 82 | public void setCacheSessions(Boolean cacheSessions) { 83 | this.cacheSessions = cacheSessions; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataFlowTaskLaunchRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest; 18 | 19 | import com.fasterxml.jackson.annotation.JsonProperty; 20 | import java.util.ArrayList; 21 | import java.util.Collection; 22 | import java.util.HashMap; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | public class DataFlowTaskLaunchRequest { 27 | @JsonProperty("args") 28 | private List commandlineArguments = new ArrayList<>(); 29 | 30 | @JsonProperty("deploymentProps") 31 | private Map deploymentProperties = new HashMap<>(); 32 | 33 | @JsonProperty("name") 34 | private String taskName; 35 | 36 | public void setCommandlineArguments(List commandlineArguments) { 37 | this.commandlineArguments = new ArrayList<>(commandlineArguments); 38 | } 39 | 40 | public List getCommandlineArguments() { 41 | return this.commandlineArguments; 42 | } 43 | 44 | public void setDeploymentProperties(Map deploymentProperties) { 45 | this.deploymentProperties = deploymentProperties; 46 | } 47 | 48 | public Map getDeploymentProperties() { 49 | return this.deploymentProperties; 50 | } 51 | 52 | public void setTaskName(String taskName) { 53 | this.taskName = taskName; 54 | } 55 | 56 | public String getTaskName() { 57 | return this.taskName; 58 | } 59 | 60 | public DataFlowTaskLaunchRequest addCommmandLineArguments(Collection args) { 61 | this.commandlineArguments.addAll(args); 62 | return this; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /common/stream-apps-ftp-common/src/main/java/org/springframework/cloud/stream/app/ftp/FtpSessionFactoryConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 the original author or authors. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.springframework.cloud.stream.app.ftp; 17 | 18 | import org.apache.commons.net.ftp.FTPFile; 19 | 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 21 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 22 | import org.springframework.context.annotation.Bean; 23 | import org.springframework.context.annotation.Configuration; 24 | import org.springframework.integration.file.remote.session.CachingSessionFactory; 25 | import org.springframework.integration.file.remote.session.SessionFactory; 26 | import org.springframework.integration.ftp.session.DefaultFtpSessionFactory; 27 | 28 | /** 29 | * FTP Session factory configuration. 30 | * 31 | * @author David Turanski 32 | * @author Gary Russell 33 | */ 34 | @Configuration 35 | @EnableConfigurationProperties(FtpSessionFactoryProperties.class) 36 | public class FtpSessionFactoryConfiguration { 37 | 38 | @Bean 39 | @ConditionalOnMissingBean 40 | public SessionFactory ftpSessionFactory(FtpSessionFactoryProperties properties) { 41 | DefaultFtpSessionFactory ftpSessionFactory = new DefaultFtpSessionFactory(); 42 | ftpSessionFactory.setHost(properties.getHost()); 43 | ftpSessionFactory.setPort(properties.getPort()); 44 | ftpSessionFactory.setUsername(properties.getUsername()); 45 | ftpSessionFactory.setPassword(properties.getPassword()); 46 | ftpSessionFactory.setClientMode(properties.getClientMode().getMode()); 47 | if (properties.getCacheSessions() != null) { 48 | CachingSessionFactory csf = new CachingSessionFactory<>(ftpSessionFactory); 49 | return csf; 50 | } 51 | else { 52 | return ftpSessionFactory; 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /common/stream-apps-ftp-common/src/main/java/org/springframework/cloud/stream/app/ftp/FtpSessionFactoryProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 the original author or authors. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.springframework.cloud.stream.app.ftp; 17 | 18 | import javax.validation.constraints.NotNull; 19 | 20 | import org.apache.commons.net.ftp.FTPClient; 21 | import org.hibernate.validator.constraints.Range; 22 | 23 | import org.springframework.boot.context.properties.ConfigurationProperties; 24 | import org.springframework.cloud.stream.app.file.remote.AbstractRemoteServerProperties; 25 | import org.springframework.validation.annotation.Validated; 26 | 27 | /** 28 | * FTP {@code SessionFactory} properties. 29 | * 30 | * @author David Turanski 31 | * @author Gary Russell 32 | */ 33 | @ConfigurationProperties("ftp.factory") 34 | @Validated 35 | public class FtpSessionFactoryProperties extends AbstractRemoteServerProperties { 36 | 37 | /** 38 | * The port of the server. 39 | */ 40 | private int port = 21; 41 | 42 | /** 43 | * The client mode to use for the FTP session. 44 | */ 45 | private ClientMode clientMode = ClientMode.PASSIVE; 46 | 47 | @Range(min = 0, max = 65535) 48 | public int getPort() { 49 | return this.port; 50 | } 51 | 52 | public void setPort(int port) { 53 | this.port = port; 54 | } 55 | 56 | @NotNull 57 | public ClientMode getClientMode() { 58 | return this.clientMode; 59 | } 60 | 61 | public void setClientMode(ClientMode clientMode) { 62 | this.clientMode = clientMode; 63 | } 64 | 65 | public static enum ClientMode { 66 | 67 | ACTIVE(FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE), 68 | PASSIVE(FTPClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE); 69 | 70 | private final int mode; 71 | 72 | private ClientMode(int mode) { 73 | this.mode = mode; 74 | } 75 | 76 | public int getMode() { 77 | return mode; 78 | } 79 | 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.adoc: -------------------------------------------------------------------------------- 1 | = Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of fostering an open 4 | and welcoming community, we pledge to respect all people who contribute through reporting 5 | issues, posting feature requests, updating documentation, submitting pull requests or 6 | patches, and other activities. 7 | 8 | We are committed to making participation in this project a harassment-free experience for 9 | everyone, regardless of level of experience, gender, gender identity and expression, 10 | sexual orientation, disability, personal appearance, body size, race, ethnicity, age, 11 | religion, or nationality. 12 | 13 | Examples of unacceptable behavior by participants include: 14 | 15 | * The use of sexualized language or imagery 16 | * Personal attacks 17 | * Trolling or insulting/derogatory comments 18 | * Public or private harassment 19 | * Publishing other's private information, such as physical or electronic addresses, 20 | without explicit permission 21 | * Other unethical or unprofessional conduct 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or reject comments, 24 | commits, code, wiki edits, issues, and other contributions that are not aligned to this 25 | Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors 26 | that they deem inappropriate, threatening, offensive, or harmful. 27 | 28 | By adopting this Code of Conduct, project maintainers commit themselves to fairly and 29 | consistently applying these principles to every aspect of managing this project. Project 30 | maintainers who do not follow or enforce the Code of Conduct may be permanently removed 31 | from the project team. 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an 34 | individual is representing the project or its community. 35 | 36 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by 37 | contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will 38 | be reviewed and investigated and will result in a response that is deemed necessary and 39 | appropriate to the circumstances. Maintainers are obligated to maintain confidentiality 40 | with regard to the reporter of an incident. 41 | 42 | This Code of Conduct is adapted from the 43 | https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at 44 | https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/] 45 | -------------------------------------------------------------------------------- /common/stream-apps-test-support/src/main/java/org/springframework/cloud/stream/app/test/BinderTestPropertiesInitializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.test; 18 | 19 | import java.util.Properties; 20 | 21 | import org.springframework.beans.BeansException; 22 | import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 23 | import org.springframework.beans.factory.support.BeanDefinitionRegistry; 24 | import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; 25 | import org.springframework.context.ConfigurableApplicationContext; 26 | import org.springframework.core.env.PropertiesPropertySource; 27 | 28 | /** 29 | * Unlike the {@code PropertiesInitializer}, this does not require boot infrastructure 30 | * to add properties to the context. Used for testing generated apps where the 31 | * {@code ApplicationContextInitializer} can't be used. Since it's a BDRPP, it runs 32 | * before any BFPPs - i.e. as early as possible. 33 | * 34 | * @author Gary Russell 35 | * 36 | */ 37 | public class BinderTestPropertiesInitializer implements BeanDefinitionRegistryPostProcessor { 38 | 39 | private final ConfigurableApplicationContext context; 40 | 41 | private final Properties properties; 42 | 43 | public BinderTestPropertiesInitializer(ConfigurableApplicationContext context, Properties properties) { 44 | this.context = context; 45 | this.properties = properties; 46 | } 47 | 48 | @Override 49 | public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 50 | } 51 | 52 | @Override 53 | public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { 54 | this.context.getEnvironment().getPropertySources() 55 | .addLast(new PropertiesPropertySource("scsAppProperties", properties)); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/src/main/java/org/springframework/cloud/stream/app/file/remote/RemoteFileDeletingTransactionSynchronizationProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.file.remote; 18 | 19 | import org.springframework.integration.file.FileHeaders; 20 | import org.springframework.integration.file.remote.RemoteFileTemplate; 21 | import org.springframework.integration.transaction.IntegrationResourceHolder; 22 | import org.springframework.integration.transaction.TransactionSynchronizationProcessor; 23 | 24 | /** 25 | * A {@link TransactionSynchronizationProcessor} that deletes a remote file on 26 | * success. 27 | * 28 | * @author Gary Russell 29 | * 30 | */ 31 | public class RemoteFileDeletingTransactionSynchronizationProcessor implements TransactionSynchronizationProcessor { 32 | 33 | private final RemoteFileTemplate template; 34 | 35 | private final String remoteFileSeparator; 36 | 37 | /** 38 | * Construct an instance with the provided template and separator. 39 | * @param template the template. 40 | * @param remoteFileSeparator the separator. 41 | */ 42 | public RemoteFileDeletingTransactionSynchronizationProcessor(RemoteFileTemplate template, 43 | String remoteFileSeparator) { 44 | this.template = template; 45 | this.remoteFileSeparator = remoteFileSeparator; 46 | } 47 | 48 | @Override 49 | public void processBeforeCommit(IntegrationResourceHolder holder) { 50 | } 51 | 52 | @Override 53 | public void processAfterRollback(IntegrationResourceHolder holder) { 54 | } 55 | 56 | @Override 57 | public void processAfterCommit(IntegrationResourceHolder holder) { 58 | String remoteDir = (String) holder.getMessage().getHeaders().get(FileHeaders.REMOTE_DIRECTORY); 59 | String remoteFile = (String) holder.getMessage().getHeaders().get(FileHeaders.REMOTE_FILE); 60 | this.template.remove(remoteDir + this.remoteFileSeparator + remoteFile); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/test/java/org/springframework/cloud/stream/app/micrometer/common/InfluxReservedKeywordHandlingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.micrometer.common; 17 | 18 | import io.micrometer.core.instrument.Meter; 19 | import io.micrometer.influx.InfluxMeterRegistry; 20 | import org.junit.Ignore; 21 | import org.junit.Test; 22 | import org.junit.runner.RunWith; 23 | 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.boot.SpringApplication; 26 | import org.springframework.boot.autoconfigure.SpringBootApplication; 27 | import org.springframework.boot.test.context.SpringBootTest; 28 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 29 | 30 | import static org.hamcrest.Matchers.is; 31 | import static org.junit.Assert.assertNotNull; 32 | import static org.junit.Assert.assertThat; 33 | 34 | /** 35 | * @author Christian Tzolov 36 | */ 37 | @RunWith(SpringJUnit4ClassRunner.class) 38 | @SpringBootTest(classes = InfluxReservedKeywordHandlingTest.AutoConfigurationApplication.class, 39 | properties = { 40 | "management.metrics.export.influx.enabled=true", 41 | "spring.cloud.dataflow.stream.app.label=time" }) 42 | public class InfluxReservedKeywordHandlingTest { 43 | 44 | @Autowired 45 | protected InfluxMeterRegistry influxMeterRegistry; 46 | 47 | @Test 48 | public void testPresetTagValues() { 49 | assertNotNull(influxMeterRegistry); 50 | Meter meter = influxMeterRegistry.find("jvm.memory.committed").meter(); 51 | assertNotNull("The jvm.memory.committed meter mast be present in SpringBoot apps!", meter); 52 | 53 | assertThat(meter.getId().getTag("application.name"), is("atime")); 54 | } 55 | 56 | @SpringBootApplication 57 | public static class AutoConfigurationApplication { 58 | public static void main(String[] args) { 59 | SpringApplication.run(AutoConfigurationApplication.class, args); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | 21 | import java.util.Map; 22 | 23 | import org.junit.jupiter.api.Test; 24 | 25 | import org.springframework.http.HttpStatus; 26 | import org.springframework.http.ResponseEntity; 27 | import org.springframework.test.context.TestPropertySource; 28 | 29 | /** 30 | * @author Christian Tzolov 31 | * @author Artem Bilan 32 | * 33 | * @since 3.0 34 | */ 35 | @TestPropertySource(properties = { 36 | "spring.main.web-application-type=reactive", 37 | "spring.autoconfigure.exclude=" + 38 | "org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration" 39 | + ",org.springframework.cloud.stream.app.security.common.AppStarterWebFluxSecurityAutoConfiguration", 40 | "management.endpoints.web.exposure.include=health,info" }) 41 | public class ReactiveSecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests extends AbstractSecurityCommonTests { 42 | 43 | @Test 44 | @SuppressWarnings("rawtypes") 45 | public void testHealthEndpoint() { 46 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/health", Map.class); 47 | assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); 48 | } 49 | 50 | @Test 51 | @SuppressWarnings("rawtypes") 52 | public void testInfoEndpoint() { 53 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); 54 | assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); 55 | } 56 | 57 | @Test 58 | @SuppressWarnings("rawtypes") 59 | public void testEnvEndpoint() { 60 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/env", Map.class); 61 | assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityDisabledManagementSecurityEnabledTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertTrue; 21 | 22 | import java.util.Map; 23 | 24 | import org.junit.jupiter.api.Test; 25 | 26 | import org.springframework.http.HttpStatus; 27 | import org.springframework.http.ResponseEntity; 28 | import org.springframework.test.context.TestPropertySource; 29 | 30 | /** 31 | * @author Artem Bilan 32 | * 33 | * @since 3.0 34 | */ 35 | @TestPropertySource(properties = { 36 | "spring.main.web-application-type=reactive", 37 | "spring.cloud.streamapp.security.enabled=false", 38 | "management.endpoints.web.exposure.include=health,info,env", 39 | "info.name=MY TEST APP" }) 40 | public class ReactiveSecurityDisabledManagementSecurityEnabledTests extends AbstractSecurityCommonTests { 41 | 42 | @Test 43 | @SuppressWarnings("rawtypes") 44 | public void testHealthEndpoint() { 45 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/health", Map.class); 46 | assertEquals(HttpStatus.OK, response.getStatusCode()); 47 | assertTrue(response.hasBody()); 48 | Map health = response.getBody(); 49 | assertEquals("UP", health.get("status")); 50 | } 51 | 52 | @Test 53 | @SuppressWarnings("rawtypes") 54 | public void testInfoEndpoint() { 55 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); 56 | assertEquals(HttpStatus.OK, response.getStatusCode()); 57 | assertTrue(response.hasBody()); 58 | Map info = response.getBody(); 59 | assertEquals("MY TEST APP", info.get("name")); 60 | } 61 | 62 | @Test 63 | @SuppressWarnings("rawtypes") 64 | public void testEnvEndpoint() { 65 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/env", Map.class); 66 | assertEquals(HttpStatus.OK, response.getStatusCode()); 67 | assertTrue(response.hasBody()); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/src/main/java/org/springframework/cloud/stream/app/file/FileConsumerProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 the original author or authors. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.springframework.cloud.stream.app.file; 17 | 18 | import javax.validation.constraints.AssertTrue; 19 | import javax.validation.constraints.NotNull; 20 | 21 | import org.springframework.boot.context.properties.ConfigurationProperties; 22 | import org.springframework.validation.annotation.Validated; 23 | 24 | /** 25 | * @author David Turanski 26 | * @author Artem Bilan 27 | */ 28 | @ConfigurationProperties("file.consumer") 29 | @Validated 30 | public class FileConsumerProperties { 31 | 32 | /** 33 | * The FileReadingMode to use for file reading sources. 34 | * Values are 'ref' - The File object, 35 | * 'lines' - a message per line, or 36 | * 'contents' - the contents as bytes. 37 | */ 38 | private FileReadingMode mode = FileReadingMode.contents; 39 | 40 | /** 41 | * Set to true to emit start of file/end of file marker messages before/after the data. 42 | * Only valid with FileReadingMode 'lines'. 43 | */ 44 | private Boolean withMarkers = null; 45 | 46 | /** 47 | * When 'fileMarkers == true', specify if they should be produced 48 | * as FileSplitter.FileMarker objects or JSON. 49 | */ 50 | private boolean markersJson = true; 51 | 52 | @NotNull 53 | public FileReadingMode getMode() { 54 | return this.mode; 55 | } 56 | 57 | public void setMode(FileReadingMode mode) { 58 | this.mode = mode; 59 | } 60 | 61 | public Boolean getWithMarkers() { 62 | return this.withMarkers; 63 | } 64 | 65 | public void setWithMarkers(Boolean withMarkers) { 66 | this.withMarkers = withMarkers; 67 | } 68 | 69 | public boolean getMarkersJson() { 70 | return this.markersJson; 71 | } 72 | 73 | public void setMarkersJson(boolean markersJson) { 74 | this.markersJson = markersJson; 75 | } 76 | 77 | @AssertTrue(message = "withMarkers can only be supplied when FileReadingMode is 'lines'") 78 | public boolean isWithMarkersValid() { 79 | return this.withMarkers == null || FileReadingMode.lines == this.mode; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityDisabledManagementSecurityEnabledTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertTrue; 21 | 22 | import java.util.Map; 23 | 24 | import org.junit.jupiter.api.Test; 25 | 26 | import org.springframework.http.HttpStatus; 27 | import org.springframework.http.ResponseEntity; 28 | import org.springframework.test.context.TestPropertySource; 29 | 30 | /** 31 | * @author Christian Tzolov 32 | * @author Artem Bilan 33 | * 34 | * @since 3.0 35 | */ 36 | @TestPropertySource(properties = { 37 | "spring.main.web-application-type=servlet", 38 | "spring.cloud.streamapp.security.enabled=false", 39 | "management.endpoints.web.exposure.include=health,info,env", 40 | "info.name=MY TEST APP" }) 41 | public class SecurityDisabledManagementSecurityEnabledTests extends AbstractSecurityCommonTests { 42 | 43 | @Test 44 | @SuppressWarnings("rawtypes") 45 | public void testHealthEndpoint() { 46 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/health", Map.class); 47 | assertEquals(HttpStatus.OK, response.getStatusCode()); 48 | assertTrue(response.hasBody()); 49 | Map health = response.getBody(); 50 | assertEquals("UP", health.get("status")); 51 | } 52 | 53 | @Test 54 | @SuppressWarnings("rawtypes") 55 | public void testInfoEndpoint() { 56 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); 57 | assertEquals(HttpStatus.OK, response.getStatusCode()); 58 | assertTrue(response.hasBody()); 59 | Map info = response.getBody(); 60 | assertEquals("MY TEST APP", info.get("name")); 61 | } 62 | 63 | @Test 64 | @SuppressWarnings("rawtypes") 65 | public void testEnvEndpoint() { 66 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/env", Map.class); 67 | assertEquals(HttpStatus.OK, response.getStatusCode()); 68 | assertTrue(response.hasBody()); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/README.adoc: -------------------------------------------------------------------------------- 1 | === `Data Flow Task Launch Request Support` Common Module 2 | 3 | This artifact contains a Spring Boot auto-configuration providing components to produce a Task Launch Request payload. 4 | In theory any message source can be used to launch a Task. The task launch request is compatible with the 5 | task-launcher-dataflow sink. 6 | 7 | 8 | ==== Data Flow Task Launch Request 9 | 10 | Data Flow Task Launch Request requests require a Data Flow server with an existing task definition. 11 | The task launch request contains the name of the task to launch. This must the name of a defined task in Data Flow. 12 | You may optionally provide command line arguments and deployment properties. 13 | 14 | ===== Task Name 15 | 16 | The task name is a required field. This may be statically configured by setting `task.launch.request.task-name`, 17 | extracted from the Message by setting `task.launch.request.task-name-expression`. 18 | You may also override the default implementation of the `TaskNameMessageMapper` bean to enable more complex runtime task name mappings. 19 | 20 | 21 | ===== Task Command Line Arguments 22 | 23 | The launched task often requires additional data which may be passed as command line arguments. 24 | The `task.launch.request.args` property accepts a comma delimited string of key-value pairs, for example 25 | `key1=val1,key2=val2`. In addition, a `task.launch.request.arg-expressions` allows you to use SpEL expressions to evaluate 26 | message contents to provide command line arguments. 27 | For example, `task.launch.request.arg-expressions=foo=payload.toUpperCase(),bar=payload.substring(0,2)`. 28 | 29 | You may also provide override implementation of the `CommandLineArgumentsMessageMapper` bean to implement more complex logic. 30 | 31 | ===== Task Deployment Properties 32 | 33 | Deployment properties are platform-specific configuration used by the `TaskLauncher` and are always statically configured by 34 | setting `task.launch.request.deployment-properties` and apply to every task launch request. 35 | 36 | === Configuration 37 | To enable any stream app to transform its output to a Task Launch Request, include a dependency on this module 38 | 39 | [source,xml] 40 | ---- 41 | 42 | org.springframework.cloud.stream.app 43 | app-starters-task-launch-request-common 44 | 45 | ---- 46 | 47 | Setting the application property `spring.cloud.stream.function.definition=taskLaunchRequest` is required to execute the transformation. 48 | You may safely add the above dependency to applications which optionally produce a task launch request. 49 | 50 | 51 | `TaskLaunchRequestIntegrationTests` provides some configuration examples. 52 | 53 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityEnabledTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertTrue; 21 | 22 | import java.util.Map; 23 | 24 | import org.junit.jupiter.api.Test; 25 | 26 | import org.springframework.http.HttpStatus; 27 | import org.springframework.http.ResponseEntity; 28 | import org.springframework.test.context.TestPropertySource; 29 | 30 | /** 31 | * @author Christian Tzolov 32 | * @author Artem Bilan 33 | * 34 | * @since 3.0 35 | */ 36 | @TestPropertySource(properties = { 37 | "spring.main.web-application-type=reactive", 38 | "management.endpoints.web.exposure.include=health,info,env", 39 | "info.name=MY TEST APP" }) 40 | public class ReactiveSecurityEnabledManagementSecurityEnabledTests extends AbstractSecurityCommonTests { 41 | 42 | @Test 43 | @SuppressWarnings("rawtypes") 44 | public void testHealthEndpoint() { 45 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/health", Map.class); 46 | assertEquals(HttpStatus.OK, response.getStatusCode()); 47 | assertTrue(response.hasBody()); 48 | Map health = response.getBody(); 49 | assertEquals("UP", health.get("status")); 50 | } 51 | 52 | @Test 53 | @SuppressWarnings("rawtypes") 54 | public void testInfoEndpoint() { 55 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); 56 | assertEquals(HttpStatus.OK, response.getStatusCode()); 57 | assertTrue(response.hasBody()); 58 | Map info = response.getBody(); 59 | assertEquals("MY TEST APP", info.get("name")); 60 | } 61 | 62 | // The ManagementWebSecurityAutoConfiguration exposes only Info and Health endpoint not Env! 63 | @Test 64 | @SuppressWarnings("rawtypes") 65 | public void testEnvEndpoint() { 66 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/env", Map.class); 67 | assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /.settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | repo.spring.io 6 | ${env.CI_DEPLOY_USERNAME} 7 | ${env.CI_DEPLOY_PASSWORD} 8 | 9 | 10 | 11 | 12 | 18 | spring 19 | 20 | true 21 | 22 | 23 | 24 | spring-snapshots 25 | Spring Snapshots 26 | https://repo.spring.io/libs-snapshot-local 27 | 28 | true 29 | 30 | 31 | 32 | spring-milestones 33 | Spring Milestones 34 | https://repo.spring.io/libs-milestone-local 35 | 36 | false 37 | 38 | 39 | 40 | spring-releases 41 | Spring Releases 42 | https://repo.spring.io/release 43 | 44 | false 45 | 46 | 47 | 51 | 52 | gemstone-release 53 | GemStone Maven Release Repository 54 | http://dist.gemstone.com/maven/release 55 | 56 | true 57 | always 58 | 59 | 60 | 61 | 62 | 63 | spring-snapshots 64 | Spring Snapshots 65 | https://repo.spring.io/libs-snapshot-local 66 | 67 | true 68 | 69 | 70 | 71 | spring-milestones 72 | Spring Milestones 73 | https://repo.spring.io/libs-milestone-local 74 | 75 | false 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityEnabledTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertTrue; 21 | 22 | import java.util.Map; 23 | 24 | import org.junit.jupiter.api.Disabled; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import org.springframework.http.HttpStatus; 28 | import org.springframework.http.ResponseEntity; 29 | import org.springframework.test.context.TestPropertySource; 30 | 31 | /** 32 | * @author Christian Tzolov 33 | * @author Artem Bilan 34 | * 35 | * @since 3.0 36 | */ 37 | @TestPropertySource(properties = { 38 | "spring.main.web-application-type=servlet", 39 | "management.endpoints.web.exposure.include=health,info,env", 40 | "info.name=MY TEST APP" }) 41 | public class SecurityEnabledManagementSecurityEnabledTests extends AbstractSecurityCommonTests { 42 | 43 | @Test 44 | @SuppressWarnings("rawtypes") 45 | public void testHealthEndpoint() { 46 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/health", Map.class); 47 | assertEquals(HttpStatus.OK, response.getStatusCode()); 48 | assertTrue(response.hasBody()); 49 | Map health = response.getBody(); 50 | assertEquals("UP", health.get("status")); 51 | } 52 | 53 | @Test 54 | @SuppressWarnings("rawtypes") 55 | public void testInfoEndpoint() { 56 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); 57 | assertEquals(HttpStatus.OK, response.getStatusCode()); 58 | assertTrue(response.hasBody()); 59 | Map info = response.getBody(); 60 | assertEquals("MY TEST APP", info.get("name")); 61 | } 62 | 63 | // The ManagementWebSecurityAutoConfiguration exposes only Info and Health endpoint not Env! 64 | @Test 65 | @SuppressWarnings("rawtypes") 66 | public void testEnvEndpoint() { 67 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/env", Map.class); 68 | assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); 69 | assertTrue(response.hasBody()); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/support/TaskLaunchRequestSupplier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest.support; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | import java.util.function.Supplier; 22 | import org.springframework.cloud.stream.app.tasklaunchrequest.DataFlowTaskLaunchRequest; 23 | import org.springframework.util.Assert; 24 | 25 | public class TaskLaunchRequestSupplier implements Supplier { 26 | 27 | private Supplier taskNameSupplier; 28 | private Supplier> commandLineArgumentsSupplier; 29 | private Supplier> deploymentPropertiesSupplier; 30 | 31 | 32 | public TaskLaunchRequestSupplier taskNameSupplier(Supplier taskNameSupplier) { 33 | this.taskNameSupplier = taskNameSupplier; 34 | return this; 35 | } 36 | 37 | public TaskLaunchRequestSupplier commandLineArgumentSupplier(Supplier> commandLineArgumentsSupplier) { 38 | this.commandLineArgumentsSupplier = commandLineArgumentsSupplier; 39 | return this; 40 | } 41 | 42 | public TaskLaunchRequestSupplier deploymentPropertiesSupplier(Supplier> deploymentPropertiesSupplier) { 43 | this.deploymentPropertiesSupplier = deploymentPropertiesSupplier; 44 | return this; 45 | } 46 | 47 | @Override 48 | public DataFlowTaskLaunchRequest get() { 49 | 50 | Assert.notNull(this.taskNameSupplier, "'taskNameSupplier' is required."); 51 | 52 | DataFlowTaskLaunchRequest dataFlowTaskLaunchRequest = new DataFlowTaskLaunchRequest(); 53 | dataFlowTaskLaunchRequest.setTaskName(this.taskNameSupplier.get()); 54 | 55 | if (this.commandLineArgumentsSupplier != null) { 56 | dataFlowTaskLaunchRequest.setCommandlineArguments(this.commandLineArgumentsSupplier.get()); 57 | } 58 | 59 | if (this.deploymentPropertiesSupplier != null) { 60 | dataFlowTaskLaunchRequest.setDeploymentProperties(this.deploymentPropertiesSupplier.get()); 61 | } 62 | 63 | return dataFlowTaskLaunchRequest; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/main/java/org/springframework/cloud/stream/app/micrometer/common/SpringCloudStreamMicrometerEnvironmentPostProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.micrometer.common; 17 | 18 | import java.util.Properties; 19 | 20 | import org.springframework.boot.SpringApplication; 21 | import org.springframework.boot.env.EnvironmentPostProcessor; 22 | import org.springframework.core.env.ConfigurableEnvironment; 23 | import org.springframework.core.env.PropertiesPropertySource; 24 | 25 | /** 26 | * Disables all Micrometer Repositories added as App Starters dependencies by default. 27 | * That means disabling Datadog, Influx and Prometheus. 28 | * 29 | * @author Christian Tzolov 30 | */ 31 | public class SpringCloudStreamMicrometerEnvironmentPostProcessor implements EnvironmentPostProcessor { 32 | 33 | protected static final String PROPERTY_SOURCE_KEY_NAME = SpringCloudStreamMicrometerEnvironmentPostProcessor.class.getName(); 34 | 35 | private final static String METRICS_PROPERTY_NAME_TEMPLATE = "management.metrics.export.%s.enabled"; 36 | 37 | private final static String[] METRICS_REPOSITORY_NAMES = 38 | new String[] { "datadog", "influx", "prometheus", "prometheus.rsocket" }; 39 | 40 | @Override 41 | public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { 42 | Properties properties = new Properties(); 43 | 44 | if (!environment.containsProperty("management.endpoints.web.exposure.include")) { 45 | properties.setProperty("management.endpoints.web.exposure.include", "prometheus"); 46 | } 47 | 48 | for (String metricsRepositoryName : METRICS_REPOSITORY_NAMES) { 49 | String propertyKey = String.format(METRICS_PROPERTY_NAME_TEMPLATE, metricsRepositoryName); 50 | 51 | // Back off if the property is already set. 52 | if (!environment.containsProperty(propertyKey)) { 53 | properties.setProperty(propertyKey, "false"); 54 | } 55 | } 56 | 57 | // This post-processor is called multiple times but sets the properties only once. 58 | if (!properties.isEmpty()) { 59 | PropertiesPropertySource propertiesPropertySource = 60 | new PropertiesPropertySource(PROPERTY_SOURCE_KEY_NAME, properties); 61 | environment.getPropertySources().addLast(propertiesPropertySource); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/test/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestPropertiesTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest; 18 | 19 | import java.util.List; 20 | 21 | import org.junit.Test; 22 | 23 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 24 | import org.springframework.boot.test.util.TestPropertyValues; 25 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.context.annotation.Import; 28 | import org.springframework.integration.config.EnableIntegration; 29 | 30 | import static org.assertj.core.api.Assertions.assertThat; 31 | 32 | /** 33 | * @author David Turanski 34 | **/ 35 | public class TaskLaunchRequestPropertiesTests { 36 | 37 | @Test 38 | public void deploymentPropertiesCanBeCustomized() { 39 | DataflowTaskLaunchRequestProperties properties = getBatchProperties( 40 | "task.launch.request.deploymentProperties:prop1=val1,prop2=val2"); 41 | assertThat(properties.getDeploymentProperties()).isEqualTo("prop1=val1,prop2=val2"); 42 | } 43 | 44 | @Test 45 | public void parametersCanBeCustomized() { 46 | DataflowTaskLaunchRequestProperties properties = getBatchProperties( 47 | "task.launch.request.args:jp1=jpv1,jp2=jpv2"); 48 | List args = properties.getArgs(); 49 | 50 | assertThat(args).isNotNull(); 51 | assertThat(args).hasSize(2); 52 | assertThat(args.get(0)).isEqualTo("jp1=jpv1"); 53 | assertThat(args.get(1)).isEqualTo("jp2=jpv2"); 54 | } 55 | 56 | private DataflowTaskLaunchRequestProperties getBatchProperties(String... var) { 57 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 58 | 59 | if (var != null) { 60 | TestPropertyValues.of(var).applyTo(context); 61 | } 62 | 63 | context.register(Conf.class); 64 | context.refresh(); 65 | 66 | return context.getBean(DataflowTaskLaunchRequestProperties.class); 67 | } 68 | 69 | 70 | @Configuration 71 | @EnableIntegration 72 | @EnableConfigurationProperties(DataflowTaskLaunchRequestProperties.class) 73 | @Import(DataFlowTaskLaunchRequestAutoConfiguration.class) 74 | static class Conf { 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019-2020 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertTrue; 21 | 22 | import java.util.Map; 23 | 24 | import org.junit.jupiter.api.Disabled; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import org.springframework.http.HttpStatus; 28 | import org.springframework.http.ResponseEntity; 29 | import org.springframework.test.context.TestPropertySource; 30 | 31 | /** 32 | * @author Christian Tzolov 33 | * @author Artem Bilan 34 | * 35 | * @since 3.0 36 | */ 37 | @TestPropertySource(properties = { 38 | "spring.main.web-application-type=servlet", 39 | "spring.autoconfigure.exclude=" + 40 | "org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration" 41 | + ",org.springframework.cloud.stream.app.security.common.AppStarterWebSecurityAutoConfiguration", 42 | "management.endpoints.web.exposure.include=health,info" }) 43 | public class SecurityEnabledManagementSecurityDisabledUnauthorizedAccessTests extends AbstractSecurityCommonTests { 44 | 45 | @Test 46 | @SuppressWarnings("rawtypes") 47 | public void testHealthEndpoint() { 48 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/health", Map.class); 49 | assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); 50 | assertTrue(response.hasBody()); 51 | Map health = response.getBody(); 52 | assertEquals("Unauthorized", health.get("error")); 53 | } 54 | 55 | @Test 56 | @SuppressWarnings("rawtypes") 57 | public void testInfoEndpoint() { 58 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); 59 | assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); 60 | assertTrue(response.hasBody()); 61 | Map info = response.getBody(); 62 | assertEquals("Unauthorized", info.get("error")); 63 | } 64 | 65 | @Test 66 | @SuppressWarnings("rawtypes") 67 | public void testEnvEndpoint() { 68 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/env", Map.class); 69 | assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); 70 | assertTrue(response.hasBody()); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/src/main/java/org/springframework/cloud/stream/app/file/remote/AbstractRemoteFileSinkProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.file.remote; 17 | 18 | import javax.validation.constraints.NotNull; 19 | 20 | import org.hibernate.validator.constraints.NotBlank; 21 | 22 | import org.springframework.expression.Expression; 23 | import org.springframework.integration.file.support.FileExistsMode; 24 | 25 | /** 26 | * @deprecated - properties are flattened. 27 | * 28 | * @author Gary Russell 29 | * 30 | */ 31 | @Deprecated 32 | public abstract class AbstractRemoteFileSinkProperties extends AbstractRemoteFileProperties { 33 | 34 | /** 35 | * A temporary directory where the file will be written if {@link #isUseTemporaryFilename()} 36 | * is true. 37 | */ 38 | private String temporaryRemoteDir = "/"; 39 | 40 | /** 41 | * Whether or not to create the remote directory. 42 | */ 43 | private boolean autoCreateDir = true; 44 | 45 | /** 46 | * Action to take if the remote file already exists. 47 | */ 48 | private FileExistsMode mode = FileExistsMode.REPLACE; 49 | 50 | /** 51 | * Whether or not to write to a temporary file and rename. 52 | */ 53 | private boolean useTemporaryFilename = true; 54 | 55 | /** 56 | * A SpEL expression to generate the remote file name. 57 | */ 58 | private Expression filenameExpression; 59 | 60 | @NotBlank 61 | public String getTemporaryRemoteDir() { 62 | return this.temporaryRemoteDir; 63 | } 64 | 65 | public void setTemporaryRemoteDir(String temporaryRemoteDir) { 66 | this.temporaryRemoteDir = temporaryRemoteDir; 67 | } 68 | 69 | public boolean isAutoCreateDir() { 70 | return this.autoCreateDir; 71 | } 72 | 73 | public void setAutoCreateDir(boolean autoCreateDir) { 74 | this.autoCreateDir = autoCreateDir; 75 | } 76 | 77 | @NotNull 78 | public FileExistsMode getMode() { 79 | return this.mode; 80 | } 81 | 82 | public void setMode(FileExistsMode mode) { 83 | this.mode = mode; 84 | } 85 | 86 | public boolean isUseTemporaryFilename() { 87 | return this.useTemporaryFilename; 88 | } 89 | 90 | public void setUseTemporaryFilename(boolean useTemporaryFilename) { 91 | this.useTemporaryFilename = useTemporaryFilename; 92 | } 93 | 94 | public Expression getFilenameExpression() { 95 | return this.filenameExpression; 96 | } 97 | 98 | public void setFilenameExpression(Expression filenameExpression) { 99 | this.filenameExpression = filenameExpression; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebFluxSecurityAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration; 20 | import org.springframework.boot.autoconfigure.AutoConfigureBefore; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 23 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 24 | import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; 25 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 26 | import org.springframework.context.annotation.Bean; 27 | import org.springframework.context.annotation.Conditional; 28 | import org.springframework.context.annotation.Configuration; 29 | import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; 30 | import org.springframework.security.config.web.server.ServerHttpSecurity; 31 | import org.springframework.security.web.server.SecurityWebFilterChain; 32 | import org.springframework.security.web.server.WebFilterChainProxy; 33 | import org.springframework.web.reactive.config.WebFluxConfigurer; 34 | 35 | import reactor.core.publisher.Flux; 36 | 37 | /** 38 | * @author Artem Bilan 39 | * 40 | * @since 3.0 41 | */ 42 | @Conditional(OnHttpCsrfOrSecurityDisabled.class) 43 | @Configuration 44 | @ConditionalOnClass({ Flux.class, EnableWebFluxSecurity.class, WebFilterChainProxy.class, WebFluxConfigurer.class }) 45 | @ConditionalOnMissingBean(WebFilterChainProxy.class) 46 | @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) 47 | @AutoConfigureBefore(value = { ReactiveManagementWebSecurityAutoConfiguration.class, 48 | ReactiveSecurityAutoConfiguration.class }) 49 | @EnableConfigurationProperties(AppStarterWebSecurityAutoConfigurationProperties.class) 50 | public class AppStarterWebFluxSecurityAutoConfiguration { 51 | 52 | @Bean 53 | public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http, 54 | AppStarterWebSecurityAutoConfigurationProperties securityProperties) { 55 | if (!securityProperties.isCsrfEnabled()) { 56 | http.csrf().disable(); 57 | } 58 | if (!securityProperties.isEnabled()) { 59 | http.authorizeExchange() 60 | .anyExchange() 61 | .permitAll(); 62 | } 63 | return http.build(); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/test/java/org/springframework/cloud/stream/app/micrometer/common/SpringCloudStreamMicrometerCommonTagsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.micrometer.common; 17 | 18 | import org.junit.Ignore; 19 | import org.junit.Test; 20 | import org.junit.experimental.runners.Enclosed; 21 | import org.junit.runner.RunWith; 22 | 23 | import org.springframework.test.context.TestPropertySource; 24 | 25 | import static org.hamcrest.Matchers.is; 26 | import static org.hamcrest.Matchers.nullValue; 27 | import static org.junit.Assert.assertThat; 28 | 29 | /** 30 | * @author Christian Tzolov 31 | */ 32 | @RunWith(Enclosed.class) 33 | public class SpringCloudStreamMicrometerCommonTagsTest { 34 | 35 | public static class TestDefaultTagValues extends AbstractMicrometerTagTest { 36 | 37 | @Test 38 | public void testDefaultTagValues() { 39 | assertThat(meter.getId().getTag("stream.name"), is("unknown")); 40 | assertThat(meter.getId().getTag("application.name"), is("unknown")); 41 | assertThat(meter.getId().getTag("instance.index"), is("0")); 42 | assertThat(meter.getId().getTag("application.type"), is("unknown")); 43 | assertThat(meter.getId().getTag("application.guid"), is("unknown")); 44 | } 45 | } 46 | 47 | @TestPropertySource(properties = { 48 | "spring.cloud.dataflow.stream.name=myStream", 49 | "spring.cloud.dataflow.stream.app.label=myApp", 50 | "spring.cloud.stream.instanceIndex=666", 51 | "spring.cloud.application.guid=666guid", 52 | "spring.cloud.dataflow.stream.app.type=source" }) 53 | public static class TestPresetTagValues extends AbstractMicrometerTagTest { 54 | 55 | @Test 56 | public void testPresetTagValues() { 57 | assertThat(meter.getId().getTag("stream.name"), is("myStream")); 58 | assertThat(meter.getId().getTag("application.name"), is("myApp")); 59 | assertThat(meter.getId().getTag("instance.index"), is("666")); 60 | assertThat(meter.getId().getTag("application.type"), is("source")); 61 | assertThat(meter.getId().getTag("application.guid"), is("666guid")); 62 | } 63 | } 64 | 65 | @TestPropertySource(properties = { "spring.cloud.stream.app.metrics.common.tags.enabled=false" }) 66 | public static class TestDisabledTagValues extends AbstractMicrometerTagTest { 67 | 68 | @Test 69 | public void testDefaultTagValues() { 70 | assertThat(meter.getId().getTag("stream.name"), is(nullValue())); 71 | assertThat(meter.getId().getTag("application.name"), is(nullValue())); 72 | assertThat(meter.getId().getTag("instance.index"), is(nullValue())); 73 | assertThat(meter.getId().getTag("application.type"), is(nullValue())); 74 | assertThat(meter.getId().getTag("application.guid"), is(nullValue())); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/main/java/org/springframework/cloud/stream/app/security/common/AppStarterWebSecurityAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration; 20 | import org.springframework.boot.autoconfigure.AutoConfigureBefore; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 23 | import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 24 | import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; 25 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 26 | import org.springframework.context.annotation.Bean; 27 | import org.springframework.context.annotation.Conditional; 28 | import org.springframework.context.annotation.Configuration; 29 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 30 | import org.springframework.security.config.annotation.web.builders.WebSecurity; 31 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 32 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 33 | 34 | /** 35 | * @author Christian Tzolov 36 | * @author Artem Bilan 37 | * 38 | * @since 2.1 39 | */ 40 | @Conditional(OnHttpCsrfOrSecurityDisabled.class) 41 | @Configuration 42 | @ConditionalOnClass(WebSecurityConfigurerAdapter.class) 43 | @ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class) 44 | @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) 45 | @AutoConfigureBefore(value = { ManagementWebSecurityAutoConfiguration.class, SecurityAutoConfiguration.class }) 46 | @EnableConfigurationProperties(AppStarterWebSecurityAutoConfigurationProperties.class) 47 | @EnableWebSecurity 48 | public class AppStarterWebSecurityAutoConfiguration { 49 | 50 | @Bean 51 | WebSecurityConfigurerAdapter appStarterWebSecurityConfigurerAdapter( 52 | AppStarterWebSecurityAutoConfigurationProperties securityProperties) { 53 | 54 | 55 | return new WebSecurityConfigurerAdapter() { 56 | 57 | @Override 58 | protected void configure(HttpSecurity http) throws Exception { 59 | super.configure(http); 60 | if (!securityProperties.isCsrfEnabled()) { 61 | http.csrf().disable(); 62 | } 63 | } 64 | 65 | @Override 66 | public void configure(WebSecurity builder) { 67 | if (!securityProperties.isEnabled()) { 68 | builder.ignoring().antMatchers("/**"); 69 | } 70 | } 71 | 72 | }; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/main/java/org/springframework/cloud/stream/app/micrometer/common/CloudFoundryMicrometerCommonTags.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.micrometer.common; 17 | 18 | import io.micrometer.core.instrument.MeterRegistry; 19 | 20 | import org.springframework.beans.factory.annotation.Value; 21 | import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | import org.springframework.context.annotation.Profile; 26 | 27 | /** 28 | * Micrometer common tags for Cloud Foundry deployment properties. Based on the CF application environment variables: 29 | * https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html 30 | * 31 | * Tags are set only if the "cloud" Spring profile is set. The "cloud" profile is activated automatically when an 32 | * application is deployed in CF: https://docs.cloudfoundry.org/buildpacks/java/configuring-service-connections/spring-service-bindings.html#cloud-profiles 33 | * 34 | * Use the spring.cloud.stream.app.metrics.cf.tags.enabled=false property to disable inserting those tags. 35 | * 36 | * @author Christian Tzolov 37 | */ 38 | @Configuration 39 | @Profile("cloud") 40 | @ConditionalOnProperty(name = "spring.cloud.stream.app.metrics.cf.tags.enabled", havingValue = "true", matchIfMissing = true) 41 | public class CloudFoundryMicrometerCommonTags { 42 | 43 | @Value("${vcap.application.org_name:default}") 44 | private String organizationName; 45 | 46 | @Value("${vcap.application.space_id:unknown}") 47 | private String spaceId; 48 | 49 | @Value("${vcap.application.space_name:unknown}") 50 | private String spaceName; 51 | 52 | @Value("${vcap.application.application_name:unknown}") 53 | private String applicationName; 54 | 55 | @Value("${vcap.application.application_id:unknown}") 56 | private String applicationId; 57 | 58 | @Value("${vcap.application.application_version:unknown}") 59 | private String applicationVersion; 60 | 61 | @Value("${vcap.application.instance_index:0}") 62 | private String instanceIndex; 63 | 64 | @Bean 65 | public MeterRegistryCustomizer cloudFoundryMetricsCommonTags() { 66 | return registry -> registry.config() 67 | .commonTags("cf.org.name", organizationName) 68 | .commonTags("cf.space.id", spaceId) 69 | .commonTags("cf.space.name", spaceName) 70 | .commonTags("cf.app.id", applicationId) 71 | .commonTags("cf.app.name", applicationName) 72 | .commonTags("cf.app.version", applicationVersion) 73 | .commonTags("cf.instance.index", instanceIndex); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/main/java/org/springframework/cloud/stream/app/micrometer/common/SpringCloudStreamMicrometerCommonTags.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.micrometer.common; 17 | 18 | import io.micrometer.core.instrument.MeterRegistry; 19 | import io.micrometer.core.instrument.config.MeterFilter; 20 | 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; 23 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 24 | import org.springframework.context.annotation.Bean; 25 | import org.springframework.context.annotation.Configuration; 26 | 27 | /** 28 | * Auto configuration extends the micrometer metrics with additional tags such as: stream name, application name, 29 | * instance index and guids. Later are necessary to allow discrimination and aggregation of app metrics by external 30 | * metrics collection and visualizaiton tools. 31 | * 32 | * Use the spring.cloud.stream.app.metrics.common.tags.enabled=false property to disable inserting those tags. 33 | * 34 | * @author Christian Tzolov 35 | */ 36 | @Configuration 37 | @ConditionalOnProperty(name = "spring.cloud.stream.app.metrics.common.tags.enabled", havingValue = "true", matchIfMissing = true) 38 | public class SpringCloudStreamMicrometerCommonTags { 39 | 40 | @Value("${spring.cloud.dataflow.stream.name:unknown}") 41 | private String streamName; 42 | 43 | @Value("${spring.cloud.dataflow.stream.app.label:unknown}") 44 | private String applicationName; 45 | 46 | @Value("${spring.cloud.stream.instanceIndex:0}") 47 | private String instanceIndex; 48 | 49 | @Value("${spring.cloud.application.guid:unknown}") 50 | private String applicationGuid; 51 | 52 | @Value("${spring.cloud.dataflow.stream.app.type:unknown}") 53 | private String applicationType; 54 | 55 | @Bean 56 | public MeterRegistryCustomizer metricsCommonTags() { 57 | return registry -> registry.config() 58 | .commonTags("stream.name", streamName) 59 | .commonTags("application.name", applicationName) 60 | .commonTags("application.type", applicationType) 61 | .commonTags("instance.index", instanceIndex) 62 | .commonTags("application.guid", applicationGuid); 63 | } 64 | 65 | @Bean 66 | public MeterRegistryCustomizer renameNameTag() { 67 | return registry -> { 68 | if (registry.getClass().getCanonicalName().contains("AtlasMeterRegistry")) { 69 | registry.config().meterFilter(MeterFilter.renameTag("spring.integration", "name", "aname")); 70 | } 71 | if (registry.getClass().getCanonicalName().contains("InfluxMeterRegistry")) { 72 | registry.config().meterFilter(MeterFilter.replaceTagValues("application.name", 73 | tagValue -> ("time".equalsIgnoreCase(tagValue)) ? "atime" : tagValue)); 74 | } 75 | }; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/ReactiveSecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertTrue; 21 | 22 | import java.util.Map; 23 | 24 | import org.junit.jupiter.api.BeforeEach; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.boot.autoconfigure.security.SecurityProperties; 29 | import org.springframework.http.HttpStatus; 30 | import org.springframework.http.ResponseEntity; 31 | import org.springframework.http.client.support.BasicAuthenticationInterceptor; 32 | import org.springframework.test.context.TestPropertySource; 33 | 34 | /** 35 | * @author Christian Tzolov 36 | * 37 | * @since 3.0 38 | */ 39 | @TestPropertySource(properties = { 40 | "spring.main.web-application-type=reactive", 41 | "org.springframework.boot.actuate.autoconfigure.security.reactive.ReactiveManagementWebSecurityAutoConfiguration" 42 | + ",org.springframework.cloud.stream.app.security.common.AppStarterWebFluxSecurityAutoConfiguration", 43 | "management.endpoints.web.exposure.include=health,info,env", 44 | "info.name=MY TEST APP" }) 45 | public class ReactiveSecurityEnabledManagementSecurityDisabledAuthorizedAccessTests extends AbstractSecurityCommonTests { 46 | 47 | @Autowired 48 | private SecurityProperties securityProperties; 49 | 50 | @BeforeEach 51 | public void before() { 52 | restTemplate.getRestTemplate().getInterceptors().add(new BasicAuthenticationInterceptor( 53 | securityProperties.getUser().getName(), securityProperties.getUser().getPassword())); 54 | } 55 | 56 | @Test 57 | @SuppressWarnings("rawtypes") 58 | public void testHealthEndpoint() { 59 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/health", Map.class); 60 | assertEquals(HttpStatus.OK, response.getStatusCode()); 61 | assertTrue(response.hasBody()); 62 | Map health = response.getBody(); 63 | assertEquals("UP", health.get("status")); 64 | } 65 | 66 | @Test 67 | @SuppressWarnings("rawtypes") 68 | public void testInfoEndpoint() { 69 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); 70 | assertEquals(HttpStatus.OK, response.getStatusCode()); 71 | assertTrue(response.hasBody()); 72 | Map info = response.getBody(); 73 | assertEquals("MY TEST APP", info.get("name")); 74 | } 75 | 76 | @Test 77 | @SuppressWarnings("rawtypes") 78 | public void testEnvEndpoint() { 79 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/env", Map.class); 80 | assertEquals(HttpStatus.OK, response.getStatusCode()); 81 | assertTrue(response.hasBody()); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /common/stream-apps-security-common/src/test/java/org/springframework/cloud/stream/app/security/common/SecurityEnabledManagementSecurityDisabledAuthorizedAccessTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.security.common; 18 | 19 | import static org.junit.Assert.assertEquals; 20 | import static org.junit.Assert.assertTrue; 21 | 22 | import java.util.Map; 23 | 24 | import org.junit.jupiter.api.BeforeEach; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.boot.autoconfigure.security.SecurityProperties; 29 | import org.springframework.http.HttpStatus; 30 | import org.springframework.http.ResponseEntity; 31 | import org.springframework.http.client.support.BasicAuthenticationInterceptor; 32 | import org.springframework.test.context.TestPropertySource; 33 | 34 | /** 35 | * @author Christian Tzolov 36 | * @author Artem Bilan 37 | * 38 | * @since 3.0 39 | */ 40 | @TestPropertySource(properties = { 41 | "spring.main.web-application-type=servlet", 42 | "spring.autoconfigure.exclude=org.springframework.boot.actuate.autoconfigure.security.servlet" + 43 | ".ManagementWebSecurityAutoConfiguration" 44 | + ",org.springframework.cloud.stream.app.security.common.AppStarterWebSecurityAutoConfiguration", 45 | "management.endpoints.web.exposure.include=health,info,env", 46 | "info.name=MY TEST APP" }) 47 | public class SecurityEnabledManagementSecurityDisabledAuthorizedAccessTests extends AbstractSecurityCommonTests { 48 | 49 | @Autowired 50 | private SecurityProperties securityProperties; 51 | 52 | @BeforeEach 53 | public void before() { 54 | restTemplate.getRestTemplate().getInterceptors().add(new BasicAuthenticationInterceptor( 55 | securityProperties.getUser().getName(), securityProperties.getUser().getPassword())); 56 | } 57 | 58 | @Test 59 | @SuppressWarnings("rawtypes") 60 | public void testHealthEndpoint() { 61 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/health", Map.class); 62 | assertEquals(HttpStatus.OK, response.getStatusCode()); 63 | assertTrue(response.hasBody()); 64 | Map health = response.getBody(); 65 | assertEquals("UP", health.get("status")); 66 | } 67 | 68 | @Test 69 | @SuppressWarnings("rawtypes") 70 | public void testInfoEndpoint() { 71 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/info", Map.class); 72 | assertEquals(HttpStatus.OK, response.getStatusCode()); 73 | assertTrue(response.hasBody()); 74 | Map info = response.getBody(); 75 | assertEquals("MY TEST APP", info.get("name")); 76 | } 77 | 78 | @Test 79 | @SuppressWarnings("rawtypes") 80 | public void testEnvEndpoint() { 81 | ResponseEntity response = this.restTemplate.getForEntity("/actuator/env", Map.class); 82 | assertEquals(HttpStatus.OK, response.getStatusCode()); 83 | assertTrue(response.hasBody()); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/TaskLaunchRequestMessageProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest; 18 | 19 | import org.springframework.cloud.stream.app.tasklaunchrequest.support.CommandLineArgumentsMessageMapper; 20 | import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskLaunchRequestSupplier; 21 | import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskNameMessageMapper; 22 | import org.springframework.messaging.Message; 23 | import org.springframework.messaging.MessageHeaders; 24 | import org.springframework.messaging.core.MessagePostProcessor; 25 | import org.springframework.messaging.support.MessageBuilder; 26 | import org.springframework.util.Assert; 27 | import org.springframework.util.MimeTypeUtils; 28 | import org.springframework.util.StringUtils; 29 | 30 | public class TaskLaunchRequestMessageProcessor implements MessagePostProcessor { 31 | 32 | private final TaskNameMessageMapper taskNameMessageMapper; 33 | private final CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper; 34 | private final TaskLaunchRequestSupplier taskLaunchRequestInitializer; 35 | 36 | public TaskLaunchRequestMessageProcessor(TaskLaunchRequestSupplier taskLaunchRequestInitializer, 37 | TaskNameMessageMapper taskNameMessageMapper, 38 | CommandLineArgumentsMessageMapper commandLIneArgumentsMessageMapper) { 39 | 40 | this.taskLaunchRequestInitializer = taskLaunchRequestInitializer; 41 | 42 | this.taskNameMessageMapper = taskNameMessageMapper; 43 | 44 | this.commandLineArgumentsMessageMapper = commandLIneArgumentsMessageMapper; 45 | 46 | } 47 | 48 | @Override 49 | public Message postProcessMessage(Message message) { 50 | DataFlowTaskLaunchRequest taskLaunchRequest = taskLaunchRequestInitializer.get(); 51 | 52 | if (!StringUtils.hasText(taskLaunchRequest.getTaskName())) { 53 | taskLaunchRequest.setTaskName(taskNameMessageMapper.processMessage(message)); 54 | Assert.hasText(taskLaunchRequest.getTaskName(), ()-> 55 | "'taskName' is required in " + DataFlowTaskLaunchRequest.class.getName()); 56 | } 57 | 58 | taskLaunchRequest.addCommmandLineArguments(commandLineArgumentsMessageMapper.processMessage(message)); 59 | 60 | MessageBuilder builder 61 | = MessageBuilder.withPayload(taskLaunchRequest).copyHeaders(message.getHeaders()); 62 | return adjustHeaders(builder).build(); 63 | } 64 | 65 | 66 | private MessageBuilder adjustHeaders(MessageBuilder builder) { 67 | builder.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON); 68 | return builder; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataflowTaskLaunchRequestProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import javax.validation.constraints.AssertFalse; 22 | import javax.validation.constraints.NotNull; 23 | import org.springframework.boot.context.properties.ConfigurationProperties; 24 | import org.springframework.util.StringUtils; 25 | import org.springframework.validation.annotation.Validated; 26 | 27 | /** 28 | * Base Properties to create a {@link DataFlowTaskLaunchRequest}. 29 | * 30 | * @author Chris Schaefer 31 | * @author David Turanski 32 | */ 33 | @Validated 34 | @ConfigurationProperties("task.launch.request") 35 | public class DataflowTaskLaunchRequestProperties { 36 | 37 | /** 38 | * Comma separated list of optional args in key=value format. 39 | */ 40 | private List args = new ArrayList<>(); 41 | 42 | /** 43 | * Comma separated list of option args as SpEL expressions in key=value format. 44 | */ 45 | private String argExpressions = ""; 46 | 47 | /** 48 | * Comma delimited list of deployment properties to be applied to the 49 | * TaskLaunchRequest. 50 | */ 51 | private String deploymentProperties = ""; 52 | 53 | /** 54 | * The Data Flow task name. 55 | */ 56 | private String taskName; 57 | 58 | 59 | /** 60 | * A SpEL expression to extract the task name from each Message, using the Message as the evaluation context. 61 | */ 62 | private String taskNameExpression; 63 | 64 | @NotNull 65 | public List getArgs() { 66 | return this.args; 67 | } 68 | 69 | public void setArgs(List args) { 70 | this.args = new ArrayList<>(args); 71 | } 72 | 73 | @NotNull 74 | public String getDeploymentProperties() { 75 | return this.deploymentProperties; 76 | } 77 | 78 | public void setDeploymentProperties(String deploymentProperties) { 79 | this.deploymentProperties = deploymentProperties; 80 | } 81 | 82 | public String getTaskName() { 83 | return taskName; 84 | } 85 | 86 | public void setTaskName(String taskName) { 87 | this.taskName = taskName; 88 | } 89 | 90 | public String getTaskNameExpression() { 91 | return taskNameExpression; 92 | } 93 | 94 | public void setTaskNameExpression(String taskNameExpression) { 95 | this.taskNameExpression = taskNameExpression; 96 | } 97 | 98 | public String getArgExpressions() { 99 | return argExpressions; 100 | } 101 | 102 | public void setArgExpressions(String argExpressions) { 103 | this.argExpressions = argExpressions; 104 | } 105 | 106 | @AssertFalse(message = "Cannot specify both 'taskName' and 'taskNameExpression'.") 107 | public boolean isTaskNameAndTaskNameExpressionSet() { 108 | return StringUtils.hasText(this.taskName) && StringUtils.hasText(this.taskNameExpression); 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/src/main/java/org/springframework/cloud/stream/app/file/remote/AbstractRemoteFileSourceProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2017 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.file.remote; 17 | 18 | import java.io.File; 19 | import java.util.regex.Pattern; 20 | 21 | import javax.validation.constraints.AssertTrue; 22 | import javax.validation.constraints.NotNull; 23 | 24 | /** 25 | * Common properties for remote file sources (e.g. (S)FTP). 26 | * 27 | * @deprecated - properties are flattened. 28 | * 29 | * @author David Turanski 30 | * @author Gary Russell 31 | * 32 | */ 33 | @Deprecated 34 | public abstract class AbstractRemoteFileSourceProperties extends AbstractRemoteFileProperties { 35 | 36 | /** 37 | * Set to true to delete remote files after successful transfer. 38 | */ 39 | private boolean deleteRemoteFiles = false; 40 | 41 | /** 42 | * The local directory to use for file transfers. 43 | */ 44 | private File localDir = new File(System.getProperty("java.io.tmpdir") + "/xd/ftp"); 45 | 46 | /** 47 | * Set to true to create the local directory if it does not exist. 48 | */ 49 | private boolean autoCreateLocalDir = true; 50 | 51 | /** 52 | * A filter pattern to match the names of files to transfer. 53 | */ 54 | private String filenamePattern; 55 | 56 | /** 57 | * A filter regex pattern to match the names of files to transfer. 58 | */ 59 | private Pattern filenameRegex; 60 | 61 | /** 62 | * Set to true to preserve the original timestamp. 63 | */ 64 | private boolean preserveTimestamp = true; 65 | 66 | public boolean isAutoCreateLocalDir() { 67 | return autoCreateLocalDir; 68 | } 69 | 70 | public void setAutoCreateLocalDir(boolean autoCreateLocalDir) { 71 | this.autoCreateLocalDir = autoCreateLocalDir; 72 | } 73 | 74 | public boolean isDeleteRemoteFiles() { 75 | return deleteRemoteFiles; 76 | } 77 | 78 | public void setDeleteRemoteFiles(boolean deleteRemoteFiles) { 79 | this.deleteRemoteFiles = deleteRemoteFiles; 80 | } 81 | 82 | @NotNull 83 | public File getLocalDir() { 84 | return localDir; 85 | } 86 | 87 | public final void setLocalDir(File localDir) { 88 | this.localDir = localDir; 89 | } 90 | 91 | public String getFilenamePattern() { 92 | return filenamePattern; 93 | } 94 | 95 | public void setFilenamePattern(String filenamePattern) { 96 | this.filenamePattern = filenamePattern; 97 | } 98 | 99 | public Pattern getFilenameRegex() { 100 | return filenameRegex; 101 | } 102 | 103 | public void setFilenameRegex(Pattern filenameRegex) { 104 | this.filenameRegex = filenameRegex; 105 | } 106 | 107 | public boolean isPreserveTimestamp() { 108 | return preserveTimestamp; 109 | } 110 | 111 | public void setPreserveTimestamp(boolean preserveTimestamp) { 112 | this.preserveTimestamp = preserveTimestamp; 113 | } 114 | 115 | @AssertTrue(message = "filenamePattern and filenameRegex are mutually exclusive") 116 | public boolean isExclusivePatterns() { 117 | return !(this.filenamePattern != null && this.filenameRegex != null); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /common/stream-apps-postprocessor-common/src/main/java/org/springframework/cloud/stream/app/postprocessor/ContentTypeEnvironmentPostProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.springframework.cloud.stream.app.postprocessor; 17 | 18 | import org.springframework.boot.SpringApplication; 19 | import org.springframework.boot.env.EnvironmentPostProcessor; 20 | import org.springframework.cloud.stream.messaging.Sink; 21 | import org.springframework.cloud.stream.messaging.Source; 22 | import org.springframework.core.env.ConfigurableEnvironment; 23 | import org.springframework.core.env.PropertiesPropertySource; 24 | 25 | import java.util.HashMap; 26 | import java.util.Map; 27 | import java.util.Properties; 28 | 29 | /** 30 | * An {@link EnvironmentPostProcessor} to set the {@code spring.cloud.stream.bindings.{input,output}.contentType} 31 | * channel properties to a default of {@code application/octet-stream} if it has not been set already. 32 | * 33 | * Subclasses may extend this class to change the default content type and channel name(s). 34 | * 35 | * @author Chris Schaefer 36 | */ 37 | public class ContentTypeEnvironmentPostProcessor implements EnvironmentPostProcessor { 38 | private Map channelMap = createChannelMap(); 39 | 40 | private Map createChannelMap() { 41 | Map channelMap = new HashMap<>(); 42 | channelMap.put(Sink.INPUT, "application/octet-stream"); 43 | channelMap.put(Source.OUTPUT, "application/octet-stream"); 44 | 45 | return channelMap; 46 | } 47 | 48 | protected static final String PROPERTY_SOURCE_KEY_NAME = ContentTypeEnvironmentPostProcessor.class.getName(); 49 | protected static final String CONTENT_TYPE_PROPERTY_PREFIX = "spring.cloud.stream.bindings."; 50 | protected static final String CONTENT_TYPE_PROPERTY_SUFFIX = ".contentType"; 51 | 52 | public ContentTypeEnvironmentPostProcessor() { 53 | super(); 54 | } 55 | 56 | protected ContentTypeEnvironmentPostProcessor(Map channelMap) { 57 | this.channelMap = channelMap; 58 | } 59 | 60 | protected ContentTypeEnvironmentPostProcessor(String contentType) { 61 | for (Map.Entry channel : channelMap.entrySet()) { 62 | channel.setValue(contentType); 63 | } 64 | } 65 | 66 | protected ContentTypeEnvironmentPostProcessor(String channelName, String contentType) { 67 | channelMap.put(channelName, contentType); 68 | } 69 | 70 | @Override 71 | public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, SpringApplication springApplication) { 72 | Properties properties = new Properties(); 73 | 74 | for (Map.Entry channel : channelMap.entrySet()) { 75 | String propertyKey = CONTENT_TYPE_PROPERTY_PREFIX + channel.getKey() + CONTENT_TYPE_PROPERTY_SUFFIX; 76 | 77 | if (!configurableEnvironment.containsProperty(propertyKey)) { 78 | properties.setProperty(propertyKey, channel.getValue()); 79 | } 80 | } 81 | 82 | if (!properties.isEmpty()) { 83 | PropertiesPropertySource propertiesPropertySource = 84 | new PropertiesPropertySource(PROPERTY_SOURCE_KEY_NAME, properties); 85 | configurableEnvironment.getPropertySources().addLast(propertiesPropertySource); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/test/java/org/springframework/cloud/stream/app/micrometer/common/AbstractMicrometerTagTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.micrometer.common; 17 | 18 | import java.io.IOException; 19 | import java.nio.charset.Charset; 20 | 21 | import io.micrometer.core.instrument.Clock; 22 | import io.micrometer.core.instrument.Meter; 23 | import io.micrometer.core.instrument.simple.SimpleConfig; 24 | import io.micrometer.core.instrument.simple.SimpleMeterRegistry; 25 | import io.pivotal.cfenv.test.CfEnvTestUtils; 26 | import org.junit.Before; 27 | import org.junit.BeforeClass; 28 | import org.junit.runner.RunWith; 29 | 30 | import org.springframework.beans.factory.annotation.Autowired; 31 | import org.springframework.boot.SpringApplication; 32 | import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleProperties; 33 | import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimplePropertiesConfigAdapter; 34 | import org.springframework.boot.autoconfigure.SpringBootApplication; 35 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 36 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 37 | import org.springframework.boot.test.context.SpringBootTest; 38 | import org.springframework.context.ConfigurableApplicationContext; 39 | import org.springframework.context.annotation.Bean; 40 | import org.springframework.core.io.DefaultResourceLoader; 41 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 42 | import org.springframework.util.StreamUtils; 43 | 44 | import static org.junit.Assert.assertNotNull; 45 | 46 | /** 47 | * @author Christian Tzolov 48 | * @author Soby Chacko 49 | */ 50 | @RunWith(SpringJUnit4ClassRunner.class) 51 | @SpringBootTest(classes = AbstractMicrometerTagTest.AutoConfigurationApplication.class) 52 | public class AbstractMicrometerTagTest { 53 | 54 | @Autowired 55 | protected SimpleMeterRegistry simpleMeterRegistry; 56 | 57 | @Autowired 58 | protected ConfigurableApplicationContext context; 59 | 60 | protected Meter meter; 61 | 62 | @Before 63 | public void before() { 64 | assertNotNull(simpleMeterRegistry); 65 | meter = simpleMeterRegistry.find("jvm.memory.committed").meter(); 66 | assertNotNull("The jvm.memory.committed meter mast be present in SpringBoot apps!", meter); 67 | } 68 | 69 | @BeforeClass 70 | public static void setup() throws IOException { 71 | String serviceJson = StreamUtils.copyToString(new DefaultResourceLoader().getResource( 72 | "classpath:/org/springframework/cloud/stream/app/micrometer/common/pcf-scs-info.json") 73 | .getInputStream(), Charset.forName("UTF-8")); 74 | CfEnvTestUtils.mockVcapServicesFromString(serviceJson); 75 | } 76 | 77 | @SpringBootApplication 78 | @EnableConfigurationProperties(SimpleProperties.class) 79 | public static class AutoConfigurationApplication { 80 | 81 | public static void main(String[] args) { 82 | SpringApplication.run(AutoConfigurationApplication.class, args); 83 | } 84 | 85 | @Bean 86 | public SimpleMeterRegistry simpleMeterRegistry(SimpleConfig config, Clock clock) { 87 | return new SimpleMeterRegistry(config, clock); 88 | } 89 | 90 | @Bean 91 | @ConditionalOnMissingBean 92 | public SimpleConfig simpleConfig(SimpleProperties simpleProperties) { 93 | return new SimplePropertiesConfigAdapter(simpleProperties); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /common/stream-apps-file-common/src/main/java/org/springframework/cloud/stream/app/file/FileUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.file; 18 | 19 | import java.util.Collections; 20 | 21 | import org.springframework.integration.dsl.IntegrationFlowBuilder; 22 | import org.springframework.integration.file.splitter.FileSplitter; 23 | import org.springframework.integration.file.transformer.FileToByteArrayTransformer; 24 | import org.springframework.integration.transformer.StreamTransformer; 25 | import org.springframework.messaging.MessageHeaders; 26 | import org.springframework.util.MimeTypeUtils; 27 | 28 | /** 29 | * @author Gary Russell 30 | * @author Artem Bilan 31 | * @author Christian Tzolov 32 | * 33 | */ 34 | public class FileUtils { 35 | 36 | /** 37 | * Enhance an {@link IntegrationFlowBuilder} to add flow snippets, depending on 38 | * {@link FileConsumerProperties}. 39 | * @param flowBuilder the flow builder. 40 | * @param fileConsumerProperties the properties. 41 | * @return the updated flow builder. 42 | */ 43 | public static IntegrationFlowBuilder enhanceFlowForReadingMode(IntegrationFlowBuilder flowBuilder, 44 | FileConsumerProperties fileConsumerProperties) { 45 | switch (fileConsumerProperties.getMode()) { 46 | case contents: 47 | flowBuilder.enrichHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, 48 | MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE)) 49 | .transform(new FileToByteArrayTransformer()); 50 | break; 51 | case lines: 52 | Boolean withMarkers = fileConsumerProperties.getWithMarkers(); 53 | if (withMarkers == null) { 54 | withMarkers = false; 55 | } 56 | flowBuilder.enrichHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, 57 | MimeTypeUtils.TEXT_PLAIN_VALUE)) 58 | .split(new FileSplitter(true, withMarkers, fileConsumerProperties.getMarkersJson())); 59 | break; 60 | case ref: 61 | flowBuilder.enrichHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, 62 | MimeTypeUtils.APPLICATION_JSON_VALUE)); 63 | break; 64 | default: 65 | throw new IllegalArgumentException(fileConsumerProperties.getMode().name() + 66 | " is not a supported file reading mode."); 67 | } 68 | return flowBuilder; 69 | } 70 | 71 | /** 72 | * Enhance an {@link IntegrationFlowBuilder} to add flow snippets, depending on 73 | * {@link FileConsumerProperties}; used for streaming sources. 74 | * @param flowBuilder the flow builder. 75 | * @param fileConsumerProperties the properties. 76 | * @return the updated flow builder. 77 | */ 78 | public static IntegrationFlowBuilder enhanceStreamFlowForReadingMode(IntegrationFlowBuilder flowBuilder, 79 | FileConsumerProperties fileConsumerProperties) { 80 | switch (fileConsumerProperties.getMode()) { 81 | case contents: 82 | flowBuilder.enrichHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, 83 | MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE)) 84 | .transform(new StreamTransformer()); 85 | break; 86 | case lines: 87 | Boolean withMarkers = fileConsumerProperties.getWithMarkers(); 88 | if (withMarkers == null) { 89 | withMarkers = false; 90 | } 91 | flowBuilder.enrichHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, 92 | MimeTypeUtils.TEXT_PLAIN_VALUE)) 93 | .split(new FileSplitter(true, withMarkers, fileConsumerProperties.getMarkersJson())); 94 | break; 95 | case ref: 96 | default: 97 | throw new IllegalArgumentException(fileConsumerProperties.getMode().name() + 98 | " is not a supported file reading mode when streaming."); 99 | } 100 | return flowBuilder; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/test/java/org/springframework/cloud/stream/app/micrometer/common/CloudFoundryMicrometerCommonTagsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.micrometer.common; 17 | 18 | import org.hamcrest.Matchers; 19 | import org.junit.Ignore; 20 | import org.junit.Test; 21 | import org.junit.experimental.runners.Enclosed; 22 | import org.junit.runner.RunWith; 23 | 24 | import org.springframework.test.context.ActiveProfiles; 25 | import org.springframework.test.context.TestPropertySource; 26 | 27 | import static org.hamcrest.Matchers.is; 28 | import static org.junit.Assert.assertThat; 29 | 30 | /** 31 | * @author Christian Tzolov 32 | */ 33 | @RunWith(Enclosed.class) 34 | public class CloudFoundryMicrometerCommonTagsTest { 35 | 36 | @ActiveProfiles("cloud") 37 | public static class ActiveCloudProfileDefaultValues extends AbstractMicrometerTagTest { 38 | @Test 39 | public void testDefaultTagValues() { 40 | assertThat(meter.getId().getTag("cf.org.name"), is("default")); 41 | assertThat(meter.getId().getTag("cf.space.id"), is("unknown")); 42 | assertThat(meter.getId().getTag("cf.space.name"), is("unknown")); 43 | assertThat(meter.getId().getTag("cf.app.name"), is("unknown")); 44 | assertThat(meter.getId().getTag("cf.app.id"), is("unknown")); 45 | assertThat(meter.getId().getTag("cf.app.version"), is("unknown")); 46 | assertThat(meter.getId().getTag("cf.instance.index"), is("0")); 47 | } 48 | } 49 | 50 | @TestPropertySource(properties = { 51 | "vcap.application.org_name=PivotalOrg", 52 | "vcap.application.space_id=SpringSpaceId", 53 | "vcap.application.space_name=SpringSpace", 54 | "vcap.application.application_name=App666", 55 | "vcap.application.application_id=666guid", 56 | "vcap.application.application_version=2.0", 57 | "vcap.application.instance_index=123" }) 58 | @ActiveProfiles("cloud") 59 | public static class ActiveCloudProfile extends AbstractMicrometerTagTest { 60 | 61 | @Test 62 | public void testPresetTagValues() { 63 | assertThat(meter.getId().getTag("cf.org.name"), is("PivotalOrg")); 64 | assertThat(meter.getId().getTag("cf.space.id"), is("SpringSpaceId")); 65 | assertThat(meter.getId().getTag("cf.space.name"), is("SpringSpace")); 66 | assertThat(meter.getId().getTag("cf.app.name"), is("App666")); 67 | assertThat(meter.getId().getTag("cf.app.id"), is("666guid")); 68 | assertThat(meter.getId().getTag("cf.app.version"), is("2.0")); 69 | assertThat(meter.getId().getTag("cf.instance.index"), is("123")); 70 | } 71 | } 72 | 73 | @TestPropertySource(properties = { 74 | "vcap.application.org_name=PivotalOrg", 75 | "vcap.application.space_id=SpringSpaceId", 76 | "vcap.application.space_name=SpringSpace", 77 | "vcap.application.application_name=App666", 78 | "vcap.application.application_id=666guid", 79 | "vcap.application.application_version=2.0", 80 | "vcap.application.instance_index=123" }) 81 | public static class InactiveCloudProfile extends AbstractMicrometerTagTest { 82 | 83 | @Test 84 | public void testDisabledTagValues() { 85 | assertThat(meter.getId().getTag("cf.org.name"), is(Matchers.nullValue())); 86 | assertThat(meter.getId().getTag("cf.space.id"), is(Matchers.nullValue())); 87 | assertThat(meter.getId().getTag("cf.space.name"), is(Matchers.nullValue())); 88 | assertThat(meter.getId().getTag("cf.app.name"), is(Matchers.nullValue())); 89 | assertThat(meter.getId().getTag("cf.app.id"), is(Matchers.nullValue())); 90 | assertThat(meter.getId().getTag("cf.app.version"), is(Matchers.nullValue())); 91 | assertThat(meter.getId().getTag("cf.instance.index"), is(Matchers.nullValue())); 92 | } 93 | } 94 | 95 | @TestPropertySource(properties = { "spring.cloud.stream.app.metrics.cf.tags.enabled=false" }) 96 | @ActiveProfiles("cloud") 97 | public static class ActiveCloudProfileDisabledProperty extends InactiveCloudProfile { 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /common/stream-apps-micrometer-common/src/test/java/org/springframework/cloud/stream/app/micrometer/common/SpringCloudStreamMicrometerEnvironmentPostProcessorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.micrometer.common; 17 | 18 | import org.hamcrest.core.Is; 19 | import org.junit.Ignore; 20 | import org.junit.Test; 21 | import org.junit.experimental.runners.Enclosed; 22 | import org.junit.runner.RunWith; 23 | 24 | import org.springframework.core.env.PropertySource; 25 | import org.springframework.test.context.TestPropertySource; 26 | 27 | import static org.junit.Assert.assertNotNull; 28 | import static org.junit.Assert.assertNull; 29 | import static org.junit.Assert.assertThat; 30 | 31 | /** 32 | * @author Christian Tzolov 33 | */ 34 | @RunWith(Enclosed.class) 35 | public class SpringCloudStreamMicrometerEnvironmentPostProcessorTest { 36 | 37 | public static class TestDefaultMetricsEnabledProperties extends AbstractMicrometerTagTest { 38 | 39 | @Test 40 | public void testDefaultProperties() { 41 | assertNotNull(context); 42 | 43 | PropertySource propertySource = context.getEnvironment().getPropertySources() 44 | .get(SpringCloudStreamMicrometerEnvironmentPostProcessor.PROPERTY_SOURCE_KEY_NAME); 45 | 46 | assertNotNull("Property source " 47 | + SpringCloudStreamMicrometerEnvironmentPostProcessor.PROPERTY_SOURCE_KEY_NAME + " is null", 48 | propertySource); 49 | 50 | assertThat(propertySource.getProperty("management.metrics.export.influx.enabled"), Is.is("false")); 51 | assertThat(propertySource.getProperty("management.metrics.export.prometheus.enabled"), Is.is("false")); 52 | assertThat(propertySource.getProperty("management.metrics.export.prometheus.rsocket.enabled"), Is.is("false")); 53 | assertThat(propertySource.getProperty("management.metrics.export.datadog.enabled"), Is.is("false")); 54 | 55 | assertThat(propertySource.getProperty("management.endpoints.web.exposure.include"), Is.is("prometheus")); 56 | 57 | assertThat(context.getEnvironment().getProperty("management.metrics.export.influx.enabled"), Is.is("false")); 58 | assertThat(context.getEnvironment().getProperty("management.metrics.export.prometheus.enabled"), Is.is("false")); 59 | assertThat(context.getEnvironment().getProperty("management.metrics.export.datadog.enabled"), Is.is("false")); 60 | 61 | assertThat(context.getEnvironment().getProperty("management.endpoints.web.exposure.include"), Is.is("prometheus")); 62 | 63 | } 64 | } 65 | 66 | @TestPropertySource(properties = { 67 | "management.metrics.export.simple.enabled=true", 68 | "management.metrics.export.influx.enabled=true", 69 | "management.metrics.export.prometheus.enabled=true", 70 | "management.metrics.export.prometheus.rsocket.enabled=true", 71 | "management.metrics.export.datadog.enabled=true", 72 | "management.endpoints.web.exposure.include=info,health"}) 73 | public static class TestOverrideMetricsEnabledProperties extends AbstractMicrometerTagTest { 74 | 75 | @Test 76 | public void testOverrideProperties() { 77 | assertNotNull(context); 78 | 79 | PropertySource propertySource = context.getEnvironment().getPropertySources() 80 | .get(SpringCloudStreamMicrometerEnvironmentPostProcessor.PROPERTY_SOURCE_KEY_NAME); 81 | 82 | assertNull("Property source " 83 | + SpringCloudStreamMicrometerEnvironmentPostProcessor.PROPERTY_SOURCE_KEY_NAME + " is not null", 84 | propertySource); 85 | 86 | assertThat(context.getEnvironment().getProperty("management.metrics.export.influx.enabled"), Is.is("true")); 87 | assertThat(context.getEnvironment().getProperty("management.metrics.export.prometheus.enabled"), Is.is("true")); 88 | assertThat(context.getEnvironment().getProperty("management.metrics.export.prometheus.rsocket.enabled"), Is.is("true")); 89 | assertThat(context.getEnvironment().getProperty("management.metrics.export.datadog.enabled"), Is.is("true")); 90 | 91 | assertThat(context.getEnvironment().getProperty("management.endpoints.web.exposure.include"), Is.is("info,health")); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/test/java/org/springframework/cloud/stream/app/tasklaunchrequest/KeyValueListParserTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest; 18 | 19 | import java.util.Map; 20 | 21 | import org.junit.Test; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | import static org.junit.Assert.assertTrue; 25 | 26 | /** 27 | * @author Chris Schaefer 28 | * @author David Turanski 29 | */ 30 | public class KeyValueListParserTests { 31 | 32 | @Test 33 | public void testParseSimpleDeploymentProperty() { 34 | Map deploymentProperties = KeyValueListParser.parseCommaDelimitedKeyValuePairs( 35 | "app.sftp.param=value"); 36 | assertTrue("Invalid number of deployment properties: " + deploymentProperties.size(), 37 | deploymentProperties.size() == 1); 38 | assertTrue("Expected deployment key not found", deploymentProperties.containsKey("app.sftp.param")); 39 | assertEquals("Invalid deployment value", "value", deploymentProperties.get("app.sftp.param")); 40 | } 41 | 42 | @Test 43 | public void testParseSimpleDeploymentPropertyMultipleValues() { 44 | Map deploymentProperties = KeyValueListParser.parseCommaDelimitedKeyValuePairs( 45 | "app.sftp.param=value1,value2,value3"); 46 | 47 | assertTrue("Invalid number of deployment properties: " + deploymentProperties.size(), 48 | deploymentProperties.size() == 1); 49 | assertTrue("Expected deployment key not found", deploymentProperties.containsKey("app.sftp.param")); 50 | assertEquals("Invalid deployment value", "value1,value2,value3", deploymentProperties.get("app.sftp.param")); 51 | } 52 | 53 | @Test 54 | public void testParseSpelExpressionMultipleValues() { 55 | Map argExpressions = KeyValueListParser.parseCommaDelimitedKeyValuePairs( 56 | "arg1=payload.substr(0,2),arg2=headers['foo'],arg3=headers['bar']==false"); 57 | 58 | assertTrue("Invalid number of deployment properties: " + argExpressions.size(), 59 | argExpressions.size() == 3); 60 | assertTrue("Expected deployment key not found", argExpressions.containsKey("arg1")); 61 | assertEquals("Invalid deployment value", "payload.substr(0,2)", argExpressions.get("arg1")); 62 | 63 | assertTrue("Expected deployment key not found", argExpressions.containsKey("arg2")); 64 | assertEquals("Invalid deployment value", "headers['foo']", argExpressions.get("arg2")); 65 | 66 | assertTrue("Expected deployment key not found", argExpressions.containsKey("arg3")); 67 | assertEquals("Invalid deployment value", "headers['bar']==false", argExpressions.get("arg3")); 68 | } 69 | 70 | @Test 71 | public void testParseMultipleDeploymentPropertiesSingleValue() { 72 | Map deploymentProperties = KeyValueListParser.parseCommaDelimitedKeyValuePairs( 73 | "app.sftp.param=value1,app.sftp.other.param=value2"); 74 | 75 | assertTrue("Invalid number of deployment properties: " + deploymentProperties.size(), 76 | deploymentProperties.size() == 2); 77 | assertTrue("Expected deployment key not found", deploymentProperties.containsKey("app.sftp.param")); 78 | assertEquals("Invalid deployment value", "value1", deploymentProperties.get("app.sftp.param")); 79 | assertTrue("Expected deployment key not found", deploymentProperties.containsKey("app.sftp.other.param")); 80 | assertEquals("Invalid deployment value", "value2", deploymentProperties.get("app.sftp.other.param")); 81 | } 82 | 83 | @Test 84 | public void testParseMultipleDeploymentPropertiesMultipleValues() { 85 | DataflowTaskLaunchRequestProperties taskLaunchRequestProperties = new DataflowTaskLaunchRequestProperties(); 86 | 87 | Map deploymentProperties = KeyValueListParser.parseCommaDelimitedKeyValuePairs( 88 | "app.sftp.param=value1,value2,app.sftp.other.param=other1,other2"); 89 | 90 | assertTrue("Invalid number of deployment properties: " + deploymentProperties.size(), 91 | deploymentProperties.size() == 2); 92 | assertTrue("Expected deployment key not found", deploymentProperties.containsKey("app.sftp.param")); 93 | assertEquals("Invalid deployment value", "value1,value2", deploymentProperties.get("app.sftp.param")); 94 | assertTrue("Expected deployment key not found", deploymentProperties.containsKey("app.sftp.other.param")); 95 | assertEquals("Invalid deployment value", "other1,other2", deploymentProperties.get("app.sftp.other.param")); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /common/stream-apps-metadata-store-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | stream-apps-common 9 | org.springframework.cloud.stream.app 10 | 3.0.0.BUILD-SNAPSHOT 11 | 12 | 13 | stream-apps-metadata-store-common 14 | stream-apps-metadata-store-common 15 | 16 | 17 | 1.11.439 18 | 2.0.0.RELEASE 19 | 1.0.0.RELEASE 20 | 4.0.1 21 | 22 | 23 | 24 | 25 | 26 | org.springframework.integration 27 | spring-integration-core 28 | 29 | 30 | 31 | 32 | org.springframework.integration 33 | spring-integration-redis 34 | true 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-data-redis 39 | true 40 | 41 | 42 | 43 | 44 | org.springframework.integration 45 | spring-integration-mongodb 46 | true 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-data-mongodb 51 | true 52 | 53 | 54 | de.flapdoodle.embed 55 | de.flapdoodle.embed.mongo 56 | test 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-logging 63 | true 64 | 65 | 66 | org.apache.logging.log4j 67 | log4j-to-slf4j 68 | 69 | 70 | 71 | 72 | org.springframework.integration 73 | spring-integration-gemfire 74 | true 75 | 76 | 77 | org.springframework.data 78 | spring-data-gemfire 79 | 80 | 81 | 82 | 83 | 84 | org.springframework.data 85 | spring-data-geode 86 | true 87 | 88 | 93 | 94 | 95 | 96 | org.springframework.integration 97 | spring-integration-jdbc 98 | true 99 | 100 | 101 | org.springframework.boot 102 | spring-boot-starter-jdbc 103 | true 104 | 105 | 106 | org.hsqldb 107 | hsqldb 108 | test 109 | 110 | 111 | 112 | 113 | org.springframework.integration 114 | spring-integration-zookeeper 115 | true 116 | 117 | 118 | org.apache.curator 119 | curator-test 120 | ${curator.version} 121 | test 122 | 123 | 124 | 125 | 126 | org.springframework.integration 127 | spring-integration-hazelcast 128 | ${spring-integration-hazelcast.version} 129 | true 130 | 131 | 132 | 133 | 134 | org.springframework.integration 135 | spring-integration-aws 136 | ${spring-integration-aws.version} 137 | true 138 | 139 | 140 | com.amazonaws 141 | aws-java-sdk-dynamodb 142 | ${aws-java-sdk.version} 143 | true 144 | 145 | 146 | org.springframework.integration 147 | spring-integration-test 148 | test 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /common/stream-apps-test-support/src/main/java/org/springframework/cloud/stream/app/test/file/remote/RemoteFileTestSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.cloud.stream.app.test.file.remote; 17 | 18 | import java.io.File; 19 | import java.io.FileOutputStream; 20 | import java.io.IOException; 21 | 22 | import org.junit.Before; 23 | import org.junit.ClassRule; 24 | import org.junit.rules.TemporaryFolder; 25 | 26 | /** 27 | * Abstract base class for tests requiring remote file servers, e.g. (S)FTP. 28 | * 29 | * @author Gary Russell 30 | * 31 | */ 32 | public abstract class RemoteFileTestSupport { 33 | 34 | protected static final int port = 0; 35 | 36 | @ClassRule 37 | public static final TemporaryFolder remoteTemporaryFolder = new TemporaryFolder(); 38 | 39 | @ClassRule 40 | public static final TemporaryFolder localTemporaryFolder = new TemporaryFolder(); 41 | 42 | protected volatile File sourceRemoteDirectory; 43 | 44 | protected volatile File targetRemoteDirectory; 45 | 46 | protected volatile File sourceLocalDirectory; 47 | 48 | protected volatile File targetLocalDirectory; 49 | 50 | public File getSourceRemoteDirectory() { 51 | return sourceRemoteDirectory; 52 | } 53 | 54 | public File getTargetRemoteDirectory() { 55 | return targetRemoteDirectory; 56 | } 57 | 58 | public File getSourceLocalDirectory() { 59 | return sourceLocalDirectory; 60 | } 61 | 62 | public File getTargetLocalDirectory() { 63 | return targetLocalDirectory; 64 | } 65 | 66 | /** 67 | * Default implementation creates the following folder structures: 68 | * 69 | *
 70 | 	 *  $ tree remoteSource/
 71 | 	 *  remoteSource/
 72 | 	 *  ├── remoteSource1.txt - contains 'source1'
 73 | 	 *  ├── remoteSource2.txt - contains 'source2'
 74 | 	 *  remoteTarget/
 75 | 	 *  $ tree localSource/
 76 | 	 *  localSource/
 77 | 	 *  ├── localSource1.txt - contains 'local1'
 78 | 	 *  ├── localSource2.txt - contains 'local2'
 79 | 	 *  localTarget/
 80 | 	 * 
81 | * 82 | * The intent is tests retrieve from remoteSource and verify arrival in localTarget or send from localSource and verify 83 | * arrival in remoteTarget. 84 | *

85 | * Subclasses can change 'remote' in these names by overriding {@link #prefix()} or override this method completely to 86 | * create a different structure. 87 | *

88 | * While a single server exists for all tests, the directory structure is rebuilt for each test. 89 | * @throws IOException IO Exception. 90 | */ 91 | @Before 92 | public void setupFolders() throws IOException { 93 | String prefix = prefix(); 94 | recursiveDelete(new File(remoteTemporaryFolder.getRoot(), prefix + "Source")); 95 | this.sourceRemoteDirectory = remoteTemporaryFolder.newFolder(prefix + "Source"); 96 | recursiveDelete(new File(remoteTemporaryFolder.getRoot(), prefix + "Target")); 97 | this.targetRemoteDirectory = remoteTemporaryFolder.newFolder(prefix + "Target"); 98 | recursiveDelete(new File(localTemporaryFolder.getRoot(), "localSource")); 99 | this.sourceLocalDirectory = localTemporaryFolder.newFolder("localSource"); 100 | recursiveDelete(new File(localTemporaryFolder.getRoot(), "localTarget")); 101 | this.targetLocalDirectory = localTemporaryFolder.newFolder("localTarget"); 102 | File file = new File(sourceRemoteDirectory, prefix + "Source1.txt"); 103 | file.createNewFile(); 104 | FileOutputStream fos = new FileOutputStream(file); 105 | fos.write("source1".getBytes()); 106 | fos.close(); 107 | file = new File(sourceRemoteDirectory, prefix + "Source2.txt"); 108 | file.createNewFile(); 109 | fos = new FileOutputStream(file); 110 | fos.write("source2".getBytes()); 111 | fos.close(); 112 | file = new File(sourceLocalDirectory, "localSource1.txt"); 113 | file.createNewFile(); 114 | fos = new FileOutputStream(file); 115 | fos.write("local1".getBytes()); 116 | fos.close(); 117 | file = new File(sourceLocalDirectory, "localSource2.txt"); 118 | file.createNewFile(); 119 | fos = new FileOutputStream(file); 120 | fos.write("local2".getBytes()); 121 | fos.close(); 122 | } 123 | 124 | public void recursiveDelete(File file) { 125 | if (file != null && file.exists()) { 126 | File[] files = file.listFiles(); 127 | if (files != null) { 128 | for (File fyle : files) { 129 | if (fyle.isDirectory()) { 130 | recursiveDelete(fyle); 131 | } 132 | else { 133 | fyle.delete(); 134 | } 135 | } 136 | } 137 | file.delete(); 138 | } 139 | } 140 | 141 | /** 142 | * Prefix for directory/file structure; default 'remote'. 143 | * @return the prefix. 144 | */ 145 | protected String prefix() { 146 | return "remote"; 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | set MAVEN_CMD_LINE_ARGS=%* 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | 121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" 122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 123 | 124 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% 125 | if ERRORLEVEL 1 goto error 126 | goto end 127 | 128 | :error 129 | set ERROR_CODE=1 130 | 131 | :end 132 | @endlocal & set ERROR_CODE=%ERROR_CODE% 133 | 134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 138 | :skipRcPost 139 | 140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 142 | 143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 144 | 145 | exit /B %ERROR_CODE% 146 | -------------------------------------------------------------------------------- /common/stream-apps-metadata-store-common/src/test/java/org/springframework/cloud/stream/app/metadata/MetadataStoreAutoConfigurationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.springframework.cloud.stream.app.metadata; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | import static org.mockito.ArgumentMatchers.any; 20 | import static org.mockito.BDDMockito.willReturn; 21 | import static org.mockito.Mockito.mock; 22 | 23 | import java.beans.Introspector; 24 | import java.nio.charset.StandardCharsets; 25 | import java.util.Arrays; 26 | import java.util.List; 27 | import java.util.function.Predicate; 28 | 29 | import org.apache.curator.test.TestingServer; 30 | import org.junit.Ignore; 31 | import org.junit.Test; 32 | import org.junit.runner.RunWith; 33 | import org.junit.runners.Parameterized; 34 | 35 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 36 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 37 | import org.springframework.boot.test.context.FilteredClassLoader; 38 | import org.springframework.boot.test.context.runner.ApplicationContextRunner; 39 | import org.springframework.cloud.aws.core.region.RegionProvider; 40 | import org.springframework.context.annotation.Bean; 41 | import org.springframework.context.annotation.Configuration; 42 | import org.springframework.integration.aws.metadata.DynamoDbMetadataStore; 43 | import org.springframework.integration.gemfire.metadata.GemfireMetadataStore; 44 | import org.springframework.integration.hazelcast.metadata.HazelcastMetadataStore; 45 | import org.springframework.integration.jdbc.metadata.JdbcMetadataStore; 46 | import org.springframework.integration.metadata.ConcurrentMetadataStore; 47 | import org.springframework.integration.metadata.MetadataStore; 48 | import org.springframework.integration.metadata.SimpleMetadataStore; 49 | import org.springframework.integration.mongodb.metadata.MongoDbMetadataStore; 50 | import org.springframework.integration.redis.metadata.RedisMetadataStore; 51 | import org.springframework.integration.zookeeper.metadata.ZookeeperMetadataStore; 52 | 53 | import com.amazonaws.auth.AWSCredentialsProvider; 54 | import com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsync; 55 | import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest; 56 | import com.amazonaws.services.dynamodbv2.model.DescribeTableResult; 57 | 58 | /** 59 | * @author Artem Bilan 60 | * 61 | * @since 2.0.2 62 | */ 63 | @RunWith(Parameterized.class) 64 | @Ignore 65 | public class MetadataStoreAutoConfigurationTests { 66 | 67 | private final static List> METADATA_STORE_CLASSES = 68 | Arrays.asList( 69 | RedisMetadataStore.class, 70 | MongoDbMetadataStore.class, 71 | GemfireMetadataStore.class, 72 | JdbcMetadataStore.class, 73 | ZookeeperMetadataStore.class, 74 | HazelcastMetadataStore.class, 75 | DynamoDbMetadataStore.class, 76 | SimpleMetadataStore.class 77 | ); 78 | 79 | private static FilteredClassLoader filteredClassLoaderBut(Class classToInclude) { 80 | return new FilteredClassLoader( 81 | METADATA_STORE_CLASSES.stream() 82 | .filter(Predicate.isEqual(classToInclude).negate()) 83 | .toArray(Class[]::new)); 84 | } 85 | 86 | private final ApplicationContextRunner contextRunner; 87 | 88 | private final Class classToInclude; 89 | 90 | 91 | public MetadataStoreAutoConfigurationTests(Class classToInclude) { 92 | this.classToInclude = classToInclude; 93 | this.contextRunner = 94 | new ApplicationContextRunner() 95 | .withUserConfiguration(TestConfiguration.class) 96 | .withClassLoader(filteredClassLoaderBut(classToInclude)); 97 | } 98 | 99 | @Parameterized.Parameters 100 | public static Iterable parameters() { 101 | return METADATA_STORE_CLASSES; 102 | } 103 | 104 | @Test 105 | public void testMetadataStore() { 106 | this.contextRunner 107 | .run(context -> { 108 | assertThat(context.getBeansOfType(MetadataStore.class)).hasSize(1); 109 | 110 | assertThat(context.getBeanNamesForType(this.classToInclude)) 111 | .containsOnlyOnce(Introspector.decapitalize(this.classToInclude.getSimpleName())); 112 | }); 113 | } 114 | 115 | @Configuration 116 | @EnableAutoConfiguration 117 | public static class TestConfiguration { 118 | 119 | @Bean(destroyMethod = "stop") 120 | @ConditionalOnClass(ZookeeperMetadataStore.class) 121 | public static TestingServer zookeeperTestingServer() throws Exception { 122 | TestingServer testingServer = new TestingServer(true); 123 | 124 | System.setProperty("metadata.store.zookeeper.connect-string", testingServer.getConnectString()); 125 | System.setProperty("metadata.store.zookeeper.encoding", StandardCharsets.US_ASCII.name()); 126 | 127 | return testingServer; 128 | } 129 | 130 | @Configuration 131 | @ConditionalOnClass(DynamoDbMetadataStore.class) 132 | protected static class DynamoDbMockConfig { 133 | 134 | @Bean 135 | public static AmazonDynamoDBAsync dynamoDB() { 136 | AmazonDynamoDBAsync dynamoDb = mock(AmazonDynamoDBAsync.class); 137 | willReturn(new DescribeTableResult()) 138 | .given(dynamoDb) 139 | .describeTable(any(DescribeTableRequest.class)); 140 | 141 | return dynamoDb; 142 | } 143 | 144 | @Bean 145 | public static AWSCredentialsProvider awsCredentialsProvider() { 146 | return mock(AWSCredentialsProvider.class); 147 | } 148 | 149 | @Bean 150 | public static RegionProvider regionProvider() { 151 | return mock(RegionProvider.class); 152 | } 153 | 154 | } 155 | 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /common/stream-apps-task-launch-request-common/src/main/java/org/springframework/cloud/stream/app/tasklaunchrequest/DataFlowTaskLaunchRequestAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.cloud.stream.app.tasklaunchrequest; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Collection; 21 | import java.util.HashMap; 22 | import java.util.LinkedList; 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | import javax.annotation.PostConstruct; 27 | import org.apache.commons.logging.Log; 28 | import org.apache.commons.logging.LogFactory; 29 | import org.springframework.beans.factory.BeanFactory; 30 | import org.springframework.beans.factory.annotation.Autowired; 31 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 32 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 33 | import org.springframework.cloud.stream.app.tasklaunchrequest.support.CommandLineArgumentsMessageMapper; 34 | import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskLaunchRequestSupplier; 35 | import org.springframework.cloud.stream.app.tasklaunchrequest.support.TaskNameMessageMapper; 36 | import org.springframework.context.annotation.Bean; 37 | import org.springframework.context.annotation.Configuration; 38 | import org.springframework.expression.EvaluationContext; 39 | import org.springframework.expression.Expression; 40 | import org.springframework.expression.spel.standard.SpelExpressionParser; 41 | import org.springframework.integration.expression.ExpressionUtils; 42 | import org.springframework.messaging.Message; 43 | import org.springframework.util.StringUtils; 44 | 45 | 46 | /** 47 | * @author David Turanski 48 | **/ 49 | @Configuration 50 | @EnableConfigurationProperties(DataflowTaskLaunchRequestProperties.class) 51 | public class DataFlowTaskLaunchRequestAutoConfiguration { 52 | 53 | @Autowired 54 | private BeanFactory beanFactory; 55 | 56 | private EvaluationContext evaluationContext; 57 | 58 | public final static String TASK_LAUNCH_REQUEST_FUNCTION_NAME = "taskLaunchRequest"; 59 | 60 | /** 61 | * A {@link java.util.function.Function} to transform a {@link Message} payload to a {@link DataFlowTaskLaunchRequest}. 62 | * 63 | * @param taskLaunchRequestMessageProcessor a {@link TaskLaunchRequestMessageProcessor}. 64 | * 65 | * @return a {code DataFlowTaskLaunchRequest} Message. 66 | */ 67 | @Bean(name = TASK_LAUNCH_REQUEST_FUNCTION_NAME) 68 | @ConditionalOnMissingBean(TaskLaunchRequestFunction.class) 69 | public TaskLaunchRequestFunction taskLaunchRequest(TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor) { 70 | return message -> taskLaunchRequestMessageProcessor.postProcessMessage(message); 71 | } 72 | 73 | @Bean 74 | @ConditionalOnMissingBean(TaskNameMessageMapper.class) 75 | public TaskNameMessageMapper taskNameMessageMapper(DataflowTaskLaunchRequestProperties taskLaunchRequestProperties) { 76 | if (StringUtils.hasText(taskLaunchRequestProperties.getTaskNameExpression())) { 77 | SpelExpressionParser expressionParser = new SpelExpressionParser(); 78 | Expression taskNameExpression = expressionParser.parseExpression(taskLaunchRequestProperties.getTaskNameExpression()); 79 | return new ExpressionEvaluatingTaskNameMessageMapper(taskNameExpression, this.evaluationContext); 80 | } 81 | 82 | return message -> taskLaunchRequestProperties.getTaskName(); 83 | } 84 | 85 | @Bean 86 | @ConditionalOnMissingBean(CommandLineArgumentsMessageMapper.class) 87 | public CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper( 88 | DataflowTaskLaunchRequestProperties dataflowTaskLaunchRequestProperties){ 89 | 90 | return new ExpressionEvaluatingCommandLineArgsMapper(dataflowTaskLaunchRequestProperties.getArgExpressions(), 91 | this.evaluationContext); 92 | } 93 | 94 | @Bean 95 | public TaskLaunchRequestSupplier taskLaunchRequestInitializer( 96 | DataflowTaskLaunchRequestProperties taskLaunchRequestProperties){ 97 | return new DataflowTaskLaunchRequestPropertiesInitializer(taskLaunchRequestProperties); 98 | } 99 | 100 | @Bean 101 | public TaskLaunchRequestMessageProcessor taskLaunchRequestMessageProcessor( 102 | TaskLaunchRequestSupplier taskLaunchRequestInitializer, 103 | TaskNameMessageMapper taskNameMessageMapper, 104 | CommandLineArgumentsMessageMapper commandLineArgumentsMessageMapper) { 105 | 106 | return new TaskLaunchRequestMessageProcessor(taskLaunchRequestInitializer, 107 | taskNameMessageMapper, 108 | commandLineArgumentsMessageMapper); 109 | } 110 | 111 | static class DataflowTaskLaunchRequestPropertiesInitializer extends TaskLaunchRequestSupplier { 112 | DataflowTaskLaunchRequestPropertiesInitializer( 113 | DataflowTaskLaunchRequestProperties taskLaunchRequestProperties){ 114 | 115 | this.commandLineArgumentSupplier( 116 | () -> new ArrayList<>(taskLaunchRequestProperties.getArgs()) 117 | ); 118 | 119 | this.deploymentPropertiesSupplier( 120 | () -> KeyValueListParser.parseCommaDelimitedKeyValuePairs( 121 | taskLaunchRequestProperties.getDeploymentProperties()) 122 | ); 123 | 124 | this.taskNameSupplier(()->taskLaunchRequestProperties.getTaskName()); 125 | } 126 | } 127 | 128 | static class ExpressionEvaluatingCommandLineArgsMapper implements CommandLineArgumentsMessageMapper { 129 | private final Map argExpressionsMap; 130 | private final EvaluationContext evaluationContext; 131 | 132 | ExpressionEvaluatingCommandLineArgsMapper(String argExpressions, EvaluationContext evaluationContext) { 133 | this.evaluationContext = evaluationContext; 134 | this.argExpressionsMap = new HashMap<>(); 135 | if (StringUtils.hasText(argExpressions)) { 136 | SpelExpressionParser expressionParser = new SpelExpressionParser(); 137 | 138 | KeyValueListParser.parseCommaDelimitedKeyValuePairs(argExpressions).forEach( 139 | (k,v)-> argExpressionsMap.put(k, expressionParser.parseExpression(v))); 140 | } 141 | 142 | } 143 | 144 | @Override 145 | public Collection processMessage(Message message) { 146 | return evaluateArgExpressions(message); 147 | } 148 | 149 | private Collection evaluateArgExpressions(Message message) { 150 | List results = new LinkedList<>(); 151 | this.argExpressionsMap.forEach((k, expression) -> 152 | results.add(String.format("%s=%s", k, expression.getValue(this.evaluationContext, message)))); 153 | return results; 154 | } 155 | } 156 | 157 | @PostConstruct 158 | public void createEvaluationContext(){ 159 | this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.beanFactory); 160 | } 161 | 162 | } 163 | -------------------------------------------------------------------------------- /common/stream-apps-metadata-store-common/src/main/java/org/springframework/cloud/stream/app/metadata/MetadataStoreProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 the original author or authors. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * https://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | package org.springframework.cloud.stream.app.metadata; 17 | 18 | import java.nio.charset.Charset; 19 | import java.nio.charset.StandardCharsets; 20 | 21 | import org.springframework.boot.context.properties.ConfigurationProperties; 22 | import org.springframework.integration.aws.metadata.DynamoDbMetadataStore; 23 | import org.springframework.integration.gemfire.metadata.GemfireMetadataStore; 24 | import org.springframework.integration.jdbc.metadata.JdbcMetadataStore; 25 | import org.springframework.integration.redis.metadata.RedisMetadataStore; 26 | 27 | /** 28 | * @author Artem Bilan 29 | * 30 | * @since 2.0.2 31 | */ 32 | @ConfigurationProperties("metadata.store") 33 | public class MetadataStoreProperties { 34 | 35 | private final Mongo mongoDb = new Mongo(); 36 | 37 | private final Gemfire gemfire = new Gemfire(); 38 | 39 | private final Redis redis = new Redis(); 40 | 41 | private final DynamoDb dynamoDb = new DynamoDb(); 42 | 43 | private final Jdbc jdbc = new Jdbc(); 44 | 45 | private final Zookeeper zookeeper = new Zookeeper(); 46 | 47 | public Mongo getMongoDb() { 48 | return this.mongoDb; 49 | } 50 | 51 | public Gemfire getGemfire() { 52 | return this.gemfire; 53 | } 54 | 55 | public Redis getRedis() { 56 | return this.redis; 57 | } 58 | 59 | public DynamoDb getDynamoDb() { 60 | return this.dynamoDb; 61 | } 62 | 63 | public Jdbc getJdbc() { 64 | return this.jdbc; 65 | } 66 | 67 | public Zookeeper getZookeeper() { 68 | return this.zookeeper; 69 | } 70 | 71 | public static class Mongo { 72 | 73 | /** 74 | * MongoDB collection name for metadata. 75 | */ 76 | private String collection = "metadataStore"; 77 | 78 | public String getCollection() { 79 | return this.collection; 80 | } 81 | 82 | public void setCollection(String collection) { 83 | this.collection = collection; 84 | } 85 | 86 | } 87 | 88 | public static class Gemfire { 89 | 90 | /** 91 | * Gemfire region name for metadata. 92 | */ 93 | private String region = GemfireMetadataStore.KEY; 94 | 95 | public String getRegion() { 96 | return this.region; 97 | } 98 | 99 | public void setRegion(String region) { 100 | this.region = region; 101 | } 102 | 103 | } 104 | 105 | public static class Redis { 106 | 107 | /** 108 | * Redis key for metadata. 109 | */ 110 | private String key = RedisMetadataStore.KEY; 111 | 112 | public String getKey() { 113 | return this.key; 114 | } 115 | 116 | public void setKey(String key) { 117 | this.key = key; 118 | } 119 | 120 | } 121 | 122 | public static class DynamoDb { 123 | 124 | /** 125 | * Table name for metadata. 126 | */ 127 | private String table = DynamoDbMetadataStore.DEFAULT_TABLE_NAME; 128 | 129 | /** 130 | * Read capacity on the table. 131 | */ 132 | private long readCapacity = 1L; 133 | 134 | /** 135 | * Write capacity on the table. 136 | */ 137 | private long writeCapacity = 1L; 138 | 139 | /** 140 | * Delay between create table retries. 141 | */ 142 | private int createDelay = 1; 143 | 144 | /** 145 | * Retry number for create table request. 146 | */ 147 | private int createRetries = 25; 148 | 149 | /** 150 | * TTL for table entries. 151 | */ 152 | private Integer timeToLive; 153 | 154 | public String getTable() { 155 | return this.table; 156 | } 157 | 158 | public void setTable(String table) { 159 | this.table = table; 160 | } 161 | 162 | public long getReadCapacity() { 163 | return this.readCapacity; 164 | } 165 | 166 | public void setReadCapacity(long readCapacity) { 167 | this.readCapacity = readCapacity; 168 | } 169 | 170 | public long getWriteCapacity() { 171 | return this.writeCapacity; 172 | } 173 | 174 | public void setWriteCapacity(long writeCapacity) { 175 | this.writeCapacity = writeCapacity; 176 | } 177 | 178 | public int getCreateDelay() { 179 | return this.createDelay; 180 | } 181 | 182 | public void setCreateDelay(int createDelay) { 183 | this.createDelay = createDelay; 184 | } 185 | 186 | public int getCreateRetries() { 187 | return this.createRetries; 188 | } 189 | 190 | public void setCreateRetries(int createRetries) { 191 | this.createRetries = createRetries; 192 | } 193 | 194 | public Integer getTimeToLive() { 195 | return this.timeToLive; 196 | } 197 | 198 | public void setTimeToLive(Integer timeToLive) { 199 | this.timeToLive = timeToLive; 200 | } 201 | 202 | } 203 | 204 | public static class Jdbc { 205 | 206 | /** 207 | * Prefix for the custom table name. 208 | */ 209 | private String tablePrefix = JdbcMetadataStore.DEFAULT_TABLE_PREFIX; 210 | 211 | /** 212 | * Unique grouping identifier for messages persisted with this store. 213 | */ 214 | private String region = "DEFAULT"; 215 | 216 | public String getTablePrefix() { 217 | return this.tablePrefix; 218 | } 219 | 220 | public void setTablePrefix(String tablePrefix) { 221 | this.tablePrefix = tablePrefix; 222 | } 223 | 224 | public String getRegion() { 225 | return this.region; 226 | } 227 | 228 | public void setRegion(String region) { 229 | this.region = region; 230 | } 231 | 232 | } 233 | 234 | public static class Zookeeper { 235 | 236 | /** 237 | * Zookeeper connect string in form HOST:PORT. 238 | */ 239 | private String connectString = "127.0.0.1:2181"; 240 | 241 | /** 242 | * Retry interval for Zookeeper operations in milliseconds. 243 | */ 244 | private int retryInterval = 1000; 245 | 246 | /** 247 | * Encoding to use when storing data in Zookeeper. 248 | */ 249 | private Charset encoding = StandardCharsets.UTF_8; 250 | 251 | /** 252 | * Root node - store entries are children of this node. 253 | */ 254 | private String root = "/SpringIntegration-MetadataStore"; 255 | 256 | public String getConnectString() { 257 | return connectString; 258 | } 259 | 260 | public void setConnectString(String connectString) { 261 | this.connectString = connectString; 262 | } 263 | 264 | public int getRetryInterval() { 265 | return this.retryInterval; 266 | } 267 | 268 | public void setRetryInterval(int retryInterval) { 269 | this.retryInterval = retryInterval; 270 | } 271 | 272 | public Charset getEncoding() { 273 | return this.encoding; 274 | } 275 | 276 | public void setEncoding(Charset encoding) { 277 | this.encoding = encoding; 278 | } 279 | 280 | public String getRoot() { 281 | return this.root; 282 | } 283 | 284 | public void setRoot(String root) { 285 | this.root = root; 286 | } 287 | 288 | } 289 | 290 | } 291 | -------------------------------------------------------------------------------- /common/stream-apps-metadata-store-common/README.adoc: -------------------------------------------------------------------------------- 1 | === `MetadataStore` Common Module 2 | 3 | This artifact contains a Spring Boot auto-configuration for the `MetadataStore`which can be used in various Spring Integration scenarios, like file polling, idempotent receiver, offset management etc. 4 | See Spring Integration "`https://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/system-management-chapter.html#metadata-store[Reference Manual]`" for more information. 5 | 6 | In addition to the standard Spring Boot configuration properties this module exposes a `MetadataStoreProperties` with the `metadata.store` prefix. 7 | 8 | To auto-configure particular `MetadataStore` you just need to bring respective dependencies into the target app starter: 9 | 10 | ==== Redis 11 | 12 | The `RedisMetadataStore` requires regular Spring Boot auto-configuration for https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-redis[Spring Data Redis] and minimal set of dependencies is like this: 13 | 14 | [source,xml] 15 | ---- 16 | 17 | org.springframework.integration 18 | spring-integration-redis 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-data-redis 23 | 24 | ---- 25 | 26 | Additional configuration property for `RedisMetadataStore` is: 27 | 28 | $$metadata.store.redis.key$$:: $$Redis key for metadata.$$ *($$String$$, default: `$$MetaData$$`)* 29 | 30 | ==== MongoDb 31 | 32 | The `MongoDbMetadataStore` requires regular Spring Boot auto-configuration for https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-mongodb[Spring Data MongoDB] and minimal set of dependencies is like this: 33 | 34 | [source,xml] 35 | ---- 36 | 37 | org.springframework.integration 38 | spring-integration-mongodb 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-starter-data-mongodb 43 | 44 | ---- 45 | 46 | Additional configuration property for `MongoDbMetadataStore` is: 47 | 48 | $$metadata.store.mongo-db.collection$$:: $$MongoDB collection name for metadata.$$ *($$String$$, default: `$$metadataStore$$`)* 49 | 50 | ==== Pivotal Gemfire / Apache Geode 51 | 52 | The `GemfireMetadataStore` requires these dependencies for auto-configuration: 53 | 54 | [source,xml] 55 | ---- 56 | 57 | org.springframework.integration 58 | spring-integration-gemfire 59 | 60 | ---- 61 | 62 | or when your environment is based on the Open Source https://geode.apache.org/[Apache Geode]: 63 | 64 | [source,xml] 65 | ---- 66 | 67 | org.springframework.integration 68 | spring-integration-gemfire 69 | 70 | 71 | org.springframework.data 72 | spring-data-gemfire 73 | 74 | 75 | 76 | 77 | org.springframework.data 78 | spring-data-geode 79 | 80 | ---- 81 | 82 | You also can consider to use https://github.com/spring-projects/spring-boot-data-geode[Spring Boot Data Geode] instead for automatic dependency management and proper Spring Boot auto-configuration for Pivotal Gemfire/Apache Geode. 83 | 84 | Additional configuration property for `GemfireMetadataStore` is: 85 | 86 | $$metadata.store.gemfire.region$$:: $$Gemfire region name for metadata.$$ *($$String$$, default: `$$MetaData$$`)* 87 | 88 | In addition, for the `GemfireMetadataStore`, a `MetadataStoreListener` bean can be configured in the application context to react to the `MetadataStore` events. 89 | 90 | A default auto-configured `ClientRegionFactoryBean`, based on the auto-configured `GemFireCache`, bean can be overridden in the target application. 91 | 92 | ==== Hazelcast 93 | 94 | The `HazelcastMetadataStore` requires regular Spring Boot auto-configuration for https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-caching-provider-hazelcast[Hazelcast] and minimal set of dependencies is like this: 95 | 96 | [source,xml] 97 | ---- 98 | 99 | org.springframework.integration 100 | spring-integration-hazelcast 101 | 102 | ---- 103 | 104 | There are no additional configuration properties for the `HazelcastMetadataStore`, however a `MetadataStoreListener` bean can be configured in the application context to react to the `MetadataStore` events. 105 | 106 | ==== Zookeeper 107 | 108 | The `ZookeeperMetadataStore` requires this dependency for auto-configuration: 109 | 110 | [source,xml] 111 | ---- 112 | 113 | org.springframework.integration 114 | spring-integration-zookeeper 115 | 116 | ---- 117 | 118 | The configuration properties for `ZookeeperMetadataStore` are: 119 | 120 | $$metadata.store.zookeeper.connect-string$$:: $$Zookeeper connect string in form HOST:PORT.$$ *($$String$$, default: `$$127.0.0.1:2181$$`)* 121 | $$metadata.store.zookeeper.retry-interval$$:: $$Retry interval for Zookeeper operations in milliseconds.$$ *($$int$$, default: `$$1000$$`)* 122 | $$metadata.store.zookeeper.encoding$$:: $$Encoding to use when storing data in Zookeeper.$$ *($$Charset$$, default: `$$UTF-8$$`)* 123 | $$metadata.store.zookeeper.root$$:: $$Root node - store entries are children of this node.$$ *($$String$$, default: `$$/SpringIntegration-MetadataStore$$`)* 124 | 125 | In addition, for the `ZookeeperMetadataStore`, a `MetadataStoreListener` bean can be configured in the application context to react to the `MetadataStore` events. 126 | Also a `CuratorFramework` bean can be provided to override a default auto-configured one. 127 | 128 | ==== AWS DymanoDb 129 | 130 | The `DynamoDbMetadataStore` requires regular Spring Cloud AWS auto-configuration for https://cloud.spring.io/spring-cloud-static/spring-cloud-aws/2.0.0.RELEASE/single/spring-cloud-aws.html#_spring_boot_auto_configuration[Spring Boot] and minimal set of dependencies is like this: 131 | 132 | [source,xml] 133 | ---- 134 | 135 | org.springframework.integration 136 | spring-integration-aws 137 | 138 | 139 | com.amazonaws 140 | aws-java-sdk-dynamodb 141 | 142 | ---- 143 | 144 | Additional configuration properties for `DynamoDbMetadataStore` are: 145 | 146 | $$metadata.store.dynamo-db.table:: $$Table name for metadata.$$ *($$String$$, default: `$$SpringIntegrationMetadataStore$$`)* 147 | $$metadata.store.dynamo-db.read-capacity:: $$Read capacity on the table.$$ *($$long$$, default: `$$1$$`)* 148 | $$metadata.store.dynamo-db.write-capacity:: $$Write capacity on the table.$$ *($$long$$, default: `$$1$$`)* 149 | $$metadata.store.dynamo-db.create-delay:: $$Delay between create table retries.$$ *($$int$$, default: `$$1$$`)* 150 | $$metadata.store.dynamo-db.create-retries:: $$Retry number for create table request.$$ *($$int$$, default: `$$25$$`)* 151 | $$metadata.store.dynamo-db.time-to-live:: $$TTL for table entries.$$ *($$Integer$$, default: `$$$$`)* 152 | 153 | A default, auto-configured `AmazonDynamoDBAsync` bean can be overridden in the target application. 154 | 155 | ==== JDBC 156 | 157 | The `JdbcMetadataStore` requires regular Spring Boot auto-configuration for https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-sql[JDBC DataSource] and minimal set of dependencies is like this: 158 | 159 | [source,xml] 160 | ---- 161 | 162 | org.springframework.integration 163 | spring-integration-jdbc 164 | 165 | 166 | org.springframework.boot 167 | spring-boot-starter-jdbc 168 | 169 | ---- 170 | 171 | Plus vendor-specific JDBC driver artifact(s). 172 | 173 | Additional configuration properties for `JdbcMetadataStore` are: 174 | 175 | $$metadata.store.jdbc.table-prefix:: $$Prefix for the custom table name.$$ *($$String$$, default: `$$INT_$$`)* 176 | $$metadata.store.jdbc.region:: $$Unique grouping identifier for messages persisted with this store.$$ *($$String$$, default: `$$DEFAULT$$`)* 177 | 178 | 179 | 180 | When no any of those technologies dependencies are preset, an in-memory `SimpleMetadataStore` is auto-configured. 181 | The target application can also provide its own `MetadataStore` bean to override any auto-configuration hooks. 182 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # 58 | # Look for the Apple JDKs first to preserve the existing behaviour, and then look 59 | # for the new JDKs provided by Oracle. 60 | # 61 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then 62 | # 63 | # Apple JDKs 64 | # 65 | export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home 66 | fi 67 | 68 | if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then 69 | # 70 | # Apple JDKs 71 | # 72 | export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 73 | fi 74 | 75 | if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then 76 | # 77 | # Oracle JDKs 78 | # 79 | export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home 80 | fi 81 | 82 | if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then 83 | # 84 | # Apple JDKs 85 | # 86 | export JAVA_HOME=`/usr/libexec/java_home` 87 | fi 88 | ;; 89 | esac 90 | 91 | if [ -z "$JAVA_HOME" ] ; then 92 | if [ -r /etc/gentoo-release ] ; then 93 | JAVA_HOME=`java-config --jre-home` 94 | fi 95 | fi 96 | 97 | if [ -z "$M2_HOME" ] ; then 98 | ## resolve links - $0 may be a link to maven's home 99 | PRG="$0" 100 | 101 | # need this for relative symlinks 102 | while [ -h "$PRG" ] ; do 103 | ls=`ls -ld "$PRG"` 104 | link=`expr "$ls" : '.*-> \(.*\)$'` 105 | if expr "$link" : '/.*' > /dev/null; then 106 | PRG="$link" 107 | else 108 | PRG="`dirname "$PRG"`/$link" 109 | fi 110 | done 111 | 112 | saveddir=`pwd` 113 | 114 | M2_HOME=`dirname "$PRG"`/.. 115 | 116 | # make it fully qualified 117 | M2_HOME=`cd "$M2_HOME" && pwd` 118 | 119 | cd "$saveddir" 120 | # echo Using m2 at $M2_HOME 121 | fi 122 | 123 | # For Cygwin, ensure paths are in UNIX format before anything is touched 124 | if $cygwin ; then 125 | [ -n "$M2_HOME" ] && 126 | M2_HOME=`cygpath --unix "$M2_HOME"` 127 | [ -n "$JAVA_HOME" ] && 128 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 129 | [ -n "$CLASSPATH" ] && 130 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 131 | fi 132 | 133 | # For Migwn, ensure paths are in UNIX format before anything is touched 134 | if $mingw ; then 135 | [ -n "$M2_HOME" ] && 136 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 137 | [ -n "$JAVA_HOME" ] && 138 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 139 | # TODO classpath? 140 | fi 141 | 142 | if [ -z "$JAVA_HOME" ]; then 143 | javaExecutable="`which javac`" 144 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 145 | # readlink(1) is not available as standard on Solaris 10. 146 | readLink=`which readlink` 147 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 148 | if $darwin ; then 149 | javaHome="`dirname \"$javaExecutable\"`" 150 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 151 | else 152 | javaExecutable="`readlink -f \"$javaExecutable\"`" 153 | fi 154 | javaHome="`dirname \"$javaExecutable\"`" 155 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 156 | JAVA_HOME="$javaHome" 157 | export JAVA_HOME 158 | fi 159 | fi 160 | fi 161 | 162 | if [ -z "$JAVACMD" ] ; then 163 | if [ -n "$JAVA_HOME" ] ; then 164 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 165 | # IBM's JDK on AIX uses strange locations for the executables 166 | JAVACMD="$JAVA_HOME/jre/sh/java" 167 | else 168 | JAVACMD="$JAVA_HOME/bin/java" 169 | fi 170 | else 171 | JAVACMD="`which java`" 172 | fi 173 | fi 174 | 175 | if [ ! -x "$JAVACMD" ] ; then 176 | echo "Error: JAVA_HOME is not defined correctly." >&2 177 | echo " We cannot execute $JAVACMD" >&2 178 | exit 1 179 | fi 180 | 181 | if [ -z "$JAVA_HOME" ] ; then 182 | echo "Warning: JAVA_HOME environment variable is not set." 183 | fi 184 | 185 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 186 | 187 | # For Cygwin, switch paths to Windows format before running java 188 | if $cygwin; then 189 | [ -n "$M2_HOME" ] && 190 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 191 | [ -n "$JAVA_HOME" ] && 192 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 193 | [ -n "$CLASSPATH" ] && 194 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 195 | fi 196 | 197 | # traverses directory structure from process work directory to filesystem root 198 | # first directory with .mvn subdirectory is considered project base directory 199 | find_maven_basedir() { 200 | local basedir=$(pwd) 201 | local wdir=$(pwd) 202 | while [ "$wdir" != '/' ] ; do 203 | if [ -d "$wdir"/.mvn ] ; then 204 | basedir=$wdir 205 | break 206 | fi 207 | wdir=$(cd "$wdir/.."; pwd) 208 | done 209 | echo "${basedir}" 210 | } 211 | 212 | # concatenates all lines of a file 213 | concat_lines() { 214 | if [ -f "$1" ]; then 215 | echo "$(tr -s '\n' ' ' < "$1")" 216 | fi 217 | } 218 | 219 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} 220 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 221 | 222 | # Provide a "standardized" way to retrieve the CLI args that will 223 | # work with both Windows and non-Windows executions. 224 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 225 | export MAVEN_CMD_LINE_ARGS 226 | 227 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 228 | 229 | echo "Running version check" 230 | VERSION=$( sed '\!//' -e 's!.*$!!' ) 231 | echo "The found version is [${VERSION}]" 232 | 233 | if echo $VERSION | egrep -q 'M|RC'; then 234 | echo Activating \"milestone\" profile for version=\"$VERSION\" 235 | echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone" 236 | else 237 | echo Deactivating \"milestone\" profile for version=\"$VERSION\" 238 | echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//') 239 | fi 240 | 241 | if echo $VERSION | egrep -q 'RELEASE'; then 242 | echo Activating \"central\" profile for version=\"$VERSION\" 243 | echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral" 244 | else 245 | echo Deactivating \"central\" profile for version=\"$VERSION\" 246 | echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//') 247 | fi 248 | 249 | exec "$JAVACMD" \ 250 | $MAVEN_OPTS \ 251 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 252 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 253 | ${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@" 254 | --------------------------------------------------------------------------------