Results 1 to 7 of 7

Thread: Splitter Question: what is happening to the header values I have modified?

  1. #1
    Join Date
    Aug 2010
    Posts
    10

    Default Splitter Question: what is happening to the header values I have modified?

    I have a spring integration splitter with the following method signature:

    Code:
    @Splitter
    public List<Message<String[]>> splitCsvIntoSeperateMessages(Message<List<String[]>> message)
    The message payload is an ArrayList of String[]. The splitter reads each row in the List, Creates a new Message setting the payload to the data item in the List, adds a CorrelationId, SequenceNumber and SequenceSize to the header and finally returns an ArrayList of Messages.

    The problem is that when each individual message is sent to the next channel, the CorrelationId, SequenceNumber and SequenceSize are all overwritten with new values. Is that expected behavior or am I missing something?

    Code:
    @Splitter
    public List<Message<String[]>> splitCsvIntoSeperateMessages(Message<List<String[]>> message) {
    
     List<Message<String[]>> returnVal = new ArrayList<Message<String[]>>();
     String headerId = null;
     int sequenceSize = 0;
     int sequenceNumber = 0;
     for(String[] payload : message.getPayload()){
    
      if(payload[0].equals("HEAD")){
       headerId = UUID.randomUUID().toString();
       sequenceSize = Integer.parseInt(payload[payload.length-1]);
       sequenceNumber=0;
      }
      sequenceNumber++;
      Message<String[]> msg = 
       MessageBuilder
            .withPayload(payload)
         .setCorrelationId(headerId)
         .setSequenceSize(sequenceSize)
         .setSequenceNumber(sequenceNumber)
         .build();
    
      returnVal.add(msg);
     }
     return returnVal;
    }

  2. #2
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    Actually, the internal Splitter implementation does write those headers itself before sending the reply (and since List is an ordered collection, it can determine sequenceNumber/sequenceSize from that).

    Are you using values that would be different from those defaults? If so, can you explain the use-case?

    Thanks,
    Mark

  3. #3
    Join Date
    Aug 2010
    Posts
    10

    Default

    That makes sense....the default implementation of a splitter...

    Can you tell me what happens if I use <serivce-activator> vs <spitter>.

    Is it important to annotate the methods with @Splitter or @ServiceActivation?

    John

  4. #4
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    The main difference between Splitter and Service-Activator is that the Splitter will send multiple Messages (one for each "payload" in the list) while a Service-Activator would send the whole list as a single payload.

  5. #5
    Join Date
    Aug 2010
    Posts
    10

    Default

    so can you take a look at my configuration file and tell me if I am "over using" service-activator? (this may not be a fair question without explaining my use case)



    Code:
    	<file:inbound-channel-adapter
    		auto-startup="true" auto-create-directory="true" directory="file:c:/temp/vaonce/load/" filename-pattern=".*\.txt"
    		channel="fileInputChannel">
    		<poller default="true">
    			<interval-trigger interval="10000" time-unit="MILLISECONDS" />
    		</poller>
    	</file:inbound-channel-adapter>
    
    	<chain input-channel="fileInputChannel">
    		<transformer ref="transformer" method="enrichHeaderWithFileInfo" />
    		<header-enricher>
    			<error-channel ref="errorChannel"/>
    			<header name="$discardChannel" ref="discardChannel"/>
    		</header-enricher>
    		<router channel-resolver="fileNameResolver">
    			<beans:bean class="org.springframework.integration.router.HeaderValueRouter">
    				<beans:constructor-arg value="$file_name" />
    			</beans:bean>
    		</router>
    	</chain>
    
    	<chain input-channel="enrollmentFile">
    		<service-activator ref="handler" method="loadVaOnceFile"/>
    		<service-activator ref="handler" method="verifyDetailRecordCounts"/>
    		<header-enricher>
    			<reply-channel ref="enrollmentFileSplit"/>
    		</header-enricher>
    		<service-activator ref="splitter" method="splitCsvIntoSeperateMessages"/>
    	</chain>
    
    	<chain input-channel="enrollmentFileSplit">
    		<aggregator/>
    		<transformer ref="transformer" method="transformEnrollmentToJpa" />
    		<splitter ref="splitter" method="splitEnrollmentJpaRecords"  />
    		<service-activator ref="handler" method="saveEnrollment" />
    	</chain>
    
    	<chain input-channel="amendmentFile">
    		<service-activator ref="handler" method="loadVaOnceFile"/>
    		<service-activator ref="handler" method="verifyDetailRecordCounts"/>
    		<header-enricher>
    			<reply-channel ref="enrollmentFileSplit"/>
    		</header-enricher>
    		<service-activator ref="splitter" method="splitCsvIntoSeperateMessages"/>
    	</chain>
    
    	<chain input-channel="amendmentFileSplit">
    		<aggregator/>
    		<transformer ref="transformer" method="transformEnrollmentToJpa" />
    		<splitter ref="splitter" method="splitEnrollmentJpaRecords"  />
    		<service-activator ref="handler" method="saveAmendment" />
    	</chain>

  6. #6
    Join Date
    Oct 2005
    Location
    Boston, MA
    Posts
    2,840

    Default

    Well, the Service Activator's replies are not going to be individual messages right?... would be the full list as a single payload.

  7. #7
    Join Date
    Aug 2010
    Posts
    10

    Default

    Actually, I am using the service activator to split and send back the individual messages with the headers I want.

    Let me show you the modified splitCsvIntoSeperateMessages method:


    Code:
    	@ServiceActivator
    	public void splitCsvIntoSeperateMessages(Message<List<String[]>> message) throws IOException {
    
        	MessageChannel replyChannel =(MessageChannel)message.getHeaders().getReplyChannel();
        	String headerId = null;
        	int sequenceSize = 0;
        	int sequenceNumber = 0;
        	for(String[] payload : message.getPayload()){
    
        		if(payload[0].equals("HEAD")){
        			headerId = UUID.randomUUID().toString();
        			sequenceSize = Integer.parseInt(payload[payload.length-1])+1;
        			sequenceNumber=0;
        		}
        		sequenceNumber++;
        		Message<String[]> msg =
        			MessageBuilder
    		    		.withPayload(payload)
    		    		.copyHeaders(message.getHeaders())
    		    		.setSequenceNumber(sequenceNumber)
    					.setSequenceSize(sequenceSize)
    					.setCorrelationId(headerId)
    		    		.build();
        		replyChannel.send(msg);
        	}
    	}

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •