Search code examples
wso2wso2-api-managerurl-parametersapi-managerwso2-esb

Dynamically replace the PATH value of an Endpoint (WSO2 - API Manager)


I have created an API in the WSO2 API Manager (1.10.0) with the next info:

POST:

/regularPath/* 

API URL:

http://<ip-address-1>/t/tenant.com/api/1.0.0/

HTTP-Endpoint:

http://<ip-address-2>:8181/{uri.var.newRestVar}

The issue is that the HTTP Endpoint has more than one path, e.g.:

http://<ip-address-2>:8181/mainService/cityInfo
http://<ip-address-2>:8181/country/cityInfo
http://<ip-address-2>:8181/country/dataKey/amountOfUsers
http://<ip-address-2>:8181/main/city/data/users

And I want that the resulting API URLs look like this:

http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/mainService/cityInfo
http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/country/cityInfo
http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/country/dataKey/amountOfUsers
http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/main/city/data/users

My initial approach was to use the REST_URL_PREFIX variable in order to capture the path after the 1.0.0 part of the API URL (e.g.: regularPath/country/dataKey/amountOfUsers) and then, assign that value to the uri.var.newRestVar variable.

Next, is the modified Service Bus Configuration of the API Manager (Carbon) I've created in the API Manager:

...    
<inSequence>
    <filter regex="PRODUCTION" source="$ctx:AM_KEY_TYPE">
        <then>
            <property expression="get-property('SYSTEM_TIME')" name="api.ut.backendRequestTime"/>

            <log>
                <property expression="$trp:To" name="ToURL"/>
            </log>

            <property expression="$axis2:REST_URL_POSTFIX" name="restURL" scope="default" type="STRING"/>

            <log>
                <property
                    expression="get-property('restURL')" name="logRestURL"/>
            </log>

            <script description="JS" language="js">
                <![CDATA[
                    var unmodifiedRestPostfix = new String(mc.getProperty("restURL"));  
                    print("value = " + unmodifiedRestPostfix);
                    unmodifiedRestPostfix = unmodifiedRestPostfix.replace("/regularPath/", "");      
                    mc.setProperty("uri.var.newRestVar", unmodifiedRestPostfix);
                ]]>
            </script>
            <log>
                 <property expression="get-property('uri.var.newRestVar')" name="URI_VAR_NEWRESTVAR"/>
            </log>                                   
            <send>
                <endpoint name="admin-AT-tenant.com--API-Main_APIproductionEndpoint_0">
                    <http uri-template="http://<ip-address-2>:8181/{uri.var.newRestVar}"/>
                </endpoint>
            </send>
...

But it does not work. I checked the logs but everything seems to be OK:

TID: [35] [] [2016-04-11 16:47:01,955] @bank.com [35] [AM] INFO {org.apache.synapse.mediators.builtin.LogMediator} -  To: local://axis2services/api/1.0.0/regularPath/mainService/cityInfo, MessageID: urn:uuid:091613ce-9fd3-4094-8638-5b112
a4214ad, Direction: request, logRestURL = /regularPath/mainService/cityInfo {org.apache.synapse.mediators.builtin.LogMediator}
a4214ad, Direction: request, URI_VAR_NEWRESTVAR = /regularPath/mainService/cityInfo {org.apache.synapse.mediators.builtin.LogMediator}

What configuration should I change in order to successfully access the HTTP-Endpoint using the paths of the API I've mentioned?


Solution

  • You can do the same thing without modifying the synapse configuration. Following are the steps. Hope it would be a solution for you

    Create the api as following

    API context : api/{version}/regularPath
    

    Note: you can define the version in the context as a template in AM 1.10. once you define the version, above context will get the version

    resources: 
    POST   mainService/cityInfo
    POST   country/cityInfo
    POST   country/dataKey/amountOfUsers
    POST   main/city/data/users
    
    HTTP Endpoint
    http://<ip-address-2>:8181
    

    After that you would be able to call a backend . No need to add custom modifications to synapse config

     http://<ip-address-2>:8181/country/dataKey/amountOfUsers
    

    with

    http://<ip-address-1>/t/tenant.com/api/1.0.0/regularPath/country/dataKey/amountOfUsers
    

    Additional information

    If something went wrong, you can enable the wire logs and check what kind of request coming and going out in the gateway. see http://mytecheye.blogspot.com/2013/09/wso2-esb-all-about-wire-logs.html on how to enable wirelogs and debug using it.