diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..d5cedf3e9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: 'type: bug, status: waiting-for-triage' +assignees: '' + +--- + +**In what version(s) of Spring Integration are you seeing this issue?** + +For example: + +2.5.3 + +Between 2.5.0 and 3.0.0 + +**Describe the bug** + +A clear and concise description of what the bug is. + +**To Reproduce** + +Steps to reproduce the behavior. + +**Expected behavior** + +A clear and concise description of what you expected to happen. + +**Sample** + +A link to a GitHub repository with a [minimal, reproducible sample](https://stackoverflow.com/help/minimal-reproducible-example). + +Reports that include a sample will take priority over reports that do not. +At times, we may require a sample, so it is good to try and include a sample up front. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..dee93ce52 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Community Support + url: https://stackoverflow.com/questions/tagged/spring-integration + about: Please ask and answer questions on StackOverflow with the tag spring-integration diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..381a8977f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,25 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: 'status: waiting-for-triage, type: enhancement' +assignees: '' + +--- + +**Expected Behavior** + + + +**Current Behavior** + + + +**Context** + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..abee66f66 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,6 @@ + diff --git a/.github/dco.yml b/.github/dco.yml new file mode 100644 index 000000000..0c4b142e9 --- /dev/null +++ b/.github/dco.yml @@ -0,0 +1,2 @@ +require: + members: false diff --git a/.github/workflows/ci-snapshot.yml b/.github/workflows/ci-snapshot.yml new file mode 100644 index 000000000..22ecb4dc5 --- /dev/null +++ b/.github/workflows/ci-snapshot.yml @@ -0,0 +1,29 @@ +name: CI SNAPSHOT + +on: + workflow_dispatch: + push: + branches: + - main + +env: + DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }} + +jobs: + build_snapshot: + runs-on: ubuntu-latest + name: CI Build SNAPSHOT for ${{ github.ref_name }} + steps: + + - uses: actions/checkout@v4 + with: + show-progress: false + + - name: Set up Gradle + uses: spring-io/spring-gradle-build-action@v2 + with: + java-version: 24 + + - name: Build + run: ./gradlew check + diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml new file mode 100644 index 000000000..e5457892c --- /dev/null +++ b/.github/workflows/pr-build.yml @@ -0,0 +1,10 @@ +name: Pull Request Build + +on: + pull_request: + branches: + - main + +jobs: + build-pull-request: + uses: spring-io/spring-github-workflows/.github/workflows/spring-gradle-pull-request-build.yml@main diff --git a/.gitignore b/.gitignore index 92ee8b1f5..0c2dc253b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ application.log application.log* target/ +bin/ log.roo .project .classpath @@ -13,5 +14,12 @@ derby.log .idea activemq-data .settings/ - - +.sts4-cache +.factorypath +out +/.gradle +build/ +/classes +.mvn +mvnw* +.vscode \ No newline at end of file diff --git a/README.md b/README.md index 78b57ad60..ad055b217 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Spring Integration Samples ========================== -# Introduction +[![Revved up by Develocity](https://img.shields.io/badge/Revved%20up%20by-Develocity-06A0CE?logo=Gradle&labelColor=02303A)](https://ge.spring.io/scans?search.rootProjectNames=spring-integration-samples) Welcome to the **Spring Integration Samples** repository which provides **50+ samples** to help you learn [Spring Integration][]. To simplify your experience, the *Spring Integration* samples are split into 4 distinct categories: @@ -9,6 +9,7 @@ Welcome to the **Spring Integration Samples** repository which provides **50+ sa * Intermediate * Advanced * Applications +* DSL Inside of each category you'll find a **README.md** file, which will contain a more detailed description of that category. Each sample also comes with its own **README.md** file explaining further details, e.g. how to run the respective sample. @@ -16,24 +17,37 @@ Inside of each category you'll find a **README.md** file, which will contain a m *Happy Integration!* +# Note + +This (main) branch requires Spring Integration 6.0 or above. +For samples running against earlier versions of Spring Integration, use the __5.5.x__ and other branches. + +The project requires now Java 17 or above. +To open the project in the IDE, use its `import` option against a `build.gradle` file from the root project directory. + ## Related GitHub projects * [Spring Integration][] * [Spring Integration Extensions][] -* [Spring Integration Templates][] -* [Spring Integration Dsl Groovy][] -* [Spring Integration Dsl Scala][] -* [Spring Integration Pattern Catalog][] + +## Community Sample Projects + +* [Xavier Padró][] # Categories Below is a short description of each category. +## DSL + +This directory holds demos/samples for Spring Integration Java Configuration as well as the Java DSL Extension. + ## Basic This is a good place to get started. The samples here are technically motivated and demonstrate the bare minimum with regard to configuration and code to help you to get introduced to the basic concepts, API and configuration of Spring Integration. For example, if you are looking for an answer on how to wire a **Service Activator** to a **Channel** or how to apply a **Gateway** to your message exchange or how to get started with using the **MAIL** or **XML** module, this would be the right place to find a relevant sample. The bottom line is that this is a good starting point. * **amqp** - Demonstrates the functionality of the various **AMQP Adapters** +* **barrier** - Shows how to suspend a thread until some asynchronous event occurs * **control-bus** - Demonstrates the functionality of the **Control Bus** * **enricher** - This sample demonstrates how the Enricher components can be used * **feed** - Demonstrates the functionality of the **Feed Adapter** (RSS/ATOM) @@ -44,21 +58,24 @@ This is a good place to get started. The samples here are technically motivated * **jdbc** - Illustrates the usage of the Jdbc Adapters, including object persistence and retrieval * **jms** - Demonstrates **JMS** support available with Spring Integration * **jmx** - Demonstrates **JMX** support using a **JMX Attribute Polling Channel** and **JMX Operation Invoking Channel Adapter** -* **jpa** - Shows the usage of the JPA Components can be used +* **jpa** - Shows the usage of the JPA Components * **mail** - Example showing **IMAP** and **POP3** support +* **mqtt** - Demonstrates the functionality of inbound and outbound **MQTT Adapters** * **mongodb** - Shows how to persist a Message payload to a **MongoDb** document store and how to read documents from **MongoDb** * **oddeven** - Example combining the functionality of **Inbound Channel Adapter**, **Filter**, **Router** and **Poller** -* **jpa** - This sample illustrates how the JPA Components can be used -* **quote** - Example demoing core EIP support using **Channel Adapter (Inbound and Stdout)**, **Poller** with Interval Trigers, **Service Activator** +* **quote** - Example demoing core EIP support using **Channel Adapter (Inbound and Stdout)**, **Poller** with Interval Triggers, **Service Activator** * **sftp** - Demonstrating SFTP support using **SFTP Inbound / Outbound Channel Adapters** * **tcp-amqp** - Demonstrates basic functionality of bridging the **Spring Integration TCP Adapters** with **Spring Integration AMQP Adapters** +* **tcp-broadcast** - Demonstrates broadcasting a message to multiple connected TCP clients. * **tcp-client-server** - Demonstrates socket communication using **TcpOutboundGateway**, **TcpInboundGateway** and also uses a **Gateway** and a **Service Activator** +* **tcp-with-headers** - Demonstrates sending headers along with the payload over TCP using JSON. * **testing-examples** - A series of test cases that show techniques to **test** Spring Integration applications. * **twitter** - Illustrates Twitter support using the **Twitter Inbound Channel Adapter**, **Twitter Inbound Search Channel Adapter**, **Twitter Outbound Channel Adapter** * **ws-inbound-gateway** - Example showing basic functionality of the **Web Service Gateway** * **ws-outbound-gateway** - Shows outbound web services support using the **Web Service Outbound Gateway**, **Content Enricher**, Composed Message Processor (**Chain**) * **xml** - Example demonstrates various aspects of the **Xml** support using an **XPath Splitter**, **XPath Router**, **XSLT Transformer** as well as **XPath Expression** support -* **xmpp** - Show the support for [**XMPP**](http://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol) (formerly known as Jabber) using e.g. GoogleTalk +* **xmpp** - Show the support for [**XMPP**](https://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol) (formerly known as Jabber) using e.g. GoogleTalk +* **zip** - Show the support for zip files manipulations ## Intermediate @@ -70,16 +87,17 @@ This category targets developers who are already more familiar with the Spring I * **errorhandling** - Demonstrates basic **Error Handling** capabilities of Spring Integration * **file-processing** - Sample demonstrates how to wire a message flow to process files either sequentially (maintain the order) or concurrently (no order). * **mail-attachments** - Demonstrates the processing of email attachments -* **monitoring** The project used in the *[Spring Integration Management and Monitoring Webinar](http://www.springsource.org/node/3598)* Also available on the *[SpringSourceDev YouTube Channel](http://www.youtube.com/SpringSourceDev)* +* **monitoring** The project used in the *[Spring Integration Management and Monitoring Webinar](https://www.springsource.org/node/3598)* Also available on the *[SpringSourceDev YouTube Channel](https://www.youtube.com/SpringSourceDev)* * **multipart-http** - Demonstrates the sending of HTTP multipart requests using Spring's **RestTemplate** and a Spring Integration **Http Outbound Gateway** * **rest-http** - This sample demonstrates how to send an HTTP request to a Spring Integration's HTTP service while utilizing Spring Integration's new HTTP Path usage. This sample also uses Spring Security for HTTP Basic authentication. With HTTP Path facility, the client program can send requests with URL Variables. * **retry-and-more** Provides samples showing the application of MessageHandler Advice Chains to endpoints - retry, circuit breaker, expression evaluating * **splitter-aggregator-reaper** A demonstration of implementing the Splitter and Aggregator *Enterprise Integration Patterns* (EIP) together. This sample also provides a concrete example of a [message store reaper][] in action. -* **stored-procedures-derby** Provides an example of the stored procedure Outbound Gateway using *[Apache Derby](http://db.apache.org/derby/)* +* **stored-procedures-derby** Provides an example of the stored procedure Outbound Gateway using *[Apache Derby](https://db.apache.org/derby/)* * **stored-procedures-ms** Provides an example of the stored procedure Outbound Gateway using *Microsoft SQL Server* * **stored-procedures-oracle** Provides an example of the stored procedure Outbound Gateway using *ORACLE XE* -* **stored-procedures-postgresql** Provides an example of the stored procedure Outbound Gateway using *[PostgreSQL](http://www.postgresql.org/)* -* **tcp-client-server-multiplex** - Demonstrates the use of *Collaborating Channel Adapters* +* **stored-procedures-postgresql** Provides an example of the stored procedure Outbound Gateway using *[PostgreSQL](https://www.postgresql.org/)* +* **tcp-async-bi-directional** - Demonstrates the use of *Collaborating Channel Adapters* for arbitrary async messaging (not request/reply) between peers. +* **tcp-client-server-multiplex** - Demonstrates the use of *Collaborating Channel Adapters* with multiple in-flight requests/responses over a single connection. * **travel** - More sophisticated example showing the retrieval of weather (SOAP Web Service) and traffic (HTTP Service) reports using real services * **tx-synch** Provides a sample demonstrating the use of transaction synchronization, renaming an input file to a different filename, depending on whether the transaction commits, or rolls back. @@ -89,28 +107,32 @@ This category targets advanced developers who are quite familiar with Spring Int * **advanced-testing-examples** - Example test cases that show advanced techniques to test Spring Integration applications * **dynamic-ftp** - Demonstrates one technique for sending files to dynamic destinations. +* **dynamic-tcp-client** - Demonstrates a technique for dynamically creating TCP clients. ## Applications This category targets developers and architects who have a good understanding of Message-Driven architecture and Enterprise Integration Patterns, and have an above average understanding of Spring and Spring integration and who are looking for samples that address a particular business problem. In other words, the emphasis of samples in this category is '**business use cases**' and how they can be solved via a Messaging architecture and Spring Integration in particular. For example, if you are interested to see how a Loan Broker process or Travel Agent process could be implemented and automated via Spring Integration, this would be the right place to find these types of samples. -* **cafe** - Emulates a simple operation of a coffee shop combining various Spring Integration adapters (Including **Router** and **Splitter**) see [Appendix A of the reference documentation](http://static.springsource.org/spring-integration/docs/latest-ga/reference/html/samples.html) for more details. Implementations are provided for: +* **cafe** - Emulates a simple operation of a coffee shop combining various Spring Integration adapters (Including **Router** and **Splitter**) see [Appendix A of the reference documentation](https://docs.spring.io/spring-integration/docs/current/reference/html/#samples) for more details. Implementations are provided for: - AMQP - JMS - - In memory channels + - In memory channels * **cafe-scripted** - Scripted implementation of the classic **cafe** sample application. Supports **JavaScript**, **Groovy**, **Ruby**, and **Python**. -* **loan-broker** - Simulates a simple banking application (Uses **Gateway**, **Chain**, **Header Enricher**, **Recipient List Router**, **Aggregator**) see [Appendix A of the reference documentation](http://static.springsource.org/spring-integration/docs/latest-ga/reference/html/samples.html) for more details +* **loan-broker** - Simulates a simple banking application (Uses **Gateway**, **Chain**, **Header Enricher**, **Recipient List Router**, **Aggregator**) see [Appendix A of the reference documentation](https://docs.spring.io/spring-integration/docs/current/reference/html/#samples) for more details * **loanshark** This extension to the loan broker sample shows how to exchange messages between Spring Integration applications (and other technologies) using **UDP**. + **file-split-ftp** - Reads a file; splits into 3 based on contents; sends files over ftp; sends email with results. + +# Contributing + +See the [Spring Integration Contributor Guidelines](https://github.com/spring-projects/spring-integration/blob/master/CONTRIBUTING.adoc) for information about how to contribute to this repository. + +# Resources -#Resources +For more information, please visit the Spring Integration website at: [https://projects.spring.io/spring-integration/](https://projects.spring.io/spring-integration/) -For more information, please visit the Spring Integration website at: [http://www.springsource.org/spring-integration](http://www.springsource.org/spring-integration) +[Spring Integration]: https://github.com/spring-projects/spring-integration +[Spring Integration Extensions]: https://github.com/spring-projects/spring-integration-extensions -[Spring Integration]: https://github.com/SpringSource/spring-integration -[Spring Integration Extensions]: https://github.com/SpringSource/spring-integration-extensions -[Spring Integration Templates]: https://github.com/SpringSource/spring-integration-templates/tree/master/si-sts-templates -[Spring Integration Dsl Groovy]: https://github.com/SpringSource/spring-integration-dsl-groovy -[Spring Integration Dsl Scala]: https://github.com/SpringSource/spring-integration-dsl-scala -[Spring Integration Pattern Catalog]: https://github.com/SpringSource/spring-integration-pattern-catalog +[message store reaper]: https://docs.spring.io/spring-integration/api/org/springframework/integration/store/MessageGroupStoreReaper.html -[message store reaper]: http://static.springsource.org/spring-integration/api/org/springframework/integration/store/MessageGroupStoreReaper.html +[Xavier Padró]: https://github.com/xpadro/spring-integration diff --git a/advanced/README.md b/advanced/README.md index c48f33675..2a9519c2e 100644 --- a/advanced/README.md +++ b/advanced/README.md @@ -1,7 +1,7 @@ Advanced Samples ================ -This category targets advanced developers who are well familiar with the [Spring Integration](http://www.springsource.org/spring-integration) framework but are looking to extend it to address a specific custom need by extending from Spring Integration's public API. +This category targets advanced developers who are well familiar with the [Spring Integration](https://www.springsource.org/spring-integration) framework but are looking to extend it to address a specific custom need by extending from Spring Integration's public API. For example; if you are looking for samples showing you how to implement a custom **Channel** or **Consumer** (event-based or polling-based), or if you trying to figure out what is the most appropriate way to implement a custom **BeanParser** on top of the Spring Integration BeanParser hierarchy when implementing custom namespaces, this would be the right place to look. diff --git a/advanced/advanced-testing-examples/pom.xml b/advanced/advanced-testing-examples/pom.xml index 50a535fbf..8265adf46 100644 --- a/advanced/advanced-testing-examples/pom.xml +++ b/advanced/advanced-testing-examples/pom.xml @@ -1,125 +1,164 @@ - - 4.0.0 - org.springframework.integration.samples - advanced-testing-examples - 2.2.0.BUILD-SNAPSHOT - Samples (Advanced) - Advanced Testing Examples - jar - - - 2.2.1 - - - - UTF-8 - 2.2.0.RELEASE - 3.1.3.RELEASE - 1.2.17 - 4.11 - - - - org.springframework.integration - spring-integration-jms - ${spring.integration.version} - - - - org.springframework.integration - spring-integration-groovy - ${spring.integration.version} - - - - log4j - log4j - ${log4j.version} - - - - junit - junit - ${junit.version} - - - org.springframework - spring-test - ${spring.version} - test - - - - org.springframework - spring-jms - ${spring.version} - - - - org.apache.geronimo.specs - geronimo-jms_1.1_spec - 1.1.1 - provided - - - - - org.mockito - mockito-all - 1.9.5 - test - - - - - - - src/test/java - - **/* - - - **/*.java - - - - src/test/resources - - **/* - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.0 - - 1.6 - 1.6 - -Xlint:all - true - true - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.12.4 - - - **/*Tests.java - - - - - - - - repo.springsource.org.milestone - SpringSource Maven Milestone Repository - https://repo.springsource.org/libs-milestone - - - \ No newline at end of file + + 4.0.0 + org.springframework.integration.samples + advanced-testing-examples + 7.0.0 + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + jakarta.jms + jakarta.jms-api + 3.1.0 + compile + + + org.springframework.integration + spring-integration-jms + compile + + + org.springframework.integration + spring-integration-groovy + compile + + + org.apache.logging.log4j + log4j-core + 2.24.3 + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + + diff --git a/advanced/advanced-testing-examples/src/main/resources/integration-config.xml b/advanced/advanced-testing-examples/src/main/resources/integration-config.xml index 8ba6be64d..80c645cba 100644 --- a/advanced/advanced-testing-examples/src/main/resources/integration-config.xml +++ b/advanced/advanced-testing-examples/src/main/resources/integration-config.xml @@ -2,9 +2,9 @@ + xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/groovy https://www.springframework.org/schema/integration/groovy/spring-integration-groovy.xsd + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> + output-channel="invalidMessageChannel" expression="payload.cause.message" /> diff --git a/advanced/advanced-testing-examples/src/test/java/org/springframework/integration/samples/advance/testing/jms/JmsMockTests-context.xml b/advanced/advanced-testing-examples/src/test/java/org/springframework/integration/samples/advance/testing/jms/JmsMockTests-context.xml index b1ba42b5b..f9f3cad27 100644 --- a/advanced/advanced-testing-examples/src/test/java/org/springframework/integration/samples/advance/testing/jms/JmsMockTests-context.xml +++ b/advanced/advanced-testing-examples/src/test/java/org/springframework/integration/samples/advance/testing/jms/JmsMockTests-context.xml @@ -1,26 +1,29 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:int="http://www.springframework.org/schema/integration" + xmlns:int-jms="http://www.springframework.org/schema/integration/jms" + xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/jms https://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> - + - - + + - + diff --git a/advanced/advanced-testing-examples/src/test/java/org/springframework/integration/samples/advance/testing/jms/JmsMockTests.java b/advanced/advanced-testing-examples/src/test/java/org/springframework/integration/samples/advance/testing/jms/JmsMockTests.java index dccfcc1c2..4981d8c3c 100644 --- a/advanced/advanced-testing-examples/src/test/java/org/springframework/integration/samples/advance/testing/jms/JmsMockTests.java +++ b/advanced/advanced-testing-examples/src/test/java/org/springframework/integration/samples/advance/testing/jms/JmsMockTests.java @@ -1,143 +1,169 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2022 the original author or authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ -package org.springframework.integration.samples.advance.testing.jms; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; +package org.springframework.integration.samples.advance.testing.jms; import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; -import javax.jms.JMSException; -import javax.jms.TextMessage; +import jakarta.jms.JMSException; +import jakarta.jms.TextMessage; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; -import org.apache.log4j.Logger; -import org.junit.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.integration.Message; -import org.springframework.integration.MessageChannel; -import org.springframework.integration.MessagingException; -import org.springframework.integration.core.MessageHandler; -import org.springframework.integration.core.SubscribableChannel; - +import org.springframework.integration.endpoint.SourcePollingChannelAdapter; import org.springframework.jms.core.JmsTemplate; import org.springframework.jms.support.converter.SimpleMessageConverter; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.MessageHandler; +import org.springframework.messaging.MessagingException; +import org.springframework.messaging.SubscribableChannel; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; -@RunWith(SpringJUnit4ClassRunner.class) +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.BDDMockito.willAnswer; +import static org.mockito.BDDMockito.willReturn; +import static org.mockito.Mockito.mock; + +/** + * @author David Turanski + * @author Gunnar Hillert + * @author Gary Russell + * @author Artem Bilan + */ +@SpringJUnitConfig @ContextConfiguration -@DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) +@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) public class JmsMockTests { - private static final Logger LOGGER = Logger.getLogger(JmsMockTests.class); + private static final Log LOGGER = LogFactory.getLog(JmsMockTests.class); + + private final AtomicReference testMessageHolder = new AtomicReference<>(); + + @Autowired + private JmsTemplate mockJmsTemplate; @Autowired - JmsTemplate mockJmsTemplate; + private SourcePollingChannelAdapter jmsInboundChannelAdapter; @Autowired @Qualifier("inputChannel") - MessageChannel inputChannel; + private MessageChannel inputChannel; @Autowired @Qualifier("outputChannel") - SubscribableChannel outputChannel; + private SubscribableChannel outputChannel; @Autowired @Qualifier("invalidMessageChannel") - SubscribableChannel invalidMessageChannel; + private SubscribableChannel invalidMessageChannel; + + @BeforeEach + public void setup() throws JMSException { + Mockito.reset(this.mockJmsTemplate); + TextMessage message = mock(TextMessage.class); + + willReturn(new SimpleMessageConverter()) + .given(this.mockJmsTemplate).getMessageConverter(); + + willReturn(message) + .given(this.mockJmsTemplate).receiveSelected(isNull()); + + willAnswer((Answer) invocation -> testMessageHolder.get()) + .given(message).getText(); + } /** * This test verifies that a message received on a polling JMS inbound channel adapter is * routed to the designated channel and that the message payload is as expected - * - * @throws JMSException - * @throws InterruptedException - * @throws IOException */ @Test public void testReceiveMessage() throws JMSException, InterruptedException, IOException { String msg = "hello"; - boolean sent = verifyJmsMessageReceivedOnOutputChannel(msg, outputChannel,new CountDownHandler() { + boolean sent = verifyJmsMessageReceivedOnOutputChannel(msg, outputChannel, new CountDownHandler() { - @Override - protected void verifyMessage(Message message) { - assertEquals("hello",message.getPayload()); - } - } + @Override + protected void verifyMessage(Message message) { + assertThat(message.getPayload()).isEqualTo("hello"); + } + } ); - assertTrue("message not sent to expected output channel", sent); + assertThat(sent).as("message not sent to expected output channel").isTrue(); } /** * This test verifies that a message received on a polling JMS inbound channel adapter is * routed to the errorChannel and that the message payload is the expected exception - * - * @throws JMSException - * @throws IOException - * @throws InterruptedException */ @Test public void testReceiveInvalidMessage() throws JMSException, IOException, InterruptedException { String msg = "whoops"; - boolean sent = verifyJmsMessageReceivedOnOutputChannel(msg, invalidMessageChannel,new CountDownHandler() { + boolean sent = verifyJmsMessageReceivedOnOutputChannel(msg, invalidMessageChannel, new CountDownHandler() { - @Override - protected void verifyMessage(Message message) { - assertEquals("invalid payload",message.getPayload()); - } + @Override + protected void verifyMessage(Message message) { + assertThat(message.getPayload()).isEqualTo("invalid payload"); + } - } + } ); - assertTrue("message not sent to expected output channel", sent); + assertThat(sent).as("message not sent to expected output channel").isTrue(); } /** - * Provide a message via a mock JMS template and wait for the default timeout to receive the message on the expected channel + * Provide a message via a mock JMS template and wait for the default timeout to receive the message + * on the expected channel * @param obj The message provided to the poller (currently must be a String) * @param expectedOutputChannel The expected output channel * @param handler An instance of CountDownHandler to handle (verify) the output message * @return true if the message was received on the expected channel - * @throws JMSException - * @throws InterruptedException */ - protected boolean verifyJmsMessageReceivedOnOutputChannel(Object obj, SubscribableChannel expectedOutputChannel, CountDownHandler handler) throws JMSException, InterruptedException{ - return verifyJmsMessageOnOutputChannel(obj, expectedOutputChannel, handler, 7000); - } + protected boolean verifyJmsMessageReceivedOnOutputChannel(Object obj, SubscribableChannel expectedOutputChannel, + CountDownHandler handler) throws InterruptedException { + return verifyJmsMessageOnOutputChannel(obj, expectedOutputChannel, handler, 10000); + } /** - * Provide a message via a mock JMS template and wait for the specified timeout to receive the message on the expected channel + * Provide a message via a mock JMS template and wait for the specified timeout to receive the message + * on the expected channel * @param obj The message provided to the poller (currently must be a String) * @param expectedOutputChannel The expected output channel * @param handler An instance of CountDownHandler to handle (verify) the output message - * @param timeoutMillisec The timeout period. Note that this must allow at least enough time to process the entire flow. Only set if the default is + * @param timeoutMillisec The timeout period. Note that this must allow at least enough time + * to process the entire flow. Only set if the default is * not long enough * @return true if the message was received on the expected channel - * @throws JMSException - * @throws InterruptedException */ - protected boolean verifyJmsMessageOnOutputChannel(Object obj, SubscribableChannel expectedOutputChannel, CountDownHandler handler,int timeoutMillisec) throws JMSException, - InterruptedException { + protected boolean verifyJmsMessageOnOutputChannel(Object obj, SubscribableChannel expectedOutputChannel, + CountDownHandler handler, int timeoutMillisec) throws InterruptedException { if (!(obj instanceof String)) { throw new IllegalArgumentException("Only TextMessage is currently supported"); @@ -148,19 +174,14 @@ protected boolean verifyJmsMessageOnOutputChannel(Object obj, SubscribableChanne * is also a mock. */ - TextMessage message = mock(TextMessage.class); - doReturn(new SimpleMessageConverter()).when(mockJmsTemplate).getMessageConverter(); - doReturn(message).when(mockJmsTemplate).receiveSelected(anyString()); - - String text = (String) obj; - + this.testMessageHolder.set((String) obj); CountDownLatch latch = new CountDownLatch(1); handler.setLatch(latch); - doReturn(text).when(message).getText(); - expectedOutputChannel.subscribe(handler); + this.jmsInboundChannelAdapter.start(); + boolean latchCountedToZero = latch.await(timeoutMillisec, TimeUnit.MILLISECONDS); if (!latchCountedToZero) { @@ -170,14 +191,15 @@ protected boolean verifyJmsMessageOnOutputChannel(Object obj, SubscribableChanne return latchCountedToZero; } + /* * A MessageHandler that uses a CountDownLatch to synchronize with the calling thread */ - private abstract class CountDownHandler implements MessageHandler { + private abstract static class CountDownHandler implements MessageHandler { CountDownLatch latch; - public final void setLatch(CountDownLatch latch){ + public final void setLatch(CountDownLatch latch) { this.latch = latch; } @@ -190,9 +212,12 @@ public final void setLatch(CountDownLatch latch){ * org.springframework.integration.core.MessageHandler#handleMessage * (org.springframework.integration.Message) */ + @Override public void handleMessage(Message message) throws MessagingException { verifyMessage(message); latch.countDown(); } + } + } diff --git a/advanced/advanced-testing-examples/src/test/resources/log4j.xml b/advanced/advanced-testing-examples/src/test/resources/log4j.xml deleted file mode 100644 index de52c70f7..000000000 --- a/advanced/advanced-testing-examples/src/test/resources/log4j.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/advanced/advanced-testing-examples/src/test/resources/log4j2.xml b/advanced/advanced-testing-examples/src/test/resources/log4j2.xml new file mode 100644 index 000000000..6241eb502 --- /dev/null +++ b/advanced/advanced-testing-examples/src/test/resources/log4j2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/advanced/dynamic-ftp/README.md b/advanced/dynamic-ftp/README.md index c5de52e4d..1131866b3 100644 --- a/advanced/dynamic-ftp/README.md +++ b/advanced/dynamic-ftp/README.md @@ -17,3 +17,4 @@ Notice in the config file, how an **expression-based router** is used to invoke expression="@channelResolver.resolve(headers['customer'])"/> +This sample shows the technique for outbound adapters. \ No newline at end of file diff --git a/advanced/dynamic-ftp/pom.xml b/advanced/dynamic-ftp/pom.xml index fa2885998..457fda71b 100644 --- a/advanced/dynamic-ftp/pom.xml +++ b/advanced/dynamic-ftp/pom.xml @@ -1,85 +1,153 @@ - + + 4.0.0 org.springframework.integration.samples - dynamic-ftp - 2.2.0.BUILD-SNAPSHOT - Samples (Advanced) - Dynamic FTP Demo - jar - - UTF-8 - 3.1.3.RELEASE - 2.2.0.RELEASE - 1.2.17 - 4.10 - - - - org.springframework - spring-context - ${spring.framework.version} - - - org.springframework.integration - spring-integration-ftp - ${spring.integration.version} - - - log4j - log4j - ${log4j.version} - - - - junit - junit - ${junit.version} - - - - - - src/test/java - - **/* - - - - src/test/resources - - **/* - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.5.1 - - 1.6 - 1.6 - -Xlint:all - true - true - - - - maven-surefire-plugin - 2.12.4 - - - **/*Tests.java - **/*Sample.java - - - - - - - - repo.springsource.org.milestone - SpringSource Maven Milestone Repository - https://repo.springsource.org/libs-milestone - - + dynamic-ftp + 7.0.0 + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.integration + spring-integration-ftp + compile + + + org.apache.logging.log4j + log4j-core + 2.24.3 + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + diff --git a/advanced/dynamic-ftp/src/main/java/org/springframework/integration/samples/ftp/DynamicFtpChannelResolver.java b/advanced/dynamic-ftp/src/main/java/org/springframework/integration/samples/dynamicftp/DynamicFtpChannelResolver.java similarity index 96% rename from advanced/dynamic-ftp/src/main/java/org/springframework/integration/samples/ftp/DynamicFtpChannelResolver.java rename to advanced/dynamic-ftp/src/main/java/org/springframework/integration/samples/dynamicftp/DynamicFtpChannelResolver.java index 889d435e0..1e4b7c2ef 100644 --- a/advanced/dynamic-ftp/src/main/java/org/springframework/integration/samples/ftp/DynamicFtpChannelResolver.java +++ b/advanced/dynamic-ftp/src/main/java/org/springframework/integration/samples/dynamicftp/DynamicFtpChannelResolver.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.integration.samples.ftp; +package org.springframework.integration.samples.dynamicftp; import java.util.HashMap; import java.util.LinkedHashMap; @@ -25,7 +25,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.StandardEnvironment; -import org.springframework.integration.MessageChannel; +import org.springframework.messaging.MessageChannel; /** * Demonstrates how a dynamic Spring Integration flow snippet can be used diff --git a/advanced/dynamic-ftp/src/main/resources/META-INF/spring/integration/dynamic-ftp-outbound-adapter-context.xml b/advanced/dynamic-ftp/src/main/resources/META-INF/spring/integration/dynamic-ftp-outbound-adapter-context.xml index 8d8f1f274..8e47e7b26 100644 --- a/advanced/dynamic-ftp/src/main/resources/META-INF/spring/integration/dynamic-ftp-outbound-adapter-context.xml +++ b/advanced/dynamic-ftp/src/main/resources/META-INF/spring/integration/dynamic-ftp-outbound-adapter-context.xml @@ -4,10 +4,10 @@ xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-ftp="http://www.springframework.org/schema/integration/ftp" xmlns:context="http://www.springframework.org/schema/context" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd - http://www.springframework.org/schema/integration/ftp http://www.springframework.org/schema/integration/ftp/spring-integration-ftp.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd + http://www.springframework.org/schema/integration/ftp https://www.springframework.org/schema/integration/ftp/spring-integration-ftp.xsd"> diff --git a/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/ftp/DynamicFtpChannelResolverTests.java b/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/dynamicftp/DynamicFtpChannelResolverTests.java similarity index 65% rename from advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/ftp/DynamicFtpChannelResolverTests.java rename to advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/dynamicftp/DynamicFtpChannelResolverTests.java index bb77a4b38..a44b51d86 100644 --- a/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/ftp/DynamicFtpChannelResolverTests.java +++ b/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/dynamicftp/DynamicFtpChannelResolverTests.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,12 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.integration.samples.ftp; +package org.springframework.integration.samples.dynamicftp; -import static org.junit.Assert.*; +import org.junit.jupiter.api.Test; -import org.junit.Test; -import org.springframework.integration.MessageChannel; +import org.springframework.integration.samples.dynamicftp.DynamicFtpChannelResolver; +import org.springframework.messaging.MessageChannel; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Gary Russell @@ -28,18 +30,17 @@ public class DynamicFtpChannelResolverTests { /** - * Test method for {@link org.springframework.integration.samples.ftp.DynamicFtpChannelResolver#resolve(java.lang.String)}. + * Test method for {@link DynamicFtpChannelResolver#resolve(java.lang.String)}. */ @Test public void testResolve() { DynamicFtpChannelResolver dynamicFtpChannelResolver = new DynamicFtpChannelResolver(); MessageChannel channel1 = dynamicFtpChannelResolver.resolve("customer1"); - assertNotNull(channel1); + assertThat(channel1).isNotNull(); MessageChannel channel2 = dynamicFtpChannelResolver.resolve("customer2"); - assertNotNull(channel2); - assertNotSame(channel1, channel2); + assertThat(channel1).isNotSameAs(channel2); MessageChannel channel1a = dynamicFtpChannelResolver.resolve("customer1"); - assertSame(channel1, channel1a); + assertThat(channel1).isSameAs(channel1a); } } diff --git a/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/dynamicftp/FtpOutboundChannelAdapterSampleTests.java b/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/dynamicftp/FtpOutboundChannelAdapterSampleTests.java new file mode 100644 index 000000000..4f2736a69 --- /dev/null +++ b/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/dynamicftp/FtpOutboundChannelAdapterSampleTests.java @@ -0,0 +1,94 @@ +/* + * Copyright 2002-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.integration.samples.dynamicftp; + +import java.io.File; +import java.net.UnknownHostException; + +import org.junit.jupiter.api.Test; + +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.integration.support.MessageBuilder; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.MessagingException; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +/** + * @author Gary Russell + * @author Amol Nayak + * @author Artem Bilan + * + */ +public class FtpOutboundChannelAdapterSampleTests { + + @Test + public void runDemo() throws Exception { + ConfigurableApplicationContext ctx = + new ClassPathXmlApplicationContext( + "META-INF/spring/integration/DynamicFtpOutboundChannelAdapterSample-context.xml"); + MessageChannel channel = ctx.getBean("toDynRouter", MessageChannel.class); + File file = File.createTempFile("temp", "txt"); + Message message = MessageBuilder.withPayload(file) + .setHeader("customer", "cust1") + .build(); + + assertThatExceptionOfType(MessagingException.class) + .isThrownBy(() -> channel.send(message)) + .withRootCauseInstanceOf(UnknownHostException.class) + .withStackTraceContaining("host.for.cust1"); + + // send another so we can see in the log we don't create the ac again. + assertThatExceptionOfType(MessagingException.class) + .isThrownBy(() -> channel.send(message)) + .withRootCauseInstanceOf(UnknownHostException.class) + .withStackTraceContaining("host.for.cust1"); + + // send to a different customer; again, check the log to see a new ac is built + assertThatExceptionOfType(MessagingException.class) + .isThrownBy(() -> channel.send( + MessageBuilder.withPayload(file) + .setHeader("customer", "cust2") + .build())) + .withRootCauseInstanceOf(UnknownHostException.class) + .withStackTraceContaining("host.for.cust2"); + + // send to a different customer; again, check the log to see a new ac is built + //and the first one created (cust1) should be closed and removed as per the max cache size restriction + assertThatExceptionOfType(MessagingException.class) + .isThrownBy(() -> channel.send( + MessageBuilder.withPayload(file) + .setHeader("customer", "cust3") + .build())) + .withRootCauseInstanceOf(UnknownHostException.class) + .withStackTraceContaining("host.for.cust3"); + + //send to cust1 again, since this one has been invalidated before, we should + //see a new ac created (with ac of cust2 destroyed and removed) + assertThatExceptionOfType(MessagingException.class) + .isThrownBy(() -> channel.send( + MessageBuilder.withPayload(file) + .setHeader("customer", "cust1") + .build())) + .withRootCauseInstanceOf(UnknownHostException.class) + .withStackTraceContaining("host.for.cust1"); + + ctx.close(); + } + +} diff --git a/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/ftp/FtpOutboundChannelAdapterSample.java b/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/ftp/FtpOutboundChannelAdapterSample.java deleted file mode 100644 index a4c185bca..000000000 --- a/advanced/dynamic-ftp/src/test/java/org/springframework/integration/samples/ftp/FtpOutboundChannelAdapterSample.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2002-2012 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.integration.samples.ftp; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.net.UnknownHostException; - -import org.junit.Test; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.integration.Message; -import org.springframework.integration.MessageChannel; -import org.springframework.integration.MessagingException; -import org.springframework.integration.support.MessageBuilder; - -/** - * @author Gary Russell - * @author Amol Nayak - * - */ -public class FtpOutboundChannelAdapterSample { - - @Test - public void runDemo() throws Exception{ - ConfigurableApplicationContext ctx = - new ClassPathXmlApplicationContext("META-INF/spring/integration/DynamicFtpOutboundChannelAdapterSample-context.xml"); - MessageChannel channel = ctx.getBean("toDynRouter", MessageChannel.class); - File file = File.createTempFile("temp", "txt"); - Message message = MessageBuilder.withPayload(file) - .setHeader("customer", "cust1") - .build(); - try { - channel.send(message); - } catch (MessagingException e) { - assertTrue(e.getCause().getCause() instanceof UnknownHostException); - assertTrue(e.getCause().getCause().getMessage().startsWith("host.for.cust1")); - } - // send another so we can see in the log we don't create the ac again. - try { - channel.send(message); - } catch (MessagingException e) { - assertTrue(e.getCause().getCause() instanceof UnknownHostException); - assertTrue(e.getCause().getCause().getMessage().startsWith("host.for.cust1")); - } - // send to a different customer; again, check the log to see a new ac is built - message = MessageBuilder.withPayload(file) - .setHeader("customer", "cust2").build(); - try { - channel.send(message); - } catch (MessagingException e) { - assertTrue(e.getCause().getCause() instanceof UnknownHostException); - assertTrue(e.getCause().getCause().getMessage().startsWith("host.for.cust2")); - } - - // send to a different customer; again, check the log to see a new ac is built - //and the first one created (cust1) should be closed and removed as per the max cache size restriction - message = MessageBuilder.withPayload(file) - .setHeader("customer", "cust3").build(); - try { - channel.send(message); - } catch (MessagingException e) { - assertTrue(e.getCause().getCause() instanceof UnknownHostException); - assertTrue(e.getCause().getCause().getMessage().startsWith("host.for.cust3")); - } - - //send to cust1 again, since this one has been invalidated before, we should - //see a new ac created (with ac of cust2 destroyed and removed) - message = MessageBuilder.withPayload(file) - .setHeader("customer", "cust1").build(); - try { - channel.send(message); - } catch (MessagingException e) { - assertTrue(e.getCause().getCause() instanceof UnknownHostException); - assertEquals("host.for.cust1", e.getCause().getCause().getMessage()); - } - - ctx.close(); - } -} diff --git a/advanced/dynamic-ftp/src/test/resources/META-INF/spring/integration/DynamicFtpOutboundChannelAdapterSample-context.xml b/advanced/dynamic-ftp/src/test/resources/META-INF/spring/integration/DynamicFtpOutboundChannelAdapterSample-context.xml index 4f90ab984..ee7772a5a 100644 --- a/advanced/dynamic-ftp/src/test/resources/META-INF/spring/integration/DynamicFtpOutboundChannelAdapterSample-context.xml +++ b/advanced/dynamic-ftp/src/test/resources/META-INF/spring/integration/DynamicFtpOutboundChannelAdapterSample-context.xml @@ -3,11 +3,11 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:context="http://www.springframework.org/schema/context" - xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> - + diff --git a/advanced/dynamic-ftp/src/test/resources/log4j.xml b/advanced/dynamic-ftp/src/test/resources/log4j.xml deleted file mode 100644 index 40d94ca5b..000000000 --- a/advanced/dynamic-ftp/src/test/resources/log4j.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/advanced/dynamic-ftp/src/test/resources/log4j2.xml b/advanced/dynamic-ftp/src/test/resources/log4j2.xml new file mode 100644 index 000000000..6241eb502 --- /dev/null +++ b/advanced/dynamic-ftp/src/test/resources/log4j2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/advanced/dynamic-tcp-client/.gitignore b/advanced/dynamic-tcp-client/.gitignore new file mode 100644 index 000000000..57a6aeaa2 --- /dev/null +++ b/advanced/dynamic-tcp-client/.gitignore @@ -0,0 +1,24 @@ +target/ +.mvn +mvn* + +### STS ### +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ diff --git a/advanced/dynamic-tcp-client/README.adoc b/advanced/dynamic-tcp-client/README.adoc new file mode 100644 index 000000000..c697f424a --- /dev/null +++ b/advanced/dynamic-tcp-client/README.adoc @@ -0,0 +1,16 @@ += Dynamic TCP Client + +Demonstrates a technique to dynamically add TCP clients on-demand, with caching and LRU removal. + +Uses the https://docs.spring.io/spring-integration/reference/html/java-dsl.html#java-dsl-runtime-flows[Spring Integration Java DSL] Runtime flow registration feature. + +The code starts two inbound channel adapters on ports 1234 and 5678 and sends a message to each. + +Run from your favorite IDE, or from the command line `./gradlew :dynamic-tcp-client:run`. + +The output messages show that each was received from a different socket... + +``` +GenericMessage [payload=byte[3], headers={ip_tcp_remotePort=59000, ip_connectionId=localhost:59000:1234:fe482d5d-46d2-4708-bde8-afdcee6d3275, ip_localInetAddress=/127.0.0.1, ip_address=127.0.0.1, history=inOne,outputChannel, id=4c66210d-3855-28ad-833c-f6862d4263fb, ip_hostname=localhost, timestamp=1474483130778}] +GenericMessage [payload=byte[3], headers={ip_tcp_remotePort=59001, ip_connectionId=localhost:59001:5678:e54f0ffe-83bc-40de-861f-9fa03df6e43d, ip_localInetAddress=/127.0.0.1, ip_address=127.0.0.1, history=inTwo,outputChannel, id=d6bd4319-00e1-550d-9511-3348d7fae907, ip_hostname=localhost, timestamp=1474483130784}] +``` diff --git a/advanced/dynamic-tcp-client/pom.xml b/advanced/dynamic-tcp-client/pom.xml new file mode 100644 index 000000000..2d50e9b08 --- /dev/null +++ b/advanced/dynamic-tcp-client/pom.xml @@ -0,0 +1,178 @@ + + + 4.0.0 + org.springframework.integration.samples + dynamic-tcp-client + 7.0.0 + jar + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.boot + spring-boot-starter-integration + compile + + + org.springframework.integration + spring-integration-ip + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.springframework.boot + spring-boot-dependencies + 4.0.0-SNAPSHOT + import + pom + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + org.springframework.boot + spring-boot-starter-parent + 4.0.0-SNAPSHOT + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + + diff --git a/advanced/dynamic-tcp-client/src/main/java/org/springframework/integration/samples/dynamictcp/DynamicTcpClientApplication.java b/advanced/dynamic-tcp-client/src/main/java/org/springframework/integration/samples/dynamictcp/DynamicTcpClientApplication.java new file mode 100644 index 000000000..4e43c2762 --- /dev/null +++ b/advanced/dynamic-tcp-client/src/main/java/org/springframework/integration/samples/dynamictcp/DynamicTcpClientApplication.java @@ -0,0 +1,167 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.samples.dynamictcp; + +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map.Entry; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.integration.annotation.MessagingGateway; +import org.springframework.integration.channel.QueueChannel; +import org.springframework.integration.config.EnableMessageHistory; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.context.IntegrationFlowContext; +import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter; +import org.springframework.integration.ip.tcp.TcpSendingMessageHandler; +import org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory; +import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory; +import org.springframework.integration.router.AbstractMessageRouter; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.util.Assert; + +@SpringBootApplication +@EnableMessageHistory +public class DynamicTcpClientApplication { + + public static void main(String[] args) { + ConfigurableApplicationContext context = SpringApplication.run(DynamicTcpClientApplication.class, args); + ToTCP toTcp = context.getBean(ToTCP.class); + toTcp.send("foo", "localhost", 1234); + toTcp.send("foo", "localhost", 5678); + QueueChannel outputChannel = context.getBean("outputChannel", QueueChannel.class); + System.out.println(outputChannel.receive(10000)); + System.out.println(outputChannel.receive(10000)); + context.close(); + } + + // Client side + + @MessagingGateway(defaultRequestChannel = "toTcp.input") + public interface ToTCP { + + public void send(String data, @Header("host") String host, @Header("port") int port); + + } + + @Bean + public IntegrationFlow toTcp() { + return f -> f.route(new TcpRouter()); + } + + // Two servers + + @Bean + public TcpNetServerConnectionFactory cfOne() { + return new TcpNetServerConnectionFactory(1234); + } + + @Bean + public TcpReceivingChannelAdapter inOne(TcpNetServerConnectionFactory cfOne) { + TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter(); + adapter.setConnectionFactory(cfOne); + adapter.setOutputChannel(outputChannel()); + return adapter; + } + + @Bean + public TcpNetServerConnectionFactory cfTwo() { + return new TcpNetServerConnectionFactory(5678); + } + + @Bean + public TcpReceivingChannelAdapter inTwo(TcpNetServerConnectionFactory cfTwo) { + TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter(); + adapter.setConnectionFactory(cfTwo); + adapter.setOutputChannel(outputChannel()); + return adapter; + } + + @Bean + public QueueChannel outputChannel() { + return new QueueChannel(); + } + + public static class TcpRouter extends AbstractMessageRouter { + + private final static int MAX_CACHED = 10; // When this is exceeded, we remove the LRU. + + @SuppressWarnings("serial") + private final LinkedHashMap subFlows = + new LinkedHashMap(MAX_CACHED, .75f, true) { + + @Override + protected boolean removeEldestEntry(Entry eldest) { + if (size() > MAX_CACHED) { + removeSubFlow(eldest); + return true; + } + else { + return false; + } + } + + }; + + @Autowired + private IntegrationFlowContext flowContext; + + @Override + protected synchronized Collection determineTargetChannels(Message message) { + MessageChannel channel = this.subFlows + .get(message.getHeaders().get("host", String.class) + message.getHeaders().get("port")); + if (channel == null) { + channel = createNewSubflow(message); + } + return Collections.singletonList(channel); + } + + private MessageChannel createNewSubflow(Message message) { + String host = (String) message.getHeaders().get("host"); + Integer port = (Integer) message.getHeaders().get("port"); + Assert.state(host != null && port != null, "host and/or port header missing"); + String hostPort = host + port; + + TcpNetClientConnectionFactory cf = new TcpNetClientConnectionFactory(host, port); + TcpSendingMessageHandler handler = new TcpSendingMessageHandler(); + handler.setConnectionFactory(cf); + IntegrationFlow flow = f -> f.handle(handler); + IntegrationFlowContext.IntegrationFlowRegistration flowRegistration = + this.flowContext.registration(flow) + .addBean(cf) + .id(hostPort + ".flow") + .register(); + MessageChannel inputChannel = flowRegistration.getInputChannel(); + this.subFlows.put(hostPort, inputChannel); + return inputChannel; + } + + private void removeSubFlow(Entry eldest) { + String hostPort = eldest.getKey(); + this.flowContext.remove(hostPort + ".flow"); + } + + } + +} diff --git a/basic/sftp/remote-target-dir/.nothing b/advanced/dynamic-tcp-client/src/main/resources/application.properties similarity index 100% rename from basic/sftp/remote-target-dir/.nothing rename to advanced/dynamic-tcp-client/src/main/resources/application.properties diff --git a/advanced/dynamic-tcp-client/src/main/resources/logback.xml b/advanced/dynamic-tcp-client/src/main/resources/logback.xml new file mode 100644 index 000000000..c0fe0db46 --- /dev/null +++ b/advanced/dynamic-tcp-client/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + diff --git a/advanced/dynamic-tcp-client/src/test/java/org/springframework/integration/samples/dynamictcp/DynamicTcpClientApplicationTests.java b/advanced/dynamic-tcp-client/src/test/java/org/springframework/integration/samples/dynamictcp/DynamicTcpClientApplicationTests.java new file mode 100644 index 000000000..a12490de2 --- /dev/null +++ b/advanced/dynamic-tcp-client/src/test/java/org/springframework/integration/samples/dynamictcp/DynamicTcpClientApplicationTests.java @@ -0,0 +1,14 @@ +package org.springframework.integration.samples.dynamictcp; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +public class DynamicTcpClientApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/advanced/pom.xml b/advanced/pom.xml deleted file mode 100644 index 1d199369e..000000000 --- a/advanced/pom.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - 4.0.0 - org.springframework.integration.samples - advanced-samples - 2.2.0.BUILD-SNAPSHOT - Spring Integration Samples - Advanced - pom - - - advanced-testing-examples - dynamic-ftp - - - diff --git a/applications/cafe-scripted/README.md b/applications/cafe-scripted/README.md index 74b4b5497..ee9fbf438 100644 --- a/applications/cafe-scripted/README.md +++ b/applications/cafe-scripted/README.md @@ -1,15 +1,13 @@ Cafe Demo - Scripted Implementation =================================== -This is the scripted implementation of the classic **cafe** sample application. You can choose among **javascript**, **groovy**, **ruby**, and **python** scripting languages. The functionality is basically identical in all cases to the original cafe demo. +This is the scripted implementation of the classic **cafe** sample application. You can choose among **groovy**, **ruby**, and **python** scripting languages. The functionality is basically identical in all cases to the original cafe demo. # Instructions for running the CafeDemo sample -The script language is passed as a command line argument. This may be run directly from maven: +The script language is passed as a command line argument. This may be run directly from Gradle: - $ mvn clean compile - - $ mvn exec:exec -Dlang=[language] + $ gradlew :cafe-scripted:runCafeDemoApp -Plang=[language] ## Groovy Control Bus @@ -17,7 +15,7 @@ This sample also demonstrates the use of Spring Integration's **groovy control b To demonstrate the control bus, while the CafeDemoApp is running, execute in a separate window: - $ mvn exec:exec -Pcontrol-bus + $ gradlew :cafe-scripted:runControlBus This will use groovy scripts to diff --git a/applications/cafe-scripted/pom.xml b/applications/cafe-scripted/pom.xml index d82f06181..be498eb2c 100644 --- a/applications/cafe-scripted/pom.xml +++ b/applications/cafe-scripted/pom.xml @@ -1,203 +1,192 @@ - - 4.0.0 - org.springframework.integration.samples - cafe-scripted - 2.2.0.BUILD-SNAPSHOT - Samples (Applications) - Cafe Sample (Scripted Implementation) - - UTF-8 - 2.2.0.RELEASE - 3.1.3.RELEASE - 1.2.17 - 4.10 - - - - - org.springframework - spring-core - ${spring.version} - - - - org.springframework - spring-test - ${spring.version} - test - - - - org.springframework - spring-context - ${spring.version} - - - - org.springframework - spring-context-support - ${spring.version} - - - - org.springframework.integration - spring-integration-core - ${spring.integration.version} - - - - org.springframework.integration - spring-integration-stream - ${spring.integration.version} - - - - org.springframework.integration - spring-integration-groovy - ${spring.integration.version} - - - org.springframework.integration - spring-integration-rmi - ${spring.integration.version} - - - org.springframework.integration - spring-integration-jmx - ${spring.integration.version} - - - - org.springframework.integration - spring-integration-scripting - ${spring.integration.version} - - - - log4j - log4j - ${log4j.version} - - - - junit - junit - ${junit.version} - - - - - - org.jruby - jruby - 1.5.6 - - - - org.python - jython-standalone - 2.5.2 - - - - org.codehaus.groovy - groovy-all - 1.7.5 - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.5.1 - - 1.6 - 1.6 - -Xlint:all - true - true - - - - - - - - - true - - demo - - - - org.codehaus.mojo - exec-maven-plugin - 1.2.1 - - - - exec - - - - - java - - -classpath - - org.springframework.integration.samples.cafe.demo.CafeDemoApp - ${lang} - - - 0 - - - - - - - - control-bus - - - - org.codehaus.mojo - exec-maven-plugin - 1.2.1 - - - - exec - - - - - java - - -classpath - - org.springframework.integration.samples.cafe.demo.ControlBusMain - - - - 0 - - - - - - - - - - repo.springsource.org.milestone - SpringSource Maven Milestone Repository - https://repo.springsource.org/libs-milestone - - + + 4.0.0 + org.springframework.integration.samples + cafe-scripted + 7.0.0 + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.integration + spring-integration-stream + compile + + + org.springframework.integration + spring-integration-groovy + compile + + + org.springframework.integration + spring-integration-jmx + compile + + + org.springframework.integration + spring-integration-rsocket + compile + + + org.jruby + jruby-complete + 10.0.0.1 + compile + + + org.graalvm.sdk + graal-sdk + 24.2.1 + compile + + + org.graalvm.polyglot + python + 24.2.1 + compile + + + org.apache.groovy + groovy-jsr223 + 4.0.27 + compile + + + org.apache.logging.log4j + log4j-core + 2.24.3 + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + diff --git a/applications/cafe-scripted/scripts/python/barista.py b/applications/cafe-scripted/scripts/python/barista.py index fef0b2f3c..63c6e5d5c 100644 --- a/applications/cafe-scripted/scripts/python/barista.py +++ b/applications/cafe-scripted/scripts/python/barista.py @@ -1,8 +1,10 @@ -from org.springframework.integration.samples.cafe import Drink import time +import java + +Drink = java.type("org.springframework.integration.samples.cafe.Drink") def prepareDrink(orderItem): - print("python: preparing %s for order %s" % (orderItem,orderItem.order.number)) + print("python: preparing %s for order %s" % (orderItem,orderItem.getOrder().getNumber())) time.sleep(eval(timeToPrepare)) return Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(), orderItem.getShots()) diff --git a/applications/cafe-scripted/scripts/ruby/barista.rb b/applications/cafe-scripted/scripts/ruby/barista.rb index 6e235b9fa..529e30975 100644 --- a/applications/cafe-scripted/scripts/ruby/barista.rb +++ b/applications/cafe-scripted/scripts/ruby/barista.rb @@ -1,14 +1,14 @@ - require 'java' +require 'java' - import org.springframework.integration.samples.cafe.Drink +java_import org.springframework.integration.samples.cafe.Drink - orderItem = payload +orderItem = payload - puts "ruby: preparing #{orderItem} for order #{orderItem.order.number}" +puts "ruby: preparing #{orderItem} for order #{orderItem.order.number}" - sleep(timeToPrepare.to_f) +sleep(timeToPrepare.to_f) - Drink.new(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(), +Drink.new(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(), orderItem.getShots()) diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java index fa48aa751..9819540cf 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java @@ -4,7 +4,7 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java index a59fbd430..436e34765 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -25,11 +25,9 @@ public class Delivery { private static final String SEPARATOR = "-----------------------"; + private final List deliveredDrinks; - private List deliveredDrinks; - - private int orderNumber; - + private final int orderNumber; public Delivery(List deliveredDrinks) { assert(deliveredDrinks.size() > 0); @@ -37,7 +35,6 @@ public Delivery(List deliveredDrinks) { this.orderNumber = deliveredDrinks.get(0).getOrderNumber(); } - public int getOrderNumber() { return orderNumber; } diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java index a8e445eef..5abadb04f 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,15 +21,14 @@ */ public class Drink { - private boolean iced; + private final boolean iced; - private int shots; + private final int shots; - private DrinkType drinkType; + private final DrinkType drinkType; - private int orderNumber; + private final int orderNumber; - public Drink(int orderNumber, DrinkType drinkType, boolean hot, int shots) { this.orderNumber = orderNumber; this.drinkType = drinkType; @@ -37,7 +36,6 @@ public Drink(int orderNumber, DrinkType drinkType, boolean hot, int shots) { this.shots = shots; } - public int getOrderNumber() { return orderNumber; } diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java index 4944ca4ce..5c1ad9146 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java index eb2d7e75a..e02c04532 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -25,9 +25,9 @@ */ public class Order { - private List orderItems = new ArrayList(); + private final List orderItems = new ArrayList(); - private int number; + private final int number; public Order(int number) { this.number = number; @@ -44,7 +44,7 @@ public int getNumber() { public List getItems() { return this.orderItems; } - + public String toString() { return "Order number " + number; } diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java index 07c5e9a4e..36c4fb604 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java index fac1e6ae0..ae3483e78 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -31,7 +31,7 @@ @ManagedResource public class Waiter { - private AtomicInteger totalDeliveries = new AtomicInteger(); + private final AtomicInteger totalDeliveries = new AtomicInteger(); public Delivery prepareDelivery(List drinks) { totalDeliveries.getAndIncrement(); @@ -39,8 +39,8 @@ public Delivery prepareDelivery(List drinks) { } @ManagedOperation - public int getTotalDeliveries() { - return this.totalDeliveries.get(); + public String getTotalDeliveries() { + return this.totalDeliveries.toString(); } } diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java index c71dfaadf..57b958c08 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java @@ -4,7 +4,7 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the @@ -14,9 +14,13 @@ /** * Send a groovy script to the control bus and return the result + * * @author David Turanski - * + * @author Artem Bilan + * */ public interface WaiterMonitor { - Object sendControlScript(String script); + + Integer sendControlScript(String script); + } diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java index adcab88bc..bde7a57ac 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,58 +20,57 @@ import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.util.StringUtils; /** * An implementation of the Cafe Demo application to demonstrate Spring Integration's * scripting capability. This process expects a command line argument corresponding to the scripting language - * to use. - * + * to use. + * * Provides the 'main' method for running the Cafe Demo application. When an * order is placed, the Cafe will send that order to the "orders" channel. * The relevant components are defined within the configuration file * ("cafeDemo.xml"). - * + * * @author Mark Fisher * @author Marius Bogoevici * @author Oleg Zhurakousky * @author David Turanski */ public class CafeDemoApp { - - + + public static void main(String[] args) { - - List languages = Arrays.asList(new String[]{"groovy","ruby","javascript","python"}); + + List languages = Arrays.asList(new String[]{"groovy","ruby","python"}); if (args.length != 1) { usage(); } String lang = args[0]; - + if (!StringUtils.hasText(lang)){ usage(); } - + lang = lang.toLowerCase(); if (!languages.contains(lang)){ usage(); } - + /* - * Create an application context and set the active profile to configure the + * Create an application context and set the active profile to configure the * corresponding scripting implementation */ - + ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(); - ((ConfigurableEnvironment)ctx.getEnvironment()).setActiveProfiles(lang); + ctx.getEnvironment().setActiveProfiles(lang); ctx.setConfigLocation("/META-INF/spring/integration/cafeDemo.xml"); ctx.refresh(); } - + private static void usage() { - System.out.println("missing or invalid commannd line argument [groovy,ruby,javascript,python]"); + System.out.println("missing or invalid command line argument [groovy,ruby,python]"); System.exit(1); } } diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java index 95c7cec05..00b83d201 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java @@ -1,56 +1,57 @@ /* - * Copyright 2002-2011 the original author or authors. - * + * Copyright 2002-2017 the original author or authors. + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * + * https://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package org.springframework.integration.samples.cafe.demo; - -import org.apache.log4j.Logger; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; - import org.springframework.integration.samples.cafe.WaiterMonitor; /** * Sets up a remote connection to the CafeDemoApp to manage it using the Groovy Control Bus. - * The WaiterMonitor queries the total delivered orders every second. + * The WaiterMonitor queries the total delivered orders every second. * If totalDeliveries >= 3, stop the cafe inbound adapter. - * + * * @author David Turanski + * @author Gary Russell * */ public class ControlBusMain { - private static Logger logger = Logger.getLogger(ControlBusMain.class); - + private static final Log logger = LogFactory.getLog(ControlBusMain.class); + public static void main(String[] args) { - - AbstractApplicationContext context = + + AbstractApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/spring/integration/cafeDemo-control-bus.xml"); - + WaiterMonitor waiterMonitor = (WaiterMonitor) context.getBean("waiterMonitor"); - + int totalDeliveries = 0; while (totalDeliveries <= 3) { try { Thread.sleep(1000); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + logger.error("Interrupted", e); } - - totalDeliveries = (Integer)waiterMonitor.sendControlScript("waiter.totalDeliveries"); - + + totalDeliveries = waiterMonitor.sendControlScript("waiter.totalDeliveries"); + logger.info("Total cafe deliveries: " + totalDeliveries); - + if (totalDeliveries > 3) { logger.info("stopping orders..."); waiterMonitor.sendControlScript("cafe.stop()"); diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml index 67764eb7b..9fbe62d93 100644 --- a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml @@ -1,30 +1,32 @@ + xmlns="http://www.springframework.org/schema/integration" + xmlns:beans="http://www.springframework.org/schema/beans" + xmlns:int-rsocket="http://www.springframework.org/schema/integration/rsocket" + xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/rsocket https://www.springframework.org/schema/integration/rsocket/spring-integration-rsocket.xsd + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> + + + This is the application context for ControlBusMain. It configures a Gateway tied to an RMI outbound gateway to + communicate + remotely with the CafeDemoApp. + + + + + + + + + + + + + - - This is the application context for ControlBusMain. It configures a Gateway tied to an RMI outbound gateway to communicate - remotely with the CafeDemoApp. - - - - - - - - - diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml index 84f26e1cf..364237f74 100644 --- a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml @@ -4,10 +4,10 @@ xmlns:beans="http://www.springframework.org/schema/beans" xmlns:stream="http://www.springframework.org/schema/integration/stream" xmlns:script="http://www.springframework.org/schema/integration/scripting" - xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/integration/script http://www.springframework.org/schema/integration/script.xsd - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/script https://www.springframework.org/schema/integration/script.xsd + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration/scripting https://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd"> payload.items diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml index 3c8245f40..d415fe611 100644 --- a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml @@ -4,10 +4,10 @@ xmlns:beans="http://www.springframework.org/schema/beans" xmlns:stream="http://www.springframework.org/schema/integration/stream" xmlns:script="http://www.springframework.org/schema/integration/scripting" - xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/integration/script http://www.springframework.org/schema/integration/script.xsd - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/script https://www.springframework.org/schema/integration/script.xsd + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration/scripting https://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd"> payload.items; diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml index dfaa92e4b..9e33d9b65 100644 --- a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml @@ -4,10 +4,10 @@ xmlns:beans="http://www.springframework.org/schema/beans" xmlns:stream="http://www.springframework.org/schema/integration/stream" xmlns:script="http://www.springframework.org/schema/integration/scripting" - xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/integration/script http://www.springframework.org/schema/integration/script.xsd - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/script https://www.springframework.org/schema/integration/script.xsd + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration/scripting https://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd"> diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml index 4c1922a7f..f195f668b 100644 --- a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml @@ -4,10 +4,10 @@ xmlns:beans="http://www.springframework.org/schema/beans" xmlns:stream="http://www.springframework.org/schema/integration/stream" xmlns:script="http://www.springframework.org/schema/integration/scripting" - xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/integration/script http://www.springframework.org/schema/integration/script.xsd - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/script https://www.springframework.org/schema/integration/script.xsd + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration/scripting https://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd"> diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml index 78ba9e2cf..0f6db7d25 100644 --- a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml @@ -1,83 +1,91 @@ - - - This is the application context for the scripted implementation of CafeDemoApp. The functionality is basically - identical to the original CafeDemoApp. - - In order to demonstrate the Groovy control bus, the original cafe Gateway is replaced with an - inbound-channel-adapter (which supports the SmartLifeCycle interface). - - The inbound-channel-adapter is backed by a Customer bean which provides the orders. - - This configuration also uses Spring 3.1 environment profiles to inject a configuration specific to the - selected scripting language. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:groovy="http://www.springframework.org/schema/integration/groovy" + xmlns:beans="http://www.springframework.org/schema/beans" + xmlns:int-rsocket="http://www.springframework.org/schema/integration/rsocket" + xmlns:stream="http://www.springframework.org/schema/integration/stream" + xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/rsocket https://www.springframework.org/schema/integration/rsocket/spring-integration-rsocket.xsd + http://www.springframework.org/schema/integration/stream https://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd + http://www.springframework.org/schema/integration/groovy https://www.springframework.org/schema/integration/groovy/spring-integration-groovy.xsd + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> + + + This is the application context for the scripted implementation of CafeDemoApp. The functionality is basically + identical to the original CafeDemoApp. + + In order to demonstrate the Groovy control bus, the original cafe Gateway is replaced with an + inbound-channel-adapter (which supports the SmartLifeCycle interface). + + The inbound-channel-adapter is backed by a Customer bean which provides the orders. + + This configuration also uses Spring 3.1 environment profiles to inject a configuration specific to the + selected scripting language. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/cafe-scripted/src/main/resources/log4j.xml b/applications/cafe-scripted/src/main/resources/log4j.xml deleted file mode 100644 index 00e7276b5..000000000 --- a/applications/cafe-scripted/src/main/resources/log4j.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/applications/cafe-scripted/src/main/resources/log4j2.xml b/applications/cafe-scripted/src/main/resources/log4j2.xml new file mode 100644 index 000000000..3e65e17e3 --- /dev/null +++ b/applications/cafe-scripted/src/main/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java b/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java index e616d3b95..6498e522b 100644 --- a/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java +++ b/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java @@ -1,48 +1,49 @@ /* - * Copyright 2002-2011 the original author or authors. - * + * Copyright 2002-2023 the original author or authors. + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * + * https://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ -package org.springframework.integration.samples.cafe; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +package org.springframework.integration.samples.cafe; import java.util.HashMap; import java.util.Map; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + import org.springframework.core.io.FileSystemResource; import org.springframework.integration.scripting.ScriptExecutor; import org.springframework.integration.scripting.jsr223.ScriptExecutorFactory; import org.springframework.scripting.support.ResourceScriptSource; + /** * @author David Turanski - * + * @author Artem Bilan */ public class ScriptTests { + @Test public void testRuby() { ScriptExecutor executor = ScriptExecutorFactory.getScriptExecutor("ruby"); Order order = new Order(0); order.addItem(DrinkType.LATTE, 2, false); - Map variables = new HashMap(); + Map variables = new HashMap<>(); variables.put("payload", order.getItems().get(0)); variables.put("timeToPrepare", 1L); Object obj = executor.executeScript( new ResourceScriptSource(new FileSystemResource("scripts/ruby/barista.rb")), variables); - assertNotNull(obj); - assertTrue(obj instanceof Drink); - + Assertions.assertNotNull(obj); + Assertions.assertInstanceOf(Drink.class, obj); } @Test @@ -50,14 +51,14 @@ public void testPython() { ScriptExecutor executor = ScriptExecutorFactory.getScriptExecutor("python"); Order order = new Order(0); order.addItem(DrinkType.LATTE, 2, false); - Map variables = new HashMap(); + Map variables = new HashMap<>(); variables.put("payload", order.getItems().get(0)); variables.put("timeToPrepare", "1"); Object obj = executor.executeScript(new ResourceScriptSource( new FileSystemResource("scripts/python/barista.py")), variables); - assertNotNull(obj); - assertTrue(obj instanceof Drink); - + Assertions.assertNotNull(obj); + Assertions.assertInstanceOf(Drink.class, obj); } + } diff --git a/applications/cafe/README.md b/applications/cafe/README.md index c63b4ef66..3787b97e8 100644 --- a/applications/cafe/README.md +++ b/applications/cafe/README.md @@ -60,11 +60,11 @@ Upon running any of the alternatives, you should see the output similar to this: Happy integration :-) -[ActiveMQ]: http://activemq.apache.org/ -[AMQP]: http://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol -[café]: http://en.wikipedia.org/wiki/Caf%C3%A9 -[Enterprise Integration Patterns]: http://www.eaipatterns.com/eaipatterns.html -[Gregor Hohpe]: http://www.eaipatterns.com/gregor.html -[JMS]: http://en.wikipedia.org/wiki/Java_Message_Service -[RabbitMQ]: http://www.rabbitmq.com/ -[Starbucks Does Not Use Two-Phase Commit]: http://www.eaipatterns.com/ramblings/18_starbucks.html +[ActiveMQ]: https://activemq.apache.org/ +[AMQP]: https://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol +[café]: https://en.wikipedia.org/wiki/Caf%25C3%25A9 +[Enterprise Integration Patterns]: https://www.enterpriseintegrationpatterns.com/eaipatterns.html +[Gregor Hohpe]: https://www.enterpriseintegrationpatterns.com/gregor.html +[JMS]: https://en.wikipedia.org/wiki/Java_Message_Service +[RabbitMQ]: https://www.rabbitmq.com/ +[Starbucks Does Not Use Two-Phase Commit]: https://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html diff --git a/applications/cafe/cafe-amqp/pom.xml b/applications/cafe/cafe-amqp/pom.xml index 1c130faab..146fb7215 100644 --- a/applications/cafe/cafe-amqp/pom.xml +++ b/applications/cafe/cafe-amqp/pom.xml @@ -1,35 +1,159 @@ - - 4.0.0 - - cafe - org.springframework.integration.samples - 2.2.0.BUILD-SNAPSHOT - - - cafe-amqp - - Cafe - With AMQP Message Broker - - This module implements the cafe sample using spring-integration components backed - by an AMQP message broker for message persistence and component distribution. This - sample uses RabbitMQ broker, but any AMQP message broker can be used. For an example - using JMS, see the JMS implementation of the cafe sample. - - - - - ${project.parent.groupId} - cafe-si - ${project.parent.version} - - - org.springframework.integration - spring-integration-amqp - ${spring.integration.version} - - - + + 4.0.0 + org.springframework.integration.samples + cafe-amqp + 7.0.0 + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.integration.samples + cafe-si + 7.0.0 + compile + + + org.springframework.integration + spring-integration-amqp + compile + + + org.apache.logging.log4j + log4j-core + 2.24.3 + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + diff --git a/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java b/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java index 9ad82701f..1c8fb74b1 100644 --- a/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java +++ b/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java b/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java index 122631969..114c4fdd5 100644 --- a/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java +++ b/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java b/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java index 5cb287174..74643d53b 100644 --- a/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java +++ b/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java b/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java index d6df06422..74eaa0ce9 100644 --- a/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java +++ b/applications/cafe/cafe-amqp/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml index 965c1c832..484abc89c 100644 --- a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml +++ b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml @@ -7,17 +7,17 @@ xmlns:int-stream="http://www.springframework.org/schema/integration/stream" xmlns:cloud="http://schema.cloudfoundry.org/spring" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd + https://www.springframework.org/schema/beans/spring-beans.xsd http://schema.cloudfoundry.org/spring - http://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd + https://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd http://www.springframework.org/schema/integration - http://www.springframework.org/schema/integration/spring-integration.xsd + https://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/amqp - http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd + https://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd http://www.springframework.org/schema/rabbit - http://www.springframework.org/schema/rabbit/spring-rabbit.xsd + https://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/integration/stream - http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> + https://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> diff --git a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml index f5bd47ee9..d15bf42ae 100644 --- a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml +++ b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml @@ -7,17 +7,17 @@ xmlns:int-stream="http://www.springframework.org/schema/integration/stream" xmlns:cloud="http://schema.cloudfoundry.org/spring" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd + https://www.springframework.org/schema/beans/spring-beans.xsd http://schema.cloudfoundry.org/spring - http://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd + https://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd http://www.springframework.org/schema/integration - http://www.springframework.org/schema/integration/spring-integration.xsd + https://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/amqp - http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd + https://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd http://www.springframework.org/schema/rabbit - http://www.springframework.org/schema/rabbit/spring-rabbit.xsd + https://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/integration/stream - http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> + https://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> diff --git a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml index f20a517b9..40bd1643f 100644 --- a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml +++ b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml @@ -4,11 +4,11 @@ xmlns:rabbit="http://www.springframework.org/schema/rabbit" xmlns:cloud="http://schema.cloudfoundry.org/spring" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd + https://www.springframework.org/schema/beans/spring-beans.xsd http://schema.cloudfoundry.org/spring - http://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd + https://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd http://www.springframework.org/schema/rabbit - http://www.springframework.org/schema/rabbit/spring-rabbit.xsd"> + https://www.springframework.org/schema/rabbit/spring-rabbit.xsd"> @@ -21,7 +21,7 @@ - + diff --git a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml index 4d1ca75c5..79e1af8a7 100644 --- a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml +++ b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml @@ -7,17 +7,17 @@ xmlns:int-stream="http://www.springframework.org/schema/integration/stream" xmlns:cloud="http://schema.cloudfoundry.org/spring" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd + https://www.springframework.org/schema/beans/spring-beans.xsd http://schema.cloudfoundry.org/spring - http://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd + https://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd http://www.springframework.org/schema/integration - http://www.springframework.org/schema/integration/spring-integration.xsd + https://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/amqp - http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd + https://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd http://www.springframework.org/schema/rabbit - http://www.springframework.org/schema/rabbit/spring-rabbit.xsd + https://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/integration/stream - http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> + https://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> diff --git a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml index 2ba9c1538..61984b08d 100644 --- a/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml +++ b/applications/cafe/cafe-amqp/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml @@ -5,19 +5,19 @@ xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp" xmlns:rabbit="http://www.springframework.org/schema/rabbit" xmlns:int-stream="http://www.springframework.org/schema/integration/stream" - xmlns:cloud="http://schema.cloudfoundry.org /spring" + xmlns:cloud="https://schema.cloudfoundry.org /spring" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd + https://www.springframework.org/schema/beans/spring-beans.xsd http://schema.cloudfoundry.org/spring - http://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd + https://schema.cloudfoundry.org/spring/cloudfoundry-spring.xsd http://www.springframework.org/schema/integration - http://www.springframework.org/schema/integration/spring-integration.xsd + https://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/amqp - http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd + https://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd http://www.springframework.org/schema/rabbit - http://www.springframework.org/schema/rabbit/spring-rabbit.xsd + https://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/integration/stream - http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> + https://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> diff --git a/applications/cafe/cafe-amqp/src/main/resources/log4j.xml b/applications/cafe/cafe-amqp/src/main/resources/log4j.xml deleted file mode 100644 index 317bd1820..000000000 --- a/applications/cafe/cafe-amqp/src/main/resources/log4j.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/applications/cafe/cafe-amqp/src/main/resources/log4j2.xml b/applications/cafe/cafe-amqp/src/main/resources/log4j2.xml new file mode 100644 index 000000000..dbab18be7 --- /dev/null +++ b/applications/cafe/cafe-amqp/src/main/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/applications/cafe/cafe-jms/README.md b/applications/cafe/cafe-jms/README.md index 86444fb88..60cd05f71 100644 --- a/applications/cafe/cafe-jms/README.md +++ b/applications/cafe/cafe-jms/README.md @@ -24,8 +24,8 @@ To run this configuration, start an instance of ActiveMQ with the openwire/TCP c 1. **CafeDemoAppBaristaColdActiveMQ - starts the ColdDrink Barista 2. **CafeDemoAppBaristaHotActiveMQ - starts the HotDrink Barista 3. **CafeDemoAppOperationsActiveMQ - starts the Cafe Operations (order splitter, drink router, etc). - 4. **CafeDemoAppAcitveMQ - places the orders + 4. **CafeDemoAppActiveMQ - places the orders ### JMS backed components -See **CafeDemoActiveMQBackedChannels** for an example of how to use the JMS-backed channels. No need to start an external ActiveMQ because one is started internally \ No newline at end of file +See **CafeDemoActiveMQBackedChannels** for an example of how to use the JMS-backed channels. No need to start an external ActiveMQ because one is started internally diff --git a/applications/cafe/cafe-jms/pom.xml b/applications/cafe/cafe-jms/pom.xml index b6b8981df..5d6d98b3a 100644 --- a/applications/cafe/cafe-jms/pom.xml +++ b/applications/cafe/cafe-jms/pom.xml @@ -1,47 +1,183 @@ - - 4.0.0 - - org.springframework.integration.samples - cafe - 2.2.0.BUILD-SNAPSHOT - - - cafe-jms - Cafe - With JMS Message Broker - - - This module implements the cafe sample using spring-integration components backed - by a JMS broker for persistent messaging as well as component distribution. This - sample uses ActiveMQ as the JMS broker, but any JMS-compliant broker can be - used. For an example using AMQP, see the AMQP implementation of the cafe sample. - - - - 5.6.0 - - - - org.apache.activemq - activemq-all - ${activemq.version} - - - org.apache.xbean - xbean-spring - 3.11.1 - - - org.springframework.integration - spring-integration-jms - ${spring.integration.version} - - - ${project.parent.groupId} - cafe-si - ${project.parent.version} - - + + 4.0.0 + org.springframework.integration.samples + cafe-jms + 7.0.0 + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.integration.samples + cafe-si + 7.0.0 + compile + + + org.apache.activemq + artemis-server + 2.41.0 + compile + + + org.jboss.logmanager + * + + + + + org.apache.activemq + artemis-jakarta-client + 2.41.0 + compile + + + org.springframework.integration + spring-integration-jms + compile + + + jakarta.jms + jakarta.jms-api + 3.1.0 + compile + + + org.apache.logging.log4j + log4j-core + 2.24.3 + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + diff --git a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoActiveMQBackedChannels.java b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoActiveMQBackedChannels.java index 0520fe265..5b3196610 100644 --- a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoActiveMQBackedChannels.java +++ b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoActiveMQBackedChannels.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppActiveMQ.java b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppActiveMQ.java index 7171ceb33..50c74d12f 100644 --- a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppActiveMQ.java +++ b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppActiveMQ.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdActiveMQ.java b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdActiveMQ.java index bb00404a0..c1f718346 100644 --- a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdActiveMQ.java +++ b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdActiveMQ.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotActiveMQ.java b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotActiveMQ.java index 3f1d15a3a..f09d9cb87 100644 --- a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotActiveMQ.java +++ b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotActiveMQ.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsActiveMQ.java b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsActiveMQ.java index 57d3f2747..0d1fe3d75 100644 --- a/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsActiveMQ.java +++ b/applications/cafe/cafe-jms/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsActiveMQ.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-baristaCold-xml.xml b/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-baristaCold-xml.xml index 6498125ea..a12f77423 100644 --- a/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-baristaCold-xml.xml +++ b/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-baristaCold-xml.xml @@ -4,9 +4,9 @@ xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-jms="http://www.springframework.org/schema/integration/jms" xsi:schemaLocation=" - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd"> + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/jms https://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd"> diff --git a/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-baristaHot-xml.xml b/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-baristaHot-xml.xml index c3b227394..361864e7d 100644 --- a/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-baristaHot-xml.xml +++ b/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-baristaHot-xml.xml @@ -4,9 +4,9 @@ xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-jms="http://www.springframework.org/schema/integration/jms" xsi:schemaLocation=" - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd"> + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/jms https://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd"> diff --git a/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-config.xml b/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-config.xml index 69cf40709..b4abf3386 100644 --- a/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-config.xml +++ b/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-config.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd "> diff --git a/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-operations.xml b/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-operations.xml index 3492443af..62157a1a6 100644 --- a/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-operations.xml +++ b/applications/cafe/cafe-jms/src/main/resources/META-INF/spring/integration/activemq/cafeDemo-amq-operations.xml @@ -5,10 +5,10 @@ xmlns:int-stream="http://www.springframework.org/schema/integration/stream" xmlns:int-jms="http://www.springframework.org/schema/integration/jms" xsi:schemaLocation=" - http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd - http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd"> + http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/stream https://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd + http://www.springframework.org/schema/integration/jms https://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd"> + on the other side of the JMS queue to which the channel adapter is connected --> diff --git a/applications/cafe/cafe-jms/src/main/resources/log4j.xml b/applications/cafe/cafe-jms/src/main/resources/log4j.xml deleted file mode 100644 index 317bd1820..000000000 --- a/applications/cafe/cafe-jms/src/main/resources/log4j.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/applications/cafe/cafe-jms/src/main/resources/log4j2.xml b/applications/cafe/cafe-jms/src/main/resources/log4j2.xml new file mode 100644 index 000000000..7d458a827 --- /dev/null +++ b/applications/cafe/cafe-jms/src/main/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/applications/cafe/cafe-si/pom.xml b/applications/cafe/cafe-si/pom.xml index d1817ad90..d71df3236 100644 --- a/applications/cafe/cafe-si/pom.xml +++ b/applications/cafe/cafe-si/pom.xml @@ -1,49 +1,158 @@ - - 4.0.0 - - cafe - org.springframework.integration.samples - 2.2.0.BUILD-SNAPSHOT - - - cafe-si - jar - - Cafe - Pure Spring Integration - - This module implements the cafe sample using spring-integration components. - The channels that are used are in-memory channels and there is no distribution of - the processes (i.e., all of the processing happens within the same JVM and there - is no message broker). To see the cafe sample with a message broker to help distribute - the components, see the AMQP or the JMS sample. - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.5.1 - - 1.6 - 1.6 - -Xlint:all - true - true - - - - org.codehaus.mojo - exec-maven-plugin - 1.2.1 - - org.springframework.integration.samples.cafe.xml.CafeDemoApp - - - - - + + 4.0.0 + org.springframework.integration.samples + cafe-si + 7.0.0 + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.integration + spring-integration-stream + compile + + + com.fasterxml.jackson.core + jackson-databind + compile + + + org.apache.logging.log4j + log4j-core + 2.24.3 + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Cafe.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Cafe.java index 7f7cb7dad..fd0ffd79b 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Cafe.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Cafe.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Delivery.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Delivery.java index edd34f60a..692c0b51f 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Delivery.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Delivery.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,34 +16,37 @@ package org.springframework.integration.samples.cafe; +import java.io.Serial; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; /** * @author Marius Bogoevici * @author Tom McCuch * @author Gunnar Hillert + * @author Artem Bilan */ -public class Delivery implements Serializable{ +public class Delivery implements Serializable { + @Serial private static final long serialVersionUID = 1L; private static final String SEPARATOR = "-----------------------"; - private List deliveredDrinks; + private ArrayList deliveredDrinks; private int orderNumber; // Default constructor required by Jackson Java JSON-processor - public Delivery() {} + public Delivery() { + } public Delivery(List deliveredDrinks) { - assert(deliveredDrinks.size() > 0); - this.deliveredDrinks = deliveredDrinks; + this.deliveredDrinks = new ArrayList<>(deliveredDrinks); this.orderNumber = deliveredDrinks.get(0).getOrderNumber(); } - public int getOrderNumber() { return orderNumber; } @@ -57,13 +60,13 @@ public List getDeliveredDrinks() { } public void setDeliveredDrinks(List deliveredDrinks) { - this.deliveredDrinks = deliveredDrinks; + this.deliveredDrinks = new ArrayList<>(deliveredDrinks); } @Override public String toString() { - StringBuffer buffer = new StringBuffer(SEPARATOR + "\n"); - buffer.append("Order #" + getOrderNumber() + "\n"); + StringBuilder buffer = new StringBuilder(SEPARATOR + "\n"); + buffer.append("Order #").append(getOrderNumber()).append("\n"); for (Drink drink : getDeliveredDrinks()) { buffer.append(drink); buffer.append("\n"); diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Drink.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Drink.java index 5cb194b40..a767dbb50 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Drink.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Drink.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java index bcca836f9..732b2e0dc 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Order.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Order.java index ee00c5776..f9aee6f53 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Order.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/Order.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,6 +16,7 @@ package org.springframework.integration.samples.cafe; +import java.io.Serial; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -25,18 +26,21 @@ * @author Marius Bogoevici * @author Tom McCuch * @author Gunnar Hillert + * @author Artem Bilan */ -public class Order implements Serializable{ +public class Order implements Serializable { + @Serial private static final long serialVersionUID = 1L; - private List orderItems = new ArrayList(); + private ArrayList orderItems = new ArrayList<>(); /** the order number used for tracking */ private int number; // Default constructor required by Jackson Java JSON-processor - public Order() {} + public Order() { + } public Order(int number) { this.number = number; @@ -59,6 +63,7 @@ public List getItems() { } public void setItems(List orderItems) { - this.orderItems = orderItems; + this.orderItems = new ArrayList<>(orderItems); } + } diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java index a3b7cb8aa..d82cdeb98 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java index 0fac9cce1..850d7ecfa 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,28 +18,33 @@ import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.integration.annotation.ServiceActivator; import org.springframework.integration.samples.cafe.Drink; import org.springframework.integration.samples.cafe.OrderItem; -import org.apache.log4j.Logger; -import org.springframework.integration.annotation.ServiceActivator; import org.springframework.stereotype.Component; /** * @author Mark Fisher * @author Marius Bogoevici * @author Tom McCuch + * @author Gary Russell */ @Component public class Barista { - private static Logger logger = Logger.getLogger(Barista.class); + + private static final Log logger = LogFactory.getLog(Barista.class); + private long hotDrinkDelay = 5000; private long coldDrinkDelay = 1000; - private AtomicInteger hotDrinkCounter = new AtomicInteger(); + private final AtomicInteger hotDrinkCounter = new AtomicInteger(); - private AtomicInteger coldDrinkCounter = new AtomicInteger(); + private final AtomicInteger coldDrinkCounter = new AtomicInteger(); public void setHotDrinkDelay(long hotDrinkDelay) { diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/CafeDemoApp.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/CafeDemoApp.java index 64c91cf60..2b98fed8f 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/CafeDemoApp.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/CafeDemoApp.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/DrinkRouter.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/DrinkRouter.java index 4bc0a9a3d..eab27d15a 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/DrinkRouter.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/DrinkRouter.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/OrderSplitter.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/OrderSplitter.java index 3709ce4ed..4e9ecbfec 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/OrderSplitter.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/OrderSplitter.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/Waiter.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/Waiter.java index 681e1f4df..e10a42047 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/Waiter.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/annotation/Waiter.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/Barista.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/Barista.java index 5466e093b..e49e91b7b 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/Barista.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/Barista.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,25 +18,30 @@ import java.util.concurrent.atomic.AtomicInteger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.integration.samples.cafe.Drink; import org.springframework.integration.samples.cafe.OrderItem; -import org.apache.log4j.Logger; /** * @author Mark Fisher * @author Marius Bogoevici * @author Tom McCuch + * @author Gary Russell */ public class Barista { - private static Logger logger = Logger.getLogger(Barista.class); + + private static final Log logger = LogFactory.getLog(Barista.class); + private long hotDrinkDelay = 5000; private long coldDrinkDelay = 1000; - private AtomicInteger hotDrinkCounter = new AtomicInteger(); + private final AtomicInteger hotDrinkCounter = new AtomicInteger(); - private AtomicInteger coldDrinkCounter = new AtomicInteger(); + private final AtomicInteger coldDrinkCounter = new AtomicInteger(); public void setHotDrinkDelay(long hotDrinkDelay) { diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoApp.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoApp.java index 4f7d0f45d..560ee3ed2 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoApp.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoApp.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppUtilities.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppUtilities.java index 4901e7a29..e814d8e45 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppUtilities.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppUtilities.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -33,7 +33,7 @@ public class CafeDemoAppUtilities { /** * * @param path path to the file - * @param targetClass the class who's classloader we will use to laod the context file + * @param targetClass the class who's classloader we will use to load the context file * @param profile a profile name * @return the spring context */ diff --git a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/Waiter.java b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/Waiter.java index ec8fcc9d6..b2cb1a22d 100644 --- a/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/Waiter.java +++ b/applications/cafe/cafe-si/src/main/java/org/springframework/integration/samples/cafe/xml/Waiter.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/cafe/cafe-si/src/main/resources/META-INF/spring/integration/cafeDemo-annotation.xml b/applications/cafe/cafe-si/src/main/resources/META-INF/spring/integration/cafeDemo-annotation.xml index 841ae18c3..470be7a92 100644 --- a/applications/cafe/cafe-si/src/main/resources/META-INF/spring/integration/cafeDemo-annotation.xml +++ b/applications/cafe/cafe-si/src/main/resources/META-INF/spring/integration/cafeDemo-annotation.xml @@ -5,13 +5,13 @@ xmlns:context="http://www.springframework.org/schema/context" xmlns:int-stream="http://www.springframework.org/schema/integration/stream" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd + https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context.xsd + https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/integration - http://www.springframework.org/schema/integration/spring-integration.xsd + https://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/stream - http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> + https://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> diff --git a/applications/cafe/cafe-si/src/main/resources/META-INF/spring/integration/cafeDemo-xml.xml b/applications/cafe/cafe-si/src/main/resources/META-INF/spring/integration/cafeDemo-xml.xml index 0a750b081..d0407763d 100644 --- a/applications/cafe/cafe-si/src/main/resources/META-INF/spring/integration/cafeDemo-xml.xml +++ b/applications/cafe/cafe-si/src/main/resources/META-INF/spring/integration/cafeDemo-xml.xml @@ -4,11 +4,11 @@ xmlns:beans="http://www.springframework.org/schema/beans" xmlns:int-stream="http://www.springframework.org/schema/integration/stream" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd + https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration - http://www.springframework.org/schema/integration/spring-integration.xsd + https://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/stream - http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> + https://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> diff --git a/applications/cafe/cafe-si/src/main/resources/log4j.xml b/applications/cafe/cafe-si/src/main/resources/log4j.xml deleted file mode 100644 index 317bd1820..000000000 --- a/applications/cafe/cafe-si/src/main/resources/log4j.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/applications/cafe/cafe-si/src/main/resources/log4j2.xml b/applications/cafe/cafe-si/src/main/resources/log4j2.xml new file mode 100644 index 000000000..7d458a827 --- /dev/null +++ b/applications/cafe/cafe-si/src/main/resources/log4j2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/applications/cafe/pom.xml b/applications/cafe/pom.xml deleted file mode 100644 index da23dd456..000000000 --- a/applications/cafe/pom.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - 4.0.0 - org.springframework.integration.samples - cafe - pom - 2.2.0.BUILD-SNAPSHOT - - - 2.2.1 - - - - cafe-jms - cafe-si - cafe-amqp - - - Samples (Applications) - Cafe Sample - - - UTF-8 - 2.2.0.RELEASE - 3.1.3.RELEASE - 1.2.17 - 4.10 - - - - org.springframework - spring-tx - ${spring.core.version} - - - org.springframework - spring-context - ${spring.core.version} - - - org.springframework.integration - spring-integration-stream - ${spring.integration.version} - - - - org.codehaus.jackson - jackson-core-asl - 1.9.2 - - - org.codehaus.jackson - jackson-mapper-asl - 1.9.2 - - - log4j - log4j - ${log4j.version} - - - - junit - junit - ${junit.version} - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.5.1 - - 1.6 - 1.6 - -Xlint:all - true - true - - - - - - - repo.springsource.org.milestone - SpringSource Maven Milestone Repository - https://repo.springsource.org/libs-milestone - - - diff --git a/applications/file-split-ftp/.gitignore b/applications/file-split-ftp/.gitignore new file mode 100644 index 000000000..ce3767e55 --- /dev/null +++ b/applications/file-split-ftp/.gitignore @@ -0,0 +1,7 @@ +/target/ +.classpath +.project +.settings +.factorypath +.mvn +mvnw* diff --git a/applications/file-split-ftp/README.adoc b/applications/file-split-ftp/README.adoc new file mode 100644 index 000000000..6d150de77 --- /dev/null +++ b/applications/file-split-ftp/README.adoc @@ -0,0 +1,23 @@ +:imagesdir: ./images + += File Split and FTP Sample + +- Looks for files `*.txt` in `/tmp/in` +- Reads file and writes to 3 files based on account (first 4 bytes in file) +- FileSplitter -> router [lines -> `lines`], [file marks -> `marks`] +- `marks` filters on EOF marker (drops SOF) +- pubsub [flush files], [ftp (x3)], [email result] +- Exceptions go to `tfrErrors` - sends failure email +- input file is renamed, based on final disposition + +Test cases are provided for happy path and failure scenarios + +Run `ApplicationTests` as a JUnit test from your IDE. + += Flow Visualization + +This visualization is generated by the https://github.com/spring-projects/spring-flo/[Spring Integration Flow Viewer] which is currently under development. + +image::flo1.png[] + +image::flo2.png[] diff --git a/applications/file-split-ftp/images/flo1.png b/applications/file-split-ftp/images/flo1.png new file mode 100644 index 000000000..d6dffd384 Binary files /dev/null and b/applications/file-split-ftp/images/flo1.png differ diff --git a/applications/file-split-ftp/images/flo2.png b/applications/file-split-ftp/images/flo2.png new file mode 100644 index 000000000..cddfcfae7 Binary files /dev/null and b/applications/file-split-ftp/images/flo2.png differ diff --git a/applications/file-split-ftp/pom.xml b/applications/file-split-ftp/pom.xml new file mode 100644 index 000000000..9f7af10f9 --- /dev/null +++ b/applications/file-split-ftp/pom.xml @@ -0,0 +1,210 @@ + + + 4.0.0 + org.springframework.integration.samples + file-split-ftp + 7.0.0 + jar + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.boot + spring-boot-starter-web + compile + + + org.springframework.boot + spring-boot-starter-mail + compile + + + org.springframework.boot + spring-boot-starter-integration + compile + + + org.springframework.integration + spring-integration-ftp + compile + + + org.springframework.integration + spring-integration-http + compile + + + org.springframework.integration + spring-integration-mail + compile + + + org.eclipse.angus + jakarta.mail + 2.0.3 + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.springframework.boot + spring-boot-starter-test + test + + + com.icegreen + greenmail + 2.1.0-alpha-3 + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.springframework.boot + spring-boot-dependencies + 4.0.0-SNAPSHOT + import + pom + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + org.springframework.boot + spring-boot-starter-parent + 4.0.0-SNAPSHOT + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + + diff --git a/applications/file-split-ftp/src/main/java/org/springframework/integration/samples/filesplit/Application.java b/applications/file-split-ftp/src/main/java/org/springframework/integration/samples/filesplit/Application.java new file mode 100644 index 000000000..2c103362a --- /dev/null +++ b/applications/file-split-ftp/src/main/java/org/springframework/integration/samples/filesplit/Application.java @@ -0,0 +1,230 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.samples.filesplit; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; + +import org.aopalliance.intercept.MethodInterceptor; +import org.apache.commons.net.ftp.FTPFile; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.mail.autoconfigure.MailProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.integration.dsl.IntegrationFlow; +import org.springframework.integration.dsl.Pollers; +import org.springframework.integration.file.FileHeaders; +import org.springframework.integration.file.FileWritingMessageHandler; +import org.springframework.integration.file.dsl.FileWritingMessageHandlerSpec; +import org.springframework.integration.file.dsl.Files; +import org.springframework.integration.file.remote.session.SessionFactory; +import org.springframework.integration.file.splitter.FileSplitter; +import org.springframework.integration.ftp.dsl.Ftp; +import org.springframework.integration.ftp.session.DefaultFtpSessionFactory; +import org.springframework.integration.http.config.EnableIntegrationGraphController; +import org.springframework.integration.mail.dsl.Mail; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.MessagingException; + +@SpringBootApplication +@EnableIntegrationGraphController(allowedOrigins = "http://localhost:8082") +public class Application { + + private static final String EMAIL_SUCCESS_SUFFIX = "emailSuccessSuffix"; + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Autowired + private MailProperties mailProperties; + + /** + * Poll for files, add an error channel, split into lines route the start/end markers + * to {@link #markers()} and the lines to {@link #lines}. + * + * @return the flow. + */ + @Bean + public IntegrationFlow fromFile() { + return IntegrationFlow.from( + Files.inboundAdapter(new File("/tmp/in")) + .preventDuplicates(false) + .patternFilter("*.txt"), e -> e.poller(Pollers.fixedDelay(5000) + .errorChannel("tfrErrors.input")) + .id("fileInboundChannelAdapter")) + .handle(Files.splitter(true, true)) + .>route(Object::getClass, m -> m + .channelMapping(FileSplitter.FileMarker.class, "markers.input") + .channelMapping(String.class, "lines.input")) + .get(); + } + + /** + * Process lines; append (no flush) to the appropriate file. + * + * @return the flow. + */ + @Bean + public IntegrationFlow lines(FileWritingMessageHandler fileOut) { + return f -> f.handle(fileOut); + } + + @Bean + public FileWritingMessageHandlerSpec fileOut() { + return Files.outboundAdapter("'/tmp/out'") + .appendNewLine(true) + .fileNameExpression("payload.substring(1, 4) + '.txt'"); + } + + /** + * Process file markers; ignore START, when END, flush the files, ftp them and + * send an email. + * + * @return the flow. + */ + @Bean + public IntegrationFlow markers() { + return f -> f.filter(m -> m.getMark().equals(FileSplitter.FileMarker.Mark.END), + e -> e.id("markerFilter")) + .publishSubscribeChannel(s -> s + + // first trigger file flushes + .subscribe(sf -> sf + .transformWith(transformer -> transformer + .id("toTriggerPattern") + .expression("'/tmp/out/.*\\.txt'")) + .trigger("fileOut", e -> e.id("flusher"))) + + // send the first file + .subscribe(sf -> sf.transform(p -> new File("/tmp/out/002.txt")) + .enrichHeaders(h -> h.header(FileHeaders.FILENAME, "002.txt", true)) + .handle(Ftp.outboundAdapter(ftp1()).remoteDirectory("foo"), e -> e.id("ftp002"))) + + // send the second file + .subscribe(sf -> sf.transform(p -> new File("/tmp/out/006.txt")) + .enrichHeaders(h -> h.header(FileHeaders.FILENAME, "006.txt", true)) + .handle(Ftp.outboundAdapter(ftp2()).remoteDirectory("foo"), e -> e.id("ftp006"))) + + // send the third file + .subscribe(sf -> sf.transform(p -> new File("/tmp/out/009.txt")) + .enrichHeaders(h -> h.header(FileHeaders.FILENAME, "009.txt", true)) + .handle(Ftp.outboundAdapter(ftp3()).remoteDirectory("foo"), e -> e.id("ftp009"))) + + // send an email + .subscribe(sf -> sf.transform(FileSplitter.FileMarker::getFilePath) + .enrichHeaders(Mail.headers() + .subject("File successfully split and transferred") + .from("foo@bar") + .toFunction(m -> new String[] {"bar@baz"})) + .enrichHeaders(h -> h.header(EMAIL_SUCCESS_SUFFIX, ".success")) + .channel("toMail.input"))); + } + + @Bean + public SessionFactory ftp1() { + DefaultFtpSessionFactory ftp = new DefaultFtpSessionFactory(); + ftp.setHost("host3"); + ftp.setUsername("user"); + ftp.setPassword("ftp"); + return ftp; + } + + @Bean + public SessionFactory ftp2() { + DefaultFtpSessionFactory ftp = new DefaultFtpSessionFactory(); + ftp.setHost("host3"); + ftp.setUsername("user"); + ftp.setPassword("ftp"); + return ftp; + } + + @Bean + public SessionFactory ftp3() { + DefaultFtpSessionFactory ftp = new DefaultFtpSessionFactory(); + ftp.setHost("host3"); + ftp.setUsername("user"); + ftp.setPassword("ftp"); + return ftp; + } + + /** + * Error flow - email failure + * + * @return the flow. + */ + @Bean + public IntegrationFlow tfrErrors() { + return f -> f + .enrichHeaders(Mail.headers() + .subject("File split and transfer failed") + .from("foo@bar") + .toFunction(m -> new String[] {"bar@baz"})) + .enrichHeaders(h -> h.header(EMAIL_SUCCESS_SUFFIX, ".failed") + .headerExpression(FileHeaders.ORIGINAL_FILE, "payload.failedMessage.headers['" + + FileHeaders.ORIGINAL_FILE + "']")) + .transform(p -> + p.getFailedMessage().getPayload() + "\n" + getStackTraceAsString(p)) + .channel("toMail.input"); + } + + @Bean + public IntegrationFlow toMail() { + return f -> f + .handle(Mail.outboundAdapter(this.mailProperties.getHost()) + // .javaMailProperties(b -> b.put("mail.debug", "true")) + .port(this.mailProperties.getPort()) + .credentials(this.mailProperties.getUsername(), this.mailProperties.getPassword()), + e -> e.id("mailOut").advice(afterMailAdvice())); + } + + /** + * Rename the input file after success/failure. + * + * @return the flow. + */ + @Bean + public MethodInterceptor afterMailAdvice() { + return invocation -> { + Message message = (Message) invocation.getArguments()[0]; + MessageHeaders headers = message.getHeaders(); + File originalFile = headers.get(FileHeaders.ORIGINAL_FILE, File.class); + try { + invocation.proceed(); + originalFile.renameTo( + new File(originalFile.getAbsolutePath() + headers.get(EMAIL_SUCCESS_SUFFIX))); + } + catch (Exception e) { + originalFile.renameTo( + new File(originalFile.getAbsolutePath() + headers.get(EMAIL_SUCCESS_SUFFIX) + ".email.failed")); + } + return null; + }; + } + + private String getStackTraceAsString(Throwable cause) { + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter, true); + cause.printStackTrace(printWriter); + return stringWriter.getBuffer().toString(); + } + +} diff --git a/applications/file-split-ftp/src/main/resources/application.properties b/applications/file-split-ftp/src/main/resources/application.properties new file mode 100644 index 000000000..330425fd4 --- /dev/null +++ b/applications/file-split-ftp/src/main/resources/application.properties @@ -0,0 +1,4 @@ +spring.mail.host=localhost +spring.mail.port=25 +spring.mail.username=user +spring.mail.password=pw diff --git a/applications/file-split-ftp/src/main/resources/logback.xml b/applications/file-split-ftp/src/main/resources/logback.xml new file mode 100644 index 000000000..23ddeb50c --- /dev/null +++ b/applications/file-split-ftp/src/main/resources/logback.xml @@ -0,0 +1,17 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + diff --git a/applications/file-split-ftp/src/test/java/org/springframework/integration/samples/filesplit/ApplicationTests.java b/applications/file-split-ftp/src/test/java/org/springframework/integration/samples/filesplit/ApplicationTests.java new file mode 100644 index 000000000..6f73b7fa3 --- /dev/null +++ b/applications/file-split-ftp/src/test/java/org/springframework/integration/samples/filesplit/ApplicationTests.java @@ -0,0 +1,239 @@ +/* + * Copyright 2002-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.samples.filesplit; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.net.ftp.FTPFile; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.integration.endpoint.SourcePollingChannelAdapter; +import org.springframework.integration.file.remote.session.Session; +import org.springframework.integration.file.remote.session.SessionFactory; +import org.springframework.integration.test.context.SpringIntegrationTest; +import org.springframework.integration.test.util.TestUtils; +import org.springframework.test.annotation.DirtiesContext; + +import com.icegreen.greenmail.store.FolderException; +import com.icegreen.greenmail.util.GreenMail; +import com.icegreen.greenmail.util.ServerSetup; +import com.icegreen.greenmail.util.ServerSetupTest; +import jakarta.mail.internet.InternetAddress; +import jakarta.mail.internet.MimeMessage; + +@SpringBootTest(properties = "spring.main.allow-bean-definition-overriding=true") +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +@SpringIntegrationTest(noAutoStartup = "fileInboundChannelAdapter") +public class ApplicationTests { + + private static GreenMail mailServer; + + @Autowired + private Session session; + + @Autowired + private SourcePollingChannelAdapter fileInboundChannelAdapter; + + @BeforeAll + public static void setup() { + ServerSetup smtp = ServerSetupTest.SMTP.dynamicPort(); + smtp.setServerStartupTimeout(10000); + mailServer = new GreenMail(smtp); + mailServer.setUser("bar@bar@baz", "user", "pw"); + mailServer.start(); + // Configure the boot property to send email to the test email server. + System.setProperty("spring.mail.port", Integer.toString(mailServer.getSmtp().getPort())); + } + + @AfterAll + static void tearDown() { + mailServer.stop(); + } + + @BeforeEach + public void beforeTest() throws FolderException, IOException { + mailServer.purgeEmailFromAllMailboxes(); + cleanup(); + this.fileInboundChannelAdapter.start(); + } + + @AfterEach + public void cleanup() throws IOException { + File inDir = new File("/tmp/in"); + if (inDir.exists()) { + FileUtils.cleanDirectory(inDir); + } + + File outDir = new File("/tmp/out"); + if (outDir.exists()) { + FileUtils.cleanDirectory(outDir); + } + } + + @Test + public void testSuccess() throws Exception { + MimeMessage message = runTest(false); + assertThat(message.getSubject()).isEqualTo("File successfully split and transferred"); + assertThat(message.getContent()).asString().contains(TestUtils.applySystemFileSeparator("/tmp/in/foo.txt")); + } + + @Test + public void testFailure() throws Exception { + willThrow(new RuntimeException("fail test exception")) + .given(this.session).write(any(InputStream.class), eq("foo/002.txt.writing")); + MimeMessage message = runTest(true); + assertThat(message.getSubject()).isEqualTo("File split and transfer failed"); + assertThat(message.getContent()).asString().contains("fail test exception"); + assertThat(message.getContent()).asString().contains(TestUtils.applySystemFileSeparator("/tmp/out/002.txt")); + } + + /* + * Create a test file containing one row per account. + * Verify the three files appear, with the correct contents. + * Verify the input file was renamed based on success/failure. + * Verify the email was sent. + */ + private MimeMessage runTest(boolean fail) throws Exception { + File in = new File("/tmp/in/", "foo"); + FileOutputStream fos = new FileOutputStream(in); + fos.write("*002,foo,bar\n*006,baz,qux\n*009,fiz,buz\n".getBytes()); + fos.close(); + in.renameTo(new File("/tmp/in/", "foo.txt")); + File out = new File("/tmp/out/002.txt"); + int n = 0; + while (n++ < 100 && (!out.exists() || out.length() < 12)) { + Thread.sleep(100); + } + assertThat(out.exists()).isTrue(); + BufferedReader br = new BufferedReader(new FileReader(out)); + assertThat(br.readLine()).isEqualTo("*002,foo,bar"); + br.close(); + out = new File("/tmp/out/006.txt"); + n = 0; + while (n++ < 100 && (!out.exists() || out.length() < 12)) { + Thread.sleep(100); + } + assertThat(out.exists()).isTrue(); + br = new BufferedReader(new FileReader(out)); + assertThat(br.readLine()).isEqualTo("*006,baz,qux"); + br.close(); + out = new File("/tmp/out/009.txt"); + n = 0; + while (n++ < 100 && (!out.exists() || out.length() < 12)) { + Thread.sleep(100); + } + assertThat(out.exists()).isTrue(); + br = new BufferedReader(new FileReader(out)); + assertThat(br.readLine()).isEqualTo("*009,fiz,buz"); + br.close(); + if (!fail) { + in = new File("/tmp/in/", "foo.txt.success"); + } + else { + in = new File("/tmp/in/", "foo.txt.failed"); + } + n = 0; + while (n++ < 100 && !in.exists()) { + Thread.sleep(100); + } + assertThat(in.exists()).isTrue(); + // verify FTP + verify(this.session).write(any(InputStream.class), eq("foo/002.txt.writing")); + if (!fail) { + verify(this.session).write(any(InputStream.class), eq("foo/006.txt.writing")); + verify(this.session).write(any(InputStream.class), eq("foo/009.txt.writing")); + verify(this.session).rename("foo/002.txt.writing", "foo/002.txt"); + verify(this.session).rename("foo/006.txt.writing", "foo/006.txt"); + verify(this.session).rename("foo/009.txt.writing", "foo/009.txt"); + } + + MimeMessage message = verifyMail(); + assertThat(message.getFrom()).containsOnly(new InternetAddress("foo@bar")); + assertThat(message.getRecipients(MimeMessage.RecipientType.TO)).containsOnly(new InternetAddress("bar@baz")); + return message; + } + + public MimeMessage verifyMail() { + mailServer.waitForIncomingEmail(10000, 1); + MimeMessage[] mail = mailServer.getReceivedMessagesForDomain("baz"); + assertThat(mail).hasSize(1); + MimeMessage message = mail[0]; + return message; + } + + /** + * Overrides the ftp session factories with mocks. + * + */ + @Configuration + @Import(Application.class) + public static class Config { + + @Bean + public SessionFactory ftp1() { + return mockSf(); + } + + @Bean + public SessionFactory ftp2() { + return mockSf(); + } + + @Bean + public SessionFactory ftp3() { + return mockSf(); + } + + private SessionFactory mockSf() { + @SuppressWarnings("unchecked") + SessionFactory mocksf = mock(SessionFactory.class); + given(mocksf.getSession()).willReturn(mockSession()); + return mocksf; + } + + @Bean + @SuppressWarnings("unchecked") + public Session mockSession() { + return mock(Session.class); + } + + } + +} diff --git a/applications/loan-broker/README.md b/applications/loan-broker/README.md index bff505189..96f2ecfe9 100644 --- a/applications/loan-broker/README.md +++ b/applications/loan-broker/README.md @@ -1,11 +1,11 @@ Loan Broker Application ======================= -The Loan Broker sample is distributed as a Maven project, so you can run it in two ways. +The Loan Broker sample is distributed as a Gradle project, so you can run it in two ways. -### Maven (command line): +### Gradle (command line): -Execute **mvn install**. You should see output that looks similar to this: +Execute **gradlew :loan-broker:run**. You should see output that looks similar to this: . . . . . INFO : org.springframework.integration.loanbroker.demo.LoanBrokerDemo - @@ -30,7 +30,7 @@ Execute **mvn install**. You should see output that looks similar to this: This extension to the loan broker sample shows how to exchange messages between Spring Integration applications (and other technologies) using UDP. Any loan quotes over 5.2% will be sent to the loanshark application. -* Deploy the **loanshark** sample to a web container (e.g. **mvn tomcat:run**); or +* Deploy the **loanshark** sample to a web container (e.g. **gradlew :loan-broker:jettyRun**); or * run the perl (**udps.pl**) or groovy (**udps.groovy**) scripts from the command line. Run the **LoanBrokerSharkDetectorDemo** test case. You can see the banks that were detected as loan sharks in the **loanshark web UI**. diff --git a/applications/loan-broker/pom.xml b/applications/loan-broker/pom.xml index fec7051cc..967402dc3 100644 --- a/applications/loan-broker/pom.xml +++ b/applications/loan-broker/pom.xml @@ -1,62 +1,153 @@ - - 4.0.0 - org.springframework.integration.samples - loan-broker - 2.2.0.BUILD-SNAPSHOT - Samples (Applications) - Loan Broker - - UTF-8 - 2.2.0.RELEASE - 1.1.1 - 1.2.17 - 4.10 - - - - commons-logging - commons-logging - ${commons-logging.version} - - - log4j - log4j - ${log4j.version} - - - org.springframework.integration - spring-integration-ip - ${spring.integration.version} - - - - junit - junit - ${junit.version} - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.5.1 - - 1.6 - 1.6 - -Xlint:all - true - true - - - - - - - repo.springsource.org.milestone - SpringSource Maven Milestone Repository - https://repo.springsource.org/libs-milestone - - + + 4.0.0 + org.springframework.integration.samples + loan-broker + 7.0.0 + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.integration + spring-integration-ip + compile + + + org.apache.logging.log4j + log4j-core + 2.24.3 + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/LoanBrokerGateway.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/LoanBrokerGateway.java index fd51feca9..343c226b2 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/LoanBrokerGateway.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/LoanBrokerGateway.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/LoanQuoteAggregator.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/LoanQuoteAggregator.java index def671863..6bc9b7201 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/LoanQuoteAggregator.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/LoanQuoteAggregator.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,8 +19,8 @@ import java.util.Collections; import java.util.List; -import org.springframework.integration.annotation.Header; import org.springframework.integration.samples.loanbroker.domain.LoanQuote; +import org.springframework.messaging.handler.annotation.Header; /** * Aggregates {@link LoanQuote}s based on the value of the 'RESPONSE_TYPE' message header. @@ -28,19 +28,20 @@ * of 'BEST'. In this example, that value is set by the 'gateway' when the * {@link LoanBrokerGateway#getBestLoanQuote(org.springframework.integration.samples.loanbroker.domain.LoanRequest)} * method is invoked by the client. - * + * * @author Oleg Zhurakousky */ public class LoanQuoteAggregator { /** * Aggregates LoanQuote Messages to return a single reply Message. - * + * * @param quotes list of loan quotes received from upstream lenders * @param responseType header that indicates the response type * @return the best {@link LoanQuote} if the 'RESPONSE_TYPE' header value is 'BEST' else all quotes */ - public Object aggregateQuotes(List quotes, @Header(value="RESPONSE_TYPE", required=false) String responseType) { + public Object aggregateQuotes(List quotes, + @Header(value="RESPONSE_TYPE", required=false) String responseType) { Collections.sort(quotes); return ("BEST".equals(responseType)) ? quotes.get(0) : quotes; } diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/demo/LoanBrokerDemo.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/demo/LoanBrokerDemo.java index 35ef6a743..88c72e35e 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/demo/LoanBrokerDemo.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/demo/LoanBrokerDemo.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,8 +18,9 @@ import java.util.List; -import org.apache.log4j.Logger; -import org.springframework.context.ApplicationContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.samples.loanbroker.LoanBrokerGateway; import org.springframework.integration.samples.loanbroker.domain.Customer; @@ -28,17 +29,19 @@ /** * @author Oleg Zhurakousky + * @author Gary Russell */ public class LoanBrokerDemo { - private static Logger logger = Logger.getLogger(LoanBrokerDemo.class); + private static final Log logger = LogFactory.getLog(LoanBrokerDemo.class); public static void main(String[] args) { new LoanBrokerDemo().runDemo(); } public void runDemo() { - ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/integration/bootstrap-config/stubbed-loan-broker.xml"); + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "META-INF/spring/integration/bootstrap-config/stubbed-loan-broker.xml"); LoanBrokerGateway broker = context.getBean("loanBrokerGateway", LoanBrokerGateway.class); LoanRequest loanRequest = new LoanRequest(); loanRequest.setCustomer(new Customer()); @@ -50,6 +53,7 @@ public void runDemo() { for (LoanQuote loanQuote : loanQuotes) { logger.info(loanQuote); } + context.close(); } } diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/demo/LoanBrokerSharkDetectorDemo.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/demo/LoanBrokerSharkDetectorDemo.java index daef1504e..ce821bb75 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/demo/LoanBrokerSharkDetectorDemo.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/demo/LoanBrokerSharkDetectorDemo.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,7 +18,9 @@ import java.util.List; -import org.apache.log4j.Logger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.samples.loanbroker.LoanBrokerGateway; @@ -31,10 +33,10 @@ */ public class LoanBrokerSharkDetectorDemo { - private static Logger logger = Logger.getLogger(LoanBrokerSharkDetectorDemo.class); + private static final Log logger = LogFactory.getLog(LoanBrokerSharkDetectorDemo.class); public static void main(String[] args) { - ConfigurableApplicationContext context = + ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/integration/bootstrap-config/stubbed-loan-broker-multicast.xml"); LoanBrokerGateway broker = context.getBean("loanBrokerGateway", LoanBrokerGateway.class); LoanRequest loanRequest = new LoanRequest(); @@ -46,6 +48,7 @@ public static void main(String[] args) { for (LoanQuote loanQuote : loanQuotes) { logger.info(loanQuote); } + context.close(); } } diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/Address.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/Address.java index 11f6fa6f0..b81a31a38 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/Address.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/Address.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/CreditReport.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/CreditReport.java index 7eb12e6be..7c0d381e0 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/CreditReport.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/CreditReport.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/Customer.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/Customer.java index 6cc11247b..2e8f7fcfa 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/Customer.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/Customer.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/LoanQuote.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/LoanQuote.java index e76af5f21..8c51f7559 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/LoanQuote.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/LoanQuote.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,6 +20,7 @@ /** * @author Oleg Zhurakousky + * @author Gary Russell */ public class LoanQuote implements Comparable{ @@ -78,8 +79,9 @@ public void setRate(float rate) { this.rate = rate; } + @Override public int compareTo(LoanQuote other) { - if (this.rate > other.rate) { + if (this.rate > other.rate) { //NOSONAR return 1; } else if (this.rate < other.rate) { @@ -88,8 +90,9 @@ else if (this.rate < other.rate) { return 0; } + @Override public String toString() { - return this.lender + ":\t" + this.rate; + return this.lender + ":\t" + this.rate; } } diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/LoanRequest.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/LoanRequest.java index 155c96202..1022a36e7 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/LoanRequest.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/domain/LoanRequest.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/stubs/BankStub.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/stubs/BankStub.java index d51cdd683..75ee49641 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/stubs/BankStub.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/stubs/BankStub.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/stubs/CreditBureauStub.java b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/stubs/CreditBureauStub.java index ddd8ea5ec..eb0c1586b 100644 --- a/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/stubs/CreditBureauStub.java +++ b/applications/loan-broker/src/main/java/org/springframework/integration/samples/loanbroker/stubs/CreditBureauStub.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,17 +18,19 @@ import java.util.Random; -import org.apache.log4j.Logger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.integration.samples.loanbroker.domain.CreditReport; import org.springframework.integration.samples.loanbroker.domain.LoanRequest; /** * @author Oleg Zhurakousky + * @author Gary Russell */ public class CreditBureauStub { - private static Logger logger = Logger.getLogger(CreditBureauStub.class); + private static final Log logger = LogFactory.getLog(CreditBureauStub.class); /** * @param loanRequest the loan request diff --git a/applications/loan-broker/src/main/resources/META-INF/spring/integration/bootstrap-config/stubbed-loan-broker-multicast.xml b/applications/loan-broker/src/main/resources/META-INF/spring/integration/bootstrap-config/stubbed-loan-broker-multicast.xml index 174cc25d3..0661b15ab 100644 --- a/applications/loan-broker/src/main/resources/META-INF/spring/integration/bootstrap-config/stubbed-loan-broker-multicast.xml +++ b/applications/loan-broker/src/main/resources/META-INF/spring/integration/bootstrap-config/stubbed-loan-broker-multicast.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> diff --git a/applications/loan-broker/src/main/resources/META-INF/spring/integration/bootstrap-config/stubbed-loan-broker.xml b/applications/loan-broker/src/main/resources/META-INF/spring/integration/bootstrap-config/stubbed-loan-broker.xml index 44d1b8dcc..f9533b0fa 100644 --- a/applications/loan-broker/src/main/resources/META-INF/spring/integration/bootstrap-config/stubbed-loan-broker.xml +++ b/applications/loan-broker/src/main/resources/META-INF/spring/integration/bootstrap-config/stubbed-loan-broker.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> diff --git a/applications/loan-broker/src/main/resources/META-INF/spring/integration/loan-broker-config.xml b/applications/loan-broker/src/main/resources/META-INF/spring/integration/loan-broker-config.xml index 69e42a013..6bc702186 100644 --- a/applications/loan-broker/src/main/resources/META-INF/spring/integration/loan-broker-config.xml +++ b/applications/loan-broker/src/main/resources/META-INF/spring/integration/loan-broker-config.xml @@ -4,11 +4,11 @@ xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd + https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util - http://www.springframework.org/schema/util/spring-util.xsd + https://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/integration - http://www.springframework.org/schema/integration/spring-integration.xsd"> + https://www.springframework.org/schema/integration/spring-integration.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/ip https://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd"> diff --git a/applications/loan-broker/src/main/resources/META-INF/spring/integration/stub-services-config.xml b/applications/loan-broker/src/main/resources/META-INF/spring/integration/stub-services-config.xml index 61b0fdc3a..b3c9c467a 100644 --- a/applications/loan-broker/src/main/resources/META-INF/spring/integration/stub-services-config.xml +++ b/applications/loan-broker/src/main/resources/META-INF/spring/integration/stub-services-config.xml @@ -3,8 +3,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:p="http://www.springframework.org/schema/p" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd"> diff --git a/applications/loan-broker/src/main/resources/log4j.xml b/applications/loan-broker/src/main/resources/log4j.xml deleted file mode 100644 index dbd3e859b..000000000 --- a/applications/loan-broker/src/main/resources/log4j.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/applications/loan-broker/src/main/resources/log4j2.xml b/applications/loan-broker/src/main/resources/log4j2.xml new file mode 100644 index 000000000..6241eb502 --- /dev/null +++ b/applications/loan-broker/src/main/resources/log4j2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/applications/loan-broker/src/test/resources/log4j.xml b/applications/loan-broker/src/test/resources/log4j.xml deleted file mode 100644 index d91ac2704..000000000 --- a/applications/loan-broker/src/test/resources/log4j.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/applications/loanshark/pom.xml b/applications/loanshark/pom.xml index 425791610..f08e76153 100644 --- a/applications/loanshark/pom.xml +++ b/applications/loanshark/pom.xml @@ -1,469 +1,368 @@ - - - 4.0.0 - org.springframework.integration.samples - 2.1.0.BUILD-SNAPSHOT - loanshark - Samples (Applications) - Loan Shark - war - - UTF-8 - 2.1.0.RELEASE - 3.1.0.RELEASE - 1.6.10 - 1.6.1 - - - - repo.springsource.org.milestone - SpringSource Maven Milestone Repository - https://repo.springsource.org/libs-milestone - - - - - - - junit - junit - 4.8.1 - test - - - log4j - log4j - 1.2.16 - - - org.slf4j - slf4j-api - ${slf4j.version} - - - org.slf4j - jcl-over-slf4j - ${slf4j.version} - - - org.slf4j - slf4j-log4j12 - ${slf4j.version} - - - org.aspectj - aspectjrt - ${aspectj.version} - - - javax.servlet - servlet-api - 2.5 - provided - - - net.sf.flexjson - flexjson - 2.0 - - - - org.springframework - spring-core - ${spring.version} - - - commons-logging - commons-logging - - - - - org.springframework - spring-test - ${spring.version} - test - - - commons-logging - commons-logging - - - - - org.springframework - spring-context - ${spring.version} - - - org.springframework - spring-aop - ${spring.version} - - - org.springframework - spring-aspects - ${spring.version} - - - org.springframework - spring-tx - ${spring.version} - - - org.hsqldb - hsqldb - 2.0.0 - - - org.hibernate - hibernate-core - 3.5.5-Final - - - org.hibernate - hibernate-entitymanager - 3.5.5-Final - - - cglib - cglib - - - dom4j - dom4j - - - - - org.hibernate.javax.persistence - hibernate-jpa-2.0-api - 1.0.0.Final - - - org.hibernate - hibernate-validator - 4.1.0.Final - - - javax.xml.bind - jaxb-api - - - com.sun.xml.bind - jaxb-impl - - - - - javax.validation - validation-api - 1.0.0.GA - - - cglib - cglib-nodep - 2.2 - - - javax.transaction - jta - 1.1 - - - org.springframework - spring-jdbc - ${spring.version} - - - org.springframework - spring-orm - ${spring.version} - - - commons-pool - commons-pool - 1.5.4 - - - commons-logging - commons-logging - - - - - commons-dbcp - commons-dbcp - 1.3 - - - commons-logging - commons-logging - - - commons-pool - commons-pool - - - xerces - xerces - - - xerces - xercesImpl - - - xml-apis - xml-apis - - - - - org.apache.tiles - tiles-core - 2.2.1 - - - commons-logging - commons-logging - - - - - org.apache.tiles - tiles-jsp - 2.2.1 - - - org.springframework - spring-web - ${spring.version} - - - commons-logging - commons-logging - - - - - org.springframework - spring-webmvc - ${spring.version} - - - commons-logging - commons-logging - - - - - org.springframework.webflow - spring-js - 2.1.1.RELEASE - - - org.springframework - spring-beans - - - org.springframework - spring-context - - - org.springframework - spring-core - - - org.springframework - spring-context-support - - - commons-logging - commons-logging - - - - - commons-digester - commons-digester - 2.0 - - - commons-logging - commons-logging - - - - - commons-fileupload - commons-fileupload - 1.2.1 - - - commons-logging - commons-logging - - - - - javax.servlet - jstl - 1.2 - - - javax.el - el-api - 1.0 - provided - - - joda-time - joda-time - 1.6 - - - org.springframework.integration - spring-integration-ip - ${spring.integration.version} - + + + 4.0.0 + org.springframework.integration.samples + loanshark + 7.0.0 + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.integration + spring-integration-ip + compile + + + org.springframework + spring-webmvc + compile + + + org.springframework + spring-orm + compile + + + org.springframework + spring-aop + compile + + + org.springframework + spring-aspects + compile + + + org.aspectj + aspectjtools + 1.9.24 + compile + + + org.springframework + spring-jdbc + compile + + + org.springframework + spring-tx + compile + + + org.springframework + spring-context + compile + + + commons-fileupload + commons-fileupload + 1.6.0 + compile + + + org.apache.commons + commons-dbcp2 + 2.13.0 + compile + + + commons-digester + commons-digester + 2.1 + compile + + + org.apache.commons + commons-pool2 + 2.12.1 + compile + + + org.apache.tiles + tiles-jsp + 2.2.1 + compile + + + joda-time + joda-time + 2.14.0 + compile + + + jakarta.transaction + jakarta.transaction-api + 2.0.1 + compile + + + org.hsqldb + hsqldb + 2.7.4 + compile + + + net.sf.flexjson + flexjson + 3.3 + compile + + + org.hibernate.validator + hibernate-validator + 9.0.1.Final + compile + + + jakarta.persistence + jakarta.persistence-api + 3.2.0 + compile + + + org.hibernate.orm + hibernate-core + 7.0.4.Final + compile + + + org.springframework.webflow + spring-js-resources + 3.0.0 + compile + + + org.slf4j + slf4j-api + 2.0.17 + compile + + + jakarta.servlet + jakarta.servlet-api + 5.0.0 + runtime + + + * + spring-boot-starter-tomcat + + + * + spring-boot-starter-jetty + + + + + jakarta.websocket + jakarta.websocket-api + 2.0.0 + runtime + + + * + spring-boot-starter-tomcat + + + * + spring-boot-starter-jetty + + + + + org.glassfish.expressly + expressly + 6.0.0 + runtime + + + * + spring-boot-starter-tomcat + + + * + spring-boot-starter-jetty + + + + + org.apache.logging.log4j + log4j-core + 2.24.3 + runtime + + + * + spring-boot-starter-tomcat + + + * + spring-boot-starter-jetty + + + + + org.slf4j + slf4j-log4j12 + 2.0.17 + runtime + + + * + spring-boot-starter-tomcat + + + * + spring-boot-starter-jetty + + + + + org.slf4j + jcl-over-slf4j + 2.0.17 + runtime + + + * + spring-boot-starter-tomcat + + + * + spring-boot-starter-jetty + + + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + - - - - org.apache.maven.plugins - maven-war-plugin - 2.1-beta-1 - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.3.2 - - 1.6 - 1.6 - - - - org.codehaus.mojo - aspectj-maven-plugin - 1.0 - - - - org.aspectj - aspectjrt - ${aspectj.version} - - - org.aspectj - aspectjtools - ${aspectj.version} - - - - - - compile - test-compile - - - - - true - - - org.springframework - spring-aspects - - - 1.6 - 1.6 - - - - org.apache.maven.plugins - maven-resources-plugin - 2.4.2 - - UTF-8 - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.5 - - - **/*_Roo_* - - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.2-beta-5 - - - jar-with-dependencies - - - - - org.apache.maven.plugins - maven-deploy-plugin - 2.5 - - - - org.apache.maven.plugins - maven-eclipse-plugin - 2.7 - - true - false - 2.0 - - - org.eclipse.ajdt.core.ajbuilder - - org.springframework.aspects - - - - org.springframework.ide.eclipse.core.springbuilder - - - - org.springframework.ide.eclipse.core.springnature - - - - - org.apache.maven.plugins - maven-idea-plugin - 2.2 - - true - true - - - - org.codehaus.mojo - tomcat-maven-plugin - 1.0 - - - org.mortbay.jetty - jetty-maven-plugin - 7.1.2.v20100523 - - - /${project.name} - - - - - + + + 17 + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + diff --git a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/Accumulator.java b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/Accumulator.java index e24737173..2163fbac5 100644 --- a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/Accumulator.java +++ b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/Accumulator.java @@ -1,11 +1,11 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -38,7 +38,7 @@ public void accumulate(SharkQuote quote) { if (shark == null) { shark = new LoanShark(); shark.setName(quote.getSharkName()); - shark.setCounter(new Long(0)); + shark.setCounter(Long.valueOf(0)); shark.setAverageRate(0.0d); shark.persist(); } @@ -46,5 +46,5 @@ public void accumulate(SharkQuote quote) { shark.setCounter(shark.getCounter().longValue() + 1); shark.setAverageRate((current + quote.getSharkRate()) / shark.getCounter()); } - + } diff --git a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/SharkQuote.java b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/SharkQuote.java index 045b69ed9..94cf03ad9 100644 --- a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/SharkQuote.java +++ b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/SharkQuote.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/SharkTransformer.java b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/SharkTransformer.java index b8ccf0655..b616aefcf 100644 --- a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/SharkTransformer.java +++ b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/biz/SharkTransformer.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/domain/LoanShark.java b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/domain/LoanShark.java index ddc650925..759ed7e99 100644 --- a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/domain/LoanShark.java +++ b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/domain/LoanShark.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -19,21 +19,20 @@ import java.util.Collection; import java.util.List; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EntityManager; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; -import javax.persistence.Version; - import org.springframework.beans.factory.annotation.Configurable; import org.springframework.transaction.annotation.Transactional; import flexjson.JSONDeserializer; import flexjson.JSONSerializer; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EntityManager; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.PersistenceContext; +import jakarta.persistence.Query; +import jakarta.persistence.Version; @Configurable @Entity diff --git a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/web/SharkController.java b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/web/SharkController.java index fc523c978..e8e3f113d 100644 --- a/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/web/SharkController.java +++ b/applications/loanshark/src/main/java/org/springframework/integration/samples/loanbroker/loanshark/web/SharkController.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -15,8 +15,6 @@ */ package org.springframework.integration.samples.loanbroker.loanshark.web; -import javax.validation.Valid; - import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.http.HttpStatus; @@ -34,6 +32,8 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import jakarta.validation.Valid; + @RequestMapping("/loansharks") @Controller public class SharkController { diff --git a/applications/loanshark/src/main/resources/META-INF/persistence.xml b/applications/loanshark/src/main/resources/META-INF/persistence.xml index 4eed4a170..5cdef62ac 100644 --- a/applications/loanshark/src/main/resources/META-INF/persistence.xml +++ b/applications/loanshark/src/main/resources/META-INF/persistence.xml @@ -1,7 +1,6 @@ - + - org.hibernate.ejb.HibernatePersistence diff --git a/applications/loanshark/src/main/resources/META-INF/spring/applicationContext.xml b/applications/loanshark/src/main/resources/META-INF/spring/applicationContext.xml index 8cf2da1e6..0493b5bdc 100644 --- a/applications/loanshark/src/main/resources/META-INF/spring/applicationContext.xml +++ b/applications/loanshark/src/main/resources/META-INF/spring/applicationContext.xml @@ -1,15 +1,20 @@ - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/loanshark/src/main/resources/META-INF/spring/integrationContext.xml b/applications/loanshark/src/main/resources/META-INF/spring/integrationContext.xml index 0e4e29725..2413db5b8 100644 --- a/applications/loanshark/src/main/resources/META-INF/spring/integrationContext.xml +++ b/applications/loanshark/src/main/resources/META-INF/spring/integrationContext.xml @@ -3,9 +3,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-ip="http://www.springframework.org/schema/integration/ip" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd - http://www.springframework.org/schema/integration/ip http://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd + http://www.springframework.org/schema/integration/ip https://www.springframework.org/schema/integration/ip/spring-integration-ip.xsd"> - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/applications/loanshark/src/main/resources/log4j2.xml b/applications/loanshark/src/main/resources/log4j2.xml new file mode 100644 index 000000000..6241eb502 --- /dev/null +++ b/applications/loanshark/src/main/resources/log4j2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/applications/loanshark/src/main/webapp/WEB-INF/layouts/layouts.xml b/applications/loanshark/src/main/webapp/WEB-INF/layouts/layouts.xml index 3c9d6d4bb..001f37127 100644 --- a/applications/loanshark/src/main/webapp/WEB-INF/layouts/layouts.xml +++ b/applications/loanshark/src/main/webapp/WEB-INF/layouts/layouts.xml @@ -1,7 +1,7 @@ + "https://tiles.apache.org/dtds/tiles-config_2_1.dtd"> diff --git a/applications/loanshark/src/main/webapp/WEB-INF/spring/webmvc-config.xml b/applications/loanshark/src/main/webapp/WEB-INF/spring/webmvc-config.xml index 3b92e03ed..e235713f2 100644 --- a/applications/loanshark/src/main/webapp/WEB-INF/spring/webmvc-config.xml +++ b/applications/loanshark/src/main/webapp/WEB-INF/spring/webmvc-config.xml @@ -1,5 +1,5 @@ - + diff --git a/applications/loanshark/src/main/webapp/WEB-INF/tags/form/fields/select.tagx b/applications/loanshark/src/main/webapp/WEB-INF/tags/form/fields/select.tagx index 09122bb0d..44fbbd99f 100644 --- a/applications/loanshark/src/main/webapp/WEB-INF/tags/form/fields/select.tagx +++ b/applications/loanshark/src/main/webapp/WEB-INF/tags/form/fields/select.tagx @@ -85,7 +85,6 @@ - diff --git a/applications/loanshark/src/main/webapp/WEB-INF/views/footer.jspx b/applications/loanshark/src/main/webapp/WEB-INF/views/footer.jspx index 89af49c71..b835924f8 100644 --- a/applications/loanshark/src/main/webapp/WEB-INF/views/footer.jspx +++ b/applications/loanshark/src/main/webapp/WEB-INF/views/footer.jspx @@ -29,7 +29,7 @@ - + ${fn:escapeXml(sponsored)} diff --git a/applications/loanshark/src/main/webapp/WEB-INF/views/loansharks/views.xml b/applications/loanshark/src/main/webapp/WEB-INF/views/loansharks/views.xml index be6b3d616..3ee56cb6d 100644 --- a/applications/loanshark/src/main/webapp/WEB-INF/views/loansharks/views.xml +++ b/applications/loanshark/src/main/webapp/WEB-INF/views/loansharks/views.xml @@ -1,5 +1,5 @@ - + diff --git a/applications/loanshark/src/main/webapp/WEB-INF/views/views.xml b/applications/loanshark/src/main/webapp/WEB-INF/views/views.xml index d12473f91..830306a6a 100644 --- a/applications/loanshark/src/main/webapp/WEB-INF/views/views.xml +++ b/applications/loanshark/src/main/webapp/WEB-INF/views/views.xml @@ -1,7 +1,7 @@ + "https://tiles.apache.org/dtds/tiles-config_2_1.dtd"> diff --git a/applications/loanshark/src/main/webapp/WEB-INF/web.xml b/applications/loanshark/src/main/webapp/WEB-INF/web.xml index 2f7bb8339..b86cc3acc 100644 --- a/applications/loanshark/src/main/webapp/WEB-INF/web.xml +++ b/applications/loanshark/src/main/webapp/WEB-INF/web.xml @@ -1,5 +1,5 @@ - + loanshark diff --git a/applications/loanshark/src/test/java/org/springframework/integration/samples/loanbroker/loanshark/biz/TestAccumulator.java b/applications/loanshark/src/test/java/org/springframework/integration/samples/loanbroker/loanshark/biz/AccumulatorTests.java similarity index 61% rename from applications/loanshark/src/test/java/org/springframework/integration/samples/loanbroker/loanshark/biz/TestAccumulator.java rename to applications/loanshark/src/test/java/org/springframework/integration/samples/loanbroker/loanshark/biz/AccumulatorTests.java index bf2c19b54..d69f8dfdc 100644 --- a/applications/loanshark/src/test/java/org/springframework/integration/samples/loanbroker/loanshark/biz/TestAccumulator.java +++ b/applications/loanshark/src/test/java/org/springframework/integration/samples/loanbroker/loanshark/biz/AccumulatorTests.java @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,41 +13,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.integration.samples.loanbroker.loanshark.biz; +package org.springframework.integration.samples.loanbroker.loanshark.biz; -import static junit.framework.Assert.assertEquals; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; -import org.junit.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.integration.samples.loanbroker.loanshark.biz.Accumulator; -import org.springframework.integration.samples.loanbroker.loanshark.biz.SharkQuote; import org.springframework.integration.samples.loanbroker.loanshark.domain.LoanShark; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.transaction.annotation.Transactional; - +import static org.assertj.core.api.Assertions.assertThat; /** * @author Gary Russell - * + * @author Artem Bilan */ -@ContextConfiguration(locations="classpath:META-INF/spring/applicationContext.xml") -@RunWith(SpringJUnit4ClassRunner.class) -public class TestAccumulator { +@SpringJUnitConfig(locations = "classpath:META-INF/spring/applicationContext.xml") +@DirtiesContext +@Transactional +@Disabled("Not clear what is going on with @Configurable") +public class AccumulatorTests { @Autowired Accumulator accumulator; - + @Test - @Transactional public void test() { accumulator.accumulate(new SharkQuote("fred", 6.0d)); accumulator.accumulate(new SharkQuote("fred", 6.2d)); LoanShark shark = (LoanShark) LoanShark.findLoanSharksByName("fred").getSingleResult(); - assertEquals(new Long(2), shark.getCounter()); - assertEquals(new Double(6.1), shark.getAverageRate()); + assertThat(shark.getCounter()).isEqualTo(2); + assertThat(shark.getAverageRate()).isEqualTo(6.1); } + } diff --git a/applications/loanshark/src/test/resources/log4j.xml b/applications/loanshark/src/test/resources/log4j.xml deleted file mode 100644 index 40d94ca5b..000000000 --- a/applications/loanshark/src/test/resources/log4j.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/applications/pom.xml b/applications/pom.xml deleted file mode 100644 index 0c9b8e90f..000000000 --- a/applications/pom.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - 4.0.0 - org.springframework.integration.samples - applications - 2.2.0.BUILD-SNAPSHOT - Spring Integration Samples - Applications - pom - - - cafe - loan-broker - loanshark - - - diff --git a/applications/stomp-chat/README.md b/applications/stomp-chat/README.md new file mode 100644 index 000000000..28636343e --- /dev/null +++ b/applications/stomp-chat/README.md @@ -0,0 +1,50 @@ +WebSockets Stomp Chat Sample +============== + +This application demonstrates the Web chat based on STOMP WebSocket sub-protocol with Spring Integration Adapters. +## Server + +The server is presented only with a single `org.springframework.integration.samples.websocket.standard.server.Application` +class, which is based on the Spring Boot AutoConfiguration and Spring Integration xml configuration `@ImportResource`. +It is a `main` and starts an embedded Tomcat server on the default `8080` port. +The WebSocket endpoint is mapped to the `/chat` path. + +The server also can be run from Gradle `gradlew :stomp-chat:run` + +The server application demonstrates how Spring Integration can be used as a STOMP Broker. + + 1. `webSocketSessionStore` - the `SimpleMetadataStore` to keep track of `WebSocketSession` and its `user`. + 2. `chatMessagesStore` - the `SimpleMessageStore` to store messages for chat rooms. + 3. `chatRoomSessions` - the `Map>` to keep track of `WebSocketSession` `subscriptions` + to the concrete chat room - STOMP `destination`. + 4. `` is subscribed to the `AbstractSubProtocolEvent` + type to handle STOMP sub-protocol events. + 5. `` is mapped to the appropriate `AbstractSubProtocolEvent` + type to provide the specific integration flow for each event type. + 6. `` receives STOMP messages, store them to the appropriate `messageGroup` + (according to the STOMP `destination`) and forward to the `` to send to + each `WebSocketSession` subscribed to that STOMP `destination` - chat room. + +## Client + +The `index.html` in the `src/main/resources/static` directory of this project demonstrates a JavaScript `STOMP` client +over `SockJS` client. + +This application covers classical STOMP scenario: + +- `connect` - requirement to enter the `user name` - chat member; +- `subscribe` - the `Join` operation on the one of chat rooms and receiving messages to that subscription for the +destination; +- `send` and `receive` - just chat messages; +- `unsubscribe` - the `Leave` operation on the chat room: the current web socket session stops receiving messages for +the destination; +- `disconnect` - close current web socket session and unsubscribe from all its subscriptions. + +To get real chat interaction it's just enough to open several tabs in browser. +When the user joins to the chat room, his subscription receives all messages, sent by other users to that room, +immediately. + +## Test Case + +The `org.springframework.integration.samples.chat.stomp.server.ApplicationTests` demonstrates the Spring Boot test +framework and just starts Server on the random port to be sure that this application is run correctly. diff --git a/applications/stomp-chat/pom.xml b/applications/stomp-chat/pom.xml new file mode 100644 index 000000000..75f326af6 --- /dev/null +++ b/applications/stomp-chat/pom.xml @@ -0,0 +1,188 @@ + + + 4.0.0 + org.springframework.integration.samples + stomp-chat + 7.0.0 + jar + https://github.com/spring-projects/spring-integration-samples + + Spring IO + https://spring.io/projects/spring-integration + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + artembilan + Artem Bilan + artem.bilan@broadcom.com + + project lead + + + + garyrussell + Gary Russell + github@gprussell.net + + project lead emeritus + + + + markfisher + Mark Fisher + mark.ryan.fisher@gmail.com + + project founder and lead emeritus + + + + + scm:git:scm:git:git://github.com/spring-projects/spring-integration-samples.git + scm:git:scm:git:ssh://git@github.com:spring-projects/spring-integration-samples.git + https://github.com/spring-projects/spring-integration-samples + + + GitHub + https://github.com/spring-projects/spring-integration-samples/issues + + + + org.springframework.boot + spring-boot-starter-websocket + compile + + + org.springframework.integration + spring-integration-websocket + compile + + + org.springframework.integration + spring-integration-event + compile + + + org.springframework.integration + spring-integration-groovy + compile + + + org.hamcrest + hamcrest-library + 2.2 + test + + + org.mockito + mockito-core + 5.18.0 + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.springframework.integration + spring-integration-test + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.jupiter + junit-jupiter-engine + runtime + + + org.junit.platform + junit-platform-launcher + runtime + + + + + + org.springframework.boot + spring-boot-dependencies + 4.0.0-SNAPSHOT + import + pom + + + org.junit + junit-bom + 5.12.2 + import + pom + + + tools.jackson + jackson-bom + 3.0.0-rc5 + import + pom + + + com.fasterxml.jackson + jackson-bom + 2.19.1 + import + pom + + + org.springframework + spring-framework-bom + 7.0.0-SNAPSHOT + import + pom + + + org.springframework.integration + spring-integration-bom + 7.0.0-SNAPSHOT + import + pom + + + + + 17 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + org.springframework.boot + spring-boot-starter-parent + 4.0.0-SNAPSHOT + + + + repo.spring.io.milestone + Spring Framework Maven Milestone Repository + https://repo.spring.io/milestone + + + repo.spring.io.snapshot + Spring Framework Maven Snapshot Repository + https://repo.spring.io/snapshot + + + diff --git a/applications/stomp-chat/src/main/java/org/springframework/integration/samples/chat/stomp/server/Application.java b/applications/stomp-chat/src/main/java/org/springframework/integration/samples/chat/stomp/server/Application.java new file mode 100644 index 000000000..02250a7b8 --- /dev/null +++ b/applications/stomp-chat/src/main/java/org/springframework/integration/samples/chat/stomp/server/Application.java @@ -0,0 +1,41 @@ +/* + * Copyright 2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.integration.samples.chat.stomp.server; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; + +/** + * @author Artem Bilan + * @since 3.0 + */ +@Configuration +@EnableAutoConfiguration +@ImportResource("classpath:org/springframework/integration/samples/chat/stomp/server/stomp-server.xml") +public class Application { + + public static void main(String[] args) throws Exception { + ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args); + System.out.println("Hit 'Enter' to terminate"); + System.in.read(); + ctx.close(); + } + +} diff --git a/applications/stomp-chat/src/main/resources/application.properties b/applications/stomp-chat/src/main/resources/application.properties new file mode 100644 index 000000000..6bef19413 --- /dev/null +++ b/applications/stomp-chat/src/main/resources/application.properties @@ -0,0 +1,2 @@ +logging.level.org.springframework.web.socket.sockjs.transport.session=trace +server.session.timeout=60 diff --git a/applications/stomp-chat/src/main/resources/logback.xml b/applications/stomp-chat/src/main/resources/logback.xml new file mode 100644 index 000000000..070671efc --- /dev/null +++ b/applications/stomp-chat/src/main/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + diff --git a/applications/stomp-chat/src/main/resources/org/springframework/integration/samples/chat/stomp/server/stomp-server.xml b/applications/stomp-chat/src/main/resources/org/springframework/integration/samples/chat/stomp/server/stomp-server.xml new file mode 100644 index 000000000..196997250 --- /dev/null +++ b/applications/stomp-chat/src/main/resources/org/springframework/integration/samples/chat/stomp/server/stomp-server.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + chatRoomSessions.each { k, v -> + v.remove(reactor.util.function.Tuples.of(headers.simpSessionId, headers.simpSubscriptionId)) + } + null + + + + + + + + + + + + + + + + + + chatRoomSessions[headers.simpDestination].collect { + org.springframework.integration.support.MessageBuilder.withPayload(payload) + .copyHeaders(headers) + .setHeader('simpSessionId', it.t1) + .setHeader('simpSubscriptionId', it.t2) + .build() + } + + + + + + + + + + + + webSocketSessionStore.remove(headers.simpSessionId) + chatRoomSessions.each { k, v -> v.removeAll { it.t1 == headers.simpSessionId } } + null + + + + diff --git a/applications/stomp-chat/src/main/resources/static/index.html b/applications/stomp-chat/src/main/resources/static/index.html new file mode 100644 index 000000000..1c9c71125 --- /dev/null +++ b/applications/stomp-chat/src/main/resources/static/index.html @@ -0,0 +1,220 @@ + + + WebSocket Chat + + + + + + + + +
+ Welcome to the Simple WebSocket Stomp Chat! +
+ Enter your name to connect: +
+
+ +
+
+ + + + + +
+ + + +
+
+
+
+ + + diff --git a/applications/stomp-chat/src/main/resources/static/sockjs.js b/applications/stomp-chat/src/main/resources/static/sockjs.js new file mode 100644 index 000000000..6943b2737 --- /dev/null +++ b/applications/stomp-chat/src/main/resources/static/sockjs.js @@ -0,0 +1,27 @@ +/* SockJS client, version 0.3.4, https://github.com/sockjs/sockjs-client, MIT License + + Copyright (c) 2011-2012 VMware, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +// JSON2 by Douglas Crockford (minified). +var JSON;JSON||(JSON={}),function(){function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c1?this._listeners[a]=d.slice(0,e).concat(d.slice(e+1)):delete this._listeners[a];return}return},d.prototype.dispatchEvent=function(a){var b=a.type,c=Array.prototype.slice.call(arguments,0);this["on"+b]&&this["on"+b].apply(this,c);if(this._listeners&&b in this._listeners)for(var d=0;d=3e3&&a<=4999},c.countRTO=function(a){var b;return a>100?b=3*a:b=a+200,b},c.log=function(){b.console&&console.log&&console.log.apply&&console.log.apply(console,arguments)},c.bind=function(a,b){return a.bind?a.bind(b):function(){return a.apply(b,arguments)}},c.flatUrl=function(a){return a.indexOf("?")===-1&&a.indexOf("#")===-1},c.amendUrl=function(b){var d=a.location;if(!b)throw new Error("Wrong url for SockJS");if(!c.flatUrl(b))throw new Error("Only basic urls are supported in SockJS");return b.indexOf("//")===0&&(b=d.protocol+b),b.indexOf("/")===0&&(b=d.protocol+"//"+d.host+b),b=b.replace(/[/]+$/,""),b},c.arrIndexOf=function(a,b){for(var c=0;c=0},c.delay=function(a,b){return typeof a=="function"&&(b=a,a=0),setTimeout(b,a)};var i=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,j={"\0":"\\u0000","\x01":"\\u0001","\x02":"\\u0002","\x03":"\\u0003","\x04":"\\u0004","\x05":"\\u0005","\x06":"\\u0006","\x07":"\\u0007","\b":"\\b","\t":"\\t","\n":"\\n","\x0b":"\\u000b","\f":"\\f","\r":"\\r","\x0e":"\\u000e","\x0f":"\\u000f","\x10":"\\u0010","\x11":"\\u0011","\x12":"\\u0012","\x13":"\\u0013","\x14":"\\u0014","\x15":"\\u0015","\x16":"\\u0016","\x17":"\\u0017","\x18":"\\u0018","\x19":"\\u0019","\x1a":"\\u001a","\x1b":"\\u001b","\x1c":"\\u001c","\x1d":"\\u001d","\x1e":"\\u001e","\x1f":"\\u001f",'"':'\\"',"\\":"\\\\","\x7f":"\\u007f","\x80":"\\u0080","\x81":"\\u0081","\x82":"\\u0082","\x83":"\\u0083","\x84":"\\u0084","\x85":"\\u0085","\x86":"\\u0086","\x87":"\\u0087","\x88":"\\u0088","\x89":"\\u0089","\x8a":"\\u008a","\x8b":"\\u008b","\x8c":"\\u008c","\x8d":"\\u008d","\x8e":"\\u008e","\x8f":"\\u008f","\x90":"\\u0090","\x91":"\\u0091","\x92":"\\u0092","\x93":"\\u0093","\x94":"\\u0094","\x95":"\\u0095","\x96":"\\u0096","\x97":"\\u0097","\x98":"\\u0098","\x99":"\\u0099","\x9a":"\\u009a","\x9b":"\\u009b","\x9c":"\\u009c","\x9d":"\\u009d","\x9e":"\\u009e","\x9f":"\\u009f","\xad":"\\u00ad","\u0600":"\\u0600","\u0601":"\\u0601","\u0602":"\\u0602","\u0603":"\\u0603","\u0604":"\\u0604","\u070f":"\\u070f","\u17b4":"\\u17b4","\u17b5":"\\u17b5","\u200c":"\\u200c","\u200d":"\\u200d","\u200e":"\\u200e","\u200f":"\\u200f","\u2028":"\\u2028","\u2029":"\\u2029","\u202a":"\\u202a","\u202b":"\\u202b","\u202c":"\\u202c","\u202d":"\\u202d","\u202e":"\\u202e","\u202f":"\\u202f","\u2060":"\\u2060","\u2061":"\\u2061","\u2062":"\\u2062","\u2063":"\\u2063","\u2064":"\\u2064","\u2065":"\\u2065","\u2066":"\\u2066","\u2067":"\\u2067","\u2068":"\\u2068","\u2069":"\\u2069","\u206a":"\\u206a","\u206b":"\\u206b","\u206c":"\\u206c","\u206d":"\\u206d","\u206e":"\\u206e","\u206f":"\\u206f","\ufeff":"\\ufeff","\ufff0":"\\ufff0","\ufff1":"\\ufff1","\ufff2":"\\ufff2","\ufff3":"\\ufff3","\ufff4":"\\ufff4","\ufff5":"\\ufff5","\ufff6":"\\ufff6","\ufff7":"\\ufff7","\ufff8":"\\ufff8","\ufff9":"\\ufff9","\ufffa":"\\ufffa","\ufffb":"\\ufffb","\ufffc":"\\ufffc","\ufffd":"\\ufffd","\ufffe":"\\ufffe","\uffff":"\\uffff"},k=/[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g,l,m=JSON&&JSON.stringify||function(a){return i.lastIndex=0,i.test(a)&&(a=a.replace(i,function(a){return j[a]})),'"'+a+'"'},n=function(a){var b,c={},d=[];for(b=0;b<65536;b++)d.push(String.fromCharCode(b));return a.lastIndex=0,d.join("").replace(a,function(a){return c[a]="\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4),""}),a.lastIndex=0,c};c.quote=function(a){var b=m(a);return k.lastIndex=0,k.test(b)?(l||(l=n(k)),b.replace(k,function(a){return l[a]})):b};var o=["websocket","xdr-streaming","xhr-streaming","iframe-eventsource","iframe-htmlfile","xdr-polling","xhr-polling","iframe-xhr-polling","jsonp-polling"];c.probeProtocols=function(){var a={};for(var b=0;b0&&h(a)};return c.websocket!==!1&&h(["websocket"]),d["xhr-streaming"]&&!c.null_origin?e.push("xhr-streaming"):d["xdr-streaming"]&&!c.cookie_needed&&!c.null_origin?e.push("xdr-streaming"):h(["iframe-eventsource","iframe-htmlfile"]),d["xhr-polling"]&&!c.null_origin?e.push("xhr-polling"):d["xdr-polling"]&&!c.cookie_needed&&!c.null_origin?e.push("xdr-polling"):h(["iframe-xhr-polling","jsonp-polling"]),e};var p="_sockjs_global";c.createHook=function(){var a="a"+c.random_string(8);if(!(p in b)){var d={};b[p]=function(a){return a in d||(d[a]={id:a,del:function(){delete d[a]}}),d[a]}}return b[p](a)},c.attachMessage=function(a){c.attachEvent("message",a)},c.attachEvent=function(c,d){typeof b.addEventListener!="undefined"?b.addEventListener(c,d,!1):(a.attachEvent("on"+c,d),b.attachEvent("on"+c,d))},c.detachMessage=function(a){c.detachEvent("message",a)},c.detachEvent=function(c,d){typeof b.addEventListener!="undefined"?b.removeEventListener(c,d,!1):(a.detachEvent("on"+c,d),b.detachEvent("on"+c,d))};var q={},r=!1,s=function(){for(var a in q)q[a](),delete q[a]},t=function(){if(r)return;r=!0,s()};c.attachEvent("unload",t),c.unload_add=function(a){var b=c.random_string(8);return q[b]=a,r&&c.delay(s),b},c.unload_del=function(a){a in q&&delete q[a]},c.createIframe=function(b,d){var e=a.createElement("iframe"),f,g,h=function(){clearTimeout(f);try{e.onload=null}catch(a){}e.onerror=null},i=function(){e&&(h(),setTimeout(function(){e&&e.parentNode.removeChild(e),e=null},0),c.unload_del(g))},j=function(a){e&&(i(),d(a))},k=function(a,b){try{e&&e.contentWindow&&e.contentWindow.postMessage(a,b)}catch(c){}};return e.src=b,e.style.display="none",e.style.position="absolute",e.onerror=function(){j("onerror")},e.onload=function(){clearTimeout(f),f=setTimeout(function(){j("onload timeout")},2e3)},a.body.appendChild(e),f=setTimeout(function(){j("timeout")},15e3),g=c.unload_add(i),{post:k,cleanup:i,loaded:h}},c.createHtmlfile=function(a,d){var e=new ActiveXObject("htmlfile"),f,g,i,j=function(){clearTimeout(f)},k=function(){e&&(j(),c.unload_del(g),i.parentNode.removeChild(i),i=e=null,CollectGarbage())},l=function(a){e&&(k(),d(a))},m=function(a,b){try{i&&i.contentWindow&&i.contentWindow.postMessage(a,b)}catch(c){}};e.open(),e.write(' + + + + + +
Starting...
+ + diff --git a/basic/web-sockets/src/main/resources/static/sockjs.js b/basic/web-sockets/src/main/resources/static/sockjs.js new file mode 100644 index 000000000..6943b2737 --- /dev/null +++ b/basic/web-sockets/src/main/resources/static/sockjs.js @@ -0,0 +1,27 @@ +/* SockJS client, version 0.3.4, https://github.com/sockjs/sockjs-client, MIT License + + Copyright (c) 2011-2012 VMware, Inc. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +// JSON2 by Douglas Crockford (minified). +var JSON;JSON||(JSON={}),function(){function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c1?this._listeners[a]=d.slice(0,e).concat(d.slice(e+1)):delete this._listeners[a];return}return},d.prototype.dispatchEvent=function(a){var b=a.type,c=Array.prototype.slice.call(arguments,0);this["on"+b]&&this["on"+b].apply(this,c);if(this._listeners&&b in this._listeners)for(var d=0;d=3e3&&a<=4999},c.countRTO=function(a){var b;return a>100?b=3*a:b=a+200,b},c.log=function(){b.console&&console.log&&console.log.apply&&console.log.apply(console,arguments)},c.bind=function(a,b){return a.bind?a.bind(b):function(){return a.apply(b,arguments)}},c.flatUrl=function(a){return a.indexOf("?")===-1&&a.indexOf("#")===-1},c.amendUrl=function(b){var d=a.location;if(!b)throw new Error("Wrong url for SockJS");if(!c.flatUrl(b))throw new Error("Only basic urls are supported in SockJS");return b.indexOf("//")===0&&(b=d.protocol+b),b.indexOf("/")===0&&(b=d.protocol+"//"+d.host+b),b=b.replace(/[/]+$/,""),b},c.arrIndexOf=function(a,b){for(var c=0;c=0},c.delay=function(a,b){return typeof a=="function"&&(b=a,a=0),setTimeout(b,a)};var i=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,j={"\0":"\\u0000","\x01":"\\u0001","\x02":"\\u0002","\x03":"\\u0003","\x04":"\\u0004","\x05":"\\u0005","\x06":"\\u0006","\x07":"\\u0007","\b":"\\b","\t":"\\t","\n":"\\n","\x0b":"\\u000b","\f":"\\f","\r":"\\r","\x0e":"\\u000e","\x0f":"\\u000f","\x10":"\\u0010","\x11":"\\u0011","\x12":"\\u0012","\x13":"\\u0013","\x14":"\\u0014","\x15":"\\u0015","\x16":"\\u0016","\x17":"\\u0017","\x18":"\\u0018","\x19":"\\u0019","\x1a":"\\u001a","\x1b":"\\u001b","\x1c":"\\u001c","\x1d":"\\u001d","\x1e":"\\u001e","\x1f":"\\u001f",'"':'\\"',"\\":"\\\\","\x7f":"\\u007f","\x80":"\\u0080","\x81":"\\u0081","\x82":"\\u0082","\x83":"\\u0083","\x84":"\\u0084","\x85":"\\u0085","\x86":"\\u0086","\x87":"\\u0087","\x88":"\\u0088","\x89":"\\u0089","\x8a":"\\u008a","\x8b":"\\u008b","\x8c":"\\u008c","\x8d":"\\u008d","\x8e":"\\u008e","\x8f":"\\u008f","\x90":"\\u0090","\x91":"\\u0091","\x92":"\\u0092","\x93":"\\u0093","\x94":"\\u0094","\x95":"\\u0095","\x96":"\\u0096","\x97":"\\u0097","\x98":"\\u0098","\x99":"\\u0099","\x9a":"\\u009a","\x9b":"\\u009b","\x9c":"\\u009c","\x9d":"\\u009d","\x9e":"\\u009e","\x9f":"\\u009f","\xad":"\\u00ad","\u0600":"\\u0600","\u0601":"\\u0601","\u0602":"\\u0602","\u0603":"\\u0603","\u0604":"\\u0604","\u070f":"\\u070f","\u17b4":"\\u17b4","\u17b5":"\\u17b5","\u200c":"\\u200c","\u200d":"\\u200d","\u200e":"\\u200e","\u200f":"\\u200f","\u2028":"\\u2028","\u2029":"\\u2029","\u202a":"\\u202a","\u202b":"\\u202b","\u202c":"\\u202c","\u202d":"\\u202d","\u202e":"\\u202e","\u202f":"\\u202f","\u2060":"\\u2060","\u2061":"\\u2061","\u2062":"\\u2062","\u2063":"\\u2063","\u2064":"\\u2064","\u2065":"\\u2065","\u2066":"\\u2066","\u2067":"\\u2067","\u2068":"\\u2068","\u2069":"\\u2069","\u206a":"\\u206a","\u206b":"\\u206b","\u206c":"\\u206c","\u206d":"\\u206d","\u206e":"\\u206e","\u206f":"\\u206f","\ufeff":"\\ufeff","\ufff0":"\\ufff0","\ufff1":"\\ufff1","\ufff2":"\\ufff2","\ufff3":"\\ufff3","\ufff4":"\\ufff4","\ufff5":"\\ufff5","\ufff6":"\\ufff6","\ufff7":"\\ufff7","\ufff8":"\\ufff8","\ufff9":"\\ufff9","\ufffa":"\\ufffa","\ufffb":"\\ufffb","\ufffc":"\\ufffc","\ufffd":"\\ufffd","\ufffe":"\\ufffe","\uffff":"\\uffff"},k=/[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g,l,m=JSON&&JSON.stringify||function(a){return i.lastIndex=0,i.test(a)&&(a=a.replace(i,function(a){return j[a]})),'"'+a+'"'},n=function(a){var b,c={},d=[];for(b=0;b<65536;b++)d.push(String.fromCharCode(b));return a.lastIndex=0,d.join("").replace(a,function(a){return c[a]="\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4),""}),a.lastIndex=0,c};c.quote=function(a){var b=m(a);return k.lastIndex=0,k.test(b)?(l||(l=n(k)),b.replace(k,function(a){return l[a]})):b};var o=["websocket","xdr-streaming","xhr-streaming","iframe-eventsource","iframe-htmlfile","xdr-polling","xhr-polling","iframe-xhr-polling","jsonp-polling"];c.probeProtocols=function(){var a={};for(var b=0;b0&&h(a)};return c.websocket!==!1&&h(["websocket"]),d["xhr-streaming"]&&!c.null_origin?e.push("xhr-streaming"):d["xdr-streaming"]&&!c.cookie_needed&&!c.null_origin?e.push("xdr-streaming"):h(["iframe-eventsource","iframe-htmlfile"]),d["xhr-polling"]&&!c.null_origin?e.push("xhr-polling"):d["xdr-polling"]&&!c.cookie_needed&&!c.null_origin?e.push("xdr-polling"):h(["iframe-xhr-polling","jsonp-polling"]),e};var p="_sockjs_global";c.createHook=function(){var a="a"+c.random_string(8);if(!(p in b)){var d={};b[p]=function(a){return a in d||(d[a]={id:a,del:function(){delete d[a]}}),d[a]}}return b[p](a)},c.attachMessage=function(a){c.attachEvent("message",a)},c.attachEvent=function(c,d){typeof b.addEventListener!="undefined"?b.addEventListener(c,d,!1):(a.attachEvent("on"+c,d),b.attachEvent("on"+c,d))},c.detachMessage=function(a){c.detachEvent("message",a)},c.detachEvent=function(c,d){typeof b.addEventListener!="undefined"?b.removeEventListener(c,d,!1):(a.detachEvent("on"+c,d),b.detachEvent("on"+c,d))};var q={},r=!1,s=function(){for(var a in q)q[a](),delete q[a]},t=function(){if(r)return;r=!0,s()};c.attachEvent("unload",t),c.unload_add=function(a){var b=c.random_string(8);return q[b]=a,r&&c.delay(s),b},c.unload_del=function(a){a in q&&delete q[a]},c.createIframe=function(b,d){var e=a.createElement("iframe"),f,g,h=function(){clearTimeout(f);try{e.onload=null}catch(a){}e.onerror=null},i=function(){e&&(h(),setTimeout(function(){e&&e.parentNode.removeChild(e),e=null},0),c.unload_del(g))},j=function(a){e&&(i(),d(a))},k=function(a,b){try{e&&e.contentWindow&&e.contentWindow.postMessage(a,b)}catch(c){}};return e.src=b,e.style.display="none",e.style.position="absolute",e.onerror=function(){j("onerror")},e.onload=function(){clearTimeout(f),f=setTimeout(function(){j("onload timeout")},2e3)},a.body.appendChild(e),f=setTimeout(function(){j("timeout")},15e3),g=c.unload_add(i),{post:k,cleanup:i,loaded:h}},c.createHtmlfile=function(a,d){var e=new ActiveXObject("htmlfile"),f,g,i,j=function(){clearTimeout(f)},k=function(){e&&(j(),c.unload_del(g),i.parentNode.removeChild(i),i=e=null,CollectGarbage())},l=function(a){e&&(k(),d(a))},m=function(a,b){try{i&&i.contentWindow&&i.contentWindow.postMessage(a,b)}catch(c){}};e.open(),e.write('