lunes, 11 de enero de 2021

WSO2 Mediator Tutorial: Como usar la cache

Hoy vamos a volver a post sobre WSO2 y sus mediadores. Veremos como funciona el Cache Mediator, el cual puede ser muy util aunque no es muy conocido. 

La idea es sencilla, a través de este mediador, WSO2 cacheará la respuesta de un backend determinado en base a la petición que vayamos a hacer. ¿Como lo hace? Obtiene un valor hash asociado al mensaje almacenado en el flujo. Si existe ejecutará la secuencia configurada en el parámetro onCacheHit, el cual es opcional, obtiene la respuesta almacenada en el cache y envía la respuesta. Si no existe, se realiza la llamada al backend y se almacena la respuesta para su posible uso futuro. 

Vamos a ver un ejemplo sencillo de su uso. Vamos a crear un recurso de una API que llame a un backend, hecho con Wiremock, y antes del cual configuraremos el Cache Mediator para su uso. En el mediador configuraremos varias cosas aparte de las que vienen por defecto. Como son que la cache se mantenga durante 20 segundos, que solo cachee las llamadas de métodos POST y que como mucho almacene 10 elementos en la cache. 

<resource methods="POST" url-mapping="/sample1">
    <inSequence>
        <property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
        <cache collector="false" timeout="20">
            <onCacheHit>
                <log level="custom">
                    <property name="testing" value="Cache Hit"/>
                </log>
                <respond/>
            </onCacheHit>
            <protocol type="HTTP">
                <methods>POST</methods>
                <headersToExcludeInHash/>
                <responseCodes>.*</responseCodes>
                <enableCacheControl>false</enableCacheControl>
                <includeAgeHeader>false</includeAgeHeader>
                <hashGenerator>org.wso2.carbon.mediator.cache.digest.DOMHASHGenerator</hashGenerator>
            </protocol>
            <implementation maxSize="10"/>
        </cache>
        <send>
            <endpoint>
                <http method="POST" uri-template="http://localhost:57001/sample1"/>
            </endpoint>
        </send>
    </inSequence>
    <outSequence>
        <cache collector="true"/>
        <respond/>
    </outSequence>
</resource>

A continuación realizaremos una invocación a la API y la primera vez veremos como el Wiremock es invocado, y cuando volvemos a llamar una segunda vez no. 

curl --location --request POST 'http://localhost:8280/cache/sample1' \
--header 'Content-Type: application/json' \
--data-raw '{}'

Como veis en el ejemplo, el uso de cache mediator se divide en dos partes. Por un lado la configuración de la propia cache antes de llamar al backend y por otro lado una nueva invocación a la misma pero para indicar que nos devuelva el valor asociado a la misma si es que hay. En esta segunda invocación no es necesario configurar nada, solo indicar a true el parámetro collector

El cache mediator también puede ser utilizado para llamadas al backend a través del call mediator. En el caso de que decidamos que queremos usarlo así, tendremos que indicar a Synapse despues de la llamada al backend, que nos encontramos tratando con un mensaje de respuesta. Esto lo haremos a través de la propiedad RESPONSE. Sin esa propiedad, en este ejemplo, el cache mediator no funcionará. 

<resource methods="POST" url-mapping="/sample2">
    <inSequence>
        <property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
        <cache collector="false" timeout="20">
            <protocol type="HTTP">
                <methods>POST</methods>
                <headersToExcludeInHash/>
                <responseCodes>.*</responseCodes>
                <enableCacheControl>false</enableCacheControl>
                <includeAgeHeader>false</includeAgeHeader>
                <hashGenerator>org.wso2.carbon.mediator.cache.digest.DOMHASHGenerator</hashGenerator>
            </protocol>
            <implementation maxSize="10"/>
        </cache>
        <call>
            <endpoint>
                <http method="POST" uri-template="http://localhost:57001/sample1"/>
            </endpoint>
        </call>
        <property name="RESPONSE" value="true" scope="default" type="STRING"/>
        <cache collector="true"/>
        <respond/>
    </inSequence>
    <outSequence />
</resource>

Como veis es muy sencillo de usar y no requiere de apenas configuración. Por ponerle alguna pega, podriamos decir que no cuenta de un método que permita borrar la cache para un determinado mensaje, por lo que en caso de que la respuesta no valiese ya, solo podría ser cambiada una vez que se dicha cache se caducase. 

No hay comentarios:

Publicar un comentario