Remove old ReportServer and move site related files to ReportSite

directory
This commit is contained in:
Keir Nellyer 2016-07-07 17:49:06 -04:00
parent 4361379eaa
commit aab5daa446
39 changed files with 0 additions and 479 deletions

View File

@ -1,62 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-app</artifactId>
<version>dev-SNAPSHOT</version>
<relativePath>../app.xml</relativePath>
</parent>
<name>ReportServer</name>
<artifactId>mineplex-reportserver</artifactId>
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-serverdata</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Main-Class>mineplex.reportserver.ReportServer</Main-Class>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,57 +0,0 @@
package mineplex.reportserver;
import java.io.File;
import java.io.FileFilter;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
import org.apache.commons.lang3.Validate;
/**
* Class responsible for deleting old files (file age is determined by the "last modified" value).
*/
public class FilePurger implements Runnable
{
private static final FileFilter FILE_FILTER = file -> file.isFile() && file.getName().endsWith(".json");
private final File _dataDir;
private final Logger _logger;
public FilePurger(File dataDir, Logger logger)
{
_dataDir = dataDir;
_logger = logger;
Validate.notNull(_dataDir, "Data directory cannot be null.");
Validate.isTrue(_dataDir.exists() && dataDir.isDirectory(), "Path non-existent or not a directory: %s", _dataDir.getAbsolutePath());
Validate.notNull(_logger, "Logger cannot be null.");
}
@Override
public void run()
{
int purgeCount = 0;
for (File file : _dataDir.listFiles(FILE_FILTER))
{
long lastModified = file.lastModified();
long timeSince = System.currentTimeMillis() - lastModified;
int days = (int) TimeUnit.MILLISECONDS.toDays(timeSince);
if (days >= 15) // keep files for 15 days
{
if (!file.delete())
{
_logger.warning("Cannot delete file: " + file.getAbsolutePath());
}
else
{
purgeCount++;
}
}
}
_logger.info("Purged " + purgeCount + " old chat snapshots.");
}
}

View File

@ -1,142 +0,0 @@
package mineplex.reportserver;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.commons.lang3.Validate;
import redis.clients.jedis.JedisPubSub;
/**
* Listens for commands from Redis (such as "deploy" or "destroy") and executes them.
*/
public class RedisCommandHandler extends JedisPubSub
{
private static final Gson _gson = new GsonBuilder()
.setPrettyPrinting()
.create();
private static final JsonParser _jsonParser = new JsonParser();
private final File _directory;
private final Logger _logger;
private final ExecutorService _executorService = Executors.newCachedThreadPool();
public RedisCommandHandler(File directory, Logger logger)
{
_directory = directory;
_logger = logger;
Validate.notNull(_directory, "Directory cannot be null.");
Validate.isTrue(directory.exists() && directory.isDirectory(), "Path non-existent or not a directory: %s", directory.getPath());
Validate.notNull(_logger, "Logger cannot be null.");
}
@Override
public void onMessage(String channel, String dataString)
{
try
{
if (channel.equals(ReportServer.CHANNEL_DEPLOY))
{
String json = dataString;
JsonObject jsonObject = _jsonParser.parse(json).getAsJsonObject();
String token = jsonObject.get("token").getAsString();
File target = new File(_directory, token + ".json");
_logger.info("Chat snapshot received [" + token + "], writing to file.");
if (target.exists() && !jsonObject.has("snapshots"))
{
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(target)))
{
JsonObject originalJsonObject = _jsonParser.parse(bufferedReader).getAsJsonObject();
JsonObject usernamesObject = jsonObject.get("usernames").getAsJsonObject();
// retrieve snapshots from original file and add to jsonObject
jsonObject.add("snapshots", originalJsonObject.get("snapshots").getAsJsonArray());
// add new UUID->Usernames, update existing usernames
for (Map.Entry<String, JsonElement> entry : originalJsonObject.get("usernames").getAsJsonObject().entrySet())
{
usernamesObject.addProperty(entry.getKey(), entry.getValue().getAsJsonPrimitive().getAsString());
}
// re-write json after updating
json = _gson.toJson(jsonObject);
}
catch (Exception e)
{
_logger.log(Level.SEVERE, "Exception whilst updating an original snapshot.", e);
}
}
writeFile(target, json);
}
else if (channel.equals(ReportServer.CHANNEL_DESTROY))
{
// dataString = token
File target = new File(_directory, dataString + ".json");
_logger.info("Destroy command received [" + dataString + "].");
if (target.exists() && !target.delete())
{
_logger.warning("Failed to delete: " + target.getPath());
}
}
}
catch (Exception e)
{
_logger.log(Level.SEVERE, "Error whilst receiving redis message.", e);
}
}
private void writeFile(File file, String json)
{
_executorService.submit(() -> Files.write(file.toPath(), Arrays.asList(json.split("\n"))));
}
@Override
public void onPMessage(String s, String s1, String s2)
{
}
@Override
public void onSubscribe(String s, int i)
{
}
@Override
public void onUnsubscribe(String s, int i)
{
}
@Override
public void onPUnsubscribe(String s, int i)
{
}
@Override
public void onPSubscribe(String s, int i)
{
}
}

View File

@ -1,106 +0,0 @@
package mineplex.reportserver;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.time.DurationFormatUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* Establishes and maintains a connection to Redis.
*/
public class RedisConnectionHandler implements Runnable
{
private final String _name;
private final JedisPool _jedisPool;
private final RedisCommandHandler _handler;
private final String[] _channels;
private final Logger _logger;
private long _lastConnectionMillis = -1;
private Throwable _lastThrowable = null;
public RedisConnectionHandler(String name, JedisPool jedisPool, RedisCommandHandler handler, String[] channels, Logger logger)
{
_name = name;
_jedisPool = jedisPool;
_handler = handler;
_channels = channels;
_logger = logger;
Validate.isTrue(channels.length > 0, "Must provide at least one channel.");
}
@Override
public void run()
{
while (!Thread.interrupted())
{
try
{
registerChannelHandlers();
}
catch (Throwable e)
{
// Only log new errors (prevents same error being spammed)
if (_lastThrowable == null || !e.getClass().equals(_lastThrowable.getClass()))
{
if (_lastThrowable == null) // connection just failed
{
_lastConnectionMillis = System.currentTimeMillis();
}
_logger.log(Level.SEVERE, prefixMessage(
"Exception in Redis connection"
+ (_lastConnectionMillis != -1 ? " (no connection for " + getLastConnectionDuration() + ")" : "")
+ ", attempting to regain connection."
), e);
_lastThrowable = e;
}
try
{
Thread.sleep(1000 * 5);
}
catch (InterruptedException ignored) {}
}
}
_jedisPool.destroy();
_logger.warning("Thread interrupted, end of connection.");
}
private void registerChannelHandlers()
{
try (Jedis jedis = _jedisPool.getResource())
{
connectionEstablished();
jedis.subscribe(_handler, _channels);
}
}
private void connectionEstablished()
{
// subscribe blocks so we need to do all this before
_logger.info(
_lastThrowable == null
? prefixMessage("Connected.")
: prefixMessage(String.format("Connected after %s.", getLastConnectionDuration()))
);
_lastThrowable = null;
}
private String prefixMessage(String message)
{
return String.format("[%s] %s", _name, message);
}
private String getLastConnectionDuration()
{
return DurationFormatUtils.formatDurationWords(System.currentTimeMillis() - _lastConnectionMillis, true, true);
}
}

View File

@ -1,112 +0,0 @@
package mineplex.reportserver;
import java.io.File;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import mineplex.serverdata.Utility;
import mineplex.serverdata.redis.RedisConfig;
import mineplex.serverdata.servers.ConnectionData;
import mineplex.serverdata.servers.ServerManager;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.Validate;
import redis.clients.jedis.JedisPool;
/**
* Main class for the Report server, parses command line arguments and initializes the Report server.
*/
public class ReportServer
{
public static final String CHANNEL_DEPLOY = "reportserver:deploy";
public static final String CHANNEL_DESTROY = "reportserver:destroy";
private static final String[] CHANNELS = new String[]{CHANNEL_DEPLOY, CHANNEL_DESTROY};
public static void main(String[] args)
{
System.setProperty("java.util.logging.SimpleFormatter.format", "%4$s: %5$s%6$s%n"); // Nicer log output
Logger logger = Logger.getLogger("ReportServer");
logger.info("Starting report server.");
Options options = new Options();
Option dirOption = Option.builder("dataDir")
.hasArg()
.longOpt("dataDirectory")
.desc("Sets the data directory where the JSON files will be stored.")
.type(File.class)
.build();
options.addOption(dirOption);
try
{
CommandLineParser parser = new DefaultParser();
CommandLine cmd = parser.parse(options, args);
File dataDirectory = (File) cmd.getParsedOptionValue(dirOption.getOpt());
if (dataDirectory == null)
{
dataDirectory = new File("data");
}
new ReportServer(ServerManager.getDefaultConfig(), dataDirectory, logger);
}
catch (ParseException e)
{
logger.log(Level.SEVERE, "Failed to parse arguments.", e);
}
}
private final File _dataDirectory;
private final Logger _logger;
private final RedisCommandHandler _handler;
private final ScheduledExecutorService _executorService = Executors.newScheduledThreadPool(1);
public ReportServer(RedisConfig redisConfig, File dataDirectory, Logger logger)
{
_dataDirectory = dataDirectory;
_logger = logger;
Validate.notNull(_dataDirectory, "Data directory cannot be null.");
// thrown if path exists but is not a directory
Validate.isTrue(!_dataDirectory.exists() || _dataDirectory.isDirectory(), "Not a directory: %s", _dataDirectory.getPath());
// throws if directory doesn't exist and cannot be created
Validate.isTrue(_dataDirectory.exists() || _dataDirectory.mkdir(), "Unable to create directory: " + _dataDirectory.getPath());
_handler = new RedisCommandHandler(_dataDirectory, _logger);
initializeConnectionsConfig(redisConfig);
schedulePurgeTask();
}
private void initializeConnectionsConfig(RedisConfig redisConfig)
{
redisConfig.getConnections(false, null).forEach(this::initializeConnection);
}
private void initializeConnection(ConnectionData connectionData)
{
JedisPool jedisPool = Utility.generatePool(connectionData);
String connectionName = connectionData.getName();
Thread thread = new Thread(new RedisConnectionHandler(connectionName, jedisPool, _handler, CHANNELS, _logger), connectionName + " - Redis PubSub Thread");
thread.setDaemon(true);
thread.start();
}
private void schedulePurgeTask()
{
_executorService.scheduleAtFixedRate(new FilePurger(_dataDirectory, _logger), 0, 30, TimeUnit.MINUTES);
}
}

View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 227 KiB

After

Width:  |  Height:  |  Size: 227 KiB

View File

Before

Width:  |  Height:  |  Size: 971 KiB

After

Width:  |  Height:  |  Size: 971 KiB