/*******************************************************************************
* Copyright 2014 Miami-Dade County
*
* 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.sharegov.cirm.stats;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.SortedSet;
import mjson.Json;
import org.sharegov.cirm.utils.GenUtilsMod;
/**
* File Directory based store for a CirmClusterStatistics.
* Format
* serverName : ""
* date : "" //isoDateAsString
* cirmStatistics : { cirmStatistics.toJson}
*
* @author Thomas Hilpold
*/
public class CirmClusterStatisticsStore {
public static final String SERVER_NAME_PROPERTY = "serverName";
public static final String DATE_PROPERTY = "date";
public static final String CIRM_STATS_PROPERTY = "cirmStatistics";
public static final String FILE_SUFFIX = ".json";
private final File storeFolder;
public static CirmClusterStatisticsStore create(File storeFolder) {
if (!storeFolder.exists()) storeFolder.mkdirs();
return new CirmClusterStatisticsStore(storeFolder);
}
public CirmClusterStatisticsStore(File storeFolder) {
this.storeFolder = storeFolder;
if (!storeFolder.exists()) throw new IllegalArgumentException("Does not exist, please create: " + storeFolder.getAbsolutePath());
if (!storeFolder.isDirectory()) throw new IllegalArgumentException();
if (!storeFolder.canRead()) throw new IllegalArgumentException();
if (!storeFolder.canWrite()) throw new IllegalArgumentException();
}
public void readAllInto(CirmClusterStatistics clusterStats) {
File[] allFiles = storeFolder.listFiles();
for (int fileIdx = 0; fileIdx < allFiles.length; fileIdx++) {
File cur = allFiles[fileIdx];
if (cur.getName().endsWith(FILE_SUFFIX)) {
try {
String fileContent = GenUtilsMod.readTextFile(cur);
Json storeJson = Json.read(fileContent);
insertSnapshotFromStoreJson(storeJson, clusterStats);
} catch (Exception e) {
System.err.println("Skipped file " + cur.getAbsolutePath() + " error was " + e.toString() + " msg " + e.getMessage());
e.printStackTrace();
}
}
}
}
void insertSnapshotFromStoreJson(Json storeJson, CirmClusterStatistics s) {
String serverName = storeJson.at(SERVER_NAME_PROPERTY).asString();
String dateStr = storeJson.at(DATE_PROPERTY).asString();
Date date = GenUtilsMod.parseDate(dateStr);
Json cirmStatisticsJson = storeJson.at(CIRM_STATS_PROPERTY);
CirmServerStatistics targetServerDataHistory = s.getDataHistoryByName(serverName);
if (targetServerDataHistory == null) {
System.err.println("server denoted in history not configured in CirmClusterStatistics " + serverName + " date " + date.getTime());
} else {
CirmStatistics newStats = new CirmStatisticsParser().read(cirmStatisticsJson);
//overwrites, if already entry at date
targetServerDataHistory.update(date, newStats);
}
}
/**
* Writes all snapshots for all servers and the cluster in a CirmClusterStatistics.
* Does not overwrite existing snapshot files.
* Order is: Cluster, Server[0], [1], ...
* @param cs
* @throws IOException
*/
public void writeAllFrom(CirmClusterStatistics cs) throws IOException {
long start = System.currentTimeMillis();
writeAllFrom(cs.getClusterDataHistory());
for (int i = 0; i < cs.getNrOfServers(); i++) {
writeAllFrom(cs.getServerDataHistory(i));
}
System.out.println("Store wrote all in " + (((System.currentTimeMillis() - start)/10)/100.0f) + " seconds");
}
/**
* Writes all snapshots for a ServerDataHistory.
* @param s
* @throws IOException
*/
void writeAllFrom(CirmServerStatistics s) throws IOException {
String serverName = s.getServerName();
SortedSet<Date> dates = s.getStatsDates();
for (Date snapshotDate : dates) {
writeSnapshot(serverName, snapshotDate, s.getStatsAt(snapshotDate), false);
}
}
/**
* Writes a single ServerDataHistory snapshot for one server at time date.
* @param server
* @param date
* @param s
* @param overwrite if a file name matches, normally we don't want to overwrite.
* @throws IOException
*/
void writeSnapshot(String server, Date date, CirmStatistics s, boolean overwrite) throws IOException {
String fileName = "" + date.getTime() + "-" + server + FILE_SUFFIX;
File newFile = new File(storeFolder.getAbsolutePath() + File.separatorChar + fileName);
if (newFile.exists() && !overwrite) return;
Json cirmStatsJson = new CirmStatisticsRenderer().render(s);
Json fileContentJson = Json.object();
fileContentJson.set(SERVER_NAME_PROPERTY, server);
fileContentJson.set(DATE_PROPERTY, GenUtilsMod.formatDate(date));
fileContentJson.with(cirmStatsJson);
String fileContent = fileContentJson.toString();
FileWriter fw = new FileWriter(newFile);
fw.write(fileContent, 0, fileContent.length());
fw.close();
}
}