Spring Integration Aggregator failing - “No reply received within timeout” message being displayed

孤街浪徒 提交于 2019-12-12 06:21:21

问题


I am building a Proof of Concept showcasing the end-to-end flow of an XML-based RESTful application built with Spring Integration, the overall idea being the following:

1) A HTTP Inbound Gateway that accepts incoming requests from the calling client

2) A set of @Router, @ServiceActivator, @Splitter & @Aggregator artifacts to process the incoming request and send a set of possible responses (the response XSD has optional elements inside a parent element that get populated based on the use-case) back to the calling client

I tested the flow on a local Tomcat 7.0.68 instance using Chrome's Advanced REST client extension and it always works fine the 1st time and that's the end of it.

Every test thereafter fails in the exact same way - after the final invocation of the @CorrelationStrategy method in the Aggregator, the flow ends with just this message, "No reply received within timeout".

The docs (http://docs.spring.io/spring-integration/docs/4.3.8.RELEASE/reference/htmlsingle/#http-timeout) say that for an HTTP Inbound Gateway, both the timeout properties default to 1000ms. I actually did try to manually set reply-timeout to 50000 but it didn't work.

Also, http://docs.spring.io/spring-integration/docs/4.3.8.RELEASE/reference/htmlsingle/#aggregator-config says, "The timeout interval to wait when sending a reply Message to the output-channel or discard-channel. Defaults to -1 - blocking indefinitely"

Since the failure seems to do with Spring Integration relying on some default timeout, can someone please let me know if there is anything else to try from my side?

Here are the most relevant pieces of code from my project:

Context file: product-integration.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:int="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
xmlns:int-http="http://www.springframework.org/schema/integration/http"
xsi:schemaLocation="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
    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/http
    http://www.springframework.org/schema/integration/http/spring-integration-http.xsd ">

<int:annotation-config/>
<context:component-scan base-package="com.amb.splitteraggregator"/>

<!-- POST -->
<int-http:inbound-gateway request-channel="gatewayProductRequests"
    reply-channel="gatewayProductResponses"
    supported-methods="POST" 
    path="/product"
    request-payload-type="java.lang.Stringe>

    <int-http:request-mapping consumes="application/xml" produces="application/xml"/>
</int-http:inbound-gateway>

<int:channel id="gatewayProductResponses" />
<int:channel id="validatedProductRequests" />
<int:channel id="upstreamProductResponses" />
<int:channel id="downStreamProductRequests" />
<int:channel id="downStreamRawProductsAndRequest" />
<int:channel id="downStreamProductRequestBatches" />
<int:channel id="compositeMessagesWithResponse" />
<int:channel id="compositeMessagesForAggregation" />
<int:channel id="compositeMessagesWithRawProductsAndRequestOrResponse" />

Aggregator: ProductAggregator.java

@MessageEndpoint 
public class ProductAggregator {
final static Logger logger = Logger.getLogger(ProductAggregator.class);

@Autowired
ProductServiceHelper productServiceHelper;

@Aggregator(inputChannel="compositeMessagesForAggregation", outputChannel="upstreamProductResponses", sendTimeout="10000")
public Message<Composite> generateAggregatedResponse(List<Message<Composite>> listOfCompositeMessagesForAggregation) {
    logger.info("generateAggregatedResponse :: START");

    PRODUCTRESPONSE productResponse = new PRODUCTRESPONSE();
    PRODUCTRESPONSEDATA productResponseData = new PRODUCTRESPONSEDATA();
    ERROR error = new ERROR();

    PRODUCTRESPONSE productResponseInComposite = null;
    List<PRODUCT> listOfProductsInComposite = null;

    List<PRODUCT> listOfProductsToReturn = new ArrayList<PRODUCT>();
    StringBuilder errorsToReturn = new StringBuilder();

    String uuid = null;

    for(Message<Composite> compositeMessage : listOfCompositeMessagesForAggregation) {
        productResponseInComposite = compositeMessage.getPayload().getProductResponse();
        if (null != productResponseInComposite.getPRODUCTRESPONSEDATA()) {
            uuid = productResponseInComposite.getPRODUCTRESPONSEDATA().getUuid();
            listOfProductsInComposite = productResponseInComposite.getPRODUCTRESPONSEDATA().getPRODUCT();
            listOfProductsToReturn.addAll(listOfProductsInComposite);
        } else if (null != productResponseInComposite.getERROR()) {
            errorsToReturn.append(productResponseInComposite.getERROR().getErrorMsgCode());
            errorsToReturn.append(",");
        }
    }

    if (null != listOfProductsToReturn && !listOfProductsToReturn.isEmpty()) {
        productResponseData.getPRODUCT().addAll(listOfProductsToReturn);
        productResponseData.setUuid(uuid);
        productResponse.setPRODUCTRESPONSEDATA(productResponseData);
    }

    if (errorsToReturn.length() != 0) {
        error.setErrorMsgCode(errorsToReturn.toString());
        error.setUuid(uuid);
        productResponse.setERROR(error);
    }

    Composite compositeWithAggregatedResponse = productServiceHelper.buildComposite(false, productResponse);
    Message<Composite> compositeMessageWithAggregatedResponse = MessageBuilder.withPayload(compositeWithAggregatedResponse).build();

    logger.info("generateAggregatedResponse :: END");
    return compositeMessageWithAggregatedResponse;
}

@CorrelationStrategy
public UUID correlateByUUID(Message<Composite> compositeMessageForAggregation) {
    logger.info("correlateByUUID :: START");
    logger.info("Correlation by UUID done");
    logger.info("correlateByUUID :: END");
    UUID correlationUUID = null;

    if (null != compositeMessageForAggregation.getPayload().getProductResponse().getPRODUCTRESPONSEDATA()) {
        correlationUUID = UUID.fromString(compositeMessageForAggregation.getPayload().getProductResponse().getPRODUCTRESPONSEDATA().getUuid());
    } else if (null != compositeMessageForAggregation.getPayload().getProductResponse().getERROR()) {
        correlationUUID = UUID.fromString(compositeMessageForAggregation.getPayload().getProductResponse().getERROR().getUuid());
    }
    return correlationUUID;
}

}

Custom composite object moving through the channels: Composite.java

public class Composite {
private PRODUCTREQUEST productRequest;
private PRODUCTRESPONSE productResponse;
private List<RawProduct> listOfRawProducts;
private boolean isError;

public Composite(boolean isError, PRODUCTREQUEST productRequest) {
    this.isError = isError;
    this.productRequest = productRequest;
}

public Composite(boolean isError, PRODUCTRESPONSE productResponse) {
    this.isError = isError;
    this.productResponse = productResponse;
}

public Composite(boolean isError, List<RawProduct> listOfRawProducts) {
    this.isError = isError;
    this.listOfRawProducts = new ArrayList<RawProduct>(listOfRawProducts);
}

public Composite(boolean isError, PRODUCTREQUEST productRequest, List<RawProduct> listOfRawProducts) {
    this.isError = isError;
    this.productRequest = productRequest;
    this.listOfRawProducts = new ArrayList<RawProduct>(listOfRawProducts);
}

public PRODUCTREQUEST getProductRequest() {
    return productRequest;
}

public PRODUCTRESPONSE getProductResponse() {
    return productResponse;
}

public boolean isError() {
    return isError;
}

public List<RawProduct> getListOfRawProducts() {
    return this.listOfRawProducts;
}

}

pom.xml

<modelVersion>4.0.0</modelVersion>
<groupId>com.amb</groupId>
<artifactId>splitteraggregator</artifactId>
<name>SpringWebSplitterAggregator</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
    <java-version>1.7</java-version>
    <org.springframework-version>4.3.7.RELEASE</org.springframework-version>
    <spring.integration.version>4.3.8.RELEASE</spring.integration.version>
    <org.aspectj-version>1.6.10</org.aspectj-version>
    <org.slf4j-version>1.6.6</org.slf4j-version>
    <log4j.version>1.2.17</log4j.version>
    <junit.version>4.11</junit.version>
</properties>
<dependencies>
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${org.springframework-version}</version>
        <exclusions>
            <!-- Exclude Commons Logging in favor of SLF4j -->
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
             </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${org.springframework-version}</version>
    </dependency>

    <!-- Spring Integration -->
    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-core</artifactId>
        <version>${spring.integration.version}</version>
    </dependency>

    <!-- Spring Integration Stream -->
    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-stream</artifactId>
        <version>${spring.integration.version}</version>
        <!-- <scope>compile</scope> -->
    </dependency>       

    <!-- Spring Integration HTTP -->    
    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-http</artifactId>
        <version>${spring.integration.version}</version>
    </dependency>       

    <!-- AspectJ -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${org.aspectj-version}</version>
    </dependency>   

    <!-- Logging -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${org.slf4j-version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${org.slf4j-version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>${org.slf4j-version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>${log4j.version}</version>
        <exclusions>
            <exclusion>
                <groupId>javax.mail</groupId>
                <artifactId>mail</artifactId>
            </exclusion>
            <exclusion>
                <groupId>javax.jms</groupId>
                <artifactId>jms</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.jdmk</groupId>
                <artifactId>jmxtools</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.jmx</groupId>
                <artifactId>jmxri</artifactId>
            </exclusion>
        </exclusions>
        <scope>compile</scope>
    </dependency>

    <!-- @Inject -->
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>

    <!-- Servlet -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

    <!-- Test -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>        
</dependencies>
<build>
    <plugins>
        <plugin>
            <artifactId>maven-eclipse-plugin</artifactId>
            <version>2.9</version>
            <configuration>
                <additionalProjectnatures>
                    <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                </additionalProjectnatures>
                <additionalBuildcommands>
                    <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                </additionalBuildcommands>
                <downloadSources>true</downloadSources>
                <downloadJavadocs>true</downloadJavadocs>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                <compilerArgument>-Xlint:all</compilerArgument>
                <showWarnings>true</showWarnings>
                <showDeprecation>true</showDeprecation>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <configuration>
                <mainClass>org.test.int1.Main</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

Please let me know if more code snippets from my project are required - this is my first question on Stack Overflow so pardon me if there is any etiquette that I missed.

- Bharath

来源:https://stackoverflow.com/questions/43987748/spring-integration-aggregator-failing-no-reply-received-within-timeout-messa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!