Forum Discussion

Chris_G_Davis_1's avatar
Chris_G_Davis_1
Icon for Nimbostratus rankNimbostratus
Dec 18, 2008

JSESSIONID Persistence

I'm trying to persist off a JSESSIONID cookie generated by the WebLogic Application Server however the follow iRule isn't working.

 

 

-------------

 

 

when HTTP_REQUEST {

 

if { [HTTP::cookie exists "JSessionID"] } {

 

persist use [HTTP::cookie "JSessionID"]

 

 

-------------

 

 

Any help would be greatly appreciated.

 

 

Thanks,

 

 

Christopher G Davis

 

Sr. Network Engineer

 

SITA Atlanta Data Center

10 Replies

  • James_Quinby_46's avatar
    James_Quinby_46
    Historic F5 Account
    Chris -

     

     

    Take a look here:

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/Weblogic_JSessionID_Persistence.html

     

    Click here
  • See below for name references.

     

     

    The JSession persistence appears not to work unless I add Source Address Affinity as a fallback. I check the persistence table before adding and no entry was made for "cce-jsession-http". Furthermore, I checked the pool members and one attempt to the url is spreading traffic across all pool members. After adding cce-jsession-addre-http I see an entry in the persistence table and one attempt to the url is being sent to one member in the pool.

     

     

    Is this correct behavior?

     

     

    Below I've included the ip header with the JsessionID and the configuration I’m using.

     

     

    Any help would be greatly appreciated.

     

     

    --------

     

     

    GET /cce-presentation-kiosk-tg/branding/tg/client/Production/css/pleaseWait.css;jsessionid=zytPJpxV0TnpssqZZRLBgsVMLhGS6M2ZNMZ622yCNvpv0gkpTwzn!956498630 HTTP/1.1

     

     

    Accept: */*

     

     

    Referer: http://selfservice-uat.sita.aero/cce-presentation-kiosk-tg/entryUpdate.do

     

     

    Accept-Language: en-us

     

     

    UA-CPU: x86

     

     

    Accept-Encoding: gzip, deflate

     

     

    User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; .NET CLR 2.0.50727)

     

     

    Host: selfservice-uat.sita.aero

     

     

    Connection: Keep-Alive

     

     

    Cookie: JSESSIONID=zytPJpxV0TnpssqZZRLBgsVMLhGS6M2ZNMZ622yCNvpv0gkpTwzn!956498630

     

     

    ---------

     

     

    virtual VS-CCE_QA_http {

     

    fallback persist cce-jsession-addre-http

     

    destination 10.9.16.34:http

     

    ip protocol tcp

     

    rules cce-direct-http

     

    profiles

     

    http

     

    oneconnect

     

    tcp

     

    persist cce-jsession-http

     

    }

     

     

    profile persist cce-jsession-http {

     

    defaults from universal

     

    mode universal

     

    timeout 180

     

    rule cce-presist-http

     

    }

     

     

    rule cce-presist-http {

     

    when HTTP_REQUEST {

     

    if { [HTTP::cookie exists "JSessionID"] } {

     

    persist uie [HTTP::cookie "JSessionID"]

     

    } else {

     

    set jsess [findstr [HTTP::uri] "JSessionID" 11 ";"]

     

    if { $jsess != "" } {

     

    persist uie $jsess

     

    }

     

    }

     

    }

     

    when HTTP_RESPONSE {

     

    if { [HTTP::cookie exists "JSessionID"] } {

     

    persist add uie [HTTP::cookie "JSessionID"]

     

    }

     

    }

     

    }

     

     

     

    profile persist cce-jsession-addre-http {

     

    defaults from source_addr

     

    mode source addr

     

    timeout 30

     

    }

     

     

     

    rule cce-direct-http {

     

    when HTTP_REQUEST {

     

    if { [HTTP::uri] starts_with "/cce-presentation-kiosk-a3/"} {

     

    pool CCE_A3_KCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-kiosk-fv/"} {

     

    pool CCE_FV_KCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-web-fv/"} {

     

    pool CCE_FV_WCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-kiosk-ma/"} {

     

    pool CCE_MA_KCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-web-ma/"} {

     

    pool CCE_MA_WCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-kiosk-mh/"} {

     

    pool CCE_MH_KCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-web-mh/"} {

     

    pool CCE_MH_WCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-kiosk-lg/"} {

     

    pool CCE_LG_KCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-web-lg/"} {

     

    pool CCE_LG_WCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-kiosk-lx/"} {

     

    pool CCE_LX_KCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-web-lx/"} {

     

    pool CCE_LX_WCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-kiosk-sp/"} {

     

    pool CCE_SP_KCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-web-sp/"} {

     

    pool CCE_SP_WCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-kiosk-tg/"} {

     

    pool CCE_TG_KCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-kiosk-un/"} {

     

    pool CCE_UN_KCI

     

     

    } elseif { [HTTP::uri] starts_with "/cce-presentation-web-un/"} {

     

    pool CCE_UN_WCI

     

     

    } else {

     

    log local0. "URI doesn't match; rejecting connection http://[HTTP::host][HTTP::uri]"

     

    reject

     

    }

     

    }

     

    }

     

     

    --------

     

     

    Thanks,

     

     

    Christopher G Davis

     

    Sr. Network Engineer

     

    SITA Atlanta Data Center
  • Hi Chris,

    There are a few possible issues with the Codeshare example:

    1. The cookie name for HTTP::cookie is case sensitive. So [HTTP::cookie JSessionID] won't match a cookie named jsessionid or JSESSIONID. I believe that the jsessionid name is always in lower case, whether set in the path or a cookie name.

    2. findstr is also case sensitive.

    3. The format for the jsessionid in the URI is /path/to/object.ext;jsessionid=jsessionid_value or with a query string /path/to/object.ext;jsessionid=jsessionid_value?param=param_value. So using findstr with a terminator of ; won't work as expected. If you were checking the URI with a terminator, it should be the ? which starts the query string. Considering the jsessionid, if present, will always be at the end of the path, you can avoid dealing with a terminator by using HTTP::path insted of HTTP::uri.

    4. The findstr command needs to account for the = in jsessionid=12345...., so it should be [findstr [HTTP::path] "jsessionid=" 11]

    Can you try this example which addresses the above points? If you run into problems, please check the /var/log/ltm log file for debug output. Once you're done testing, youc can comment out the log statements. If it does work, please reply so we can update the Codeshare example.

    Thanks,

    Aaron

      
      when HTTP_REQUEST {  
        
          Log details for the request  
         log local0. "[IP::client_addr]:[TCP::client_port]: Request to [HTTP::uri] with cookie: [HTTP::cookie value jsessionid]"  
        
          Check if there is a jsessionid cookie  
         if { [HTTP::cookie exists "jsessionid"] } {  
        
             Persist off of the cookie value  
            persist uie [HTTP::cookie "jsessionid"]  
        
             Log that we're using the cookie value for persistence and the persistence key if it exists.  
            log local0. "[IP::client_addr]:[TCP::client_port]: Used persistence record from cookie: [persist lookup uie [HTTP::cookie "jsessionid"]]"  
        
         } else {  
        
             Parse the jsessionid from the path (URI minus the query string)  
            set jsess [findstr [HTTP::path] "jsessionid=" 11]  
        
             Use the jsessionid from the path for persisting  
            if { $jsess != "" } {  
        
               persist uie $jsess  
        
                Log that we're using the path jessionid for persistence and the persistence key if it exists.  
               log local0. "[IP::client_addr]:[TCP::client_port]: Used persistence record from path: [persist lookup uie $jsess]"  
            }  
         }  
      }  
      when HTTP_RESPONSE {  
        
          Check if there is a jsessionid cookie in the response  
         if { [HTTP::cookie exists "jsessionid"] } {  
        
             Persist off of the cookie value  
            persist add uie [HTTP::cookie "jsessionid"]  
        
            log local0. "[IP::client_addr]:[TCP::client_port]: Added persistence record from cookie: [persist lookup uie [HTTP::cookie "jsessionid"]]"  
         }  
      }  
      

  • That appears to have fixed it.

     

     

    I now see two entries in the persistence table one with the jsessionid as the "Persistence Value" and a second with "/" as the "Persistence Value" for the Source Address Affinity profile. However without the "Source Address Affinity" fallback traffic is still spread across all pool members.

     

     

    With the fallback in place; when I test a second time before the two persistence entries timeout I'm sent to the same node, hence, my belief this is working.

     

     

    Thanks,

     

     

    --cd

     

  • Thanks for the confirmation. I updated the Codeshare example. Also, you can set the persistence timeout from the iRule and avoid the extra configuration step of adding a universal persistence profile.

     

     

    Aaron
  • Actually, it looks like the cookie name is in all caps and the string in the URIs is all lower case. I've updated the Codeshare example with this. If you see differently in your installation, can you let me know?

     

     

    Thanks,

     

    Aaron
  • Hopefully it not to late to revisit this,

     

     

    Here is the rule that in place now.

     

     

    ------------------

     

     

    when HTTP_REQUEST {

     

     

    Log details for the request

     

    log local0. "[IP::client_addr]:[TCP::client_port]: Request to [HTTP::uri] with cookie: [HTTP::cookie value JSESSIONID]"

     

     

    Check if there is a jsessionid cookie

     

    if { [HTTP::cookie exists "JSESSIONID"] } {

     

     

    Persist off of the cookie value

     

    persist uie [HTTP::cookie "JSESSIONID"]

     

     

    Log that we're using the cookie value for persistence and the persistence key if it exists.

     

    log local0. "[IP::client_addr]:[TCP::client_port]: Used persistence record from cookie: [persist lookup uie [HTTP::cookie JSESSIONID"]]"

     

     

    } else {

     

     

    Parse the jsessionid from the path (URI minus the query string)

     

    set jsess [findstr [HTTP::path] "JSESSIONID" 11]

     

     

    Use the jsessionid from the path for persisting

     

    if { $jsess != "" } {

     

     

    persist uie $jsess

     

     

    Log that we're using the path jessionid for persistence and the persistence key if it exists.

     

    log local0. "[IP::client_addr]:[TCP::client_port]: Used persistence record from path: [persist lookup uie $jsess]"

     

    }

     

    }

     

    }

     

    when HTTP_RESPONSE {

     

     

    Check if there is a jsessionid cookie in the response

     

    if { [HTTP::cookie exists "JSESSIONID"] } {

     

     

    Persist off of the cookie value

     

    persist add uie [HTTP::cookie "JSESSIONID"]

     

     

    log local0. "[IP::client_addr]:[TCP::client_port]: Added persistence record from cookie: [persist lookup uie [HTTP::cookie "JSESSIONID"]]"

     

    }

     

    }

     

     

    But I'm receiving errors, Any thoughs

     

     

    ------------------

     

     

    Jan 30 16:52:02 tmm tmm[1616]: Rule cce-jsession-persist : 57.250.242.249:49297: Request to /cce-presentation-kiosk-tg/entryUpdate.do with cookie: fn2XJC1TL2sgBsz3XWnbrDMp49Dwd0nyhdQnSgn16hHqyDPJ0Lyk!779042597

     

    Jan 30 16:52:02 tmm tmm[1616]: 01220001:3: TCL error: cce-jsession-persist - Prerequisite operation not in progress (line 1) invoked from within "persist lookup uie [HTTP::cookie "JSESSIONID"] "

     

    Jan 30 16:53:49 tmm tmm[1616]: Rule cce-jsession-persist : 57.250.242.249:53325: Request to /cce-presentation-kiosk-tg/entryUpdate.do with cookie: fn2XJC1TL2sgBsz3XWnbrDMp49Dwd0nyhdQnSgn16hHqyDPJ0Lyk!779042597

     

    Jan 30 16:53:49 tmm tmm[1616]: 01220001:3: TCL error: cce-jsession-persist - Prerequisite operation not in progress (line 8) invoked from within "persist lookup uie [HTTP::cookie "JSESSIONID"] "

     

    ------------
  • Hi Chris,

     

     

    I'm not sure why you'd be seeing this error. Typically it's seen when there isn't a default pool on the VIP. However, I assume you already have a pool on the VIP as it's not being specified in the iRule. Is this the case? Do you have any other iRules added to the VIP? If so, can you post an anonymized copy?

     

     

    If you do have a default pool and no other iRules, you might try opening a case with F5 Support to ask them to help troubleshoot the issue. If you find anything via this route, could you reply back here?

     

     

    Thanks,

     

    Aaron
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    FWIW, there actually doesn't seem to be a default pool defined in the originally posted VS config above...