package com.github.triceo.splitlog; import java.io.File; import java.io.IOException; import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.triceo.splitlog.api.Follower; import com.github.triceo.splitlog.api.Message; /** * Write a message to a given log file. */ public class LogWriter { private static final Logger LOGGER = LoggerFactory.getLogger(LogWriter.class); public synchronized static File createTempFile() { try { return File.createTempFile("test-", null); } catch (final IOException e) { throw new IllegalStateException("Cannot create temp files.", e); } } public static boolean write(final File target, final String line) { try { FileUtils.writeStringToFile(target, line + "\n", "UTF-8", true); LogWriter.LOGGER.info("Written '{}' into {}.", line, target); return true; } catch (final IOException ex) { LogWriter.LOGGER.error("Failed writing '{}' into {}.", line, target, ex); return false; } } /** * Writes a line to the log and waits until the follower receives it. * * @param line * Message to write. * @param follower * Follower to wait for the message. * @return The line that was written, or null otherwise. */ public static String write(final Follower follower, final String line) { final Future<Message> future = follower.expect((evaluate, status, source) -> { final List<String> lines = evaluate.getLines(); final String lastLine = lines.get(lines.size() - 1); final String textStr[] = line.split("\\r?\\n"); return (textStr[textStr.length - 1].trim().equals(lastLine.trim())); }); if (!LogWriter.write(follower.getFollowed().getWatchedFile(), line)) { throw new IllegalStateException("Failed writing message."); } else if (follower.isStopped()) { throw new IllegalStateException("Follower cannot receive message as it is already stopped."); } try { // wait until the last part of the string is finally present LogWriter.LOGGER.info("Waiting for '{}' starting in {}.", line, follower); final Message result = future.get(10, TimeUnit.SECONDS); final List<String> lines = result.getLines(); return lines.get(lines.size() - 1); } catch (final Exception e) { throw new IllegalStateException("No message received in time.", e); } } }