Announcement Announcement Module
Collapse
No announcement yet.
Does <header-enricher> element's 'expression' attribute suppt LinkedHashMap via SpEL? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Does <header-enricher> element's 'expression' attribute suppt LinkedHashMap via SpEL?

    Hi

    I'm using google's Gson utility to convert my message String payload (JSON based) to Java Value Object.

    I see that Gson parses the value of a Map as a LinkedHashMap<K,V>.

    However looks likes SpEL is not supporting LinkedHashaMap.
    Below is the header-enricher element that I've defined in my spring config file :

    Code:
    		<int:header-enricher>
    			<int:header name="MSG_REQ_MQ_PUB_SVCCODE" 
    						value="erx"/>
    			<int:header name="MSG_REQ_MQ_PUB_CLASSKEY" 
    						expression="'erx.svc.'+payload.messageHeader.cbrInfo['exCtxCode']"/>
    		</int:header-enricher>
    During runtime, I get the usual "generic" error of HeadeEnricher class as :
    org.springframework.integration.MessagingException : failed to transform message headers

    Can someone pls confirm if SpEL will *not* support extracting values from a LinkedHashMap<K,V> ?

    If yes, then what is the alternative ?

    Note - I'm restricted to use Gson util even though Spring Integration provides out-of-box transformers to convert from/to JSON.

    Thanks in advance.

    Best Regards
    LB

  • #2
    Hi!

    Can you show more StackTrace?
    By you confing it's not clear who is LinkedHashMap: messageHeader or cbrInfo?
    For SpEL there is no difference which implementation of Map you are provide. It just should implement necessary methods.
    I'm restricted to use Gson util even though Spring Integration provides out-of-box transformers
    Since 3.0.M2 we introduce new JsonObjectMapper strategy for json transfomers: https://jira.springsource.org/browse/INT-2831
    So, you can simply implement Gson mapper on your own.

    Take care,
    Artem

    Comment


    • #3
      Hi

      cbrInfo is the LinkedHashMap.

      Below is the hierarchy :

      Code:
      public class MsgBaseEnvelope {
      
      	/* Instance Variables */
      	protected MessageHeader messageHeader;
      	protected MessageFooter messageFooter;
      
             /* Getters and Setters */
      }
      
      public class MessageHeader {
      
        /* Instance Variables */	
        private String sourceApp;
        private ReportInfo reportInfo;
        private UserInfo userInfo;
        private Map<String,String> cbrInfo;
      
        /* Getters and Setters */
      
      }
      Attached is the scrnshot of Java value-object that gets populated by Gson.

      Also thanks for informing the updates on 3.0.M2 version, however I'm currently using the 2.2.3GA release.

      Thanks & Regards
      LBAttachment
      Attached Files

      Comment


      • #4
        As Cleric asked, please provide the full exception and stack trace.

        Comment


        • #5
          Your usage:
          cbrInfo['exCtxCode']
          a contents of the cbrInfo:
          executionCtxCode, outputFormatCode, flowCode, rptInstanceID
          So, as you see, your map doesn't contains a key exCtxCode.
          Here you end up with Exception, that there is no similar property on the cbrInfo, because SpEL uses property accessor to the map keys.

          Comment


          • #6
            Hi

            Sorry, the Map key I mentioned in my earlier post was a typo (as I just wanted to show a snippet of my configuration). Indeed I've used the correct key name in my config file but the issue still persist. Pls find below the complete configuration that didn't work.

            Code:
            <!--  
            		<int:header-enricher>
            			<int:header name="MSG_REQ_MQ_PUB_SVCCODE" 
            						value="'erx"/>
            			<int:header name="MSG_REQ_MQ_PUB_CLASSKEY" 
            						expression="'erx.svc.mq.pub.req.'
            									+ payload.messageHeader.reportInfo.lobOwner.toUpperCase()
            									+ '.'
            									+ payload.messageHeader.cbrInfo['executionCtxCode'].toUpperCase()"/>
            			<int:header name="MSG_REQ_MQ_PUB_DESTKEY" 
            						expression="'erx.svc.'
            									+ payload.messageHeader.reportInfo.lobOwner.toLowerCase() 
            									+ '.'
            									+ payload.messageHeader.cbrInfo['executionCtxCode'].toLowerCase()
            									+ 'request.mq.queue.alias'"/>
            		</int:header-enricher>		
            -->
            I changed the configuration as below and this change works fine. However, I will be more than happy if it works with SpEL.

            Code:
            		<int:header-enricher>
            			<int:header name="MSG_REQ_MQ_PUB_SVCCODE" value="erx"/>
            		</int:header-enricher>		
            		<int:header-enricher>
            			<int:header name="MSG_REQ_MQ_PUB_CLASSKEY" method="getHeaderEnricherForMsgPubClassKey" ref="ersOrcSvcUtil"/>
            			<int:header name="MSG_REQ_MQ_PUB_DESTKEY" method="getHeaderEnricherForMsgJMSDestinationKey" ref="ersOrcSvcUtil"/>
            		</int:header-enricher>
            Thanks
            LB

            Comment


            • #7
              I will be more than happy if it works with SpEL.
              That's why I ask you to show full StackTrace.
              Or even better if you'll travel through the DEBUG in the HeaderEnricher & ExpressionEvaluatingHeaderValueMessageProcessor

              Comment


              • #8
                I've just tested it and it worked well:
                Code:
                Map<String, String> payload = new LinkedHashMap<String, String>();
                payload.put("foo", "foO");
                payload.put("bar", "bAr");
                Message<?> message = MessageBuilder.withPayload(payload).build();
                input.send(message);
                HTML Code:
                <header name="myHeader" expression="'erx.svc.'
                	+ payload['foo'].toUpperCase()
                	+ '.'
                	+ payload['bar'].toLowerCase()
                	+ 'request.mq.queue.alias'"/>

                Comment


                • #9
                  I would have been more than happy to provide you the stack trace if at all it was present.

                  Pls find the scrn-shot of the exception object that I get while debugging. Stack Trace is NULL.

                  Attachment

                  Thanks
                  LB
                  Attached Files

                  Comment


                  • #10
                    It will be printed if you turn on logging; in the debugger, you must drill down using the 'cause' field. To find the root cause.

                    Comment


                    • #11
                      Thanks for pointing.

                      This is the root cause message:

                      EL1008Epos 137): Field or property 'cbrInfo' cannot be found on object of type 'com.bnym.ecs.common.service.framework.domain.Mess ageHeader'

                      Also attaching the scrnshot.

                      Attachment

                      Thanks in advance for pointing where I could be wrong.

                      Best Regards
                      Lalit
                      Attached Files

                      Comment


                      • #12
                        cbrInfo is a private field - does it have a getter?

                        Comment


                        • #13
                          got the issue !

                          The getters and setters I defined were not as per "Bean" convention.

                          This is what I defined:

                          Code:
                          	
                                  public Map<String, String> getCBRInfo() {
                          		return cbrInfo;
                          	}
                          
                          	public void setCBRInfo(Map<String, String> cbrInfo) {
                          		this.cbrInfo = cbrInfo;
                          	}
                          I've modified it to

                          Code:
                          	
                                  public Map<String, String> getCbrInfo() {
                          		return cbrInfo;
                          	}
                          
                          	public void setCbrInfo(Map<String, String> cbrInfo) {
                          		this.cbrInfo = cbrInfo;
                          	}
                          and it now works fine.

                          Strange that Gson ignored the "Bean" conventions and was still able to parse the message String correctly.

                          Many thanks to all for all your guidance.

                          Best Regards
                          LB

                          Comment

                          Working...
                          X