/*
* * This file is part of the Hesperides distribution.
* * (https://github.com/voyages-sncf-technologies/hesperides)
* * Copyright (c) 2016 VSCT.
* *
* * Hesperides is free software: you can redistribute it and/or modify
* * it under the terms of the GNU General Public License as
* * published by the Free Software Foundation, version 3.
* *
* * Hesperides is distributed in the hope that it will be useful, but
* * WITHOUT ANY WARRANTY; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* * General Public License for more details.
* *
* * You should have received a copy of the GNU General Public License
* * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.vsct.dt.hesperides.templating.packages;
import com.google.common.cache.LoadingCache;
import com.vsct.dt.hesperides.HesperidesCacheParameter;
import com.vsct.dt.hesperides.storage.EventStore;
import com.vsct.dt.hesperides.templating.modules.template.Template;
import com.vsct.dt.hesperides.templating.modules.template.TemplateRegistryInterface;
import com.vsct.dt.hesperides.templating.packages.cache.TemplatePackageCacheLoader;
import com.vsct.dt.hesperides.templating.packages.event.TemplatePackageContainer;
import com.vsct.dt.hesperides.util.HesperidesCacheBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
/**
* Created by emeric_martineau on 19/01/2016.
*/
public class TemplatePackageRegistry implements TemplateRegistryInterface {
/**
* Logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(TemplatePackageRegistry.class);
/**
* Lazy loader.
*/
private final TemplatePackageCacheLoader templateCacheLoader;
/**
* Cache contain module or load it.
*/
private final LoadingCache<String, TemplatePackageContainer> cache;
/**
* Constructor.
*
* @param store store of event for lazy load
* @param nbEventBeforePersiste nb event before store cache
* @param config config of cache
*/
public TemplatePackageRegistry(final EventStore store, final long nbEventBeforePersiste,
final HesperidesCacheParameter config) {
this.templateCacheLoader = new TemplatePackageCacheLoader(store, nbEventBeforePersiste);
this.cache = HesperidesCacheBuilder.newBuilder(config, (key, value) -> ((TemplatePackageContainer) value).loadAllTemplate().size())
.build(this.templateCacheLoader);
}
@Override
public Collection<Template> allTemplates() {
LOGGER.debug("Get all template package from store.");
return this.templateCacheLoader.getAllTemplates();
}
@Override
public Optional<Template> getTemplate(final String namespace, final String name) {
try {
LOGGER.debug("Search package template '{}' for namespace '{}'.", name, namespace);
final TemplatePackageContainer templateCache = this.cache.get(namespace);
return Optional.ofNullable(templateCache.getTemplate(name));
} catch (final ExecutionException e) {
LOGGER.debug("Can't find package template '{}' for namespace '{}'.", name, namespace);
// Module not found
return Optional.empty();
}
}
@Override
public Optional<Template> getTemplate(final TemplatePackageKey packageKey, final String name) {
return getTemplate(packageKey.getNamespace(), name);
}
@Override
public boolean existsTemplate(final String namespace, final String name) {
return getTemplate(namespace, name).isPresent();
}
@Override
public void createOrUpdateTemplate(final Template template) {
LOGGER.debug("Add package template '{}'.", template);
TemplatePackageContainer templateCache;
try {
templateCache = this.cache.get(template.getNamespace());
templateCache.addTemplate(template);
} catch (final ExecutionException e) {
// When not found in database -> create
templateCache = new TemplatePackageContainer();
templateCache.addTemplate(template);
}
// Write snapshot
templateCacheLoader.saveSnapshot(template.getNamespace(), templateCache);
}
@Override
public void deleteTemplate(final String namespace, final String name) {
TemplatePackageContainer templateCache;
try {
templateCache = this.cache.get(namespace);
} catch (final ExecutionException e) {
templateCache = null;
}
// Delete template only if in cache
if (templateCache != null) {
templateCache.removeTemplate(name);
// Write snapshot
templateCacheLoader.saveSnapshot(namespace, templateCache);
}
}
@Override
public Set<Template> getAllTemplatesForNamespace(final String namespace) {
try {
LOGGER.debug("Get all package template for namespace '{}'.", namespace);
final TemplatePackageContainer templateCache = this.cache.get(namespace);
return templateCache.loadAllTemplate();
} catch (final ExecutionException e) {
LOGGER.debug("Can't get all package template for namespace '{}'.", namespace);
// Module not found
return new HashSet<>();
}
}
@Override
public Set<Template> getAllTemplates(TemplatePackageKey packageKey) {
return getAllTemplatesForNamespace(packageKey.getNamespace());
}
@Override
public boolean templateHasNamespace(final String namespace) {
return this.templateCacheLoader.isNamespaceExist(namespace);
}
@Override
public void removeFromCache(final TemplatePackageKey packageKey) {
this.cache.invalidate(packageKey.getNamespace());
}
@Override
public void removeAllCache() {
this.cache.invalidateAll();
}
}