Hello,

I have an exchange process that I've modeled using Spring Integration.

The process accepts a request (with a list of 'presentments'), then process it by calling a service for each single presentment, and create a response with a global result, some original data, and a list of the individual result of processing each single presentment.

The messages exchanged are XML files. I manage them using JAXB2.

It's easy to see that I need a Splitter-Aggregator, a Service Activator for each individual object of the list, and a Transformation (from the Request to the Response, besides the Marshalling/Unmarshalling of the XML files)

My question is, is it better to Split, to call the Service Activator, then to aggregate and finally to make a transformation or to use the Service Activator for performing both the business logic and the transformation?

I'd rather the former, because otherwise, I'd need to keep the individual result in MesssageHeaders to be managed in the aggregator. Furthermore, I avoid a double loop in the list.

However, in spite that seems clear enough that a ServiceActivator accepts a request and returns a Response, to aggregate responses from a list of request could create some confussion. Since the response list must have the same size of the request list, it's not actually an issue.

Any advice regarding this issue?

NOTE: spring integration XML file:

HTML Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>


	<!-- Ficticious -->
	<int:inbound-channel-adapter id="request" ref="" />
	<oxm:jaxb2-marshaller id="requestJaxb2Marshaller">
		<oxm:class-to-be-bound name="com.malsolo.integration.schema.REQUESTSCHEMA"/>
	</oxm:jaxb2-marshaller>
	<int-xml:unmarshalling-transformer id="unmarshaller" unmarshaller="requestJaxb2Marshaller" input-channel="request" output-channel="processRequest"/>
	<int:channel id="processRequest" />
	<!-- For the aggregator -->
	<int:header-enricher id="enrichHeaderWithRequester" input-channel="processRequest" output-channel="splitPresentments">
		<int:header name="REQUESTER" value="payload.getREQUESTER()"/>
		<int:header name="REQUESTER_IDENTIFIER" value="payload.getIDENTIFIER()"/>
	</int:header-enricher>
	<int:channel id="splitPresentments" />
	<!-- Split the REQUESTSCHEMA into a List<REQUESTSCHEMA.PRESENTMENTS> -->
	<int:splitter id="presentmentsSplitter" input-channel="splitPresentments" output-channel="processPresentments" ref="presentmentSplitter" method="splitRequestIntoPresentments"/>
	<int:channel id="processPresentments" />
	<!-- @ServiceActivator public RESPONSESCHEMA.PRESENTMENTS doStuff(REQUESTSCHEMA.PRESENTMENTS presentmentRequested) {} -->
	<int:service-activator id="presentmentProcessor" input-channel="processPresentments" output-channel="aggregatePresentments" ref="presentmentServiceActivator" method="doStuff" />
	<int:channel id="aggregatePresentments" />
	<!-- Aggregate the List<RESPONSESCHEMA.PRESENTMENTS> into a RESPONSESCHEMA using the headers managed by enrichHeaderWithRequester -->
	<int:aggregator id="presentmentsAggregator" input-channel="aggregatePresentments" output-channel="response"
		correlation-strategy="presentmentsAggregator" correlation-strategy-method="correlateBy"
		ref="presentmentsAggregator" method="aggregateCasosConfirmacionIntoConfirmacion"
		release-strategy="presentmentsAggregator" release-strategy-method="releaseCasosConfirmacion"
	/><!-- Yes, the same @Component for the @Aggregator, the @ReleaseStrategy and the @CorrelationStrategy -->
	<!-- Ficticious -->
	<int:outbound-channel-adapter id="response" ref="" />
</beans>
NOTE: a summary of the classes created by JAXB2

REQUEST
Code:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
...})
@XmlRootElement(name = "REQUEST_SCHEMA")
public class REQUESTSCHEMA {

    @XmlElement(name = "REQUESTER", required = true)
    protected String requester;
    @XmlElement(name = "IDENTIFIER", required = true)
    protected ID identifier;
    @XmlElement(name = "NUMBER_OF_PRESENTMENTS")
    protected short numberOfPresentments;
    @XmlElement(name = "PRESENTMENTS", required = true)
    protected List<REQUESTSCHEMA.PRESENTMENTS> presentments;

        
    //~ setters/getters...

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
...    })
    public static class PRESENTMENTS {

        @XmlElement(name = "SEQUENCE")
        protected short sequence;
        @XmlElement(name = "CYCLE", required = true)
        protected String cycle;
        @XmlElement(name = "TYPE", required = true)
        protected String type;
        @XmlElement(name = "DATA", required = true)
        protected REQUESTSCHEMA.PRESENTMENTS.DATA data;
        
        //~ setters/getters...

        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "", propOrder = {
...        })
        public static class DATA {

            @XmlElement(name = "IDENTIFIER", required = true)
            protected ID identifier;
            @XmlElement(name = "PRESENTMENT_DATA", required = true)
            protected REQUESTSCHEMA.PRESENTMENTS.DATA.PRESENTMENTDATA presentmentData;
            @XmlElement(name = "ISSUER_NUMBER", required = true)
            protected String issuerNumber;
            @XmlElement(name = "REQUIERED", defaultValue = "true")
            protected boolean requiered;
            @XmlElement(name = "PRIORITY")
            protected String priority;

        //~ setters/getters... and so on

        }

    }

}
RESPONSE
Code:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
...})
@XmlRootElement(name = "RESPONSE_SCHEMA")
public class RESPONSESCHEMA {

    @XmlElement(name = "RESPONSER", required = true)
    protected String responser;
    @XmlElement(name = "IDENTIFIER", required = true)
    protected ID identifier;
    @XmlElement(name = "IDENTIFIER_ORIGINAL", required = true)
    protected ID identifierOriginal;
    @XmlElement(name = "RESULT", required = true)
    protected String result;
    @XmlElement(name = "RESULT_DESCRIPTION", required = true)
    protected String resultDescription;
    @XmlElement(name = "NUMBER_OF_PRESENTMENTS")
    protected short numberOfPresentments;
    @XmlElement(name = "PRESENTMENTS", required = true)
    protected List<RESPONSESCHEMA.PRESENTMENTS> presentments;

        
    //~ setters/getters...

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
...    })
    public static class PRESENTMENTS {

        @XmlElement(name = "SEQUENCE")
        protected short sequence;
        @XmlElement(name = "CYCLE", required = true)
        protected String cycle;
        @XmlElement(name = "TYPE", required = true)
        protected String type;
        @XmlElement(name = "DATA", required = true)
        protected RESPONSESCHEMA.PRESENTMENTS.DATA data;
        @XmlElement(name = "PROCESS_RESULT", required = true)
        protected RESPONSESCHEMA.PRESENTMENTS.PROCESSRESULT processResult;
        
        //~ setters/getters...

        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "", propOrder = {
            "identifier",
            "presentmentData",
            "issuerNumber",
            "requiereimagen",
            "priority"
        })
        public static class DATA {

            @XmlElement(name = "IDENTIFIER", required = true)
            protected ID identifier;
            @XmlElement(name = "PRESENTMENT_DATA", required = true)
            protected RESPONSESCHEMA.PRESENTMENTS.DATA.PRESENTMENTDATA presentmentData;
            @XmlElement(name = "ISSUER_NUMBER", required = true)
            protected String issuerNumber;
            @XmlElement(name = "REQUIERED", defaultValue = "true")
            protected boolean requiered;
            @XmlElement(name = "PRIORITY")
            protected String priority;

        //~ setters/getters... and so on

        }

        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "", propOrder = {
...        })
        public static class PROCESSRESULT {

            @XmlElement(name = "NAME", required = true)
            protected String name;
            @XmlElement(name = "ORDER")
            protected short order;
            @XmlElement(name = "CALCULUS", required = true)
            protected String calculus;
            @XmlElement(name = "RESULT", required = true)
            protected String result;
            @XmlElement(name = "RESULT_DESCRIPTION", required = true)
            protected String resultDescription;
            @XmlElement(name = "ATTEMPTS")
            protected short attempts;

        //~ setters/getters... and so on

        }
    }

}