Tuesday 12 July 2016

Invalidate Result Cache in OSB 12c

Starting from Oracle Service Bus 11g, provides built-in cache functionality that utilise Oracle Coherence. One of the common use case of built-in cache is result caching of OSB business service response that do not change often, you can configure those business services to cache results.  

Each entry in OSB built-in result cache uniquely identified by a cache key. Cache key is made up of following component;


  • Cache Token - The token configured in Business Service (e.g - Customer ID)
  • ServiceRef - Service Type (i.e - BusinessService) + Fully qualified path name of the service (e.g - <OSBProjectName>/<Business>/<BusinessServiceName>)
  • Operation - Operation nae of the business service.
Service Bus with Coherence can invalidate an individual cached result, all cached results for a business service, or the entire result cache. Built-in result cache invalidation is based on one of following events.
  • Cache TTL has expired
  • Disable result caching on a single business service.
  • Update, rename, or delete a business service.
  • Globally disable result caching
Recently, I had a requirement to invalidate result cache entry in  OSB pipeline. Unfortunately OSB 12c doesn't provide any functionality to invalidate result cache entry in OSB pipeline. I developed following custom XPath function to invalidate result cache entry. By calling this XPath function in OSB Request pipeline will flush the already cached entry and invoke external service. The XPath function tested successfully in OSB 12.2.1. 

Following Weblogic JAR files required for compilation
<FMW_HOME>/osb/lib/modules/oracle.servicebus.resources.service.jar
<FMW_HOME>/osb/lib/modules/oracle.servicebus.configfwk.jar

    /**
     * Method for invalidate single OSB result cache entry.
     * @param serviceType - Type of the server (BusinessService or ProxyService)
     * @param servicePath - Fully qualified path name of the service
     * @param operationName - Operation nae of the business service.
     * @param cacheTokenID - The token configured in Business Service (e.g - Customer ID)
     * @return true if succesfully invalidate the cache entry, otherwise false
     * @throws XPathFunctionException
     */
    public static Boolean invalidateCacheEntry(final String serviceType, final String servicePath,
                                               final String operationName,
                                               final String cacheTokenID) throws XPathFunctionException {
        Boolean invalidateResult = false;
        // Costructing Ref for business or proxy service
        Ref serviceRef = constructRef(serviceType, servicePath);
        ResultCacheKey key = new ResultCacheKey(serviceRef, operationName, cacheTokenID);

        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.log(Level.FINE, "Checking result cache for " + key);
        }

        try {
            // Check cache having the search key
            Result cachedValue = ResultCacheManager.get().getResultCache().get(key);
            if (cachedValue != null) {
                // Remove the cached value
                ResultCacheManager.get().getResultCache().remove(key);
                invalidateResult = true;
            }

        } catch (ResultCacheException e) {
            throw new XPathFunctionException("Error invalidating result cache entry " + key + ", " + e);
        }
        return invalidateResult;
    }

    /**
     * Construct OSB service reference.
     *
     * @param refType - Type of the reference type
     * @param serviceuri - Service URI
     * @return
     */
    private static Ref constructRef(String refType, String serviceuri) {
        Ref ref = null;
        String[] uriData = serviceuri.split("/");
        ref = new Ref(refType, uriData);
        return ref;
    }