From 4f12d39d10a84f751fc8e4e31a3317cf419c7d5a Mon Sep 17 00:00:00 2001
From: David Trattnig <david.trattnig@o94.at>
Date: Fri, 26 Jun 2020 13:22:59 +0200
Subject: [PATCH] Push logentry to sync host.

---
 .../sample/sample-development.engine-api.ini  | 17 +++++--
 src/service.py                                | 47 +++++++++++++++----
 2 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/config/sample/sample-development.engine-api.ini b/config/sample/sample-development.engine-api.ini
index 175300a..225e84f 100644
--- a/config/sample/sample-development.engine-api.ini
+++ b/config/sample/sample-development.engine-api.ini
@@ -23,6 +23,12 @@ api_port=8008
 
 [federation]
 
+# Defines the engine number id for identification of record sources. Default values are:
+# 
+#   1 ... Engine 1 (main node)
+#   2 ... Engine 2 (main node, not needed for single deployment)
+#   0 ... Sync Host (sync node, not needed for single engine deployment)
+#
 # Engine API supports two deployment models:
 #
 #   - "main": Deployed together with some `engine` (Single instance or for redundant engines)
@@ -30,11 +36,16 @@ api_port=8008
 #
 # The `synch_host` identifies the host where data is gathered from/synced to, depended on the
 # chosen `node_type`.
-#
 
-node_type="main"
+host_id=1
 sync_host="http://localhost:8010"
 
-; node_type="sync"
+; host_id=2
+; sync_host="http://localhost:8010"
+
+; host_id=0
 ; main_host_1="http://localhost:8008"
 ; main_host_2="http://localhost:8009"
+
+
+sync_api_store_playlog="/api/v1/playlog/store"
\ No newline at end of file
diff --git a/src/service.py b/src/service.py
index aa2ded2..1dec65b 100644
--- a/src/service.py
+++ b/src/service.py
@@ -18,9 +18,10 @@
 
 
 import datetime
+import requests
 
 from enum import Enum
-from models import PlayLog, TrackSchema
+from models import PlayLog, PlayLogSchema, TrackSchema
 
 
 class NodeType(Enum):
@@ -52,21 +53,32 @@ class ApiService():
         self.logger = logger
 
         # Evaluate deployment mode
-        node_type = config.get("node_type")
-        if not node_type == NodeType.MAIN.value:
+        node_type = NodeType.MAIN
+        host_id = config.get("host_id")
+        if host_id == 0:
+            node_type = NodeType.SYNC
+
+        # Configured as Sync node
+        if not node_type == NodeType.MAIN:
             self.node_type = NodeType.SYNC
             self.main_hosts = [ config.get("main_host_1"), config.get("main_host_2") ]
-            self.logger.info("Running in 'SYNC' mode. Syncing data of '%s'" % (self.main_hosts))
+            if not self.main_hosts[0] and not self.main_hosts[1]:
+                self.logger.warn("Not a single main host defined. Be aware what you are doing.")
+                msg = "No sync possible as no host nodes are configured."
+            else:
+                msg = "Syncing data of hosts '%s'" % (self.main_hosts)
 
+        # Configured as Main node
         else:
             self.node_type = NodeType.MAIN
-
-            # Validate sync host
             self.sync_host = config.get("sync_host")
             if not self.sync_host:
-                raise ValueError("Invalid sync_host '%s'!" % self.sync_host)    
+                msg = "No child node for synchronization defined."
+            else:
+                msg = "Pushing data to '%s'" % (self.sync_host)
+
+        self.logger.info("Running in '%s' mode. %s" % (self.node_type, msg))
 
-            self.logger.info("Running in 'MAIN' mode. Pushing data to '%s'" % (self.sync_host))
 
 
     def current_track(self):  
@@ -122,8 +134,27 @@ class ApiService():
         Returns:
             (PlayLogEntry)
         """
+        if not data.log_source:
+            data.log_source = self.host_id
+
         playlog = PlayLog(data)
         playlog.save()
+        self.logger.info("Stored playlog for '%s'" % playlog.track_start)
+
+        # Push to sync node if configured
+        if self.sync_host:
+            playlog_schema = PlayLogSchema()
+            json_playlog = playlog_schema.dump(playlog)
+            
+            try:
+                api_url = self.sync_host + self.config.get("sync_api_store_playlog")
+                r = requests.post(api_url, json=json_playlog)
+                if r.status_code == 200:
+                    self.logger.info("Successfully pushed playlog for '%s' to '%s'" % (playlog.track_start, self.sync_host))
+                else:
+                    self.logger.error("Error while pushing playlog to sync-node: " + r.json())
+            except Exception as e:
+                self.logger.error("Error while posting to sync-node API '%s'!" % (api_url), e)
 
 
     def clock_info(self):
-- 
GitLab