Announcement Announcement Module
Collapse
No announcement yet.
Custom Header Message over TCP Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Custom Header Message over TCP

    Hi,

    I am new to Spring and trying to send a message with payload from client to server (running in separate JVMs) over TCP.

    I have read through the post here, http://forum.springsource.org/showth...pass-to-server and tried to understand how the payload is being enhanced on the client and then being stripped on the server however I'm not doing too well.

    I like the idea of keeping the enhancement within Spring rather than wrapping the message in another serializable object before sending it through and would be grateful if anyone could point me in the direction of any more examples of this?

    What I want to do is give my message object a header of ('REQUEST-TYPE', 'CREATE') and then strip this off once it gets to the server and pipe it to the create class using a header-value-router. Equally there will be a header for 'READ', 'AMEND' and 'DELETE' again distributed by the header router.

    If anyone could give any more detail on the method described in the thread above I would appreciate it!

    Thanks,
    Alex

  • #2
    Can you provide an example of what your payload looks like? I should then be able to give you a strategy.

    Comment


    • #3
      Hi Gary,
      Thanks for the quick response, I'll go into more detail of what I would like to achieve..

      I have Scheduler service (using Quartz) and other services who want to CRUD on the schedule. The services run as standalone Java apps all using Spring to talk to each other.

      I have a Schedule Object (the payload) which has setters and getters for the other services to complete before sending to the schedule service which then extracts the information and does what ever it needs to do to the schedule.

      I have a class containing four methods, one for Create, Read, Update and Delete and if I wasn't using TCP I would get whatever creates the schedule object and adds it to the message to just set the headers. Then I would use a header value router in order to send the payload to whichever of the four methods matches the header.

      The problem I have is getting the schedule object to keep the header so spring knows which method to route the object to.

      I hope that helps?

      Thanks for your help!

      Comment


      • #4
        I assume the Schedule object is Serializable. The enhance/strip logic in that other post assumes a String payload.

        You can simply wrap your Schedule object in a wrapper...

        Code:
        @SuppressWarnings("serial")
        public class Wrapper implements Serializable {
        
        	private final Schedule schedule;
        
        	private final String command;
        
        	public Wrapper(Schedule schedule, String command) {
        		this.schedule = schedule;
        		this.command = command;
        	}
        
        	public Schedule getSchedule() {
        		return this.schedule.
        	}
        
        	public String getCommand() {
        		return command;
        	}
        
        }
        Then, on the outbound side, right before the tcp outbound endpoint, add a transformer

        Code:
        <transformer input-channel="input" output-channel="toTcp"
          expression="new foo.Wrapper(payload, 'CREATE')"/>
        and on the inbound side, right after the TCP inbound...

        Code:
        <chain input-channel="fromTCP" output-channel="toHeaderRouter">
        	<header-enricher>
        		<header name="COMMAND" expression="payload.command"/>
        	</header-enricher>
        	<transformer expression="payload.schedule"/>
        </chain>
        This all assumes you're TCP connection factories are configured to use the Java serialization (de)serializers...

        Code:
        <bean id="defaultSerializer" class="org.springframework.core.serializer.DefaultSerializer" />
        
        <bean id="defaultDeserializer" class="org.springframework.core.serializer.DefaultDeserializer" />

        Comment


        • #5
          Cheers, that looks great!

          I've got all the serialization in place as you suggested.

          Just to confirm my understanding with what is going on..

          Code:
          <transformer input-channel="input" output-channel="toTcp"
            expression="new foo.Wrapper(payload, 'CREATE')"/>
          When the transformer expression passes the payload (Schedule Object) to the Wrapper does Spring know the reference 'payload' is the payload being passed down the channel?


          Code:
          <chain input-channel="fromTCP" output-channel="toHeaderRouter">
          	<header-enricher>
          		<header name="COMMAND" expression="payload.command"/>
          	</header-enricher>
          	<transformer expression="payload.schedule"/>
          </chain>
          I see that this is extracting the payload from the wrapper, and then creating a new header, does the expression of the header become what mapping value in the header value router?

          Also, is the rest of the wrapper discarded so I just end up with schedule object passed down the pipe to the router and ultimately the method in the schedule service?


          I appreciate your help with this!

          Comment


          • #6
            Correct; the Wrapper is just a JavaBean; SpEL expressions (in most Spring Integration uses) have the message as the #root object. A message has two properties 'payload' and 'headers'.

            Payload is the main content; headers are metadata; headers are a map.

            In SpEL, we can use JavaBean conventions when acting on objects so things like <transform ... expression="payload.schedule" /> actually invokes

            Code:
            message.getPayload().getSchedule();
            A map in SpEL is referenced using map['key'], so if, on your client side, your command was in a header called 'COMMAND', you could create the wrapper object in SpEL using

            Code:
            expression="new foo.Wrapper(payload, headers['COMMAND'])"
            In my example above, I used a literal "CREATE" instead...

            Code:
            expression="new foo.Wrapper(payload, 'CREATE')"
            Similarly, on the server side, we are simply accessing the wrapper as a JavaBean

            Code:
            <header name="COMMAND" expression="payload.command"/>
            means the message coming out of the header-enricher (and going into the transformer) gets a new header, called "COMMAND", with the value

            Code:
            message.getPayload().getCommand()
            and

            <transformer expression="payload.schedule"/>

            means the "new" payload after the transformer has the value

            Code:
            message.getPayload().getSchedule()
            The "old" payload is simply discarded at this point and you are left with a message with the Schedule as its payload and a header that you subsequently use in a header value router, where you route on header "COMMAND" and have mappings for CREATE, UPDATE etc...

            Hope that helps.

            Comment


            • #7
              This looks great! Thanks for your explanation, I appreciate it.

              Will give it all a go when I get back in the office on Monday.

              Comment


              • #8
                I just wanted to follow up and say I got all this working.

                Thanks Gary!

                Comment

                Working...
                X