This is a follow-up to: Serializing JSON data coming from two URLs in the same object
I have two URLs (urlA
and urlB
) and they both give me a JSON response back in the same JSON format. Below is my JSON string which I am getting back by calling from urlA
. I have shortened it down by having only three reportRecords
for understanding purposes. In general, it might have more than ~500 reportRecords
.
{
"aggRecords": {
"reportRecords": [
{
"min": 0,
"max": 12,
"avg": 0.3699187,
"count": 246,
"sumSq": 571,
"stddev": 1.4779372,
"median": 0,
"percentileMap": {
"95": 4
},
"metricName": "TransactionDuration",
"dimensions": {
"env": "dev",
"pool": "titan",
"Name": "PostProcessing",
"Type": "PostProcessing"
},
"value": 91
},
{
"min": 0,
"max": 23,
"avg": 2.3991289E-4,
"count": 1463031,
"sumSq": 3071,
"stddev": 0.045814946,
"median": 0,
"percentileMap": {
"95": 0
},
"metricName": "TransactionDuration",
"dimensions": {
"env": "dev",
"pool": "titan",
"Name": "ResourceContext",
"Type": "ResourceContext"
},
"value": 351
},
{
"min": 0,
"max": 1209,
"avg": 1.9203402,
"count": 7344636,
"sumSq": 71832774,
"stddev": 2.4683187,
"median": 2,
"percentileMap": {
"95": 4
},
"metricName": "TransactionDuration",
"dimensions": {
"env": "dev",
"pool": "titan",
"Name": "DataSync",
"Type": "DataSync"
},
"value": 14104200
}
]
}
}
Similarly I am also getting another JSON response back by calling urlB
and it is in the exact same JSON format as shown above, but the values for all the keys are different.
Now what I need to do is, I need to serialize JSON response coming from both the URLs (urlA
and urlB
) in DataTransactionMetrics
object only and then iterate DataTransactionMetrics
object and extract relevant information from it in which I am interested in it. Meaning, I will be extracting few Name
values from the DataTransactionMetrics
object in which I am interested in it and populate it into hostMetricsList
object and at the end print out the full list.
Below is my full code which does the JSON serialization of both the URL's -
private static final List<String> hostNames = Arrays.asList("hostA", "hostB", "hostC");
public static void main(String[] args) throws IOException {
List<HostMetrics> hostMetricsList = new ArrayList<HostMetrics>();
for (String hostName : hostNames) {
Calendar startDate = new GregorianCalendar();
startDate.set(Calendar.MINUTE, 0);
Calendar endDate = (Calendar) startDate.clone();
startDate.set(Calendar.HOUR_OF_DAY, 0);
HostMetrics hostMetrics = new HostMetrics(hostName, startDate, endDate);
hostMetricsList.add(hostMetrics);
}
// and then print out the list
System.out.println(hostMetricsList);
}
And below is my DataTransactionMetrics
class -
public class DataTransactionMetrics {
private String metricName;
private Map<String, Integer> percentileMap;
private String median;
private String stddev;
private String sumSq;
private String count;
private String avg;
private String max;
private String min;
// getters here
public Dimensions dimensions;
class Dimensions {
private String env;
private String pool;
@SerializedName("Name")
private String name;
// getters here
}
}
And below is my HostMetrics
class which has all the logic. Can we do some improvements here?
public class HostMetrics {
private String hostName;
private String totalNumberOfSyncCall;
private String syncNinetyFivePercentileCall;
private String syncAvgCall;
private String syncMaxCall;
private String totalNumberOfAsyncCall;
private String asyncNinetyFivePercentileCall;
private String asyncAvgCall;
private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm");
private static RestTemplate restTemplate = new RestTemplate();
private static final Gson gson = new Gson();
private static final Type listOfMetricsType = new TypeToken<List<DataTransactionMetrics>>() {}.getType();
private static final String BASE_URL = "http://data.host.com/reports/";
private static final String TRANSACTION_METRIC = "/Transaction?defaultDim=Name&defaultDim=Type&metric=TransactionDuration&percentile=95";
private static final String EVENT_METRIC = "/Event?defaultDim=Name&defaultDim=Type&metric=TotalCount&percentile=95";
public HostMetrics(String hostname, Calendar startDate, Calendar endDate) {
constructURL(hostname, startDate, endDate);
}
private void constructURL(String hostname, Calendar startDate, Calendar endDate) {
String startTime = df.format(startDate.getTime());
String endTime = df.format(endDate.getTime());
// construct urlA
String urlA = BASE_URL + hostName + TRANSACTION_METRIC + "&startTime=" + startTime
+ "&endTime=" + endTime;
// construct urlB
String urlB = BASE_URL + hostName + EVENT_METRIC + "&startTime=" + startTime
+ "&endTime=" + endTime;
// serialize everything in DataTransactionMetrics object, both the URL's
List<DataTransactionMetrics> dataMetrics = loadMetrics(urlA);
dataMetrics.addAll(loadMetrics(urlB));
hostName = hostname;
for (DataTransactionMetrics metrics : clientMetrics) {
if (metrics.getDimensions().getName().equalsIgnoreCase("DataSync")) {
totalNumberOfSyncCall = metrics.getCount();
syncNinetyFivePercentileCall = String.valueOf(metrics.getPercentileMap().get("95"));
syncAvgCall = metrics.getAvg();
syncMaxCall = metrics.getMax();
} else if (metrics.getDimensions().getName().equalsIgnoreCase("DataASync")) {
totalNumberOfAsyncCall = metrics.getCount();
asyncNinetyFivePercentileCall = String.valueOf(metrics.getPercentileMap().get("95"));
asyncAvgCall = metrics.getAvg();
}
}
}
private static List<DataTransactionMetrics> loadMetrics(String url) {
String jsonString = restTemplate.getForObject(url, String.class);
JsonObject json = new JsonParser().parse(jsonString).getAsJsonObject();
JsonArray jarr = json.getAsJsonObject("aggRecords").getAsJsonArray("reportRecords");
return gson.fromJson(jarr, listOfMetricsType);
}
// toString method here
}
Now I have got everything working in the above code. I am opting for code review to see whether we can improve anything here in the code.