Forum Discussion

RiverFish's avatar
RiverFish
Icon for Altostratus rankAltostratus
Mar 06, 2013

Search xml for string and send to specified pool

I'm currently on version 10.2.2 but will be upgrading to 11.3 very soon. Attached is an example of what the request will contain. The "To Qualifier="Q"" section is our point of interest here. Basically what I need is to send the request to a certain pool based on what that number is. For example, if the number is 1231231 send to pool 1231231. If the number is 4564561 send to pool 4564561, and so on. I was thinking maybe the tcp::payload query command could help us here?

 

Thanks in advance!

 

2 Replies

  • You could certainly do this is layer 4 (TCP), but there are a few other really cool options:

    HTTP payload parsing

    Because XML rides on HTTP, you can use HTTP commands to capture the payload and make routing decisions. Here's an iRule to get you started:

    when CLIENT_ACCEPTED {

    capture the default pool (what is configured for the virtual server)

    set default_pool [LB::server pool]

    }

    when HTTP_REQUEST {

    if { [HTTP::header Content-Type] equals "text/xml" } {

    HTTP::collect [HTTP::header Content-Length]

    }

    }

    when HTTP_REQUEST_DATA {

    set pool_tmp [findstr [HTTP::payload] "" 18 "<"]

    set xml_pool "pool-$pool_tmp"

    if { [catch { pool $xml_pool }] } {

    log local0. "($xml_pool) pool doesn't exist - using default pool"

    pool $default_pool

    }

    }

    This iRule assumes that every request is an XML POST, so you'll have to work in a way to set persistence if you don't want it to use the default pool in non-POST requests.

    XML Content Based Routing

    XMLCBR is designed specifically for this situation, to route based on incoming XML request payload information. Review the following documents to get acquainted with XMLCBR:

    Manual Chapter: Configuring XML Content-Based Routing

    https://support.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/ltm_implementation/sol_xml_cbr.html?sr=102037931060876

    iRules WIKI: XML_CONTENT_BASED_ROUTING

    https://devcentral.f5.com/wiki/iRules.XML_CONTENT_BASED_ROUTING.ashx

    Once you have the XML profile properly configured to capture the numeric value in the "To" node of your XML POST data, use something like the following iRule to make the pool assignments.

    
    when CLIENT_ACCEPTED {
             capture the default pool (what is configured for the virtual server)
    set default_pool [LB::server pool]
    }
    when HTTP_REQUEST {
             initial pool selection
    pool $default_pool
    }
    when XML_CONTENT_BASED_ROUTING {
             If there is a match, the pool value will be overwritten by the returned XPath query value
    set cbr_pool "pool-$XML_values(0)"
             In this example, the pool is called "pool-" where  is the value returned from the XPath query
             Make sure the specified pool actually exists using this catch statement. If it doesn't, use the default pool.
    if { [catch { pool $cbr_pool }] } {
    log local0. "($cbr_pool) pool doesn't exist - using default pool"
    pool $default_pool
    }
    }
    

    As in the HTTP payload example, this iRule assumes that all requests are XML POST requests, so you'll have to work in a way to set persistence if you don't want it to use the default pool in non-POST requests.
  • Very nice. I will give this a shot and post results. Thanks Kevin.