CacheAgent.java 16.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.scene7.is.cache.CacheServerEntry
 *  com.scene7.is.cache.clustering.CacheService
 *  com.scene7.is.cacheserver.shared.CacheServerAccess
 *  com.scene7.is.cacheserver.shared.CacheServerAccess$PutResult
 *  com.scene7.is.cacheserver.shared.CacheServerCacheEntry
 *  com.scene7.is.provider.Response
 *  com.scene7.is.provider.ResponseData
 *  com.scene7.is.sleng.CacheAction
 *  com.scene7.is.sleng.CacheEnum
 *  com.scene7.is.sleng.ImageAccessException
 *  com.scene7.is.sleng.ipp.IppConnectionException
 *  com.scene7.is.util.ServerCacheUseEnum
 *  com.scene7.is.util.callbacks.Option
 *  com.scene7.is.util.diskcache.Cache
 *  com.scene7.is.util.diskcache.CacheAccess
 *  com.scene7.is.util.diskcache.CacheException
 *  com.scene7.is.util.diskcache.CacheKey
 *  org.jetbrains.annotations.NotNull
 *  org.jetbrains.annotations.Nullable
 */
package com.scene7.is.ps.provider.util;

import com.scene7.is.cache.CacheServerEntry;
import com.scene7.is.cache.clustering.CacheService;
import com.scene7.is.cacheserver.shared.CacheServerAccess;
import com.scene7.is.cacheserver.shared.CacheServerCacheEntry;
import com.scene7.is.provider.Response;
import com.scene7.is.provider.ResponseData;
import com.scene7.is.ps.provider.CacheEntry;
import com.scene7.is.ps.provider.IZoomException;
import com.scene7.is.ps.provider.util.CachingPolicy;
import com.scene7.is.ps.provider.util.Requester;
import com.scene7.is.sleng.CacheAction;
import com.scene7.is.sleng.CacheEnum;
import com.scene7.is.sleng.ImageAccessException;
import com.scene7.is.sleng.ipp.IppConnectionException;
import com.scene7.is.util.ServerCacheUseEnum;
import com.scene7.is.util.callbacks.Option;
import com.scene7.is.util.diskcache.Cache;
import com.scene7.is.util.diskcache.CacheAccess;
import com.scene7.is.util.diskcache.CacheException;
import com.scene7.is.util.diskcache.CacheKey;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class CacheAgent {
    private static final Logger LOGGER = Logger.getLogger(CacheAgent.class.getName());
    private final Cache cache;
    private final CacheService cacheService;
    private final CacheServerAccess cacheServerAccess;
    private final double probabilityToPushCacheEntryToCacheServer;

    public CacheAgent(@NotNull Cache cache, @NotNull CacheService cacheService, @NotNull CacheServerAccess cacheServerAccess, double probabilityToPushCacheEntryToCacheServer) {
        this.cache = cache;
        this.cacheService = cacheService;
        this.cacheServerAccess = cacheServerAccess;
        this.probabilityToPushCacheEntryToCacheServer = probabilityToPushCacheEntryToCacheServer;
    }

    @NotNull
    public Response getResponse(@Nullable String companyName, @NotNull Requester requester, @NotNull CachingPolicy cachingPolicy) throws ImageAccessException, IZoomException {
        if (cachingPolicy.cacheEnabled()) {
            return this.getCachedResponse(companyName, requester, cachingPolicy);
        }
        return this.getUnCachedResponse(requester);
    }

    @NotNull
    private Response getUnCachedResponse(@NotNull Requester requester) throws ImageAccessException, IZoomException {
        ResponseData data = requester.createResponseData(requester.getPixels(CacheEnum.OFF));
        return new Response().setServerCacheUse(ServerCacheUseEnum.IGNORED).setData(data);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @NotNull
    private Response getCachedResponse(@Nullable String companyName, @NotNull Requester requester, @NotNull CachingPolicy cachingPolicy) throws ImageAccessException, IZoomException {
        Response response;
        CacheKey key = requester.getCacheKey();
        CacheAccess entry = this.cache.lookup(key);
        try {
            Response response2 = entry.isCacheHit() ? this.processCacheHit(companyName, requester, cachingPolicy, entry) : this.processCacheMiss(companyName, requester, cachingPolicy, entry);
            response2.setCacheKey(key.getBase16Digest());
            response = response2;
        }
        catch (Throwable var8_9) {
            try {
                entry.dispose();
                throw var8_9;
            }
            catch (CacheException e) {
                LOGGER.log(Level.SEVERE, "Error accessing cache entry: ", (Throwable)e);
                return this.getUnCachedResponse(requester);
            }
        }
        entry.dispose();
        return response;
    }

    @NotNull
    private Response processCacheHit(@Nullable String companyName, @NotNull Requester requester, @NotNull CachingPolicy cachingPolicy, @NotNull CacheAccess entry) throws ImageAccessException, CacheException, IZoomException {
        long timeStamp = entry.getLastModified();
        CacheAction cacheAction = cachingPolicy.getCacheHitAction(timeStamp);
        switch (cacheAction) {
            case REUSE: {
                Response response = this.handleReuse(requester, entry, companyName, timeStamp);
                return response;
            }
            case UPDATE: {
                return this.handleUpdate(requester, cachingPolicy, entry);
            }
            case VALIDATE: {
                return this.handleValidation(companyName, requester, cachingPolicy, entry);
            }
            case DELETE: {
                return CacheAgent.handleDelete(requester, entry);
            }
        }
        throw new AssertionError((Object)cacheAction);
    }

    @NotNull
    private Response processCacheMiss(@Nullable String companyName, @NotNull Requester requester, @NotNull CachingPolicy cachingPolicy, @NotNull CacheAccess entry) throws ImageAccessException, CacheException, IZoomException {
        CacheAction cacheAction = cachingPolicy.getCacheMissAction();
        switch (cacheAction) {
            case CREATE: {
                return this.handleCreate(companyName, requester, cachingPolicy, entry);
            }
            case IGNORE: {
                return this.getUnCachedResponse(requester);
            }
        }
        throw new AssertionError((Object)("Illegal cache action: " + (Object)cacheAction));
    }

    @NotNull
    private static Response handleDelete(@NotNull Requester requester, @NotNull CacheAccess entry) throws CacheException {
        CacheEntry payload = (CacheEntry)entry.getPayload();
        entry.clear();
        return new Response().setData(requester.createResponseData(payload.pixels)).setServerCacheUse(ServerCacheUseEnum.DELETED);
    }

    @NotNull
    private Response handleUpdate(@NotNull Requester requester, @NotNull CachingPolicy cachingPolicy, @NotNull CacheAccess entry) throws ImageAccessException, CacheException, IZoomException {
        CacheEntry payload = this.createPayload(requester, cachingPolicy.getCacheSetting());
        entry.setPayload((Object)payload);
        entry.setLastModified(cachingPolicy.getValidationTime());
        return new Response().setData(requester.createResponseData(payload.pixels)).setServerCacheUse(ServerCacheUseEnum.UPDATED);
    }

    @NotNull
    private Response handleReuse(@NotNull Requester requester, @NotNull CacheAccess entry, @Nullable String companyName, long timeStamp) throws CacheException {
        byte[] data;
        CacheEntry payload = (CacheEntry)entry.getPayload();
        Random random = new Random();
        if (random.nextDouble() < this.probabilityToPushCacheEntryToCacheServer && (data = CacheAgent.getByteArrayFromCacheEntry(payload)) != null) {
            String client = new String("IsOrIr");
            String name = companyName != null ? companyName : "UnknownCompanyName";
            this.cacheServerAccess.put(client, name, requester.getCacheKey(), data, timeStamp);
        }
        return new Response().setData(requester.createResponseData(payload.pixels)).setServerCacheUse(ServerCacheUseEnum.REUSED);
    }

    @NotNull
    private Response handleValidation(@Nullable String companyName, @NotNull Requester requester, @NotNull CachingPolicy cachingPolicy, @NotNull CacheAccess entry) throws ImageAccessException, CacheException, IZoomException {
        try {
            CacheEntry payload = (CacheEntry)entry.getPayload();
            if (!this.isModified(payload.versionKey, requester, cachingPolicy.getCacheSetting())) {
                entry.setLastModified(cachingPolicy.getValidationTime());
                return new Response().setData(requester.createResponseData(payload.pixels)).setServerCacheUse(ServerCacheUseEnum.VALIDATED);
            }
            Response remote = this.handleRemoteEntry(companyName, requester, cachingPolicy, entry);
            if (remote != null) {
                if (this.cacheService.getUpdateLocalCache()) {
                    remote.setServerCacheUse(ServerCacheUseEnum.REMOTE_UPDATED);
                } else {
                    remote.setServerCacheUse(ServerCacheUseEnum.REMOTE_CACHE);
                }
                return remote;
            }
            Response serverResponse = this.handleServerEntry(companyName, requester, cachingPolicy, entry);
            if (serverResponse != null) {
                serverResponse.setServerCacheUse(ServerCacheUseEnum.CACHE_SERVER_UPDATED);
            }
            CacheEntry newPayload = this.createPayload(requester, cachingPolicy.getCacheSetting());
            entry.setPayload((Object)newPayload);
            entry.setLastModified(cachingPolicy.getValidationTime());
            byte[] data = CacheAgent.getByteArrayFromCacheEntry(newPayload);
            if (data != null) {
                String client = new String("IsOrIr");
                String name = companyName != null ? companyName : "UnknownCompanyName";
                this.cacheServerAccess.put(client, name, requester.getCacheKey(), data, cachingPolicy.getValidationTime());
            }
            return new Response().setData(requester.createResponseData(newPayload.pixels)).setServerCacheUse(ServerCacheUseEnum.UPDATED);
        }
        catch (IppConnectionException e) {
            if (e.getCode() == 7) {
                LOGGER.log(Level.WARNING, e.getMessage(), (Throwable)e);
                return this.handleReuse(requester, entry, companyName, entry.getLastModified());
            }
            throw e;
        }
    }

    @NotNull
    private Response handleCreate(@Nullable String companyName, @NotNull Requester requester, @NotNull CachingPolicy cachingPolicy, @NotNull CacheAccess entry) throws ImageAccessException, CacheException, IZoomException {
        Response remote = this.handleRemoteEntry(companyName, requester, cachingPolicy, entry);
        if (remote != null) {
            if (this.cacheService.getUpdateLocalCache()) {
                return remote.setServerCacheUse(ServerCacheUseEnum.REMOTE_CREATED);
            }
            return remote.setServerCacheUse(ServerCacheUseEnum.REMOTE_CACHE);
        }
        Response serverResponse = this.handleServerEntry(companyName, requester, cachingPolicy, entry);
        if (serverResponse != null) {
            return serverResponse;
        }
        CacheEntry payload = this.createPayload(requester, cachingPolicy.getCacheSetting());
        entry.setPayload((Object)payload);
        entry.setLastModified(cachingPolicy.getValidationTime());
        byte[] data = CacheAgent.getByteArrayFromCacheEntry(payload);
        if (data != null) {
            String client = new String("IsOrIr");
            String name = companyName != null ? companyName : "UnknownCompanyName";
            this.cacheServerAccess.put(client, name, requester.getCacheKey(), data, cachingPolicy.getValidationTime());
        }
        return new Response().setData(requester.createResponseData(payload.pixels)).setServerCacheUse(ServerCacheUseEnum.CREATED);
    }

    @NotNull
    private CacheEntry createPayload(@NotNull Requester requester, CacheEnum cacheSetting) throws ImageAccessException, IZoomException {
        CacheEntry payload = new CacheEntry();
        payload.pixels = requester.getPixels(cacheSetting);
        payload.versionKey = requester.getVersionKey(cacheSetting);
        return payload;
    }

    @Nullable
    private Response handleRemoteEntry(@Nullable String companyName, @NotNull Requester requester, @NotNull CachingPolicy cachingPolicy, @NotNull CacheAccess entry) throws ImageAccessException, CacheException {
        CacheServerEntry remoteEntry = this.cacheService.getRemote("response", requester.getCacheKey());
        if (!remoteEntry.isCacheHit()) {
            return null;
        }
        CacheEntry payload = (CacheEntry)remoteEntry.getPayload();
        CacheAction cacheAction = cachingPolicy.getCacheHitAction(remoteEntry.getLastModified());
        switch (cacheAction) {
            case REUSE: {
                break;
            }
            case VALIDATE: {
                if (!this.isModified(payload.versionKey, requester, cachingPolicy.getCacheSetting())) break;
                return null;
            }
            default: {
                return null;
            }
        }
        if (this.cacheService.getUpdateLocalCache()) {
            entry.setPayload((Object)payload);
            entry.setLastModified(cachingPolicy.getValidationTime());
        } else {
            entry.clear();
        }
        return new Response().setPeerServer(remoteEntry.getPeerServer()).setData(requester.createResponseData(payload.pixels));
    }

    @Nullable
    private Response handleServerEntry(@Nullable String companyName, @NotNull Requester requester, @NotNull CachingPolicy cachingPolicy, @NotNull CacheAccess entry) throws ImageAccessException, CacheException {
        String client = new String("IsOrIr");
        String name = companyName != null ? companyName : "UnknownCompanyName";
        CacheServerCacheEntry serverEntry = this.cacheServerAccess.get(client, name, requester.getCacheKey());
        if (serverEntry.getData() == null) {
            return null;
        }
        CacheEntry payload = null;
        try {
            payload = CacheAgent.getServerAccessFromServerEntry(serverEntry, requester);
        }
        catch (Exception ex) {
            LOGGER.log(Level.SEVERE, "Bad cache entry retrieved from cache server for cache key " + (Object)requester.getCacheKey(), ex);
            return null;
        }
        CacheAction cacheAction = cachingPolicy.getCacheHitAction(serverEntry.getLastModified());
        switch (cacheAction) {
            case REUSE: {
                break;
            }
            case VALIDATE: {
                if (this.isModified(payload.versionKey, requester, cachingPolicy.getCacheSetting())) {
                    return null;
                }
                this.cacheServerAccess.setLastModified(client, name, requester.getCacheKey(), cachingPolicy.getValidationTime());
                break;
            }
            default: {
                return null;
            }
        }
        entry.setPayload((Object)payload);
        entry.setLastModified(cachingPolicy.getValidationTime());
        Response response = new Response();
        response.setData(requester.createResponseData(payload.pixels));
        response.setServerCacheUse(cacheAction == CacheAction.VALIDATE ? ServerCacheUseEnum.CACHE_SERVER_VALIDATED : ServerCacheUseEnum.CACHE_SERVER_CREATED);
        return response;
    }

    private boolean isModified(byte[] cachedVersionKey, @NotNull Requester requester, CacheEnum cacheSetting) throws ImageAccessException {
        byte[] versionKey = requester.getVersionKey(cacheSetting);
        return !Arrays.equals(versionKey, cachedVersionKey);
    }

    private static CacheEntry getServerAccessFromServerEntry(CacheServerCacheEntry cacheServerAccessEntry, Requester requester) throws CacheException {
        byte[] buffer = cacheServerAccessEntry.getData();
        ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
        int pixelsLength = byteBuffer.getInt();
        byte[] pixels = new byte[pixelsLength];
        byteBuffer.get(pixels);
        int versionKeyLength = byteBuffer.getInt();
        byte[] versionKey = new byte[versionKeyLength];
        byteBuffer.get(versionKey);
        CacheEntry cacheEntry = new CacheEntry();
        cacheEntry.versionKey = versionKey;
        cacheEntry.pixels = pixels;
        return cacheEntry;
    }

    private static byte[] getByteArrayFromCacheEntry(CacheEntry entry) {
        int arrayLength = entry.pixels.length + entry.versionKey.length + 8;
        byte[] data = new byte[arrayLength];
        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        byteBuffer.putInt(entry.pixels.length);
        byteBuffer.put(entry.pixels);
        byteBuffer.putInt(entry.versionKey.length);
        byteBuffer.put(entry.versionKey);
        return data;
    }

}