Layer7 API Management

 View Only
  • 1.  Context variable String keyword expansion

    Posted May 11, 2022 04:11 AM
    Edited by Tony Svedlund May 11, 2022 04:12 AM
    Hi Community!

    What is the best way to do the following in a service policy in policy manager (using L7 API GW 10)?

    I have a context variable string that contains a keyword that I want to replace with it's value from another variable, e.g:

    • Context variable 1: name: "appname", type: String, value: "app1"
    • Context variable 2: name: "url", type: String, value: "http://${appname}.mysite.com"
    • Wanted result: Context variable 3. name: "appUrl", type: String, value: "http://app1.mysite.com"

      Script assertion handling it in javascript code, or..?

      BR,
      Tony


    • 2.  RE: Context variable String keyword expansion

      Posted May 11, 2022 11:56 AM
      Tony,

      You should already see as the value "http://app1.mysite.com" for url context variable. Now you want to reassign the value of url variable to appUrl, you can do something like this.

      name: "appUrl", type: String, value: ${url}

      Looks like you got it.



    • 3.  RE: Context variable String keyword expansion

      Posted May 12, 2022 03:42 AM
      Hi Aniket and thanks for you reply!

      No, the url variable (in my case a Cluster Wide Property) is literally the string "http://${appname}.mysite.com", so the value app1 is set separately in the appname variable.

      So, some regex substitution or similar need to be applied on the url variable to expand the value of appname into the resulting string.



    • 4.  RE: Context variable String keyword expansion
      Best Answer

      Broadcom Employee
      Posted May 12, 2022 01:25 PM
      Correct, you can use a regex in this use case. Since $, { and } have **** meaning to regex they must be escaped. This should do the job:

      <?xml version="1.0" encoding="UTF-8"?>
      <wsp:Policy xmlns:L7p="http://www.layer7tech.com/ws/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
          <wsp:All wsp:Usage="Required">
              <L7p:Regex>
                  <L7p:AutoTarget booleanValue="false"/>
                  <L7p:OtherTargetMessageVariable stringValue="url"/>
                  <L7p:Regex stringValue="\$\{appname\}"/>
                  <L7p:Replace booleanValue="true"/>
                  <L7p:Replacement stringValue="${appname}"/>
                  <L7p:Target target="OTHER"/>
              </L7p:Regex>
          </wsp:All>
      </wsp:Policy>​


      Here is a whole service policy to illustrate the case. I think this covers what you are asking:

      <?xml version="1.0" encoding="UTF-8"?>
      <wsp:Policy xmlns:L7p="http://www.layer7tech.com/ws/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
          <wsp:All wsp:Usage="Required">
              <L7p:CommentAssertion>
                  <L7p:Comment stringValue="**************************************************************************************************************"/>
              </L7p:CommentAssertion>
              <L7p:CommentAssertion>
                  <L7p:Comment stringValue="* Investigate regex to substitute a context variable syntax with a value from another context variable"/>
              </L7p:CommentAssertion>
              <L7p:CommentAssertion>
                  <L7p:Comment stringValue="* "/>
              </L7p:CommentAssertion>
              <L7p:CommentAssertion>
                  <L7p:Comment stringValue="**************************************************************************************************************"/>
              </L7p:CommentAssertion>
              <L7p:AuditAssertion/>
              <L7p:SetVariable>
                  <L7p:Base64Expression stringValue="YXBwMQ=="/>
                  <L7p:VariableToSet stringValue="appname"/>
              </L7p:SetVariable>
              <L7p:SetVariable>
                  <L7p:AssertionComment assertionComment="included">
                      <L7p:Properties mapValue="included">
                          <L7p:entry>
                              <L7p:key stringValue="RIGHT.COMMENT"/>
                              <L7p:value stringValue="// Pull ${url} from cluster-wider property"/>
                          </L7p:entry>
                      </L7p:Properties>
                  </L7p:AssertionComment>
                  <L7p:Base64Expression stringValue="JHtnYXRld2F5LnVybH0="/>
                  <L7p:Enabled booleanValue="false"/>
                  <L7p:VariableToSet stringValue="url"/>
              </L7p:SetVariable>
              <L7p:SetVariable>
                  <L7p:AssertionComment assertionComment="included">
                      <L7p:Properties mapValue="included">
                          <L7p:entry>
                              <L7p:key stringValue="RIGHT.COMMENT"/>
                              <L7p:value stringValue="// Need this to build the string in ${url}"/>
                          </L7p:entry>
                      </L7p:Properties>
                  </L7p:AssertionComment>
                  <L7p:Base64Expression stringValue="JA=="/>
                  <L7p:VariableToSet stringValue="dollar"/>
              </L7p:SetVariable>
              <L7p:SetVariable>
                  <L7p:AssertionComment assertionComment="included">
                      <L7p:Properties mapValue="included">
                          <L7p:entry>
                              <L7p:key stringValue="RIGHT.COMMENT"/>
                              <L7p:value stringValue="// Build ${url} in policy"/>
                          </L7p:entry>
                      </L7p:Properties>
                  </L7p:AssertionComment>
                  <L7p:Base64Expression stringValue="aHR0cDovLyR7ZG9sbGFyfXthcHBuYW1lfS5teXNpdGUuY29t"/>
                  <L7p:VariableToSet stringValue="url"/>
              </L7p:SetVariable>
              <L7p:Regex>
                  <L7p:AutoTarget booleanValue="false"/>
                  <L7p:OtherTargetMessageVariable stringValue="url"/>
                  <L7p:Regex stringValue="\$\{appname\}"/>
                  <L7p:Replace booleanValue="true"/>
                  <L7p:Replacement stringValue="${appname}"/>
                  <L7p:Target target="OTHER"/>
              </L7p:Regex>
              <L7p:HardcodedResponse>
                  <L7p:Base64ResponseBody stringValue="YXBwbmFtZSA9ICR7YXBwbmFtZX0KCnVybCA9ICR7dXJsfQ=="/>
                  <L7p:ResponseContentType stringValue="text/plain; charset=UTF-8"/>
              </L7p:HardcodedResponse>
          </wsp:All>
      </wsp:Policy>

      Cheers!

      JayMac

      ------------------------------
      Jay MacDonald - Adoption Architect - Broadcom API Management (Layer 7)
      ------------------------------



    • 5.  RE: Context variable String keyword expansion

      Posted May 13, 2022 03:18 AM
      Hi Jay,

      Yes, this does the trick neatly.

      Would be a nice feature to add as a built-in assertion.
      I find it very handy to use sting patterns/keyword expansion for CWPs when dealing different target environments and such.
      Maybe in version 11? ;-)

      Many thanks!
      /Tony



    • 6.  RE: Context variable String keyword expansion

      Broadcom Employee
      Posted May 13, 2022 08:31 AM
      Hello Tony,


      It sound like what your trying to accomplish could be better handled in policy instead of this variable substitution from a cluster properly. Building dynamic URLs from a combination of cluster properties and local policy variables is a common practice. 

      would this accomplish the same thing with out requiring using a regex?

      • Cluster property Domain = mysite.com 
      • policy variable appname = app1
      • Context variable 2: name: "appurl", type: String, value: "http://${appname}.${domain}"





    • 7.  RE: Context variable String keyword expansion

      Posted May 13, 2022 08:56 AM
      Hi Barry,

      Yes, that is how we usually do it for some straightforward use cases.
      There are cases involving a lot of different apps, domains, paths, environments, contexts etc. where we need to avoid having too many policy implementations handling a lot of CWPs or policy variables that really clutters the policy logic.
      So I was looking for ways of simplifying that. In this case by using variables within variables, which is quite common concept for other developers and readable by operations etc.

      Thanks for your thoughts & feedback!
      /Tony