瀏覽代碼

Added configuration for SensLog servers

Lukas Cerny 4 年之前
父節點
當前提交
2419f4ac61
共有 20 個文件被更改,包括 857 次插入752 次删除
  1. 9 8
      config/foodie.yaml
  2. 93 0
      config/test-foodie.yaml
  3. 4 2
      src/main/java/cz/senslog/watchdog/app/Application.java
  4. 27 17
      src/main/java/cz/senslog/watchdog/config/Configuration.java
  5. 47 38
      src/main/java/cz/senslog/watchdog/config/EmailServerConfig.java
  6. 70 59
      src/main/java/cz/senslog/watchdog/config/GroupConfig.java
  7. 6 3
      src/main/java/cz/senslog/watchdog/config/PropertyConfig.java
  8. 65 0
      src/main/java/cz/senslog/watchdog/config/SensLogServerConfig.java
  9. 17 17
      src/main/java/cz/senslog/watchdog/config/SuperGroupConfig.java
  10. 7 46
      src/main/java/cz/senslog/watchdog/config/WSSensLogDataProviderConfig.java
  11. 0 17
      src/main/java/cz/senslog/watchdog/core/DataProviderInstanceCreator.java
  12. 0 4
      src/main/java/cz/senslog/watchdog/core/InstanceCreator.java
  13. 0 6
      src/main/java/cz/senslog/watchdog/core/MessageBrokerInstanceCreator.java
  14. 55 55
      src/main/java/cz/senslog/watchdog/core/connection/EmailServerConnection.java
  15. 104 0
      src/main/java/cz/senslog/watchdog/core/connection/SensLogWSConnection.java
  16. 62 62
      src/main/java/cz/senslog/watchdog/messagebroker/MessageBrokerManager.java
  17. 124 124
      src/main/java/cz/senslog/watchdog/messagebroker/broker/EmailMessageBroker.java
  18. 59 51
      src/main/java/cz/senslog/watchdog/provider/DataProviderManager.java
  19. 12 151
      src/main/java/cz/senslog/watchdog/provider/ws/WSSensLogDataProvider.java
  20. 96 92
      src/main/java/cz/senslog/watchdog/util/schedule/ScheduleTask.java

+ 9 - 8
config/foodie.yaml

@@ -8,6 +8,13 @@ emailServers:
     authUsername: "watchdog@senslog.org"
     authPassword: "5jspdD"
 
+senslogServers:
+  lspSenslog15:
+    baseUrl: "http://sensor.lesprojekt.cz/senslog15"
+    auth:
+      username: "watchdog"
+      password: "HAFhaf"
+
 messageBrokers:
   emailToAll:
     type: EMAIL
@@ -21,20 +28,14 @@ dataProviders:
   wsOldFoodieKynsperk:
     type: WEB_SERVICE
     config:
-      baseUrl: "http://sensor.lesprojekt.cz/senslog15"
+      server: lspSenslog15
       groupName: "kynsperk"
-      auth:
-        username: "watchdog"
-        password: "HAFhaf"
 
   wsOldFoodieRostenice:
     type: WEB_SERVICE
     config:
-      baseUrl: "http://sensor.lesprojekt.cz/senslog15"
+      server: lspSenslog15
       groupName: "rostenice_pudni"
-      auth:
-        username: "watchdog"
-        password: "HAFhaf"
 
 groups:
   kynsperk:

+ 93 - 0
config/test-foodie.yaml

@@ -0,0 +1,93 @@
+general:
+  firstStartAt: "12:00:00" # hh:mm:ss
+
+emailServers:
+  lspEmail:
+    smtpHost: "mail.lesprojekt.cz"
+    smtpPort: 465
+    authUsername: "watchdog@senslog.org"
+    authPassword: "5jspdD"
+
+senslogServers:
+  lspSenslog15:
+    baseUrl: "http://sensor.lesprojekt.cz/senslog15"
+    auth:
+      username: "watchdog"
+      password: "HAFhaf"
+
+messageBrokers:
+  emailToAll:
+    type: EMAIL
+    config:
+      server: lspEmail
+      senderEmail: "watchdog@senslog.org"
+      recipientEmail: "luccerny@ntis.zcu.cz"
+      subject: "[Watchdog] Report Foodie SensLog (CZ)"
+
+dataProviders:
+  wsOldFoodieKynsperk:
+    type: WEB_SERVICE
+    config:
+      server: lspSenslog15
+      groupName: "kynsperk"
+
+  wsOldFoodieRostenice:
+    type: WEB_SERVICE
+    config:
+      server: lspSenslog15
+      groupName: "rostenice_pudni"
+
+groups:
+  kynsperk:
+    name: "Kynsperk"
+    dataProvider: wsOldFoodieKynsperk
+    messageBroker: emailToAll
+    resultType: FAIL
+    period: 86400
+
+  rostenice:
+    name: "Rostenice"
+    dataProvider: wsOldFoodieRostenice
+    messageBroker: emailToAll
+    resultType: FAIL
+    period: 86400
+
+
+monitoredObjects:
+  1305167562293765: # no data
+    period: 86400
+    groups: [kynsperk]
+    sensors: [ 340340092, 360200000, 410130092 ]
+
+  1305167562275270: # no data
+    period: 86400
+    groups: [kynsperk]
+    sensors: [ 340240003, 360200000, 410090003 ]
+
+  1305167562292824: # no data
+    period: 86400
+    groups: [kynsperk]
+
+  1305167549173046: # no data
+    period: 86400
+    groups: [ kynsperk ]
+
+  1305167549144045:
+    period: 86400
+    groups: [ kynsperk ]
+
+  1305167549158198:
+    period: 86400
+    groups: [ kynsperk ]
+
+  1305167549167050:
+    period: 86400
+    groups: [ kynsperk ]
+
+  1305167549167886:
+    period: 86400
+    groups: [ kynsperk ]
+
+  1305167549149707:
+    period: 86400
+    groups: [ kynsperk ]

+ 4 - 2
src/main/java/cz/senslog/watchdog/app/Application.java

@@ -15,6 +15,8 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 
+import static cz.senslog.watchdog.util.DateTrunc.trunc;
+
 
 public class Application extends Thread {
 
@@ -60,7 +62,7 @@ public class Application extends Thread {
         );
 
         DataProviderManager dataProviderManager = DataProviderManager.createInstance(
-                config.getDataProviderConfigs()
+                config.getSensLogServerConfigs(), config.getDataProviderConfigs()
         );
 
         LocalDateTime now = LocalDateTime.now();
@@ -82,7 +84,7 @@ public class Application extends Thread {
             if (params.isExecuteImmediately()) {
                 schedulerBuilder.addTask(taskName, watcher::check);
             } else {
-             //   schedulerBuilder.addTask(taskName, watcher::check, period, trunc(now, period).plusSeconds(period));
+          //      schedulerBuilder.addTask(taskName, watcher::check, period, trunc(now, period).plusSeconds(period));
                 schedulerBuilder.addTask(taskName, watcher::check, period, startAt);
             }
         }

+ 27 - 17
src/main/java/cz/senslog/watchdog/config/Configuration.java

@@ -24,6 +24,7 @@ public class Configuration {
     private final Collection<ExecutableGroup> executableGroups;
     private final Collection<MessageBrokerConfig> messageBrokerConfigs;
     private final Collection<EmailServerConfig> emailServerConfigs;
+    private final Collection<SensLogServerConfig> sensLogServerConfigs;
     private final Collection<DataProviderConfig> dataProviderConfigs;
 
     private Configuration(
@@ -31,12 +32,14 @@ public class Configuration {
             Collection<ExecutableGroup> executableGroups,
             Collection<EmailServerConfig> emailServerConfigs,
             Collection<MessageBrokerConfig> messageBrokerConfigs,
+            Collection<SensLogServerConfig> sensLogServerConfigs,
             Collection<DataProviderConfig> dataProviderConfigs
     ){
         this.generalConfig = generalConfig;
         this.executableGroups = executableGroups;
         this.messageBrokerConfigs = messageBrokerConfigs;
         this.emailServerConfigs = emailServerConfigs;
+        this.sensLogServerConfigs = sensLogServerConfigs;
         this.dataProviderConfigs = dataProviderConfigs;
     }
 
@@ -45,11 +48,11 @@ public class Configuration {
             List<TempUnitConfig> monitoredObjects,
             Map<String, EmailServerConfig> emailServers,
             Map<String, MessageBrokerConfig> messageBrokers,
+            Map<String, SensLogServerConfig> sensLogServers,
             Map<String, DataProviderConfig> dataProviders,
             Map<String, GroupConfig> groups,
             Map<String, SuperGroupConfig> superGroups
     ) {
-
         Map<String, ExecutableGroup> executableGroupsMap = new HashMap<>();
         for (TempUnitConfig mObject : monitoredObjects) {
             Set<String> unitGroups = mObject.groups;
@@ -138,11 +141,14 @@ public class Configuration {
         Collection<ExecutableGroup> execGroups = executableGroupsMap.values();
         Collection<SuperGroup> execSGroups = executableSGroupsMap.values();
         Collection<EmailServerConfig> emailServerConfigs = emailServers.values();
+        Collection<SensLogServerConfig> sensLogServerConfigs = sensLogServers.values();
         Collection<DataProviderConfig> dataProviderConfigs = dataProviders.values();
         Collection<MessageBrokerConfig> messageBrokerConfigs = messageBrokers.values();
 
         return new Configuration(generalConfig, execGroups,
-                emailServerConfigs, messageBrokerConfigs, dataProviderConfigs);
+                emailServerConfigs, messageBrokerConfigs,
+                sensLogServerConfigs, dataProviderConfigs
+        );
     }
 
     public static Configuration load(String fileName) throws IOException {
@@ -179,6 +185,7 @@ public class Configuration {
                     parseMonitoredObjects(createPropertyConfig(properties, "monitoredObjects")),
                     parseEmailServers(createPropertyConfig(properties, "emailServers")),
                     parseMessageBrokers(createPropertyConfig(properties, "messageBrokers")),
+                    parseSensLogServers(createPropertyConfig(properties, "senslogServers")),
                     parseDataProviders(createPropertyConfig(properties, "dataProviders")),
                     parseGroups(createPropertyConfig(properties, "groups")),
                     parseSuperGroups(createPropertyConfig(properties, "superGroups"))
@@ -199,12 +206,7 @@ public class Configuration {
         Map<String, EmailServerConfig> emailServers = new HashMap<>();
         for (String id : serverIds) {
             PropertyConfig serverConfig = config.getPropertyConfig(id);
-            emailServers.put(id, new EmailServerConfig(id,
-               serverConfig.getStringProperty("smtpHost"),
-               serverConfig.getIntegerProperty("smtpPort"),
-               serverConfig.getStringProperty("authUsername"),
-               serverConfig.getStringProperty("authPassword")
-            ));
+            emailServers.put(id, EmailServerConfig.create(serverConfig));
         }
         return emailServers;
     }
@@ -221,6 +223,16 @@ public class Configuration {
         return messageBrokers;
     }
 
+    private static Map<String, SensLogServerConfig> parseSensLogServers(PropertyConfig config) {
+        Set<String> serverIds = config.getAttributes();
+        Map<String, SensLogServerConfig> serverConfigs = new HashMap<>(serverIds.size());
+        for (String id : serverIds) {
+            PropertyConfig serverConfig = config.getPropertyConfig(id);
+            serverConfigs.put(id, SensLogServerConfig.create(serverConfig));
+        }
+        return serverConfigs;
+    }
+
     private static Map<String, DataProviderConfig> parseDataProviders(PropertyConfig config) {
         Set<String> providerIds = config.getAttributes();
         Map<String, DataProviderConfig> dataProviders = new HashMap<>(providerIds.size());
@@ -237,13 +249,7 @@ public class Configuration {
         Map<String, GroupConfig> groups = new HashMap<>(groupIds.size());
         for (String id : groupIds) {
             PropertyConfig groupConfig = config.getPropertyConfig(id);
-            groups.put(id, new GroupConfig(id,
-                    groupConfig.getStringProperty("name"),
-                    groupConfig.getStringProperty("dataProvider"),
-                    groupConfig.getStringProperty("messageBroker"),
-                    ResultType.of(groupConfig.getStringProperty("resultType")),
-                    groupConfig.getOptionalProperty("period", Integer.class).orElse(null)
-            ));
+            groups.put(id, GroupConfig.create(groupConfig));
         }
         return groups;
     }
@@ -302,14 +308,14 @@ public class Configuration {
     private static PropertyConfig createPropertyConfig(Map<Object, Object> properties, String propertyName) throws IOException {
         Object generalConfig = properties.get(propertyName);
         if (generalConfig == null) {
-            return new PropertyConfig(propertyName);
+            return new PropertyConfig(propertyName, propertyName);
         }
         if (!(generalConfig instanceof Map)) {
             throw new IOException(propertyName);
         }
 
         Map<?, ?> generalConfigMap = (Map<?, ?>) generalConfig;
-        PropertyConfig propertyConfig = new PropertyConfig(propertyName);
+        PropertyConfig propertyConfig = new PropertyConfig(propertyName, propertyName);
 
         for (Map.Entry<?, ?> entry : generalConfigMap.entrySet()) {
             String keyName = entry.getKey().toString();
@@ -326,6 +332,10 @@ public class Configuration {
         return emailServerConfigs;
     }
 
+    public Collection<SensLogServerConfig> getSensLogServerConfigs() {
+        return sensLogServerConfigs;
+    }
+
     public Collection<DataProviderConfig> getDataProviderConfigs() {
         return dataProviderConfigs;
     }

+ 47 - 38
src/main/java/cz/senslog/watchdog/config/EmailServerConfig.java

@@ -1,38 +1,47 @@
-package cz.senslog.watchdog.config;
-
-public class EmailServerConfig {
-
-    private final String id;
-    private final String smtpHost;
-    private final int smtpPort;
-    private final String authUsername;
-    private final String authPassword;
-
-    public EmailServerConfig(String id, String smtpHost, int smtpPort, String authUsername, String authPassword) {
-        this.id = id;
-        this.smtpHost = smtpHost;
-        this.smtpPort = smtpPort;
-        this.authUsername = authUsername;
-        this.authPassword = authPassword;
-    }
-
-    public String getSmtpHost() {
-        return smtpHost;
-    }
-
-    public int getSmtpPort() {
-        return smtpPort;
-    }
-
-    public String getAuthUsername() {
-        return authUsername;
-    }
-
-    public String getAuthPassword() {
-        return authPassword;
-    }
-
-    public String getId() {
-        return id;
-    }
-}
+package cz.senslog.watchdog.config;
+
+public class EmailServerConfig {
+
+    private final String id;
+    private final String smtpHost;
+    private final int smtpPort;
+    private final String authUsername;
+    private final String authPassword;
+
+    public static EmailServerConfig create(PropertyConfig config) {
+        return new EmailServerConfig(config.getId(),
+                config.getStringProperty("smtpHost"),
+                config.getIntegerProperty("smtpPort"),
+                config.getStringProperty("authUsername"),
+                config.getStringProperty("authPassword")
+        );
+    }
+
+    public EmailServerConfig(String id, String smtpHost, int smtpPort, String authUsername, String authPassword) {
+        this.id = id;
+        this.smtpHost = smtpHost;
+        this.smtpPort = smtpPort;
+        this.authUsername = authUsername;
+        this.authPassword = authPassword;
+    }
+
+    public String getSmtpHost() {
+        return smtpHost;
+    }
+
+    public int getSmtpPort() {
+        return smtpPort;
+    }
+
+    public String getAuthUsername() {
+        return authUsername;
+    }
+
+    public String getAuthPassword() {
+        return authPassword;
+    }
+
+    public String getId() {
+        return id;
+    }
+}

+ 70 - 59
src/main/java/cz/senslog/watchdog/config/GroupConfig.java

@@ -1,59 +1,70 @@
-package cz.senslog.watchdog.config;
-
-import java.util.Objects;
-
-public class GroupConfig {
-
-    private final String id;
-    private final String name;
-    private final String dataProviderId;
-    private final String messageBrokerId;
-    private final ResultType resultType;
-    private final Integer period;
-
-    public GroupConfig(String id, String name, String dataProviderId, String messageBrokerId, ResultType resultType, Integer period) {
-        this.id = id;
-        this.name = name;
-        this.dataProviderId = dataProviderId;
-        this.messageBrokerId = messageBrokerId;
-        this.resultType = resultType;
-        this.period = period;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public String getDataProviderId() {
-        return dataProviderId;
-    }
-
-    public String getMessageBrokerId() {
-        return messageBrokerId;
-    }
-
-    public ResultType getResultType() {
-        return resultType;
-    }
-
-    public Integer getPeriod() {
-        return period;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        GroupConfig that = (GroupConfig) o;
-        return id.equals(that.id);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id);
-    }
-}
+package cz.senslog.watchdog.config;
+
+import java.util.Objects;
+
+public class GroupConfig {
+
+    private final String id;
+    private final String name;
+    private final String dataProviderId;
+    private final String messageBrokerId;
+    private final ResultType resultType;
+    private final Integer period;
+
+    public static GroupConfig create(PropertyConfig config) {
+        return new GroupConfig(config.getId(),
+                config.getStringProperty("name"),
+                config.getStringProperty("dataProvider"),
+                config.getStringProperty("messageBroker"),
+                ResultType.of(config.getStringProperty("resultType")),
+                config.getOptionalProperty("period", Integer.class).orElse(null)
+
+        );
+    }
+
+    public GroupConfig(String id, String name, String dataProviderId, String messageBrokerId, ResultType resultType, Integer period) {
+        this.id = id;
+        this.name = name;
+        this.dataProviderId = dataProviderId;
+        this.messageBrokerId = messageBrokerId;
+        this.resultType = resultType;
+        this.period = period;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getDataProviderId() {
+        return dataProviderId;
+    }
+
+    public String getMessageBrokerId() {
+        return messageBrokerId;
+    }
+
+    public ResultType getResultType() {
+        return resultType;
+    }
+
+    public Integer getPeriod() {
+        return period;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        GroupConfig that = (GroupConfig) o;
+        return id.equals(that.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+}

+ 6 - 3
src/main/java/cz/senslog/watchdog/config/PropertyConfig.java

@@ -29,6 +29,8 @@ public class PropertyConfig {
     /** Identifier of path. */
     private final String id;
 
+    private final String fullId;
+
     /** Map of properties. */
     private final Map<String, Object> properties;
 
@@ -36,8 +38,9 @@ public class PropertyConfig {
      * Constructor sets new identifier of node.
      * @param id - identifier of node.
      */
-    protected PropertyConfig(String id) {
+    protected PropertyConfig(String id, String fullId) {
         this.id = id;
+        this.fullId = fullId;
         this.properties = new HashMap<>();
     }
 
@@ -214,7 +217,7 @@ public class PropertyConfig {
      */
     public PropertyConfig getPropertyConfig(String name) {
         Object property = getProperty(name);
-        PropertyConfig config = new PropertyConfig(getNewPropertyId(name));
+        PropertyConfig config = new PropertyConfig(name, getNewPropertyId(name));
 
         if (property instanceof Map) {
             Map<?, ?> properties = (Map<?, ?>) property;
@@ -232,7 +235,7 @@ public class PropertyConfig {
     }
 
     private String getNewPropertyId(String name) {
-        return id + PATH_DELIMITER + name;
+        return fullId + PATH_DELIMITER + name;
     }
 
     public String getId() {

+ 65 - 0
src/main/java/cz/senslog/watchdog/config/SensLogServerConfig.java

@@ -0,0 +1,65 @@
+package cz.senslog.watchdog.config;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class SensLogServerConfig {
+
+    public static class AuthConfig {
+
+        private final String username;
+        private final String password;
+
+        private AuthConfig(PropertyConfig config) {
+            this.username = config.getStringProperty("username");
+            this.password = config.getStringProperty("password");
+        }
+
+        public String getUsername() {
+            return username;
+        }
+
+        public String getPassword() {
+            return password;
+        }
+    }
+
+    private final String id;
+    private final String baseUrl;
+    private final URI baseUri;
+    private final AuthConfig auth;
+
+    public static SensLogServerConfig create(PropertyConfig config) {
+        return new SensLogServerConfig(config.getId(),
+                config.getStringProperty("baseUrl"),
+                new AuthConfig(config.getPropertyConfig("auth"))
+        );
+    }
+
+    public SensLogServerConfig(String id, String baseUrl, AuthConfig auth) {
+        this.id = id;
+        this.baseUrl = baseUrl;
+        this.auth = auth;
+        try {
+            this.baseUri = new URI(baseUrl);
+        } catch (URISyntaxException e) {
+            throw new RuntimeException("The config is in invalid format. " + e.getMessage());
+        }
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getBaseUrl() {
+        return baseUrl;
+    }
+
+    public URI getBaseURI() {
+        return baseUri;
+    }
+
+    public AuthConfig getAuth() {
+        return auth;
+    }
+}

+ 17 - 17
src/main/java/cz/senslog/watchdog/config/SuperGroupConfig.java

@@ -1,17 +1,17 @@
-package cz.senslog.watchdog.config;
-
-import java.util.Set;
-
-public class SuperGroupConfig extends GroupConfig {
-
-    private final Set<String> groups;
-
-    public SuperGroupConfig(String id, String name, String messageBrokerId, ResultType resultType, Integer period, Set<String> groups) {
-        super(id, name,null, messageBrokerId, resultType, period);
-        this.groups = groups;
-    }
-
-    public Set<String> getGroups() {
-        return groups;
-    }
-}
+package cz.senslog.watchdog.config;
+
+import java.util.Set;
+
+public class SuperGroupConfig extends GroupConfig {
+
+    private final Set<String> groups;
+
+    public SuperGroupConfig(String id, String name, String messageBrokerId, ResultType resultType, Integer period, Set<String> groups) {
+        super(id, name,null, messageBrokerId, resultType, period);
+        this.groups = groups;
+    }
+
+    public Set<String> getGroups() {
+        return groups;
+    }
+}

+ 7 - 46
src/main/java/cz/senslog/watchdog/config/WSSensLogDataProviderConfig.java

@@ -1,67 +1,28 @@
 package cz.senslog.watchdog.config;
 
-import java.net.URI;
-import java.net.URISyntaxException;
-
 public class WSSensLogDataProviderConfig extends DataProviderConfig {
 
-    public static class SensLogAuthConfig {
-
-        private final String username;
-        private final String password;
-
-        private SensLogAuthConfig(PropertyConfig config) {
-            this.username = config.getStringProperty("username");
-            this.password = config.getStringProperty("password");
-        }
-
-        public String getUsername() {
-            return username;
-        }
-
-        public String getPassword() {
-            return password;
-        }
-    }
-
-    private final String baseUrl;
-    private final URI baseUri;
+    private final String serverId;
     private final String groupName;
-    private final SensLogAuthConfig auth;
 
     public static WSSensLogDataProviderConfig create(String id, PropertyConfig config) {
         return new WSSensLogDataProviderConfig(id,
-                config.getStringProperty("baseUrl"),
-                config.getStringProperty("groupName"),
-                new SensLogAuthConfig(config.getPropertyConfig("auth"))
+                config.getStringProperty("server"),
+                config.getStringProperty("groupName")
         );
     }
 
-    public WSSensLogDataProviderConfig(String id, String baseUrl, String groupName, SensLogAuthConfig auth) {
+    public WSSensLogDataProviderConfig(String id, String serverId, String groupName) {
         super(id, DataProviderType.WEB_SERVICE);
-        this.baseUrl = baseUrl;
+        this.serverId = serverId;
         this.groupName = groupName;
-        this.auth = auth;
-        try {
-            this.baseUri = new URI(baseUrl);
-        } catch (URISyntaxException e) {
-            throw new RuntimeException("The config is in invalid format. " + e.getMessage());
-        }
-    }
-
-    public String getBaseUrl() {
-        return baseUrl;
     }
 
-    public URI getBaseURI() {
-        return baseUri;
+    public String getServerId() {
+        return serverId;
     }
 
     public String getGroupName() {
         return groupName;
     }
-
-    public SensLogAuthConfig getAuth() {
-        return auth;
-    }
 }

+ 0 - 17
src/main/java/cz/senslog/watchdog/core/DataProviderInstanceCreator.java

@@ -1,17 +0,0 @@
-package cz.senslog.watchdog.core;
-
-import cz.senslog.watchdog.config.DatabaseDataProviderConfig;
-import cz.senslog.watchdog.config.WSSensLogDataProviderConfig;
-import cz.senslog.watchdog.provider.database.DBDataProvider;
-import cz.senslog.watchdog.provider.ws.WSSensLogDataProvider;
-
-public class DataProviderInstanceCreator implements InstanceCreator {
-
-    DBDataProvider create(DatabaseDataProviderConfig config) {
-        return new DBDataProvider(null);
-    }
-
-    WSSensLogDataProvider create(WSSensLogDataProviderConfig config) {
-        return new WSSensLogDataProvider(null);
-    }
-}

+ 0 - 4
src/main/java/cz/senslog/watchdog/core/InstanceCreator.java

@@ -1,4 +0,0 @@
-package cz.senslog.watchdog.core;
-
-public interface InstanceCreator {
-}

+ 0 - 6
src/main/java/cz/senslog/watchdog/core/MessageBrokerInstanceCreator.java

@@ -1,6 +0,0 @@
-package cz.senslog.watchdog.core;
-
-public class MessageBrokerInstanceCreator implements InstanceCreator {
-
-
-}

+ 55 - 55
src/main/java/cz/senslog/watchdog/core/EmailServerConnection.java → src/main/java/cz/senslog/watchdog/core/connection/EmailServerConnection.java

@@ -1,55 +1,55 @@
-package cz.senslog.watchdog.core;
-
-import cz.senslog.watchdog.config.EmailMessageBrokerConfig;
-import cz.senslog.watchdog.config.EmailServerConfig;
-
-import javax.mail.*;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-import java.util.Properties;
-
-import static javax.mail.Message.RecipientType.TO;
-
-public class EmailServerConnection {
-
-    private final EmailServerConfig config;
-
-    public EmailServerConnection(EmailServerConfig config) {
-        this.config = config;
-    }
-
-    private Session openSession(EmailServerConfig config) {
-        Properties props = new Properties();
-        props.put("mail.smtp.host", config.getSmtpHost());
-        props.put("mail.smtp.port", config.getSmtpPort());
-        props.put("mail.smtp.auth", "true");
-        props.put("mail.smtp.starttls.enable", "true");
-        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
-
-        Authenticator auth = new Authenticator() {
-            protected PasswordAuthentication getPasswordAuthentication() {
-                return new PasswordAuthentication(config.getAuthUsername(), config.getAuthPassword());
-            }
-        };
-        return Session.getInstance(props, auth);
-    }
-
-    public void send(String content, EmailMessageBrokerConfig messageConfig) throws MessagingException {
-        Session session = openSession(config);
-        Message message = new MimeMessage(session);
-        message.setFrom(new InternetAddress(messageConfig.getSenderEmail()));
-        message.setRecipients(TO, InternetAddress.parse(messageConfig.getRecipientEmail()));
-        message.setSubject(messageConfig.getSubject());
-
-        MimeBodyPart mimeBodyPart = new MimeBodyPart();
-        mimeBodyPart.setContent(content, "text/html");
-
-        Multipart multipart = new MimeMultipart();
-        multipart.addBodyPart(mimeBodyPart);
-        message.setContent(multipart);
-
-        Transport.send(message);
-    }
-}
+package cz.senslog.watchdog.core.connection;
+
+import cz.senslog.watchdog.config.EmailMessageBrokerConfig;
+import cz.senslog.watchdog.config.EmailServerConfig;
+
+import javax.mail.*;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import java.util.Properties;
+
+import static javax.mail.Message.RecipientType.TO;
+
+public class EmailServerConnection {
+
+    private final EmailServerConfig config;
+
+    public EmailServerConnection(EmailServerConfig config) {
+        this.config = config;
+    }
+
+    private Session openSession(EmailServerConfig config) {
+        Properties props = new Properties();
+        props.put("mail.smtp.host", config.getSmtpHost());
+        props.put("mail.smtp.port", config.getSmtpPort());
+        props.put("mail.smtp.auth", "true");
+        props.put("mail.smtp.starttls.enable", "true");
+        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+
+        Authenticator auth = new Authenticator() {
+            protected PasswordAuthentication getPasswordAuthentication() {
+                return new PasswordAuthentication(config.getAuthUsername(), config.getAuthPassword());
+            }
+        };
+        return Session.getInstance(props, auth);
+    }
+
+    public void send(String content, EmailMessageBrokerConfig messageConfig) throws MessagingException {
+        Session session = openSession(config);
+        Message message = new MimeMessage(session);
+        message.setFrom(new InternetAddress(messageConfig.getSenderEmail()));
+        message.setRecipients(TO, InternetAddress.parse(messageConfig.getRecipientEmail()));
+        message.setSubject(messageConfig.getSubject());
+
+        MimeBodyPart mimeBodyPart = new MimeBodyPart();
+        mimeBodyPart.setContent(content, "text/html");
+
+        Multipart multipart = new MimeMultipart();
+        multipart.addBodyPart(mimeBodyPart);
+        message.setContent(multipart);
+
+        Transport.send(message);
+    }
+}

+ 104 - 0
src/main/java/cz/senslog/watchdog/core/connection/SensLogWSConnection.java

@@ -0,0 +1,104 @@
+package cz.senslog.watchdog.core.connection;
+
+import com.google.gson.reflect.TypeToken;
+import cz.senslog.watchdog.config.SensLogServerConfig;
+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.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static cz.senslog.watchdog.util.json.BasicJson.jsonToObject;
+import static java.util.Collections.emptyList;
+
+public class SensLogWSConnection {
+
+    private static final Logger logger = LogManager.getLogger(SensLogWSConnection.class);
+
+    private final HttpClient httpClient;
+    private final SensLogServerConfig config;
+
+    private Tuple<Boolean, HttpCookie> authCookie;
+
+    public SensLogWSConnection(SensLogServerConfig config) {
+        this.config = config;
+        this.httpClient = HttpClient.newHttpClient();
+        this.authCookie = Tuple.of(false, null);
+    }
+
+    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;
+    }
+
+    public List<Map<String, Object>> loadLastObservation(String groupName) {
+        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(), "/rest/watchdog/group")
+                        .addParam("group_name", groupName)
+                        .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());
+            throw new IllegalStateException(response.getBody());
+        }
+
+        final Type lastObsType = new TypeToken<Collection<Map<String, Object>>>() {}.getType();
+        return jsonToObject(response.getBody(), lastObsType);
+    }
+
+    public String getHost() {
+        return config.getBaseUrl();
+    }
+}

+ 62 - 62
src/main/java/cz/senslog/watchdog/messagebroker/MessageBrokerManager.java

@@ -1,63 +1,63 @@
-package cz.senslog.watchdog.messagebroker;
-
-import cz.senslog.watchdog.config.*;
-import cz.senslog.watchdog.core.EmailServerConnection;
-import cz.senslog.watchdog.messagebroker.broker.ConsoleMessageBroker;
-import cz.senslog.watchdog.messagebroker.broker.EmailMessageBroker;
-import cz.senslog.watchdog.messagebroker.broker.SignalMessageBroker;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-public class MessageBrokerManager {
-
-    private final Map<String, MessageBroker> brokerInstances;
-
-    public static MessageBrokerManager createInstance(
-            Collection<EmailServerConfig> emailServerConfigs,
-            Collection<MessageBrokerConfig> brokerConfigs
-    ) {
-        Map<String, EmailServerConnection> emailServers = new HashMap<>(emailServerConfigs.size());
-        for (EmailServerConfig config : emailServerConfigs) {
-            emailServers.put(config.getId(), new EmailServerConnection(config));
-        }
-
-        Map<String, MessageBroker> instances = new HashMap<>();
-        for (MessageBrokerConfig config : brokerConfigs) {
-            String id = config.getId();
-            switch (config.getType()) {
-                case EMAIL: {
-                    EmailMessageBrokerConfig emailConfig = (EmailMessageBrokerConfig) config;
-                    EmailServerConnection connection = emailServers.get(emailConfig.getServerId());
-                    instances.put(id, new EmailMessageBroker(connection, emailConfig));
-                } break;
-                case SIGNAL: {
-                    SignalMessageBrokerConfig signalConfig = (SignalMessageBrokerConfig) config;
-                    instances.put(id, new SignalMessageBroker(signalConfig));
-                } break;
-                case CONSOLE: {
-                    ConsoleMessageBrokerConfig consoleConfig = (ConsoleMessageBrokerConfig) config;
-                    instances.put(id, new ConsoleMessageBroker(consoleConfig));
-                } break;
-                default: throw new IllegalStateException(
-                        "Message broker for the type of '"+config.getType()+"' is not implemented yet"
-                );
-            }
-        }
-
-        return new MessageBrokerManager(instances);
-    }
-
-    public MessageBrokerManager(Map<String, MessageBroker> brokerInstances) {
-        this.brokerInstances = brokerInstances;
-    }
-
-    public MessageBroker getInstance(String messageBrokerId) {
-        MessageBroker instance = brokerInstances.get(messageBrokerId);
-        if (instance != null) {
-            return instance;
-        }
-        throw new IllegalStateException("Message broker '"+messageBrokerId+"' does not exist.");
-    }
+package cz.senslog.watchdog.messagebroker;
+
+import cz.senslog.watchdog.config.*;
+import cz.senslog.watchdog.core.connection.EmailServerConnection;
+import cz.senslog.watchdog.messagebroker.broker.ConsoleMessageBroker;
+import cz.senslog.watchdog.messagebroker.broker.EmailMessageBroker;
+import cz.senslog.watchdog.messagebroker.broker.SignalMessageBroker;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MessageBrokerManager {
+
+    private final Map<String, MessageBroker> brokerInstances;
+
+    public static MessageBrokerManager createInstance(
+            Collection<EmailServerConfig> emailServerConfigs,
+            Collection<MessageBrokerConfig> brokerConfigs
+    ) {
+        Map<String, EmailServerConnection> emailServers = new HashMap<>(emailServerConfigs.size());
+        for (EmailServerConfig config : emailServerConfigs) {
+            emailServers.put(config.getId(), new EmailServerConnection(config));
+        }
+
+        Map<String, MessageBroker> instances = new HashMap<>();
+        for (MessageBrokerConfig config : brokerConfigs) {
+            String id = config.getId();
+            switch (config.getType()) {
+                case EMAIL: {
+                    EmailMessageBrokerConfig emailConfig = (EmailMessageBrokerConfig) config;
+                    EmailServerConnection connection = emailServers.get(emailConfig.getServerId());
+                    instances.put(id, new EmailMessageBroker(connection, emailConfig));
+                } break;
+                case SIGNAL: {
+                    SignalMessageBrokerConfig signalConfig = (SignalMessageBrokerConfig) config;
+                    instances.put(id, new SignalMessageBroker(signalConfig));
+                } break;
+                case CONSOLE: {
+                    ConsoleMessageBrokerConfig consoleConfig = (ConsoleMessageBrokerConfig) config;
+                    instances.put(id, new ConsoleMessageBroker(consoleConfig));
+                } break;
+                default: throw new IllegalStateException(
+                        "Message broker for the type of '"+config.getType()+"' is not implemented yet"
+                );
+            }
+        }
+
+        return new MessageBrokerManager(instances);
+    }
+
+    public MessageBrokerManager(Map<String, MessageBroker> brokerInstances) {
+        this.brokerInstances = brokerInstances;
+    }
+
+    public MessageBroker getInstance(String messageBrokerId) {
+        MessageBroker instance = brokerInstances.get(messageBrokerId);
+        if (instance != null) {
+            return instance;
+        }
+        throw new IllegalStateException("Message broker '"+messageBrokerId+"' does not exist.");
+    }
 }

+ 124 - 124
src/main/java/cz/senslog/watchdog/messagebroker/broker/EmailMessageBroker.java

@@ -1,124 +1,124 @@
-package cz.senslog.watchdog.messagebroker.broker;
-
-import cz.senslog.watchdog.config.EmailMessageBrokerConfig;
-import cz.senslog.watchdog.config.MessageBrokerType;
-import cz.senslog.watchdog.core.EmailServerConnection;
-import cz.senslog.watchdog.domain.*;
-import cz.senslog.watchdog.messagebroker.MessageBroker;
-import cz.senslog.watchdog.messagebroker.MessageBrokerHandler;
-import cz.senslog.watchdog.messagebroker.MessageStatus;
-import cz.senslog.watchdog.messagebroker.writer.HtmlTableWriter;
-import cz.senslog.watchdog.messagebroker.writer.TableWriter;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import javax.mail.*;
-import java.util.*;
-
-import static java.time.format.DateTimeFormatter.ofPattern;
-
-public class EmailMessageBroker implements MessageBroker {
-
-    private static final String BREAK_LINE = "<br />";
-
-    private static final Logger logger = LogManager.getLogger(EmailMessageBroker.class);
-
-    private final EmailServerConnection serverConnection;
-    private final EmailMessageBrokerConfig messageConfig;
-
-    public EmailMessageBroker(EmailServerConnection serverConnection, EmailMessageBrokerConfig messageConfig) {
-        this.serverConnection = serverConnection;
-        this.messageConfig = messageConfig;
-    }
-
-    private String createMessage(Report report) {
-        StringBuilder content = new StringBuilder();
-        final String rowStyle = "border: 1px solid #dddddd; text-align: left; padding: 8px;";
-
-        boolean isMessages = !report.getMessages().isEmpty();
-        boolean isRecords = !report.getReports().isEmpty();
-
-        if (!report.getOperationProperties().isEmpty()) {
-
-            TableWriter tableSourceWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
-                    .cell("Operation Type").cell("Operation Value").end();
-
-            for (Map.Entry<String, String> operationEntry : report.getOperationProperties().entrySet()) {
-                tableSourceWriter.row(rowStyle)
-                            .cell(operationEntry.getKey(), rowStyle)
-                            .cell(operationEntry.getValue(), rowStyle)
-                        .end();
-            }
-
-            content.append(tableSourceWriter.table()).append(BREAK_LINE);
-        }
-
-        if (isMessages || !isRecords) {
-            TableWriter tableMsgWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
-                    .cell("Messages").end();
-
-            for (String message : report.getMessages()) {
-                tableMsgWriter.row(rowStyle).cell(message, rowStyle).end();
-            }
-
-            if (!isRecords) {
-                tableMsgWriter.row(rowStyle).cell("All received observations are valid.");
-            }
-
-            content.append(tableMsgWriter.table()).append(BREAK_LINE);
-        }
-
-        if (isRecords) {
-            TableWriter tableReportWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
-                    .cell("unitName (unitId)").cell("sensorName (sensorId)").cell("timestamp").cell("reported").cell("status").end();
-
-            String reportedTime = report.getCreated().format(ofPattern("yyyy-MM-dd HH:mm:ss"));
-
-            report.getReports().sort(Comparator.comparing(SimpleReport::getStatus).reversed());
-            for (SimpleReport simpleReport : report.getReports()) {
-                boolean isOk = simpleReport.getStatus().equals(StatusReport.OK);
-                if (simpleReport.getRecord() instanceof ObservationInfo) {
-                    ObservationInfo observation = (ObservationInfo) simpleReport.getRecord();
-                    Source source = observation.getSource();
-
-                    String unitCell = String.format("%s (%s)", source.getUnit().getName(), source.getUnit().getId());
-                    String sensorCell = String.format("%s (%s)", source.getSensor().getName(), source.getSensor().getId());
-
-                    tableReportWriter.row(rowStyle + "background-color: " + (isOk ? "#CCFFCC" : "#FFCCCC"))
-                            .cell(unitCell, rowStyle)
-                            .cell(sensorCell, rowStyle)
-                            .cell(observation.getTimestamp().toString(), rowStyle)
-                            .cell(reportedTime, rowStyle)
-                            .cell(simpleReport.getStatus().name(), rowStyle)
-                            .end();
-                }
-            }
-            content.append(tableReportWriter.table()).append(BREAK_LINE);
-        }
-
-        return content.toString();
-    }
-
-    @Override
-    public void send(Report report, MessageBrokerHandler status) {
-        if (report == null) {
-            logger.info("Nothing to send. The receive report is null.");
-            status.handle(new MessageStatus(null, "No report to send.")); return;
-        }
-
-        try {
-            logger.info("Sending a message via email.");
-            serverConnection.send(createMessage(report), messageConfig);
-            logger.info("The message was send successfully.");
-            status.handle(new MessageStatus(report));
-        } catch (MessagingException e) {
-            logger.catching(e);
-            status.handle(new MessageStatus(report, e.getMessage()));
-        }
-    }
-
-    @Override
-    public MessageBrokerType getType() {
-        return MessageBrokerType.EMAIL;
-    }
-}
+package cz.senslog.watchdog.messagebroker.broker;
+
+import cz.senslog.watchdog.config.EmailMessageBrokerConfig;
+import cz.senslog.watchdog.config.MessageBrokerType;
+import cz.senslog.watchdog.core.connection.EmailServerConnection;
+import cz.senslog.watchdog.domain.*;
+import cz.senslog.watchdog.messagebroker.MessageBroker;
+import cz.senslog.watchdog.messagebroker.MessageBrokerHandler;
+import cz.senslog.watchdog.messagebroker.MessageStatus;
+import cz.senslog.watchdog.messagebroker.writer.HtmlTableWriter;
+import cz.senslog.watchdog.messagebroker.writer.TableWriter;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.mail.*;
+import java.util.*;
+
+import static java.time.format.DateTimeFormatter.ofPattern;
+
+public class EmailMessageBroker implements MessageBroker {
+
+    private static final String BREAK_LINE = "<br />";
+
+    private static final Logger logger = LogManager.getLogger(EmailMessageBroker.class);
+
+    private final EmailServerConnection serverConnection;
+    private final EmailMessageBrokerConfig messageConfig;
+
+    public EmailMessageBroker(EmailServerConnection serverConnection, EmailMessageBrokerConfig messageConfig) {
+        this.serverConnection = serverConnection;
+        this.messageConfig = messageConfig;
+    }
+
+    private String createMessage(Report report) {
+        StringBuilder content = new StringBuilder();
+        final String rowStyle = "border: 1px solid #dddddd; text-align: left; padding: 8px;";
+
+        boolean isMessages = !report.getMessages().isEmpty();
+        boolean isRecords = !report.getReports().isEmpty();
+
+        if (!report.getOperationProperties().isEmpty()) {
+
+            TableWriter tableSourceWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
+                    .cell("Operation Type").cell("Operation Value").end();
+
+            for (Map.Entry<String, String> operationEntry : report.getOperationProperties().entrySet()) {
+                tableSourceWriter.row(rowStyle)
+                            .cell(operationEntry.getKey(), rowStyle)
+                            .cell(operationEntry.getValue(), rowStyle)
+                        .end();
+            }
+
+            content.append(tableSourceWriter.table()).append(BREAK_LINE);
+        }
+
+        if (isMessages || !isRecords) {
+            TableWriter tableMsgWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
+                    .cell("Messages").end();
+
+            for (String message : report.getMessages()) {
+                tableMsgWriter.row(rowStyle).cell(message, rowStyle).end();
+            }
+
+            if (!isRecords) {
+                tableMsgWriter.row(rowStyle).cell("All received observations are valid.");
+            }
+
+            content.append(tableMsgWriter.table()).append(BREAK_LINE);
+        }
+
+        if (isRecords) {
+            TableWriter tableReportWriter = HtmlTableWriter.createWithHeader("width: 100%;", "background-color: #dddddd")
+                    .cell("unitName (unitId)").cell("sensorName (sensorId)").cell("timestamp").cell("reported").cell("status").end();
+
+            String reportedTime = report.getCreated().format(ofPattern("yyyy-MM-dd HH:mm:ss"));
+
+            report.getReports().sort(Comparator.comparing(SimpleReport::getStatus).reversed());
+            for (SimpleReport simpleReport : report.getReports()) {
+                boolean isOk = simpleReport.getStatus().equals(StatusReport.OK);
+                if (simpleReport.getRecord() instanceof ObservationInfo) {
+                    ObservationInfo observation = (ObservationInfo) simpleReport.getRecord();
+                    Source source = observation.getSource();
+
+                    String unitCell = String.format("%s (%s)", source.getUnit().getName(), source.getUnit().getId());
+                    String sensorCell = String.format("%s (%s)", source.getSensor().getName(), source.getSensor().getId());
+
+                    tableReportWriter.row(rowStyle + "background-color: " + (isOk ? "#CCFFCC" : "#FFCCCC"))
+                            .cell(unitCell, rowStyle)
+                            .cell(sensorCell, rowStyle)
+                            .cell(observation.getTimestamp().toString(), rowStyle)
+                            .cell(reportedTime, rowStyle)
+                            .cell(simpleReport.getStatus().name(), rowStyle)
+                            .end();
+                }
+            }
+            content.append(tableReportWriter.table()).append(BREAK_LINE);
+        }
+
+        return content.toString();
+    }
+
+    @Override
+    public void send(Report report, MessageBrokerHandler status) {
+        if (report == null) {
+            logger.info("Nothing to send. The receive report is null.");
+            status.handle(new MessageStatus(null, "No report to send.")); return;
+        }
+
+        try {
+            logger.info("Sending a message via email.");
+            serverConnection.send(createMessage(report), messageConfig);
+            logger.info("The message was send successfully.");
+            status.handle(new MessageStatus(report));
+        } catch (MessagingException e) {
+            logger.catching(e);
+            status.handle(new MessageStatus(report, e.getMessage()));
+        }
+    }
+
+    @Override
+    public MessageBrokerType getType() {
+        return MessageBrokerType.EMAIL;
+    }
+}

+ 59 - 51
src/main/java/cz/senslog/watchdog/provider/DataProviderManager.java

@@ -1,52 +1,60 @@
-package cz.senslog.watchdog.provider;
-
-import cz.senslog.watchdog.config.DataProviderConfig;
-import cz.senslog.watchdog.config.DatabaseDataProviderConfig;
-import cz.senslog.watchdog.config.WSSensLogDataProviderConfig;
-import cz.senslog.watchdog.provider.database.DBDataProvider;
-import cz.senslog.watchdog.provider.ws.WSSensLogDataProvider;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-public class DataProviderManager {
-
-    private final Map<String, DataProvider> providerInstances;
-
-    public static DataProviderManager createInstance(
-            Collection<DataProviderConfig> providerConfigs
-    ) {
-        Map<String, DataProvider> instances = new HashMap<>();
-        for (DataProviderConfig config : providerConfigs) {
-            String id = config.getId();
-            switch (config.getType()) {
-                case WEB_SERVICE: {
-                    WSSensLogDataProviderConfig wsConfig = (WSSensLogDataProviderConfig) config;
-                    instances.put(id, new WSSensLogDataProvider(wsConfig));
-                } break;
-                case DATABASE: {
-                    DatabaseDataProviderConfig dbConfig = (DatabaseDataProviderConfig) config;
-                    instances.put(id, new DBDataProvider(dbConfig));
-                } break;
-                default: throw new IllegalStateException(
-                        "Data provider for the type of '"+config.getType()+"' is not implemented yet"
-                );
-            }
-        }
-
-        return new DataProviderManager(instances);
-    }
-
-    public DataProviderManager(Map<String, DataProvider> providerInstances) {
-        this.providerInstances = providerInstances;
-    }
-
-    public DataProvider getInstance(String dataProviderId) {
-        DataProvider instance = providerInstances.get(dataProviderId);
-        if (instance != null) {
-            return instance;
-        }
-        throw new IllegalStateException("Data provider '"+dataProviderId+"' does not exist.");
-    }
+package cz.senslog.watchdog.provider;
+
+import cz.senslog.watchdog.config.DataProviderConfig;
+import cz.senslog.watchdog.config.DatabaseDataProviderConfig;
+import cz.senslog.watchdog.config.SensLogServerConfig;
+import cz.senslog.watchdog.config.WSSensLogDataProviderConfig;
+import cz.senslog.watchdog.core.connection.SensLogWSConnection;
+import cz.senslog.watchdog.provider.database.DBDataProvider;
+import cz.senslog.watchdog.provider.ws.WSSensLogDataProvider;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class DataProviderManager {
+
+    private final Map<String, DataProvider> providerInstances;
+
+    public static DataProviderManager createInstance(
+            Collection<SensLogServerConfig> sensLogServerConfigs, Collection<DataProviderConfig> providerConfigs
+    ) {
+        Map<String, SensLogWSConnection> connectionMap = new HashMap<>(sensLogServerConfigs.size());
+        for (SensLogServerConfig config : sensLogServerConfigs) {
+            connectionMap.put(config.getId(), new SensLogWSConnection(config));
+        }
+
+        Map<String, DataProvider> instances = new HashMap<>();
+        for (DataProviderConfig config : providerConfigs) {
+            String id = config.getId();
+            switch (config.getType()) {
+                case WEB_SERVICE: {
+                    WSSensLogDataProviderConfig wsConfig = (WSSensLogDataProviderConfig) config;
+                    SensLogWSConnection connection = connectionMap.get(wsConfig.getServerId());
+                    instances.put(id, new WSSensLogDataProvider(connection, wsConfig));
+                } break;
+                case DATABASE: {
+                    DatabaseDataProviderConfig dbConfig = (DatabaseDataProviderConfig) config;
+                    instances.put(id, new DBDataProvider(dbConfig));
+                } break;
+                default: throw new IllegalStateException(
+                        "Data provider for the type of '"+config.getType()+"' is not implemented yet"
+                );
+            }
+        }
+
+        return new DataProviderManager(instances);
+    }
+
+    public DataProviderManager(Map<String, DataProvider> providerInstances) {
+        this.providerInstances = providerInstances;
+    }
+
+    public DataProvider getInstance(String dataProviderId) {
+        DataProvider instance = providerInstances.get(dataProviderId);
+        if (instance != null) {
+            return instance;
+        }
+        throw new IllegalStateException("Data provider '"+dataProviderId+"' does not exist.");
+    }
 }

+ 12 - 151
src/main/java/cz/senslog/watchdog/provider/ws/WSSensLogDataProvider.java

@@ -1,187 +1,48 @@
 package cz.senslog.watchdog.provider.ws;
 
-import com.google.gson.reflect.TypeToken;
 import cz.senslog.watchdog.config.WSSensLogDataProviderConfig;
+import cz.senslog.watchdog.core.connection.SensLogWSConnection;
 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.*;
+import static java.util.Collections.emptyList;
 
 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 DateTimeFormatter TIMESTAMP_PATTERN = ofPattern("yyyy-MM-dd HH:mm:ssX");
 
-    private final HttpClient httpClient = HttpClient.newHttpClient();
+    private final SensLogWSConnection connection;
     private final WSSensLogDataProviderConfig config;
 
-    private Tuple<Boolean, HttpCookie> authCookie;
-
-    public WSSensLogDataProvider(WSSensLogDataProviderConfig config) {
+    public WSSensLogDataProvider(SensLogWSConnection connection, WSSensLogDataProviderConfig config) {
         this.config = config;
-        this.authCookie = Tuple.of(false, null);
-    }
-
-    /*
-    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(), "/rest/watchdog/group")
-                        .addParam("group_name", config.getGroupName())
-                        .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;
+        this.connection = connection;
     }
 
     @Override
     public ProvidedData getLastData() {
 
-        List<Map<String, Object>> lastObservations = loadLastObservations();
-
         List<String> errorMessages = new ArrayList<>();
         boolean isServerAlive = true;
-        if (!lastObservations.isEmpty() && lastObservations.get(0).containsKey(ERROR_KEY)) {
-            errorMessages.add((String) lastObservations.get(0).get(ERROR_KEY));
+        List<Map<String, Object>> lastObservations = emptyList();
+        try {
+            lastObservations = connection.loadLastObservation(config.getGroupName());
+        } catch (IllegalStateException e) {
+            errorMessages.add(e.getMessage());
             isServerAlive = false;
         }
 
-        String source = String.format("%s: %s", config.getId(), config.getBaseUrl());
+        String source = String.format("%s: %s", config.getId(), connection.getHost());
         ProvidedData providedData = new ProvidedData(new ProviderInfo(source, WEB_SERVICE, isServerAlive), errorMessages);
 
         if (isServerAlive) {
@@ -201,4 +62,4 @@ public class WSSensLogDataProvider implements DataProvider {
         }
         return providedData;
     }
-}
+}

+ 96 - 92
src/main/java/cz/senslog/watchdog/util/schedule/ScheduleTask.java

@@ -1,92 +1,96 @@
-package cz.senslog.watchdog.util.schedule;
-
-
-import cz.senslog.watchdog.messagebroker.broker.EmailMessageBroker;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.time.LocalDateTime;
-import java.time.temporal.ChronoUnit;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-
-import static cz.senslog.watchdog.util.TimeConverter.secToMillis;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-
-public class ScheduleTask implements Task {
-
-    private static final Logger logger = LogManager.getLogger(EmailMessageBroker.class);
-
-    private static final int DEFAULT_DELAY_MILLIS = 2_000; // 2s
-
-    private TaskDescription description;
-    private final Runnable task;
-    private final long periodMillis;
-
-    private final LocalDateTime startAt;
-    private final long delayMillis;
-
-    private ScheduleTask(String name, Runnable task, long periodSec, LocalDateTime startAt, long delaySec) {
-        this.description = new TaskDescription(name, Status.STOPPED);
-        this.task = task;
-        this.periodMillis = secToMillis(periodSec);
-        this.startAt = startAt;
-        this.delayMillis = secToMillis(delaySec);
-    }
-
-    public ScheduleTask(String name, Runnable task, long periodSec, LocalDateTime startAt) {
-        this(name, task, periodSec, startAt, -1);
-    }
-
-    public ScheduleTask(String name, Runnable task, long periodSec, int delaySec) {
-        this(name, task, periodSec, null, delaySec);
-    }
-
-    public ScheduleTask(String name, Runnable task, long periodSec) {
-        this(name, task, periodSec, null);
-    }
-
-    public long getPeriodMillis() {
-        return periodMillis;
-    }
-
-    @Override
-    public Runnable getRunnable() {
-        return task;
-    }
-
-    @Override
-    public TaskDescription getDescription() {
-        return description;
-    }
-
-    @Override
-    public void schedule(ScheduledExecutorService scheduledService, CountDownLatch latch) {
-
-        long delay = DEFAULT_DELAY_MILLIS;
-        if (startAt != null) {
-            delay = LocalDateTime.now().until(startAt, ChronoUnit.MILLIS);
-            if (delay <= 0) {
-                delay = DEFAULT_DELAY_MILLIS;
-            }
-        } else if (delayMillis > 0) {
-            delay = delayMillis;
-        }
-
-        logger.info("The task '{}' is going to be executed in {} ms.", description.getName(), delay);
-        ScheduledFuture<?> future = scheduledService.scheduleAtFixedRate(task, delay, periodMillis, MILLISECONDS);
-        description = new TaskDescription(description.getName(), Status.RUNNING);
-        new Thread(() -> {
-            try {
-                future.get();
-            } catch (Exception e) {
-                e.printStackTrace();
-            } finally {
-                future.cancel(true);
-                latch.countDown();
-                description = new TaskDescription(description.getName(), Status.STOPPED);
-            }
-        }, "thread-" + description.getName()).start();
-    }
-}
+package cz.senslog.watchdog.util.schedule;
+
+
+import cz.senslog.watchdog.messagebroker.broker.EmailMessageBroker;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+
+import static cz.senslog.watchdog.util.TimeConverter.secToMillis;
+import static java.time.format.DateTimeFormatter.ofPattern;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class ScheduleTask implements Task {
+
+    private static final Logger logger = LogManager.getLogger(EmailMessageBroker.class);
+
+    private static final int DEFAULT_DELAY_MILLIS = 2_000; // 2s
+
+    private TaskDescription description;
+    private final Runnable task;
+    private final long periodMillis;
+
+    private final LocalDateTime startAt;
+    private final long delayMillis;
+
+    private ScheduleTask(String name, Runnable task, long periodSec, LocalDateTime startAt, long delaySec) {
+        this.description = new TaskDescription(name, Status.STOPPED);
+        this.task = task;
+        this.periodMillis = secToMillis(periodSec);
+        this.startAt = startAt;
+        this.delayMillis = secToMillis(delaySec);
+    }
+
+    public ScheduleTask(String name, Runnable task, long periodSec, LocalDateTime startAt) {
+        this(name, task, periodSec, startAt, -1);
+    }
+
+    public ScheduleTask(String name, Runnable task, long periodSec, int delaySec) {
+        this(name, task, periodSec, null, delaySec);
+    }
+
+    public ScheduleTask(String name, Runnable task, long periodSec) {
+        this(name, task, periodSec, null);
+    }
+
+    public long getPeriodMillis() {
+        return periodMillis;
+    }
+
+    @Override
+    public Runnable getRunnable() {
+        return task;
+    }
+
+    @Override
+    public TaskDescription getDescription() {
+        return description;
+    }
+
+    @Override
+    public void schedule(ScheduledExecutorService scheduledService, CountDownLatch latch) {
+
+        long delay = DEFAULT_DELAY_MILLIS;
+        if (startAt != null) {
+            delay = LocalDateTime.now().until(startAt, ChronoUnit.MILLIS);
+            if (delay <= 0) {
+                delay = DEFAULT_DELAY_MILLIS;
+            }
+        } else if (delayMillis > 0) {
+            delay = delayMillis;
+        }
+
+        ScheduledFuture<?> future = scheduledService.scheduleAtFixedRate(task, delay, periodMillis, MILLISECONDS);
+        String startAtDateTime = LocalDateTime.now().plus(delay, ChronoUnit.MILLIS).format(ofPattern("yyyy-MM-dd hh:mm:ss"));
+        logger.info("The task '{}' is going to be executed in {} ms at {}.", description.getName(), delay, startAtDateTime);
+        description = new TaskDescription(description.getName(), Status.RUNNING);
+
+        new Thread(() -> {
+            try {
+                future.get();
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                future.cancel(true);
+                latch.countDown();
+                description = new TaskDescription(description.getName(), Status.STOPPED);
+            }
+        }, "thread-" + description.getName()).start();
+    }
+}