From f6cc5f269fd4391a75edaea6fb23e846d413029e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Thu, 21 Nov 2019 10:54:08 +0100 Subject: Add basic data fetching backend --- .../edu/mimuw/cloudatlas/client/ClientController.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java index 022c665..be853b9 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java @@ -202,6 +202,23 @@ public class ClientController { @GetMapping("/values") public String valuesPage(Model model) { + model.addAttribute("zoneName", new ContactsString()); + return "attribChart"; + } + + @PostMapping("/values") + public String valuesPage(@ModelAttribute ContactsString zoneName, Model model) { + boolean success = true; + AttributesMap attribData; + + try { + attribData = api.getZoneAttributeValues(zoneName.getString()); + } catch (Exception e) { + success = false; + System.err.println("Client exception:"); + e.printStackTrace(); + } + return "attribChart"; } } -- cgit v1.2.3 From d81a616cfbcd0148ce2f8914693527ec164d80d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Thu, 21 Nov 2019 18:41:30 +0100 Subject: Add zone prompt to attribs chart html --- .../edu/mimuw/cloudatlas/client/templates/attribChart.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/main') diff --git a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html index 7e0b37f..29721e8 100644 --- a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html +++ b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html @@ -34,6 +34,18 @@
+
+
+
+ + + + +
+ +
+
+
-- cgit v1.2.3 From 6770de681fa2f6cce05f709b2fce93a606194faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Thu, 21 Nov 2019 18:42:24 +0100 Subject: Add zone fetch backend for zone prompt --- .../mimuw/cloudatlas/client/ClientController.java | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java index be853b9..df32f50 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java @@ -200,8 +200,30 @@ public class ClientController { return "home"; } + private String getAvailableZonesString() { + boolean success = true; + Set availableZones; + String availableZonesString = ""; + + try { + availableZones = api.getZoneSet(); + availableZonesString = availableZones.toString().substring(1, availableZones.toString().length() - 1); + } catch (Exception e) { + success = false; + System.err.println("Client exception:"); + e.printStackTrace(); + } + + if (success) { + return "Available zones are: " + availableZonesString; + } else { + return "No zones available, error occured during fetch"; + } + } + @GetMapping("/values") public String valuesPage(Model model) { + model.addAttribute("availableZones", getAvailableZonesString()); model.addAttribute("zoneName", new ContactsString()); return "attribChart"; } @@ -219,6 +241,7 @@ public class ClientController { e.printStackTrace(); } + model.addAttribute("availableZones", getAvailableZonesString()); return "attribChart"; } } -- cgit v1.2.3 From e1f6630b45fa63f41b8ffc5976d195e6995907c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Thu, 21 Nov 2019 21:06:55 +0100 Subject: Add periodic attribute values fetch and storage --- .../pl/edu/mimuw/cloudatlas/client/Client.java | 2 ++ .../mimuw/cloudatlas/client/ClientController.java | 40 +++++++++++++++++----- .../cloudatlas/client/templates/attribChart.html | 2 +- 3 files changed, 34 insertions(+), 10 deletions(-) (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/Client.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/Client.java index b63e4fd..ca9e7e0 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/Client.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/Client.java @@ -2,8 +2,10 @@ package pl.edu.mimuw.cloudatlas.client; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication +@EnableScheduling public class Client { public static void main(String[] args) { SpringApplication.run(Client.class, args); diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java index df32f50..510b721 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java @@ -1,6 +1,7 @@ package pl.edu.mimuw.cloudatlas.client; import com.google.gson.Gson; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.stereotype.Controller; @@ -11,10 +12,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; /* should enable reading attribute values stored by the agent @@ -31,6 +29,9 @@ plotting the attributes with numeric values as real-time graphs. public class ClientController { private Api api; + private Map attributes; + private String currentZoneName; + ClientController() { try { Registry registry = LocateRegistry.getRegistry("localhost"); @@ -39,6 +40,9 @@ public class ClientController { System.err.println("Client exception:"); e.printStackTrace(); } + + this.attributes = new LinkedHashMap(); + this.currentZoneName = "/"; } @GetMapping("/") @@ -224,23 +228,41 @@ public class ClientController { @GetMapping("/values") public String valuesPage(Model model) { model.addAttribute("availableZones", getAvailableZonesString()); + model.addAttribute("currentZone", "Current zone: " + this.currentZoneName); model.addAttribute("zoneName", new ContactsString()); return "attribChart"; } - @PostMapping("/values") - public String valuesPage(@ModelAttribute ContactsString zoneName, Model model) { - boolean success = true; + @Scheduled(fixedRate = 5000) + private void fetchAttributeData() { AttributesMap attribData; + ValueTime currentTime; try { - attribData = api.getZoneAttributeValues(zoneName.getString()); + if (!this.currentZoneName.isEmpty()) { + attribData = api.getZoneAttributeValues(this.currentZoneName); + currentTime = new ValueTime(System.currentTimeMillis()); + this.attributes.put(currentTime, attribData); + System.out.println(currentTime.toString() + ": " + attribData.toString()); + } } catch (Exception e) { - success = false; System.err.println("Client exception:"); e.printStackTrace(); } + Iterator it = this.attributes.keySet().iterator(); + while (it.hasNext() && this.attributes.size() > 1000) { + it.next(); + it.remove(); + System.out.println(this.attributes.toString()); + } + } + + @PostMapping("/values") + public String valuesPage(@ModelAttribute ContactsString zoneName, Model model) { + this.currentZoneName = zoneName.getString(); + this.attributes.clear(); + model.addAttribute("currentZone", "Current zone: " + this.currentZoneName); model.addAttribute("availableZones", getAvailableZonesString()); return "attribChart"; } diff --git a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html index 29721e8..2a9e1e0 100644 --- a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html +++ b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html @@ -34,6 +34,7 @@
+

@@ -45,7 +46,6 @@
-
-- cgit v1.2.3 From 7f776e3dfba1db479a208e274f6b191f22a5c6b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Thu, 21 Nov 2019 21:10:43 +0100 Subject: Remove debug messages --- src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java index 510b721..bb19ac4 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java @@ -243,7 +243,6 @@ public class ClientController { attribData = api.getZoneAttributeValues(this.currentZoneName); currentTime = new ValueTime(System.currentTimeMillis()); this.attributes.put(currentTime, attribData); - System.out.println(currentTime.toString() + ": " + attribData.toString()); } } catch (Exception e) { System.err.println("Client exception:"); @@ -254,7 +253,6 @@ public class ClientController { while (it.hasNext() && this.attributes.size() > 1000) { it.next(); it.remove(); - System.out.println(this.attributes.toString()); } } -- cgit v1.2.3 From adb0285565a4afb93e55d17fb615a60c49b98901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Fri, 22 Nov 2019 12:41:54 +0100 Subject: Add data processing functions for charts and small fixes --- .../pl/edu/mimuw/cloudatlas/client/Attribute.java | 51 ---------------- .../mimuw/cloudatlas/client/AttributeInput.java | 51 ++++++++++++++++ .../mimuw/cloudatlas/client/ClientController.java | 69 ++++++++++++++++++---- .../mimuw/cloudatlas/client/ContactsString.java | 20 ------- .../mimuw/cloudatlas/client/DataStringInput.java | 20 +++++++ .../cloudatlas/client/templates/attribChart.html | 4 +- 6 files changed, 131 insertions(+), 84 deletions(-) delete mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/client/Attribute.java create mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/client/AttributeInput.java delete mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/client/ContactsString.java create mode 100644 src/main/java/pl/edu/mimuw/cloudatlas/client/DataStringInput.java (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/Attribute.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/Attribute.java deleted file mode 100644 index abaa02a..0000000 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/Attribute.java +++ /dev/null @@ -1,51 +0,0 @@ -package pl.edu.mimuw.cloudatlas.client; - -import pl.edu.mimuw.cloudatlas.model.Value; - -public class Attribute { - private String zoneName; - private String attributeName; - private String valueString; - private String attributeType; - private Value value; - - public String getZoneName() { - return zoneName; - } - - public void setZoneName(String zoneName) { - this.zoneName = zoneName; - } - - public String getAttributeName() { - return attributeName; - } - - public void setAttributeName(String attributeName) { - this.attributeName = attributeName; - } - - public String getValueString() { - return valueString; - } - - public void setValueString(String valueString) { - this.valueString = valueString; - } - - public Value getValue() { - return value; - } - - public void setValue(Value value) { - this.value = value; - } - - public String getAttributeType() { - return attributeType; - } - - public void setAttributeType(String attributeType) { - this.attributeType = attributeType; - } -} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/AttributeInput.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/AttributeInput.java new file mode 100644 index 0000000..58e1a30 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/AttributeInput.java @@ -0,0 +1,51 @@ +package pl.edu.mimuw.cloudatlas.client; + +import pl.edu.mimuw.cloudatlas.model.Value; + +public class AttributeInput { + private String zoneName; + private String attributeName; + private String valueString; + private String attributeType; + private Value value; + + public String getZoneName() { + return zoneName; + } + + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + + public String getAttributeName() { + return attributeName; + } + + public void setAttributeName(String attributeName) { + this.attributeName = attributeName; + } + + public String getValueString() { + return valueString; + } + + public void setValueString(String valueString) { + this.valueString = valueString; + } + + public Value getValue() { + return value; + } + + public void setValue(Value value) { + this.value = value; + } + + public String getAttributeType() { + return attributeType; + } + + public void setAttributeType(String attributeType) { + this.attributeType = attributeType; + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java index bb19ac4..58770b6 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java @@ -9,7 +9,6 @@ import pl.edu.mimuw.cloudatlas.api.Api; import pl.edu.mimuw.cloudatlas.model.*; import java.net.InetAddress; -import java.net.UnknownHostException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.util.*; @@ -84,11 +83,11 @@ public class ClientController { @GetMapping("/contacts") public String contactPage(Model model) { - model.addAttribute("contactsObject" , new ContactsString()); + model.addAttribute("contactsObject" , new DataStringInput()); return "contactsForm"; } - private Set parseContactsString(ContactsString contactsInput) throws Exception { + private Set parseContactsString(DataStringInput contactsInput) throws Exception { Gson gson = new Gson(); Map contactStrings = gson.fromJson(contactsInput.getString(), Map.class); Set contactObjects = new HashSet(); @@ -110,7 +109,7 @@ public class ClientController { } @PostMapping("/contacts") - public String contactPage(@ModelAttribute ContactsString contactsObject, Model model) { + public String contactPage(@ModelAttribute DataStringInput contactsObject, Model model) { boolean success = true; Set contactObjects; @@ -134,11 +133,11 @@ public class ClientController { @GetMapping("/attribs") public String attribPage(Model model) { - model.addAttribute("attributeObject", new Attribute()); + model.addAttribute("attributeObject", new AttributeInput()); return "attribForm"; } - private Value parseAttributeValue(Attribute attributeObject) throws Exception { + private Value parseAttributeValue(AttributeInput attributeObject) throws Exception { Value attributeValue = null; switch (attributeObject.getAttributeType()) { @@ -163,7 +162,7 @@ public class ClientController { attributeValue = new ValueDuration(attributeObject.getValueString()); break; case "Contact": - ContactsString contactsString = new ContactsString(); + DataStringInput contactsString = new DataStringInput(); contactsString.setString(attributeObject.getValueString()); attributeValue = parseContactsString(contactsString).iterator().next(); break; @@ -179,7 +178,7 @@ public class ClientController { } @PostMapping("/attribs") - public String attribPage(@ModelAttribute Attribute attributeObject, Model model) { + public String attribPage(@ModelAttribute AttributeInput attributeObject, Model model) { boolean success = true; Value attributeValue; @@ -229,7 +228,7 @@ public class ClientController { public String valuesPage(Model model) { model.addAttribute("availableZones", getAvailableZonesString()); model.addAttribute("currentZone", "Current zone: " + this.currentZoneName); - model.addAttribute("zoneName", new ContactsString()); + model.addAttribute("zoneName", new DataStringInput()); return "attribChart"; } @@ -250,18 +249,66 @@ public class ClientController { } Iterator it = this.attributes.keySet().iterator(); - while (it.hasNext() && this.attributes.size() > 1000) { + while (it.hasNext() && this.attributes.size() > 50) { it.next(); it.remove(); } } + private boolean isValueNumerical(Value val) { + Type valType = val.getType(); + + if (TypePrimitive.DOUBLE.isCompatible(valType) || + TypePrimitive.INTEGER.isCompatible(valType) || + TypePrimitive.TIME.isCompatible(valType) || + TypePrimitive.DURATION.isCompatible(valType)) { + return true; + } else { + return false; + } + } + + private String processAttribNumValues() { + String jsonAttributes = ""; + Gson gson = new Gson(); + Value val; + ArrayList> chartValues = new ArrayList<>(); + ArrayList chartValueNames = new ArrayList<>(); + + System.out.println(this.attributes); + for (AttributesMap m : this.attributes.values()) { + ArrayList chartValueColumn = new ArrayList<>(); + chartValueNames.clear(); + for (Map.Entry e : m) { + val = e.getValue(); + System.out.println(val); + if (isValueNumerical(val)) { + chartValueNames.add(e.getKey().getName()); + chartValueColumn.add(val.toString()); + } + } + chartValues.add(chartValueColumn); + } + + chartValues.add(0, chartValueNames); + jsonAttributes = gson.toJson(chartValues); + System.out.println(jsonAttributes); + return jsonAttributes; + } + + @GetMapping("/attribNumValues") + @ResponseBody + public String attribNumValuesApi() { + return processAttribNumValues(); + } + @PostMapping("/values") - public String valuesPage(@ModelAttribute ContactsString zoneName, Model model) { + public String valuesPage(@ModelAttribute DataStringInput zoneName, Model model) { this.currentZoneName = zoneName.getString(); this.attributes.clear(); model.addAttribute("currentZone", "Current zone: " + this.currentZoneName); model.addAttribute("availableZones", getAvailableZonesString()); + model.addAttribute("zoneName", new DataStringInput()); return "attribChart"; } } diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ContactsString.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ContactsString.java deleted file mode 100644 index 7cdd82e..0000000 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ContactsString.java +++ /dev/null @@ -1,20 +0,0 @@ -package pl.edu.mimuw.cloudatlas.client; - -public class ContactsString { - private String string; - - public String getString() { - return string; - } - - public void setString(String string) { - this.string = string; - } - - @Override - public String toString() { - return "ContactString{" + - "string='" + string + '\'' + - '}'; - } -} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/DataStringInput.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/DataStringInput.java new file mode 100644 index 0000000..e1465c7 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/DataStringInput.java @@ -0,0 +1,20 @@ +package pl.edu.mimuw.cloudatlas.client; + +public class DataStringInput { + private String string; + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } + + @Override + public String toString() { + return "ContactString{" + + "string='" + string + '\'' + + '}'; + } +} diff --git a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html index 2a9e1e0..a476301 100644 --- a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html +++ b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html @@ -6,6 +6,8 @@ Attributes chart + + - -- cgit v1.2.3 From f4d89b38e6540e0d50b6907989bd2ee79a18d08e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Fri, 22 Nov 2019 17:08:45 +0100 Subject: Add chart refreshing --- .../cloudatlas/client/templates/attribChart.html | 31 +++++++++++++--------- 1 file changed, 18 insertions(+), 13 deletions(-) (limited to 'src/main') diff --git a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html index a476301..d1353ed 100644 --- a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html +++ b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html @@ -10,24 +10,29 @@ -- cgit v1.2.3 From 2ae058e3465b2ba2495c294b82c65de5d48eb7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Fri, 22 Nov 2019 17:09:31 +0100 Subject: Add proper data processing for attribute chart --- .../mimuw/cloudatlas/client/ClientController.java | 71 +++++++++++++++++----- 1 file changed, 56 insertions(+), 15 deletions(-) (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java index 58770b6..a4a9097 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java @@ -8,9 +8,11 @@ import org.springframework.stereotype.Controller; import pl.edu.mimuw.cloudatlas.api.Api; import pl.edu.mimuw.cloudatlas.model.*; +import java.lang.reflect.Array; import java.net.InetAddress; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; +import java.time.format.DateTimeFormatter; import java.util.*; /* @@ -255,6 +257,27 @@ public class ClientController { } } + private ArrayList getNumericalValues(AttributesMap attribs) { + Value val; + Type valType; + ArrayList valuesList = new ArrayList<>(); + + for (Map.Entry entry : attribs) { + val = entry.getValue(); + valType = val.getType(); + if (TypePrimitive.DOUBLE.isCompatible(valType)) { + valuesList.add(Double.parseDouble(val.toString())); + } else if (TypePrimitive.INTEGER.isCompatible(valType)) { + valuesList.add(Long.parseLong(val.toString())); + } else if (TypePrimitive.TIME.isCompatible(valType)) { + valuesList.add(Long.parseLong(val.toString())); + } else if (TypePrimitive.DURATION.isCompatible(valType)) { + valuesList.add(Long.parseLong(val.convertTo(TypePrimitive.INTEGER).toString())); + } + } + return valuesList; + } + private boolean isValueNumerical(Value val) { Type valType = val.getType(); @@ -268,29 +291,47 @@ public class ClientController { } } - private String processAttribNumValues() { - String jsonAttributes = ""; - Gson gson = new Gson(); - Value val; - ArrayList> chartValues = new ArrayList<>(); + private AttributesMap getLastAttributesMap() { + ArrayList> attribsMap = new ArrayList<>(this.attributes.entrySet()); + return attribsMap.get(attribsMap.size() - 1).getValue(); + } + + private ArrayList getChartColumnNames() { ArrayList chartValueNames = new ArrayList<>(); + AttributesMap lastAttribMap = getLastAttributesMap(); + + for (Map.Entry e : lastAttribMap) { + if (isValueNumerical(e.getValue())) { + chartValueNames.add(e.getKey().getName()); + } + } + chartValueNames.add(0, "Timestamp"); + return chartValueNames; + } + + private ArrayList getNumericalValuesTable() { + ArrayList chartValues = new ArrayList<>(); + ArrayList chartValueNames = getChartColumnNames(); + ArrayList chartValueColumn; System.out.println(this.attributes); - for (AttributesMap m : this.attributes.values()) { - ArrayList chartValueColumn = new ArrayList<>(); - chartValueNames.clear(); - for (Map.Entry e : m) { - val = e.getValue(); - System.out.println(val); - if (isValueNumerical(val)) { - chartValueNames.add(e.getKey().getName()); - chartValueColumn.add(val.toString()); - } + for (Map.Entry attribsMap : this.attributes.entrySet()) { + chartValueColumn = getNumericalValues(attribsMap.getValue()); + chartValueColumn.add(0, attribsMap.getKey().toString().substring(11, 19)); + while (chartValueColumn.size() < chartValueNames.size()) { + chartValueColumn.add(null); } chartValues.add(chartValueColumn); } chartValues.add(0, chartValueNames); + return chartValues; + } + + private String processAttribNumValues() { + String jsonAttributes = ""; + Gson gson = new Gson(); + ArrayList chartValues = getNumericalValuesTable(); jsonAttributes = gson.toJson(chartValues); System.out.println(jsonAttributes); return jsonAttributes; -- cgit v1.2.3 From 9f2ffecdf146a9def7bc90e877e1d69fa53fd022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Fri, 22 Nov 2019 18:07:36 +0100 Subject: Enhance naming and add comments --- .../pl/edu/mimuw/cloudatlas/client/ClientController.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java index a4a9097..e40484e 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java @@ -8,11 +8,9 @@ import org.springframework.stereotype.Controller; import pl.edu.mimuw.cloudatlas.api.Api; import pl.edu.mimuw.cloudatlas.model.*; -import java.lang.reflect.Array; import java.net.InetAddress; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; -import java.time.format.DateTimeFormatter; import java.util.*; /* @@ -257,7 +255,7 @@ public class ClientController { } } - private ArrayList getNumericalValues(AttributesMap attribs) { + private ArrayList getNumericalAttributeValue(AttributesMap attribs) { Value val; Type valType; ArrayList valuesList = new ArrayList<>(); @@ -296,7 +294,7 @@ public class ClientController { return attribsMap.get(attribsMap.size() - 1).getValue(); } - private ArrayList getChartColumnNames() { + private ArrayList getNumericalColumnNames() { ArrayList chartValueNames = new ArrayList<>(); AttributesMap lastAttribMap = getLastAttributesMap(); @@ -309,14 +307,16 @@ public class ClientController { return chartValueNames; } + // data format compatible with Google Line Chart + // https://developers.google.com/chart/interactive/docs/gallery/linechart private ArrayList getNumericalValuesTable() { ArrayList chartValues = new ArrayList<>(); - ArrayList chartValueNames = getChartColumnNames(); + ArrayList chartValueNames = getNumericalColumnNames(); ArrayList chartValueColumn; System.out.println(this.attributes); for (Map.Entry attribsMap : this.attributes.entrySet()) { - chartValueColumn = getNumericalValues(attribsMap.getValue()); + chartValueColumn = getNumericalAttributeValue(attribsMap.getValue()); chartValueColumn.add(0, attribsMap.getKey().toString().substring(11, 19)); while (chartValueColumn.size() < chartValueNames.size()) { chartValueColumn.add(null); -- cgit v1.2.3 From 137c4b5ca7ec1a384e053ec3460a913d2c8e352a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Fri, 22 Nov 2019 20:44:43 +0100 Subject: Add table drawing frontend --- .../cloudatlas/client/templates/attribChart.html | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/main') diff --git a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html index d1353ed..52a8458 100644 --- a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html +++ b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html @@ -9,6 +9,7 @@ @@ -53,6 +71,7 @@
+
-- cgit v1.2.3 From 2f0d6c452b2600aae00297dc92ff77173586e3c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Fri, 22 Nov 2019 20:45:18 +0100 Subject: Make AttributesMap a LinkedHashMap for ease of handling --- src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesMap.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesMap.java b/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesMap.java index c74c1df..3391417 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesMap.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/model/AttributesMap.java @@ -27,6 +27,7 @@ package pl.edu.mimuw.cloudatlas.model; import java.io.Serializable; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; @@ -34,7 +35,7 @@ import java.util.Map.Entry; * Represents a map from Attribute to Value. It cannot contain duplicate keys. */ public class AttributesMap implements Iterable>, Cloneable, Serializable { - private Map map = new HashMap(); + private Map map = new LinkedHashMap(); private void checkNulls(Attribute attribute, Value value) { if(attribute == null) -- cgit v1.2.3 From ea9cc3590b1401663e2d52f233218450ef430f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Fri, 22 Nov 2019 20:45:52 +0100 Subject: Add data processing for all values retrieval --- .../mimuw/cloudatlas/client/ClientController.java | 92 +++++++++++----------- 1 file changed, 47 insertions(+), 45 deletions(-) (limited to 'src/main') diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java index e40484e..ae649c0 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/client/ClientController.java @@ -30,6 +30,7 @@ public class ClientController { private Map attributes; private String currentZoneName; + private static final int MAX_ENTRIES = 10; ClientController() { try { @@ -40,8 +41,12 @@ public class ClientController { e.printStackTrace(); } - this.attributes = new LinkedHashMap(); - this.currentZoneName = "/"; + this.attributes = new LinkedHashMap() { + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > MAX_ENTRIES; + } + }; + this.currentZoneName = "/uw/violet07"; } @GetMapping("/") @@ -247,42 +252,30 @@ public class ClientController { System.err.println("Client exception:"); e.printStackTrace(); } - - Iterator it = this.attributes.keySet().iterator(); - while (it.hasNext() && this.attributes.size() > 50) { - it.next(); - it.remove(); - } } - private ArrayList getNumericalAttributeValue(AttributesMap attribs) { - Value val; - Type valType; + private ArrayList getAllAttributeValues(AttributesMap attribs, Boolean justNumerical) { ArrayList valuesList = new ArrayList<>(); + Value val; for (Map.Entry entry : attribs) { val = entry.getValue(); - valType = val.getType(); - if (TypePrimitive.DOUBLE.isCompatible(valType)) { + // casting to ValueDouble and ValueInt caused some errors + // and gson turns all numerical values into doubles anyway + if (justNumerical && isValueNumerical(val)) { valuesList.add(Double.parseDouble(val.toString())); - } else if (TypePrimitive.INTEGER.isCompatible(valType)) { - valuesList.add(Long.parseLong(val.toString())); - } else if (TypePrimitive.TIME.isCompatible(valType)) { - valuesList.add(Long.parseLong(val.toString())); - } else if (TypePrimitive.DURATION.isCompatible(valType)) { - valuesList.add(Long.parseLong(val.convertTo(TypePrimitive.INTEGER).toString())); + } else if (!justNumerical) { + valuesList.add(val.toString()); } } + return valuesList; } private boolean isValueNumerical(Value val) { Type valType = val.getType(); - if (TypePrimitive.DOUBLE.isCompatible(valType) || - TypePrimitive.INTEGER.isCompatible(valType) || - TypePrimitive.TIME.isCompatible(valType) || - TypePrimitive.DURATION.isCompatible(valType)) { + if (TypePrimitive.DOUBLE.isCompatible(valType) || TypePrimitive.INTEGER.isCompatible(valType)) { return true; } else { return false; @@ -294,12 +287,12 @@ public class ClientController { return attribsMap.get(attribsMap.size() - 1).getValue(); } - private ArrayList getNumericalColumnNames() { + private ArrayList getAttributesColumnNames(Boolean justNumerical) { ArrayList chartValueNames = new ArrayList<>(); AttributesMap lastAttribMap = getLastAttributesMap(); for (Map.Entry e : lastAttribMap) { - if (isValueNumerical(e.getValue())) { + if (!justNumerical || isValueNumerical(e.getValue())) { chartValueNames.add(e.getKey().getName()); } } @@ -307,32 +300,35 @@ public class ClientController { return chartValueNames; } - // data format compatible with Google Line Chart - // https://developers.google.com/chart/interactive/docs/gallery/linechart - private ArrayList getNumericalValuesTable() { - ArrayList chartValues = new ArrayList<>(); - ArrayList chartValueNames = getNumericalColumnNames(); - ArrayList chartValueColumn; - - System.out.println(this.attributes); - for (Map.Entry attribsMap : this.attributes.entrySet()) { - chartValueColumn = getNumericalAttributeValue(attribsMap.getValue()); - chartValueColumn.add(0, attribsMap.getKey().toString().substring(11, 19)); - while (chartValueColumn.size() < chartValueNames.size()) { - chartValueColumn.add(null); + // data format compatible with Google Charts Table and Google Line Chart input + // but it's a generic 2d array table representation + // https://developers.google.com/chart/interactive/docs/gallery/table + private ArrayList getValuesTable(Boolean justNumerical) { + ArrayList valueRow; + ArrayList allValues = new ArrayList<>(); + ArrayList valueNames = getAttributesColumnNames(justNumerical); + + for (Map.Entry attribMapEntry : this.attributes.entrySet()) { + valueRow = getAllAttributeValues(attribMapEntry.getValue(), justNumerical); + while (valueRow.size() < valueNames.size() - 1) { + valueRow.add(null); } - chartValues.add(chartValueColumn); + valueRow.add(0, attribMapEntry.getKey().toString().substring(11, 19)); + allValues.add(valueRow); } - chartValues.add(0, chartValueNames); - return chartValues; + // optional trimming of table length + // if (allValues.size() > 10) { + // allValues = new ArrayList(allValues.subList(allValues.size() - 11, allValues.size() - 1)); + // } + allValues.add(0, valueNames); + return allValues; } - private String processAttribNumValues() { + private String processAttribValues(ArrayList valuesTable) { String jsonAttributes = ""; Gson gson = new Gson(); - ArrayList chartValues = getNumericalValuesTable(); - jsonAttributes = gson.toJson(chartValues); + jsonAttributes = gson.toJson(valuesTable); System.out.println(jsonAttributes); return jsonAttributes; } @@ -340,7 +336,13 @@ public class ClientController { @GetMapping("/attribNumValues") @ResponseBody public String attribNumValuesApi() { - return processAttribNumValues(); + return processAttribValues(getValuesTable(true)); + } + + @GetMapping("/attribAllValues") + @ResponseBody + public String attribAllValuesApi() { + return processAttribValues(getValuesTable(false)); } @PostMapping("/values") -- cgit v1.2.3 From af0519c958a72ee3e2432c0089009ec4f905a0f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magdalena=20Grodzi=C5=84ska?= Date: Sat, 23 Nov 2019 20:35:52 +0100 Subject: Small fixes to charts --- .../pl/edu/mimuw/cloudatlas/client/templates/attribChart.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main') diff --git a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html index 52a8458..1a49261 100644 --- a/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html +++ b/src/main/resources/pl/edu/mimuw/cloudatlas/client/templates/attribChart.html @@ -32,8 +32,9 @@ var options = { title: 'Attribute values', hAxis: {title: 'Timestamp', titleTextStyle: {color: '#333'}}, - vAxis: {minValue: 0}, - interpolateNulls: true + vAxis: {scaleType: 'log'}, + interpolateNulls: true, + crosshair: {trigger: 'both', orientation: 'vertical'} }; var chart = new google.visualization.LineChart(document.getElementById('chart_div')); -- cgit v1.2.3