001/*
002 * (C) Copyright 2015 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 * Nuxeo - initial API and implementation
016 */
017
018package org.nuxeo.ecm.core.redis.contribs;
019
020import java.io.IOException;
021
022import org.apache.commons.logging.Log;
023import org.apache.commons.logging.LogFactory;
024import org.nuxeo.ecm.core.cache.Cache;
025import org.nuxeo.ecm.core.redis.RedisAdmin;
026import org.nuxeo.ecm.core.redis.RedisCallable;
027import org.nuxeo.ecm.core.redis.RedisExecutor;
028import org.nuxeo.ecm.core.transientstore.AbstractTransientStore;
029import org.nuxeo.ecm.core.transientstore.api.TransientStore;
030import org.nuxeo.ecm.core.transientstore.api.TransientStoreConfig;
031import org.nuxeo.runtime.api.Framework;
032
033import redis.clients.jedis.Jedis;
034
035/**
036 * Redis implementation (i.e. Cluster Aware) implementation of the {@link TransientStore}
037 *
038 * @author <a href="mailto:tdelprat@nuxeo.com">Tiry</a>
039 * @since 7.2
040 */
041
042public class RedisTransientStore extends AbstractTransientStore {
043
044    protected RedisExecutor redisExecutor;
045
046    protected String namespace;
047
048    protected RedisAdmin redisAdmin;
049
050    protected Log log = LogFactory.getLog(RedisTransientStore.class);
051
052    public RedisTransientStore() {
053        redisExecutor = Framework.getService(RedisExecutor.class);
054        redisAdmin = Framework.getService(RedisAdmin.class);
055    }
056
057    @Override
058    public void init(TransientStoreConfig config) {
059        super.init(config);
060        namespace = redisAdmin.namespace("transientCache", config.getName(), "size");
061    }
062
063    @Override
064    protected void incrementStorageSize(final long size) {
065        try {
066            redisExecutor.execute((RedisCallable<Void>) jedis -> {
067                jedis.incrBy(namespace, size);
068                return null;
069            });
070        } catch (Exception e) {
071            log.error("Error while accessing Redis", e);
072        }
073    }
074
075    @Override
076    protected void decrementStorageSize(final long size) {
077        try {
078            redisExecutor.execute((RedisCallable<Void>) jedis -> {
079                jedis.decrBy(namespace, size);
080                return null;
081            });
082        } catch (Exception e) {
083            log.error("Error while accessing Redis", e);
084        }
085    }
086
087    @Override
088    public long getStorageSize() {
089        try {
090            return redisExecutor.execute(jedis -> {
091                String value = jedis.get(namespace);
092                return Long.parseLong(value);
093            });
094        } catch (Exception e) {
095            log.error("Error while accessing Redis", e);
096            return 0;
097        }
098    }
099
100    @Override
101    protected void setStorageSize(final long newSize) {
102        try {
103            redisExecutor.execute((RedisCallable<Void>) jedis -> {
104                jedis.set(namespace, ""+newSize);
105                return null;
106            });
107        } catch (Exception e) {
108            log.error("Error while accesing Redis", e);
109        }
110    }
111
112    @Override
113    public Class<? extends Cache> getCacheImplClass() {
114        return RedisCache.class;
115    }
116
117}