Apache camel: data from exchange header to another route

2.6k Views Asked by At

I have to ask about camel route behaviour, which is silly (but simple to understand) logical description. In main themes - i need to push info from exchange header of one route to another one. It's all about CMDB system and monitoring tool zabbix. Well, at the first i have a route which can switch CI state in CMDB:

<route>
    <description> route catching CI ID in jms queue, check it on exist and switch CI state to incident
    </description>
    <from uri="jms:switchCIStateQueue"/>
    <filter>
        <simple>${body} regex '[\d]+'</simple>
        <to uri="bean:otrsCIApi?method=getCIBodyByID(${body})"/>
        <filter>
            <simple>${body} regex '\{.+?\}'</simple>
            <marshal>
                <json library="Jackson"/>
            </marshal>
            <unmarshal>
                <json library="Jackson" unmarshalTypeName="ts.team.otrs.ci.OtrsCI"/>
            </unmarshal>
            <to uri="bean:otrsCIApi?method=switchOTRSCIState(${body})"/>
        </filter>
    </filter>
</route>

It's working good, but i have to use this action from another route, which have many checks, filters and choices. My problem is that i don't have a CI ID as a body (but keep it in header) in depth of main logical route.

<route>
    <description>Route catch triggerid 
     and creates a ticket in OTRS, link it to host
    </description>
    <from uri="direct:zab_trig_2_otrs_tick"/>
    <to uri="bean:zabbixApi?method=getTriggerByID(body)"/>
    <filter>
        <simple>${body} regex '\{.+?\}'</simple>
            <marshal>
                <json library="Jackson"/>
            </marshal> 
            <unmarshal>
                 <json library="Jackson" unmarshalTypeName="ts.team.zabbix.trigger.SingleTrigger"/>
            </unmarshal>
            <setHeader headerName="ZabbixTrigger" id="_setZabbixTrigger">
                <simple>${body}</simple>
            </setHeader>
            <!-- search CI in OTRS -->
            <to uri="bean:otrsCIApi?method=searchCI(${body.getHosts().get(0).getName()})"/>
            <!-- Array of CI ID like [] or ["1"] -->
            <split streaming="true">
                <simple>${body}</simple>
                <!-- place it in header-->
                <setHeader headerName="HostID">
                    <simple>${body}</simple>
                </setHeader>
                <to uri="bean:otrsLinkApi?method=ListLinkedTicketsTitleFiltered(${body},${header.ZabbixTrigger.getDescription()})"/>
                <!-- return JSONArray  with State=open otrs Tickets ID -->
                <choice>
                    <when id="ticketslist_empty">
                        <simple>${body} == ''</simple>
                        <!-- Create ticket, connect it to host in OTRS -->
                        <to uri="bean:otrsTicketApi?method=createNewTicket(${header.ZabbixTrigger.getDescription()},${header.ZabbixTrigger.getPriority()})"/>
                        <!-- return body body with ticket id, create link with  ${header.HostID} -->
                        <to uri="bean:otrsLinkApi?method=LinkAdd(${header.HostID},${body})"/>
                        <!-- Here i need to switch CI state if incident priority is higher than 3(Normal)-->
                        <when>
                            <simple>${header.ZabbixTrigger.getPriority()} > 3</simple>
                            <!-- here i need to send  ${header.HostID} to previous described route (jms:switchCIStateQueue)-->
                        </when>
                    </when>
                </choice>
            </split>
    </filter>
</route>

So, there is piece of this route:

                    <when>
                        <simple>${header.ZabbixTrigger.getPriority()} > 3</simple>
                        <!-- here i need to send  ${header.HostID} to previous described route (jms:switchCIStateQueue)-->
                    </when>

where i need to send some info from my header to jms:switchCIStateQueue (or route direct, it's no matter where to). I hope, my description of problem is quite full and simple.

1

There are 1 best solutions below

3
On BEST ANSWER

OK. You asked two questions:

  1. i need to push CIID into first described route

You have to push a jms message to jms:switchCIStateQueue so, in your source route (second "big one") it should be like:

<to uri="jms:switchCIStateQueue"/>

whatever is in Exchange headers will be in JMS message headers. Exchange message body will be JMS message body. if you will do it in source route with code as is, there will be JMS header HostID and your first route which gets that JMS message has access to it as ${header.HostID}

Then depends on what your otrsCIApi.getCIBodyByID expects and does your call may look like

a. <to uri="bean:otrsCIApi?method=getCIBodyByID(${header.HostID})"/>

b. But if expected parameter for 'getCIBodyByID' has a different structure/format with something more that CIID you have to build it properly either when you send it to the queue (in "big" route) or after you get a message from queue.

  1. How can i place ${header.HostID} into body

again it depends on what is a structure/format of expected JMS message body

a. just place HostID header value in the body as is:

<when>
     <simple>${header.ZabbixTrigger.getPriority()} > 3</simple>
       <!-- here i set  ${header.HostID} into body -->
       <body>
         <simple>${header.HostID}</simple>
       </body>
        <!-- here i can set  ${header.HostID} into another header if i'd like to  -->
        <setHeader headerName="CIID">
                        <simple>${header.HostID}</simple>
        </setHeader>
        <!-- finally I send message to queue -->
        <to uri="jms:switchCIStateQueue"/> 
</when>

b. Something more than just CIID value - build it as needed (in place of <body> element there could be processor or another bean method call which will do that.

Did I understand your questions properly and is it what you are looking for?