/* * -----------------------------------------------------------------------\ * PerfCake *   * Copyright (C) 2010 - 2016 the original author or authors. *   * 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 org.perfcake.message.sequence; import org.perfcake.util.Utils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; import java.io.UncheckedIOException; import java.net.URL; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; /** * The individual sequence values are read from external files listed as separate lines in the provided index text file. * * @author <a href="mailto:marvenec@gmail.com">Martin Večeřa</a> */ public class FilesContentSequence extends FileLinesSequence { /** * The sequence's logger. */ private static final Logger log = LogManager.getLogger(FileLinesSequence.class); /** * Cache of files content. */ private Map<String, String> cache = new ConcurrentHashMap<>(); /** * When true, the content of individual files is cached in memory. * This can consume significant amount of memory so use with caution. */ private boolean cacheContent = true; /** * Gets whether the content of individual files is cached in the memory. * * @return True if and only if the content of individual files is cached in the memory. */ public boolean isCacheContent() { return cacheContent; } /** * Sets whether the content of individual files is cached in the memory. * * @param cacheContent * True if and only if the content of individual files is cached in the memory. * @return Instance of this to support fluent API. */ public FilesContentSequence setCacheContent(final boolean cacheContent) { this.cacheContent = cacheContent; return this; } @Override public void publishNext(final String sequenceId, final Properties values) { final Properties props = new Properties(); super.publishNext(sequenceId, props); final String fileName = props.getProperty(sequenceId); final String content; if (cacheContent) { content = cache.computeIfAbsent(fileName, this::readFile); } else { content = readFile(fileName); } if (content != null && !content.isEmpty()) { values.setProperty(sequenceId, content); } else { log.warn("Empty sequence value for '" + sequenceId + "'."); } } /** * Tries to obtain the content of the given file or URL as a string. * * @param fileName * File name or URL to read from. * @return The content of the specified location or empty string when there was an error reading the location. */ private String readFile(final String fileName) { try { return Utils.readFilteredContent(fileName); } catch (UncheckedIOException | IOException e) { log.warn("Unable to read file content for use in sequence: ", e); } return ""; } }