|
|
@@ -1,160 +1,213 @@
|
|
|
-package cz.senslog.watchdog.provider.ws;
|
|
|
-
|
|
|
-import com.google.gson.reflect.TypeToken;
|
|
|
-import cz.senslog.watchdog.config.WSSensLogDataProviderConfig;
|
|
|
-import cz.senslog.watchdog.provider.*;
|
|
|
-import cz.senslog.watchdog.util.Tuple;
|
|
|
-import cz.senslog.watchdog.util.http.HttpClient;
|
|
|
-import cz.senslog.watchdog.util.http.HttpRequest;
|
|
|
-import cz.senslog.watchdog.util.http.HttpResponse;
|
|
|
-import cz.senslog.watchdog.util.http.URLBuilder;
|
|
|
-import org.apache.logging.log4j.LogManager;
|
|
|
-import org.apache.logging.log4j.Logger;
|
|
|
-
|
|
|
-import java.lang.reflect.Type;
|
|
|
-import java.time.OffsetDateTime;
|
|
|
-import java.time.format.DateTimeFormatter;
|
|
|
-import java.util.*;
|
|
|
-
|
|
|
-import static cz.senslog.watchdog.config.DataProviderType.WEB_SERVICE;
|
|
|
-import static cz.senslog.watchdog.util.json.BasicJson.jsonToObject;
|
|
|
-import static java.time.format.DateTimeFormatter.ofPattern;
|
|
|
-import static java.util.Collections.*;
|
|
|
-
|
|
|
-public class WSSensLogDataProvider implements DataProvider {
|
|
|
-
|
|
|
- private static final Logger logger = LogManager.getLogger(WSSensLogDataProvider.class);
|
|
|
-
|
|
|
- private static final String ERROR_KEY = "__error";
|
|
|
-
|
|
|
- private static final String DEFAULT_NAME = "unknown";
|
|
|
- private static final Tuple<String, Map<String, String>> DEFAULT_UNIT_INFO = Tuple.of(DEFAULT_NAME, emptyMap());
|
|
|
-
|
|
|
- private static final DateTimeFormatter TIMESTAMP_PATTERN = ofPattern("yyyy-MM-dd HH:mm:ssX");
|
|
|
-
|
|
|
- private final HttpClient httpClient = HttpClient.newHttpClient();
|
|
|
- private final WSSensLogDataProviderConfig config;
|
|
|
-
|
|
|
- public WSSensLogDataProvider(WSSensLogDataProviderConfig config) {
|
|
|
- this.config = config;
|
|
|
- }
|
|
|
-
|
|
|
- /* Map<unitId, Tuple<unitName, Map<sensorId, sensorName>>> */
|
|
|
- private Map<String, Tuple<String, Map<String, String>>> loadUnitsInfo() {
|
|
|
- HttpRequest request = HttpRequest.newBuilder().GET()
|
|
|
- .url(URLBuilder.newBuilder(config.getBaseUrl(), "/DataService")
|
|
|
- .addParam("Operation", "GetUnits")
|
|
|
- .addParam("group", config.getGroupName())
|
|
|
- .addParam("user", config.getUserName())
|
|
|
- .build()
|
|
|
- ).build();
|
|
|
- logger.info("Getting new data from the server: {}.", request.getUrl());
|
|
|
-
|
|
|
- HttpResponse response = httpClient.send(request);
|
|
|
- logger.info("Received data with the status '{}' from the server {}.", response.getStatus(), request.getUrl());
|
|
|
-
|
|
|
- if (response.isError()) {
|
|
|
- logger.error("code: {}, message: {}", response.getStatus(), response.getBody());
|
|
|
- Map<String, Tuple<String, Map<String, String>>> errorMap = new HashMap<>();
|
|
|
- errorMap.put(ERROR_KEY, Tuple.of(response.getBody(), emptyMap()));
|
|
|
- return errorMap;
|
|
|
- }
|
|
|
-
|
|
|
- Map<String, Tuple<String, Map<String, String>>> unitsInfo = new HashMap<>();
|
|
|
-
|
|
|
- final Type unitInfoType = new TypeToken<Collection<Map<String, Object>>>() {}.getType();
|
|
|
- List<Map<String, Object>> unitInfoList = jsonToObject(response.getBody(), unitInfoType);
|
|
|
- for (Map<String, Object> unitInfo : unitInfoList) {
|
|
|
- Object unitObj = unitInfo.get("unit");
|
|
|
- if (unitObj instanceof Map) {
|
|
|
- Map<?, ?> unitMap = (Map<?, ?>)unitObj;
|
|
|
- String unitName = unitMap.get("description").toString();
|
|
|
- String unitId = String.format("%d", ((Double)unitMap.get("unitId")).longValue());
|
|
|
-
|
|
|
- Map<String, String> resultSensorInfo = new HashMap<>();
|
|
|
- Object sensorsObj = unitInfo.get("sensors");
|
|
|
- if (sensorsObj instanceof List) {
|
|
|
- List<?> sensorsList = (List<?>)sensorsObj;
|
|
|
- for (Object sensorInfoObj : sensorsList) {
|
|
|
- if (sensorInfoObj instanceof Map) {
|
|
|
- Map<?, ?> sensorMap = (Map<?, ?>)sensorInfoObj;
|
|
|
- String sensorName = sensorMap.get("sensorName").toString();
|
|
|
- String sensorId = String.format("%d", ((Double)sensorMap.get("sensorId")).longValue());
|
|
|
-
|
|
|
- resultSensorInfo.put(sensorId, sensorName);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- unitsInfo.put(unitId, Tuple.of(unitName, resultSensorInfo));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return unitsInfo;
|
|
|
- }
|
|
|
-
|
|
|
- private List<Map<String, Object>> loadLastObservations() {
|
|
|
- HttpRequest request = HttpRequest.newBuilder().GET()
|
|
|
- .url(URLBuilder.newBuilder(config.getBaseUrl(), "/SensorService")
|
|
|
- .addParam("Operation", "GetLastObservations")
|
|
|
- .addParam("group", config.getGroupName())
|
|
|
- .addParam("user", config.getUserName())
|
|
|
- .build()
|
|
|
- ).build();
|
|
|
- logger.info("Getting new data from the server: {}.", request.getUrl());
|
|
|
-
|
|
|
- HttpResponse response = httpClient.send(request);
|
|
|
- logger.info("Received data with the status '{}' from the server {}.", response.getStatus(), request.getUrl());
|
|
|
-
|
|
|
- if (response.isError()) {
|
|
|
- logger.error("code: {}, message: {}", response.getStatus(), response.getBody());
|
|
|
- Map<String, Object> errorMap = new HashMap<>();
|
|
|
- errorMap.put(ERROR_KEY, response.getBody());
|
|
|
- return singletonList(errorMap);
|
|
|
- }
|
|
|
-
|
|
|
- final Type lastObsType = new TypeToken<Collection<Map<String, Object>>>() {}.getType();
|
|
|
- return jsonToObject(response.getBody(), lastObsType);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public ProvidedData getLastData() {
|
|
|
-
|
|
|
- Map<String, Tuple<String, Map<String, String>>> unitsInfo = loadUnitsInfo();
|
|
|
- List<Map<String, Object>> lastObservations = loadLastObservations();
|
|
|
-
|
|
|
- List<String> errorMessages = new ArrayList<>();
|
|
|
- if (unitsInfo.containsKey(ERROR_KEY)) {
|
|
|
- errorMessages.add(unitsInfo.get(ERROR_KEY).getItem1());
|
|
|
- }
|
|
|
- boolean isServerAlive = true;
|
|
|
- if (!lastObservations.isEmpty() && lastObservations.get(0).containsKey(ERROR_KEY)) {
|
|
|
- errorMessages.add((String) lastObservations.get(0).get(ERROR_KEY));
|
|
|
- isServerAlive = false;
|
|
|
- }
|
|
|
-
|
|
|
- String source = String.format("%s: %s", config.getId(), config.getBaseUrl());
|
|
|
- ProvidedData providedData = new ProvidedData(new ProviderInfo(source, WEB_SERVICE, isServerAlive), errorMessages);
|
|
|
-
|
|
|
- if (isServerAlive) {
|
|
|
- for (Map<String, Object> obMap : lastObservations) {
|
|
|
- long unitId = ((Double) obMap.get("unitId")).longValue();
|
|
|
- long sensorId = ((Double) obMap.get("sensorId")).longValue();
|
|
|
- OffsetDateTime timestamp = OffsetDateTime.parse(obMap.get("timeStamp").toString(), TIMESTAMP_PATTERN);
|
|
|
-
|
|
|
- String unitIdStr = String.format("%d", unitId);
|
|
|
- String sensorIdStr = String.format("%d", sensorId);
|
|
|
-
|
|
|
- Tuple<String, Map<String, String>> unitInfo = unitsInfo.getOrDefault(unitIdStr, DEFAULT_UNIT_INFO);
|
|
|
- String unitName = unitInfo.getItem1();
|
|
|
- String sensorName = unitInfo.getItem2().getOrDefault(sensorIdStr, DEFAULT_NAME);
|
|
|
-
|
|
|
- providedData.computeIfAbsent(unitIdStr, k -> new ProvidedObject(k, unitName, null))
|
|
|
- .addNode(sensorIdStr, new ProvidedObject(sensorIdStr, sensorName, timestamp));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return providedData;
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
+package cz.senslog.watchdog.provider.ws;
|
|
|
+
|
|
|
+import com.google.gson.reflect.TypeToken;
|
|
|
+import cz.senslog.watchdog.config.WSSensLogDataProviderConfig;
|
|
|
+import cz.senslog.watchdog.provider.*;
|
|
|
+import cz.senslog.watchdog.util.Tuple;
|
|
|
+import cz.senslog.watchdog.util.http.*;
|
|
|
+import org.apache.logging.log4j.LogManager;
|
|
|
+import org.apache.logging.log4j.Logger;
|
|
|
+
|
|
|
+import java.lang.reflect.Type;
|
|
|
+import java.time.OffsetDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+import static cz.senslog.watchdog.config.DataProviderType.WEB_SERVICE;
|
|
|
+import static cz.senslog.watchdog.util.json.BasicJson.jsonToObject;
|
|
|
+import static java.time.format.DateTimeFormatter.ofPattern;
|
|
|
+import static java.util.Collections.*;
|
|
|
+
|
|
|
+public class WSSensLogDataProvider implements DataProvider {
|
|
|
+
|
|
|
+ private static final Logger logger = LogManager.getLogger(WSSensLogDataProvider.class);
|
|
|
+
|
|
|
+ private static final String ERROR_KEY = "__error";
|
|
|
+
|
|
|
+ private static final String DEFAULT_NAME = "unknown";
|
|
|
+ private static final Tuple<String, Map<String, String>> DEFAULT_UNIT_INFO = Tuple.of(DEFAULT_NAME, emptyMap());
|
|
|
+
|
|
|
+ private static final DateTimeFormatter TIMESTAMP_PATTERN = ofPattern("yyyy-MM-dd HH:mm:ssX");
|
|
|
+
|
|
|
+ private final HttpClient httpClient = HttpClient.newHttpClient();
|
|
|
+ private final WSSensLogDataProviderConfig config;
|
|
|
+
|
|
|
+ private Tuple<Boolean, HttpCookie> authCookie;
|
|
|
+
|
|
|
+ public WSSensLogDataProvider(WSSensLogDataProviderConfig config) {
|
|
|
+ this.config = config;
|
|
|
+ this.authCookie = Tuple.of(false, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Map<unitId, Tuple<unitName, Map<sensorId, sensorName>>> */
|
|
|
+ private Map<String, Tuple<String, Map<String, String>>> loadUnitsInfo() {
|
|
|
+ HttpCookie authCookie = getAuthCookie();
|
|
|
+ if (!authCookie.isSecure()) {
|
|
|
+ logger.warn("Auth cookie is not valid to be used.");
|
|
|
+ return emptyMap();
|
|
|
+ }
|
|
|
+
|
|
|
+ HttpRequest request = HttpRequest.newBuilder().GET()
|
|
|
+ .url(URLBuilder.newBuilder(config.getBaseUrl(), "/DataService")
|
|
|
+ .addParam("Operation", "GetUnits")
|
|
|
+ .addParam("group", config.getGroupName())
|
|
|
+ .addParam("user", config.getUserName())
|
|
|
+ .build())
|
|
|
+ .addCookie(authCookie)
|
|
|
+ .build();
|
|
|
+ logger.info("Getting new data from the server: {}.", request.getUrl());
|
|
|
+
|
|
|
+ HttpResponse response = httpClient.send(request);
|
|
|
+ logger.info("Received data with the status '{}' from the server {}.", response.getStatus(), request.getUrl());
|
|
|
+
|
|
|
+ if (response.isError()) {
|
|
|
+ logger.error("code: {}, message: {}", response.getStatus(), response.getBody());
|
|
|
+ Map<String, Tuple<String, Map<String, String>>> errorMap = new HashMap<>();
|
|
|
+ errorMap.put(ERROR_KEY, Tuple.of(response.getBody(), emptyMap()));
|
|
|
+ return errorMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Tuple<String, Map<String, String>>> unitsInfo = new HashMap<>();
|
|
|
+
|
|
|
+ final Type unitInfoType = new TypeToken<Collection<Map<String, Object>>>() {}.getType();
|
|
|
+ List<Map<String, Object>> unitInfoList = jsonToObject(response.getBody(), unitInfoType);
|
|
|
+ for (Map<String, Object> unitInfo : unitInfoList) {
|
|
|
+ Object unitObj = unitInfo.get("unit");
|
|
|
+ if (unitObj instanceof Map) {
|
|
|
+ Map<?, ?> unitMap = (Map<?, ?>)unitObj;
|
|
|
+ String unitName = unitMap.get("description").toString();
|
|
|
+ String unitId = String.format("%d", ((Double)unitMap.get("unitId")).longValue());
|
|
|
+
|
|
|
+ Map<String, String> resultSensorInfo = new HashMap<>();
|
|
|
+ Object sensorsObj = unitInfo.get("sensors");
|
|
|
+ if (sensorsObj instanceof List) {
|
|
|
+ List<?> sensorsList = (List<?>)sensorsObj;
|
|
|
+ for (Object sensorInfoObj : sensorsList) {
|
|
|
+ if (sensorInfoObj instanceof Map) {
|
|
|
+ Map<?, ?> sensorMap = (Map<?, ?>)sensorInfoObj;
|
|
|
+ String sensorName = sensorMap.get("sensorName").toString();
|
|
|
+ String sensorId = String.format("%d", ((Double)sensorMap.get("sensorId")).longValue());
|
|
|
+
|
|
|
+ resultSensorInfo.put(sensorId, sensorName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ unitsInfo.put(unitId, Tuple.of(unitName, resultSensorInfo));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return unitsInfo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Map<String, Object>> loadLastObservations() {
|
|
|
+ HttpCookie authCookie = getAuthCookie();
|
|
|
+ if (!authCookie.isSecure()) {
|
|
|
+ logger.warn("Auth cookie is not valid to be used.");
|
|
|
+ return emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ HttpRequest request = HttpRequest.newBuilder().GET()
|
|
|
+ .url(URLBuilder.newBuilder(config.getBaseUrl(), "/SensorService")
|
|
|
+ .addParam("Operation", "GetLastObservations")
|
|
|
+ .addParam("group", config.getGroupName())
|
|
|
+ .addParam("user", config.getUserName())
|
|
|
+ .build())
|
|
|
+ .addCookie(authCookie)
|
|
|
+ .build();
|
|
|
+ logger.info("Getting new data from the server: {}.", request.getUrl());
|
|
|
+
|
|
|
+ HttpResponse response = httpClient.send(request);
|
|
|
+ logger.info("Received data with the status '{}' from the server {}.", response.getStatus(), request.getUrl());
|
|
|
+
|
|
|
+ if (response.isError()) {
|
|
|
+ logger.error("code: {}, message: {}", response.getStatus(), response.getBody());
|
|
|
+ Map<String, Object> errorMap = new HashMap<>();
|
|
|
+ errorMap.put(ERROR_KEY, response.getBody());
|
|
|
+ return singletonList(errorMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ final Type lastObsType = new TypeToken<Collection<Map<String, Object>>>() {}.getType();
|
|
|
+ return jsonToObject(response.getBody(), lastObsType);
|
|
|
+ }
|
|
|
+
|
|
|
+ private HttpCookie getAuthCookie() {
|
|
|
+ if (authCookie.getItem1()) {
|
|
|
+ return authCookie.getItem2();
|
|
|
+ }
|
|
|
+
|
|
|
+ HttpRequest request = HttpRequest.newBuilder().GET()
|
|
|
+ .url(URLBuilder.newBuilder(config.getBaseUrl(), "/ControllerServlet")
|
|
|
+ .addParam("username", config.getAuth().getUsername())
|
|
|
+ .addParam("password", config.getAuth().getPassword())
|
|
|
+ .build()
|
|
|
+ ).build();
|
|
|
+ logger.info("Getting new data from the server: {}.", request.getUrl());
|
|
|
+
|
|
|
+ HttpResponse response = httpClient.send(request);
|
|
|
+ logger.info("Received data with the status '{}' from the server {}.", response.getStatus(), request.getUrl());
|
|
|
+
|
|
|
+ if (response.isError()) {
|
|
|
+ logger.warn("Authorization failed. Error code {} with the reason '{}'.", response.getStatus(), response.getBody());
|
|
|
+ HttpCookie cookie = HttpCookie.empty();
|
|
|
+ authCookie = Tuple.of(false, cookie);
|
|
|
+ return cookie;
|
|
|
+ }
|
|
|
+
|
|
|
+ final Type lastObsType = new TypeToken<Map<String, Object>>() {}.getType();
|
|
|
+ Map<String, Object> jsonResponse = jsonToObject(response.getBody(), lastObsType);
|
|
|
+
|
|
|
+ if (!jsonResponse.containsKey("sessionid")) {
|
|
|
+ logger.error("Authorization failed. JSON does not contain session id. {}", response.getBody());
|
|
|
+ HttpCookie cookie = HttpCookie.empty();
|
|
|
+ authCookie = Tuple.of(false, cookie);
|
|
|
+ return cookie;
|
|
|
+ }
|
|
|
+
|
|
|
+ String sessionId = (String) jsonResponse.get("sessionid");
|
|
|
+ String domain = config.getBaseURI().getHost();
|
|
|
+ String path = config.getBaseURI().getPath();
|
|
|
+ HttpCookie cookie = new HttpCookie("JSESSIONID", sessionId, domain, path);
|
|
|
+ authCookie = Tuple.of(true, cookie);
|
|
|
+ return cookie;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ProvidedData getLastData() {
|
|
|
+
|
|
|
+ Map<String, Tuple<String, Map<String, String>>> unitsInfo = loadUnitsInfo();
|
|
|
+ List<Map<String, Object>> lastObservations = loadLastObservations();
|
|
|
+
|
|
|
+ List<String> errorMessages = new ArrayList<>();
|
|
|
+ if (unitsInfo.containsKey(ERROR_KEY)) {
|
|
|
+ errorMessages.add(unitsInfo.get(ERROR_KEY).getItem1());
|
|
|
+ }
|
|
|
+ boolean isServerAlive = true;
|
|
|
+ if (!lastObservations.isEmpty() && lastObservations.get(0).containsKey(ERROR_KEY)) {
|
|
|
+ errorMessages.add((String) lastObservations.get(0).get(ERROR_KEY));
|
|
|
+ isServerAlive = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ String source = String.format("%s: %s", config.getId(), config.getBaseUrl());
|
|
|
+ ProvidedData providedData = new ProvidedData(new ProviderInfo(source, WEB_SERVICE, isServerAlive), errorMessages);
|
|
|
+
|
|
|
+ if (isServerAlive) {
|
|
|
+ for (Map<String, Object> obMap : lastObservations) {
|
|
|
+ long unitId = ((Double) obMap.get("unitId")).longValue();
|
|
|
+ long sensorId = ((Double) obMap.get("sensorId")).longValue();
|
|
|
+ OffsetDateTime timestamp = OffsetDateTime.parse(obMap.get("timeStamp").toString(), TIMESTAMP_PATTERN);
|
|
|
+
|
|
|
+ String unitIdStr = String.format("%d", unitId);
|
|
|
+ String sensorIdStr = String.format("%d", sensorId);
|
|
|
+
|
|
|
+ Tuple<String, Map<String, String>> unitInfo = unitsInfo.getOrDefault(unitIdStr, DEFAULT_UNIT_INFO);
|
|
|
+ String unitName = unitInfo.getItem1();
|
|
|
+ String sensorName = unitInfo.getItem2().getOrDefault(sensorIdStr, DEFAULT_NAME);
|
|
|
+
|
|
|
+ providedData.computeIfAbsent(unitIdStr, k -> new ProvidedObject(k, unitName, null))
|
|
|
+ .addNode(sensorIdStr, new ProvidedObject(sensorIdStr, sensorName, timestamp));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return providedData;
|
|
|
+ }
|
|
|
+}
|