All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.wl4g.infra.common.store.EhCacheMapStore Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2017 ~ 2025 the original authors James Wong.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.wl4g.infra.common.store;

import static com.wl4g.infra.common.lang.Assert2.hasTextOf;
import static com.wl4g.infra.common.lang.Assert2.notNullOf;
import static java.lang.String.format;
import static org.ehcache.config.builders.CacheManagerBuilder.newCacheManagerBuilder;

import java.io.Closeable;
import java.io.IOException;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.stream.StreamSupport;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

import org.ehcache.PersistentCacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.core.Ehcache;
import org.ehcache.core.EhcacheManager;
import org.ehcache.impl.config.persistence.CacheManagerPersistenceConfiguration;

import com.wl4g.infra.common.store.MapStoreConfig.EhCacheStoreConfig;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * {@link EhCacheResponseCacheTests}
 * 
 * @author James Wong <[email protected], [email protected]>
 * @version 2022-05-13 v3.0.0
 * @since v1.0.0
 */
@Slf4j
@Getter
public class EhCacheMapStore implements MapStore, Closeable {
    protected final EhCacheStoreConfig config;
    protected final EhcacheManager cacheManager;
    protected final Ehcache originalCache;

    public EhCacheMapStore(@NotNull EhCacheStoreConfig config, @NotBlank String name) {
        this.config = notNullOf(config, "config");
        hasTextOf(name, "name");
        this.cacheManager = (EhcacheManager) buildCacheManager(config, name);
        this.originalCache = (Ehcache) cacheManager
                .getCache(EhCacheMapStore.class.getSimpleName().concat("-").concat(name), String.class, Serializable.class);
    }

    @Override
    public Object getOriginalStore() {
        return originalCache;
    }

    @Override
    public  Iterator> iterator() {
        Iterator> it = originalCache.iterator();
        return new Iterator>() {
            @Override
            public boolean hasNext() {
                return it.hasNext();
            }

            @SuppressWarnings("unchecked")
            @Override
            public Entry next() {
                org.ehcache.Cache.Entry entry = (org.ehcache.Cache.Entry) it.next();
                return new Entry() {
                    @Override
                    public String getKey() {
                        return entry.getKey();
                    }

                    @Override
                    public T getValue() {
                        return entry.getValue();
                    }

                    @Override
                    public T setValue(T value) {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }

    @SuppressWarnings("unchecked")
    @Override
    public  T get(@NotNull String key) {
        notNullOf(key, "key");
        try {
            return (T) originalCache.get(key);
        } catch (Exception e) {
            log.error(format("Cannot to get response cache of '%s'", key), e);
        }
        return null;
    }

    @Override
    public  Boolean put(@NotNull String key, @NotNull T value) {
        notNullOf(key, "key");
        notNullOf(value, "value");
        try {
            originalCache.put(key, value);
            return true;
        } catch (Exception e) {
            log.error(format("Cannot to put response cache of '%s' -> %s ...", key, value), e);
        }
        return false;
    }

    @Override
    public Long remove(String key) {
        notNullOf(key, "key");
        try {
            originalCache.remove(key);
            return 1L;
        } catch (Exception e) {
            log.error(format("Cannot to invalidate response cache of '%s'", key), e);
        }
        return 0L;
    }

    @Override
    public Boolean removeAll() {
        originalCache.clear();
        return true;
    }

    @Override
    public Long size() {
        // TODO using EHCACHE statistics for count.
        return StreamSupport.stream(originalCache.spliterator(), true).count();
    }

    @Override
    public void close() throws IOException {
        cacheManager.close();
    }

    /**
     * Build EhCache cache manager for name.
     * 
     * see:https://www.ehcache.org/documentation/3.10/
     * see:https://github.com/ehcache/ehcache3-samples
     * see:https://github1s.com/ehcache/ehcache3/blob/HEAD/ehcache-impl/src/test/java/org/ehcache/config/builders/PersistentCacheManagerTest.java#L92-L100
     * 
     * @param config
     * @param alias
     * @return
     */
    static PersistentCacheManager buildCacheManager(EhCacheStoreConfig config, String name) {
        try {
            //@formatter:off
            // String prefix = "ehcache-tmp-";
            // File rootDir = new File(SystemUtils.JAVA_IO_TMPDIR, prefix + currentTimeMillis());
            // FileIOUtils.forceMkdir(rootDir);
            // rootDir.toPath().toFile().deleteOnExit();
            //@formatter:on

            String alias = EhCacheMapStore.class.getSimpleName().concat("-").concat(name);
            return newCacheManagerBuilder().with(new CacheManagerPersistenceConfiguration(config.getDataDir()))
                    .withCache(alias,
                            CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, Serializable.class,
                                    ResourcePoolsBuilder.newResourcePoolsBuilder()
                                            .heap(config.getHeapEntries(), EntryUnit.ENTRIES)
                                            .offheap(config.getOffHeapSize().toBytes(), MemoryUnit.B)
                                            .disk(config.getDiskSize().toBytes(), MemoryUnit.B, true)))
                    .build(true);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy