package org.zalando.baigan.service; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.ListenableFuture; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.zalando.baigan.model.Configuration; import javax.annotation.Nonnull; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; import java.util.Map; import java.util.Optional; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; /** * Implementation of {@link ConfigurationRepository} supporting a file on * Classpath as the persistence storage for the Baigan configuration. * * @author mchand */ public class FileSystemConfigurationRepository extends AbstractConfigurationRepository { private final LoadingCache<String, Map<String, Configuration>> cachedConfigurations; private final String fileName; private Logger LOG = LoggerFactory .getLogger(FileSystemConfigurationRepository.class); public FileSystemConfigurationRepository(long refreshIntervalInMinutes, final String fileName) { this.fileName = fileName; cachedConfigurations = CacheBuilder.newBuilder() .refreshAfterWrite(refreshIntervalInMinutes, TimeUnit.MINUTES) .build(new CacheLoader<String, Map<String, Configuration>>() { @Override public Map<String, Configuration> load(String key) throws Exception { final String configurationText = loadResource(key); final Collection<Configuration> configurations = getConfigurations( configurationText); final ImmutableMap.Builder<String, Configuration> builder = ImmutableMap.builder(); for (Configuration each : configurations) { builder.put(each.getAlias(), each); } return builder.build(); } @Override public ListenableFuture<Map<String, Configuration>> reload( String key, Map<String, Configuration> oldValue) throws Exception { LOG.info("Reloading the configuration from file {}", key); return super.reload(key, oldValue); } }); } @Nonnull @Override public Optional<Configuration> get(@Nonnull String key) { try { return Optional.ofNullable(cachedConfigurations.get(fileName).get(key)); } catch (ExecutionException e) { LOG.warn("Exception while trying to get configuration for key {}", key, e); } return Optional.empty(); } @Override public void put(@Nonnull String key, @Nonnull String value) { throw new UnsupportedOperationException(); } public String loadResource(final String file) throws IOException { final Path filePath = Paths.get(file); final String contents = new String(Files.readAllBytes(filePath)); return contents; } }