From 27b72c4f4fe98c85ee3b289322ff8955274a59a1 Mon Sep 17 00:00:00 2001
From: Benedikt Heinrichs <Heinrichs@itc.rwth-aachen.de>
Date: Tue, 5 Mar 2019 11:33:03 +0100
Subject: [PATCH] Add a Listener

---
 ConfigurationUpdater/Consul.cs  | 10 +++++
 ConfigurationUpdater/Program.cs | 75 ++++++++++++++++++++++++++++-----
 README.md                       |  8 ++--
 3 files changed, 80 insertions(+), 13 deletions(-)

diff --git a/ConfigurationUpdater/Consul.cs b/ConfigurationUpdater/Consul.cs
index 625d3a8..b77d969 100644
--- a/ConfigurationUpdater/Consul.cs
+++ b/ConfigurationUpdater/Consul.cs
@@ -1,6 +1,7 @@
 using Consul;
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -53,5 +54,14 @@ namespace ConfigurationUpdater
             return task.Result;
         }
 
+        internal static void UpdateConfigurationFile(string templateConfigurationFile, string outputConfigurationFile, Dictionary<string, string> listenKeys, Dictionary<string, string> currentValues)
+        {
+            string text = File.ReadAllText(templateConfigurationFile);
+            foreach (var kv in listenKeys)
+            {
+                text = text.Replace(kv.Value, currentValues[kv.Key]);
+            }
+            File.WriteAllText(outputConfigurationFile, text);
+        }
     }
 }
diff --git a/ConfigurationUpdater/Program.cs b/ConfigurationUpdater/Program.cs
index 03404d0..ac30b51 100644
--- a/ConfigurationUpdater/Program.cs
+++ b/ConfigurationUpdater/Program.cs
@@ -28,7 +28,7 @@ namespace ConfigurationUpdater
                             }
                             else
                             {
-                                Console.WriteLine("Please call \"SetValue\" with \"Key\" and \"Value\"");
+                                Console.WriteLine("Please call \"SetValue\" with \"ConsulKey\" and \"ConsulValue\"");
                             }
                             break;
                         case "GetValue":
@@ -38,21 +38,29 @@ namespace ConfigurationUpdater
                             }
                             else
                             {
-                                Console.WriteLine("Please call \"GetValue\" with \"Key\"");
+                                Console.WriteLine("Please call \"GetValue\" with \"ConsulKey\"");
                             }
                             break;
                         case "SetValueOnConfiguration":
-                            if (args.Length == 4)
+                            if (args.Length >= 5)
                             {
-                                string value = Consul.TaskRetriever(Consul.GetValue(args[1]));
-                                string text = File.ReadAllText(args[2]);
-                                text = text.Replace(args[3], value);
-                                File.WriteAllText(args[2], text);
-                                Console.WriteLine("Replaced \"" + args[3] + "\" with \"" + value + "\" in \"" + args[2] + "\"");
+                                string templateConfigFile = args[1];
+                                string outputConfigFile = args[2];
+
+                                Dictionary<string, string> listenKeys = new Dictionary<string, string>();
+                                Dictionary<string, string> currentValues = new Dictionary<string, string>();
+                                for (int i = 3; i < args.Length; i = i + 2)
+                                {
+                                    listenKeys.Add(args[i + 1], args[i]);
+                                    currentValues.Add(args[i + 1], Consul.TaskRetriever(Consul.GetValue(args[i + 1])));
+                                }
+
+                                Consul.UpdateConfigurationFile(templateConfigFile, outputConfigFile, listenKeys, currentValues);
+                                Console.WriteLine("Replaced \"" + string.Join(";", listenKeys.Select(x => x.Key + "=" + x.Value).ToArray()) + "\" with \"" + string.Join(";", currentValues.Select(x => x.Key + "=" + x.Value).ToArray()) + "\" in \"" + outputConfigFile + "\"");
                             }
                             else
                             {
-                                Console.WriteLine("Please call \"SetValueOnConfiguration\" with \"Key\", \"ConfigurationFile\" and \"ReplaceKey\"");
+                                Console.WriteLine("Please call \"SetValueOnConfiguration\" with \"TemplateConfigurationFile\", \"OutputConfigurationFile\" and n-combinations of \"ReplaceKey\" and \"ConsulKey\"");
                             }
                             break;
                         case "RestartNomadJob":
@@ -67,8 +75,55 @@ namespace ConfigurationUpdater
                                 Console.WriteLine("Please call \"RestartNomadJob\" with the \"JobId\"");
                             }
                             break;
+                        case "Listen":
+                            if(args.Length >= 6)
+                            {
+                                string jobId = args[1];
+                                string templateConfigFile = args[2];
+                                string outputConfigFile = args[3];
+                                Dictionary<string, string> listenKeys = new Dictionary<string, string>();
+                                Dictionary<string, string> currentValues = new Dictionary<string, string>();
+                                for (int i = 4; i < args.Length; i = i + 2)
+                                {
+                                    listenKeys.Add(args[i + 1], args[i]);
+                                    currentValues.Add(args[i + 1], Consul.TaskRetriever(Consul.GetValue(args[i + 1])));
+                                }
+                                Consul.UpdateConfigurationFile(templateConfigFile, outputConfigFile, listenKeys, currentValues);
+                                Nomad.UpdateJob(jobId);
+                                Console.WriteLine("Replaced \"" + string.Join(";", listenKeys.Select(x => x.Key + "=" + x.Value).ToArray()) + "\" with \"" + string.Join(";", currentValues.Select(x => x.Key + "=" + x.Value).ToArray()) + "\" in \"" + outputConfigFile + "\"");
+
+                                while (true)
+                                {
+                                    // Checks every minute
+                                    System.Threading.Thread.Sleep(60000);
+
+                                    bool valueChange = false;
+                                    foreach(var kv in listenKeys)
+                                    {
+                                        var currentValue = Consul.TaskRetriever(Consul.GetValue(kv.Key));
+                                        if (currentValue != kv.Value)
+                                        {
+                                            currentValues[kv.Key] = currentValue;
+                                            valueChange = true;
+                                        }
+                                    }
+
+                                    if (valueChange)
+                                    {
+                                        Consul.UpdateConfigurationFile(templateConfigFile, outputConfigFile, listenKeys, currentValues);
+                                        Nomad.UpdateJob(jobId);
+                                        Console.WriteLine("Replaced \"" + string.Join(";", listenKeys.Select(x => x.Key + "=" + x.Value).ToArray()) + "\" with \"" + string.Join(";", currentValues.Select(x => x.Key + "=" + x.Value).ToArray()) + "\" in \"" + outputConfigFile + "\"");
+                                    }
+                                }
+
+                            } 
+                            else
+                            {
+                                Console.WriteLine("Please call \"Listen\" with \"JobId\", \"TemplateConfigurationFile\", \"OutputConfigurationFile\" and n-combinations of \"ReplaceKey\" and \"ConsulKey\"");
+                            }
+                            break;
                         default:
-                            Console.WriteLine("Please call this program with the method \"SetValue\", \"GetValue\", \"SetValueOnConfiguration\" or \"RestartNomadJob\"");
+                            Console.WriteLine("Please call this program with the method \"SetValue\", \"GetValue\", \"SetValueOnConfiguration\", \"RestartNomadJob\" or \"Listen\"");
                             break;
                     }
                 }
diff --git a/README.md b/README.md
index 1c23efb..92628d6 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,11 @@
-Call this program with the method "SetValue", "GetValue", "SetValueOnConfiguration" or "RestartNomadJob".
+Call this program with the method "SetValue", "GetValue", "SetValueOnConfiguration", "RestartNomadJob" or "Listen".
 
 Call "SetValue" with "Key" and "Value".
                            
 Call "GetValue" with "Key".
 
-Call "SetValueOnConfiguration" with "Key", "ConfigurationFile" and "ReplaceKey".
+Call "SetValueOnConfiguration" with "Key", "TemplateConfigurationFile", "OutputConfigurationFile" and n-combinations of "ReplaceKey" and "ConsulKey".
 
-Call "RestartNomadJob" with the "JobId".
\ No newline at end of file
+Call "RestartNomadJob" with the "JobId".
+
+Call "Listen" with "JobId", "Key", "TemplateConfigurationFile", "OutputConfigurationFile" and n-combinations of "ReplaceKey" and "ConsulKey".
\ No newline at end of file
-- 
GitLab