/*******************************************************************************
* 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.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeMap;
import mjson.Json;
import util.JsonUrlConnector;
/**
* ServerDataHistoryProvider currently does too much...
*
* @author Thomas Hilpold
*/
public class CirmServerStatistics {
private final String serverName;
private final URL serverStatsJsonUrl;
private final String jsonStatsArrayProperty;
protected TreeMap<Date, CirmStatistics> statsDataHistory = new TreeMap<>();
//protected TreeMap<Date, CirmStatistics> statsSpeedHistory = new TreeMap<>();
/**
* Createa a ServerDataHistoryProvider which can't load statistics from a URL.
* It fails on update(Date).
* use (update(Date, CirmStatistics)
* @param serverName
*/
public CirmServerStatistics(String serverName) {
this(serverName, null, null);
}
/**
*
* @param serverStatsJsonUrl
* @param serverName
* @param jsonStatsArrayProperty "stats-all"
*/
public CirmServerStatistics(String serverName, URL serverStatsJsonUrl, String jsonStatsArrayProperty)
{
this.serverStatsJsonUrl = serverStatsJsonUrl;
this.serverName = serverName;
this.jsonStatsArrayProperty = jsonStatsArrayProperty;
}
public String getServerName() {
return serverName;
}
public CirmStatistics getStatsAt(Date d) {
return statsDataHistory.get(d);
}
/**
* Sorted from first (oldest) to last (newest)
* @return
*/
public SortedSet<Date> getStatsDates()
{
return (SortedSet)statsDataHistory.keySet();
}
public Date getLastUpdateTime() {
if (statsDataHistory.isEmpty()) return null;
return statsDataHistory.lastKey();
}
/**
* retrieves stats now from url and inserts it into data history.
* @param now use an equal now date for all servers and cluster
* @throws exceptions, use try.
*/
public void updateFromUrl(Date now) throws IOException {
if (serverStatsJsonUrl == null) throw new IllegalStateException("This data provider is not configured for from URL updates: " + getServerName());
CirmStatistics statsNow = retrieveStatsNow();
if (statsNow == null) throw new IllegalStateException("Stats was null after retrieve !!");
statsDataHistory.put(now, statsNow);
}
/**
* updates the history with the given parameters. e.g. for cluster history.
* @param time
* @param stats
*/
public void update(Date time, CirmStatistics stats)
{
statsDataHistory.put(time, stats);
}
protected CirmStatistics retrieveStatsNow() throws IOException {
System.out.println("Loading stats from url" + serverStatsJsonUrl);
JsonUrlConnector c = new JsonUrlConnector();
Json statsRaw = c.getJsonFromUrl(serverStatsJsonUrl);
CirmStatistics nextStats = null;
if (statsRaw.is("ok", true))
{
CirmStatisticsParser p = new CirmStatisticsParser();
nextStats = p.read(statsRaw.at(jsonStatsArrayProperty));
}
return nextStats;
}
/**
* Returns a history for a given key with where the first date is the oldest.
* parallel execution!
*
* @param key
* @return
*/
public List<DateStatsValuePair> getHistoryForKey(CirmStatistics.StatsKey key) {
List<DateStatsValuePair> result = new ArrayList<>();
SortedSet<Date> dates = getStatsDates();
dates.stream().parallel().map((curDate) -> {
CirmStatistics curStats = getStatsAt(curDate);
CirmStatistics.StatsValue curValue = curStats.getEntry(key.getComponent(), key.getAction(), key.gettype());
DateStatsValuePair pair = new DateStatsValuePair(curDate, curValue);
return pair;
}).forEach((pair) -> {
result.add(pair);
});
return result;
}
}