/*********************************************************************************** * * Copyright (c) 2014 Kamil Baczkowicz * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * * The Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * * Kamil Baczkowicz - initial API and implementation and/or initial documentation * */ package pl.baczkowicz.mqttspy.logger; import java.io.File; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.baczkowicz.mqttspy.messages.BaseMqttMessage; import pl.baczkowicz.spy.utils.ThreadingUtils; import pl.baczkowicz.spy.utils.TimeUtils; /** * Implementation of the interface between a script and the messageLog object. */ public class MqttMessageLogIO implements IMqttMessageLogIO, Runnable { /** Diagnostic logger. */ private final static Logger logger = LoggerFactory.getLogger(MqttMessageLogIO.class); /** Messages. */ private List<BaseMqttMessage> messages; /** Current replay time (as in the message log). */ private long replayTime; /** Timestamp of the last time checker run. */ private long lastUpdated; /** Flag indicating whether the time checker is running. */ private boolean running = false; /** The current running speed. */ private double speed = 1; @Override public int readFromFile(final String logLocation) { try { messages = MqttMessageLogParserUtils.readAndConvertMessageLog(new File(logLocation)); return messages.size(); } catch (Exception e) { logger.error("Cannot read message log at " + logLocation, e); return 0; } } @Override public void start() { if (messages != null) { replayTime = messages.get(0).getDate().getTime(); lastUpdated = TimeUtils.getMonotonicTime(); running = true; new Thread(this).start(); } } @Override public void stop() { running = false; } @Override public void setSpeed(double newSpeed) { if (newSpeed > 1) { if (this.speed <= 1) { logger.info("Warp enabled. Changing replay speed from {} to {}", this.speed, newSpeed); } else { logger.info("Warp still on. Changing replay speed from {} to {}", this.speed, newSpeed); } } else if (newSpeed == 1) { logger.info("Back to normal. Changing replay speed from {} to {}", this.speed, newSpeed); } else { logger.info("Tea time! Changing replay speed from {} to {}", this.speed, newSpeed); } this.speed = newSpeed; } @Override public boolean isReadyToPublish(final int messageIndex) { if (messages != null && messages.size() > messageIndex) { if (replayTime > messages.get(messageIndex).getDate().getTime()) { return true; } } return false; } @Override public BaseMqttMessage getMessage(final int messageIndex) { if (messages != null && messages.size() > messageIndex) { return messages.get(messageIndex); } return null; } @Override public void run() { ThreadingUtils.logThreadStarting("Message Audit Log IO"); while (running) { final long now = TimeUtils.getMonotonicTime(); if (now > lastUpdated) { final long sinceLastUpdated = now - lastUpdated; final double increase = sinceLastUpdated * speed; replayTime = replayTime + (long) increase; lastUpdated = now; } if (ThreadingUtils.sleep(10)) { break; } } stop(); ThreadingUtils.logThreadEnding(); } @Override public int getMessageCount() { if (messages == null) { return 0; } return messages.size(); } }