using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.IO; using System.Linq; namespace CustomTasks.Endpoint { /// /// Implementation of a IEndpointOverrider /// Endpoint overrider: will override the endpoints.json file and remove/add endpoints /// Based on a json input file for addition and removal /// public class EndpointOverrider : IEndpointOverrider { private readonly IFileSystem _fs; public EndpointOverrider() : this(new FileSystem()) { } public EndpointOverrider(IFileSystem fs) { _fs = fs; } /// /// Applies overrides to an endpoints.json file /// /// The endpoints-original.json source location /// The path to the endpoints override json file /// String: the new endpoints.json input text. public string ApplyOverrides(string endpointsJsonSourceFilePath, string endpointsOverrideFilePath) { // Retrieve the current endpoints-original.json file string input = _fs.ReadAllText(endpointsJsonSourceFilePath); JObject endpointsData = JObject.Parse(input); // Retrieve the endpoints-override.json file string overrideJson = _fs.ReadAllText(endpointsOverrideFilePath); if (!string.IsNullOrWhiteSpace(overrideJson)) { JObject configuration = JObject.Parse(overrideJson); if (configuration != null) { foreach (var service in configuration.Children()) { var servicePrefix = service.Path; JToken serviceNode = endpointsData["partitions"][0]["services"][servicePrefix]; if (serviceNode != null) { JObject endpointsNode = serviceNode["endpoints"] as JObject; var endpointsToRemove = configuration.SelectTokens($"{servicePrefix}.remove"); foreach (var endpointToRemove in endpointsToRemove.Children()) { endpointsNode.Remove(endpointToRemove.ToObject()); } var endpointsToAdd = configuration.SelectTokens($"{servicePrefix}.add"); foreach (var endpointToAdd in endpointsToAdd.Children()) { // We can not have two properties with the same name var endpointProperty = endpointToAdd as JProperty; var exists = endpointsNode.Properties().ToList().Exists(p => p.Name == endpointProperty.Name); if (!exists) { endpointsNode.Add(endpointToAdd); } else { throw new InvalidOperationException($"The endpoint {endpointProperty.Name} already exists for service {servicePrefix}"); } } } else { throw new InvalidOperationException($"The service {servicePrefix} does not exist in the endpoints.json file"); } } } } var targetPath = Path.Combine(Path.GetDirectoryName(endpointsJsonSourceFilePath), "endpoints.json"); string output = JsonConvert.SerializeObject(endpointsData, Formatting.Indented); _fs.WriteAllText(targetPath, output); return output; } } }