Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revisit mediators after introducing new expression support for performance assessment such as passthrough experience. #3838

Closed
chathuranga-jayanath-99 opened this issue Dec 16, 2024 · 1 comment

Comments

@chathuranga-jayanath-99
Copy link
Contributor

Description

$subject

Version

No response

@Bhashinee
Copy link
Member

Ran a performance test to do a comparison between the new expressions vs the old.

The synapse configs used,

old

<?xml version="1.0" encoding="UTF-8"?>
<api context="/userapiold" name="userAPIOld" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="POST" uri-template="/?storeId={storeId}">
        <inSequence>
            <property name="username" type="STRING" value="admin"/>
            <property name="password" type="STRING" value="admin"/>
            <header name="Authorization" action="set" scope="transport" expression="concat('Basic ', fn:base64Encode(fn:concat($ctx:username, ':', $ctx:password)))"/>
            <log category="INFO">
                <property name="Array size = " expression="json-eval($.products.length())"/>
            </log>
            <property name="array_size" expression="json-eval($.products.length())"/>
            <property name="item_1_cat" expression="json-eval($.products[0].category)"/>
            <filter xpath="number($ctx:array_size) > 5 and $ctx:item_1_cat = 'CategoryA'">
                <then>
                    <log category="INFO">
                        <property name="Do " value="foreach"/>
                    </log>
                    <foreach expression="json-eval($.products)">
                        <sequence>
                            <property name="product_name" type="STRING" expression="json-eval($.name)"/>
                            <property name="price" expression="json-eval($.price)"/>
                            <property name="newPrice" expression="number($ctx:price) * 1.05" scope="default"/>
                            <property name="stock" expression="json-eval($.stock)" scope="default"/>
                            <property name="newStock" expression="number($ctx:stock) - 5" scope="default"/>
                            <property name="supplier_name" expression="json-eval($.supplier.name)" scope="default"/>
                            <property name="supplier_name_up" expression="fn:upper-case($ctx:supplier_name)" scope="default"/>
                            <property name="supplier_contact" expression="json-eval($.supplier.contact)" scope="default"/>
                            <property name="supplier_contact_replaced" xmlns:fn="http://www.w3.org/2005/xpath-functions" expression="fn:replace($ctx:supplier_contact, 'supplier', 'distributer')" scope="default"/>
                            <property name="currentTime" xmlns:fn="http://www.w3.org/2005/xpath-functions" expression="fn:format-dateTime(current-dateTime(), '[Y]-[M]-[D] [H]:[m]')" scope="default"/>
                            <payloadFactory media-type="json" template-type="default">
                                <format>{
                                    "operation": "updateInventory",
                                    "storeDetails": {
                                    "storeId": "$1",
                                    "updatedTime": "$2"
                                    },
                                    "product": {
                                    "id": "$3",
                                    "name": "$4",
                                    "newPrice": "$5",
                                    "newStock": "$6"
                                    },
                                    "supplier": {
                                    "name": "$7",
                                    "contact": "$8"
                                    }
                                    }
                                </format>
                                <args>
                                    <arg expression="get-property('query.param.storeId')" evaluator="xml"/>
                                    <arg expression="$ctx:currentTime"/>
                                    <arg expression="$.id" evaluator="json"/>
                                    <arg expression="fn:upper-case($ctx:product_name)"/>
                                    <arg expression="$ctx:newPrice"/>
                                    <arg expression="$ctx:newStock"/>
                                    <arg expression="$ctx:supplier_name_up"/>
                                    <arg expression="$ctx:supplier_contact_replaced"/>
                                </args>
                            </payloadFactory>
                        </sequence>
                    </foreach>
                </then>
                <else>
                    <property name="product_name" type="STRING" expression="json-eval($.products[0].name)"/>
                    <property name="price" expression="json-eval($.products[0].price)"/>
                    <property name="newPrice" expression="number($ctx:price) * 1.05" scope="default"/>
                    <property name="stock" expression="json-eval($.products[0].stock)" scope="default"/>
                    <property name="newStock" expression="number($ctx:stock) - 5" scope="default"/>
                    <property name="supplier_name" expression="json-eval($.products[0].supplier.name)" scope="default"/>
                    <property name="supplier_name_up" expression="fn:upper-case($ctx:supplier_name)" scope="default"/>
                    <property name="supplier_contact" expression="json-eval($.products[0].supplier.contact)" scope="default"/>
                    <property name="supplier_contact_replaced" xmlns:fn="http://www.w3.org/2005/xpath-functions" expression="fn:replace($ctx:supplier_contact, 'supplier', 'distributer')" scope="default"/>
                    <property name="currentTime" xmlns:fn="http://www.w3.org/2005/xpath-functions" expression="fn:format-dateTime(current-dateTime(), '[Y]-[M]-[D] [H]:[m]')" scope="default"/>
                    <payloadFactory media-type="json" template-type="default">
                        <format>{
                            "operation": "updateInventory",
                            "storeDetails": {
                            "storeId": "$1",
                            "updatedTime": "$2"
                            },
                            "product": {
                            "id": "$3",
                            "name": "$4",
                            "newPrice": "$5",
                            "newStock": "$6"
                            },
                            "supplier": {
                            "name": "$7",
                            "contact": "$8"
                            }
                            }
                        </format>
                        <args>
                            <arg expression="get-property('query.param.storeId')" evaluator="xml"/>
                            <arg expression="$ctx:currentTime"/>
                            <arg expression="$.products[0].id" evaluator="json"/>
                            <arg expression="fn:upper-case($ctx:product_name)"/>
                            <arg expression="$ctx:newPrice"/>
                            <arg expression="$ctx:newStock"/>
                            <arg expression="$ctx:supplier_name_up"/>
                            <arg expression="$ctx:supplier_contact_replaced"/>
                        </args>
                    </payloadFactory>
                </else>
            </filter>
            <respond/>
        </inSequence>
        <faultSequence>
        </faultSequence>
    </resource>
</api>

New expressions

<?xml version="1.0" encoding="UTF-8"?>
<api context="/userapi" name="userAPI" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="POST" uri-template="/?storeId={storeId}">
        <inSequence>
            <variable name="username" type="STRING" value="admin"/>
            <variable name="password" type="STRING" value="admin"/>
            <header name="Authorization" action="set" scope="transport" expression="${'Basic ' + base64encode(vars.username + ':' + vars.password)}"/>
            <log category="INFO">
                <message>Array size = ${length(payload.products)}</message>
            </log>
            <filter xpath="${(length(payload.products) &gt; 5) and (payload.products[0].category == 'CategoryA')}">
                <then>
                    <log category="INFO">
                        <message>Do foreach</message>
                    </log>
                    <foreach collection="${payload.products}" parallel-execution="false">
                        <sequence>
                            <payloadFactory media-type="json" template-type="default">
                                <format>{
                                    "operation": "updateInventory",
                                    "storeDetails": {
                                    "storeId": "${params.queryParams.storeId}",
                                    "updatedTime": "${formatDateTime(now(), 'yyyy-MM-dd HH:mm')}"
                                    },
                                    "product": {
                                    "id": "${payload.id}",
                                    "name": "${toUpper(payload.name)}",
                                    "newPrice": "${payload.price * 1.05}",
                                    "newStock": "${payload.stock - 5}"
                                    },
                                    "supplier": {
                                    "name": "${toUpper(payload.supplier.name)}",
                                    "contact": "${replace(payload.supplier.contact, 'supplier', 'distributer')}"
                                    }
                                    }</format>
                            </payloadFactory>
                        </sequence>
                    </foreach>
                </then>
                <else>
                    <payloadFactory media-type="json" template-type="default">
                        <format>{
                            "operation": "updateInventory",
                            "storeDetails": {
                            "storeId": "${params.queryParams.storeId}",
                            "updatedTime": "${formatDateTime(now(), 'yyyy-MM-dd HH:mm')}"
                            },
                            "product": {
                            "id": "${payload.products[0].id}",
                            "name": "${toUpper(payload.products[0].name)}",
                            "newPrice": "${payload.products[0].price * 1.05}",
                            "newStock": "${payload.products[0].stock - 5}"
                            },
                            "supplier": {
                            "name": "${toUpper(payload.products[0].supplier.name)}",
                            "contact": "${replace(payload.products[0].supplier.contact, 'supplier', 'distributer')}"
                            }
                            }</format>
                    </payloadFactory>
                </else>
            </filter>
            <respond/>
        </inSequence>
        <faultSequence>
        </faultSequence>
    </resource>
</api>

Ran the above two scenarios and did a comparison test. Found out an issue with concurrency (#3921) and fixed it.

The results can be found here,
https://docs.google.com/spreadsheets/d/1PzTAgSTk-AmCV4Rwwy29-ZAZ3VWAe7i6WQl0dkR7-G4/edit?usp=sharing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants