Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions basic/barrier/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ Barrier Sample
==============

This example demonstrates the use of a process barrier component to suspend a thread until some asynchronous operation
completes. The first example uses an **HTTP Inbound Gateway**, splits the request, sends the splits to rabbitmq and then
waits for
the publisher confirms. Finally, the results are returned to the caller.
completes. The first example uses an **HTTP Inbound Gateway**, splits the request, sends the splits to RabbitMQ and then
waits for the publisher confirms. Finally, the results are returned to the caller.

The sample is a Spring Boot application that loads 2 contexts:

Expand All @@ -19,19 +18,35 @@ http -> splitter -> amqp
amqp(Acks) -> aggregator -> barrier (release)
qmqp(inbound) -> nullChannel
amqp(inbound) -> nullChannel
```

The last flow drains the messages and allows the auto-delete queue to be removed when the application is closed.

## Configuration Options

This sample supports both **XML-based** and **Java-based** Spring Integration configurations. You can select which configuration to use by setting the active profile in `application.properties`:

* `spring.profiles.active=xml-config` - Uses XML configuration files from `META-INF/spring/integration/`
* `spring.profiles.active=java-config` - Uses Java `@Configuration` classes from the `configuration` package

## Running the sample

### Using Maven

$ mvn spring-boot:run

Or with a specific profile:

$ mvn spring-boot:run -Dspring-boot.run.arguments=--spring.profiles.active=java-config

### Using Gradle

$ gradlew :barrier:run

This will package the application and run it using the [Gradle Application Plugin](https://www.gradle.org/docs/current/userguide/application_plugin.html)

#### Using an IDE such as SpringSource Tool Suite™ (STS)
### Using an IDE such as SpringSource Tool Suite™ (STS)

In STS (Eclipse), go to package **org.springframework.integration.samples.barrier**, right-click **Application** and select **Run as** --> **Java Application** (or Spring Boot Application).

Expand All @@ -52,8 +67,14 @@ An aggregator is used to aggregate the results; if there are no errors, the resu
errors occurred, an exception is sent to release the barrier; this is thrown to the caller and has all the consolidated
results in a property.

#### Running the Error Handling Example

You can run this example from an IDE, such as STS using the technique above; in this case, the class is
**ErrorHandlingApplication** in the **org.springframework.integration.samples.barrier** package.
**ErrorHandlingApplication** in the **org.springframework.integration.samples.barrier2** package.

Or using Maven:

$ mvn spring-boot:run -Dspring-boot.run.main-class=org.springframework.integration.samples.barrier2.ErrorHandlingApplication

It sends a list of integers to the flow:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.env.Environment;

/**
* @author Gary Russell
* @author Glenn Renfro
*
* @since 4.2
*/
@SpringBootApplication
Expand All @@ -37,11 +40,22 @@ public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext server = SpringApplication.run(Application.class, args);

runClient(args);
server.close();
Environment env = server.getEnvironment();

// Get configurationType via profile
String configurationType = env.getProperty("spring.profiles.active");
System.out.println("Configuration-Type: " + configurationType);
if (configurationType == null || configurationType.equals("xml-config")) {
runClientWithXMLConfig(args);
}
else {
RequestGateway requestGateway = server.getBean("requestGateway", RequestGateway.class);
echoMessage(requestGateway);
}
System.exit(0);
}

static void runClient(String[] args) {
static void runClientWithXMLConfig(String[] args) {
SpringApplication application = new SpringApplicationBuilder()
.web(WebApplicationType.NONE)
.bannerMode(Mode.OFF)
Expand All @@ -52,11 +66,15 @@ static void runClient(String[] args) {
ConfigurableApplicationContext client = application.run(args);

RequestGateway requestGateway = client.getBean("requestGateway", RequestGateway.class);
echoMessage(requestGateway);
client.close();
}

private static void echoMessage(RequestGateway requestGateway) {
String request = "A,B,C";
System.out.println("\n\n++++++++++++ Sending: " + request + " ++++++++++++\n");
String reply = requestGateway.echo(request);
System.out.println("\n\n++++++++++++ Replied with: " + reply + " ++++++++++++\n");
client.close();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@
*/
package org.springframework.integration.samples.barrier;

import org.springframework.integration.annotation.MessagingGateway;

/**
* @author Oleg Zhurakousky
* @author Gunnar Hillert
* @author Glenn Renfro
*
*/

@MessagingGateway(defaultRequestChannel = "requestChannel")
public interface RequestGateway {

String echo(String request);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.springframework.integration.samples.barrier.configuration;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpMethod;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.http.dsl.Http;
import org.springframework.messaging.MessageChannel;

/**
* Configure client-side Spring Integration flows for the Barrier pattern sample.
* <p>
* Define the integration flow for sending HTTP requests to the server endpoint.
* Demonstrate how to configure an HTTP outbound gateway that sends POST requests
* and waits for responses.
* <p>
* Activate this configuration using the "java-config" profile.
*
* @author Glenn Renfro
*/
@Configuration
@Profile("java-config")
public class ClientConfiguration {

/**
* The URL endpoint of the server's HTTP inbound gateway.
* Defaults to http://localhost:8080/postGateway if not configured.
*/
@Value("${barrier.url:http://localhost:8080/postGateway}")
private String url;

/**
* Define the main client integration flow.
* <p>
* Receive messages from the {@link #requestChannel()} and send them
* via HTTP POST to the configured server URL. Wait for and return
* the HTTP response as a String.
*
* @return the integration flow definition
*/
@Bean
public IntegrationFlow clientFlow() {
return IntegrationFlow.from(requestChannel())
.handle(Http.outboundGateway(url)
.httpMethod(HttpMethod.POST)
.expectedResponseType(String.class))
.get();
}

/**
* Create the request channel that feeds messages into the client flow.
* <p>
* Use a direct channel that provides point-to-point semantics,
* delivering messages to a single subscriber.
*
* @return a new DirectChannel instance
*/
@Bean
public MessageChannel requestChannel() {
return new DirectChannel();
}

}
Loading
Loading