From 3b0306967b2afbbe979b72447ae069f8a05f8f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Mari=C4=87?= Date: Fri, 15 Oct 2021 14:59:43 +0200 Subject: [PATCH 1/4] Add support for additional routes on the Dashboard --- docs/reference/schema.md | 4 ++++ src/Microsoft.Tye.Core/ApplicationFactory.cs | 1 + src/Microsoft.Tye.Core/BindingBuilder.cs | 1 + src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs | 1 + src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs | 3 +++ src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor | 5 +++++ src/Microsoft.Tye.Hosting/DockerRunner.cs | 1 + src/Microsoft.Tye.Hosting/Model/ServiceBinding.cs | 1 + src/tye/ApplicationBuilderExtensions.cs | 6 ++++-- 9 files changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/reference/schema.md b/docs/reference/schema.md index 876ffa3f2..8119c9259 100644 --- a/docs/reference/schema.md +++ b/docs/reference/schema.md @@ -402,6 +402,10 @@ Specifies the protocol used by the binding. The protocol is used in [service dis Specifies the hostname used by the binding. The protocol is used in [service discovery](/docs/reference/service_discovery.md) to construct a URL. It's safe to omit the `host` when localhost should be used for local development. +#### `routes` (string) + +Specifies the additional routes as semicolon separated list to show in Bindings on the Dashboard for easy access. Example value: /swagger;/graphql + #### `port` (string) Specifies the port used by the binding. The port is used in [service discovery](/docs/reference/service_discovery.md) to construct a URL. diff --git a/src/Microsoft.Tye.Core/ApplicationFactory.cs b/src/Microsoft.Tye.Core/ApplicationFactory.cs index dd126b479..dd8bf1a81 100644 --- a/src/Microsoft.Tye.Core/ApplicationFactory.cs +++ b/src/Microsoft.Tye.Core/ApplicationFactory.cs @@ -376,6 +376,7 @@ service is ProjectServiceBuilder project2 && ContainerPort = configBinding.ContainerPort, Port = configBinding.Port, Protocol = configBinding.Protocol, + Routes = configBinding.Routes }; // Assume HTTP for projects only (containers may be different) diff --git a/src/Microsoft.Tye.Core/BindingBuilder.cs b/src/Microsoft.Tye.Core/BindingBuilder.cs index 8e795075e..1a10ddad2 100644 --- a/src/Microsoft.Tye.Core/BindingBuilder.cs +++ b/src/Microsoft.Tye.Core/BindingBuilder.cs @@ -12,5 +12,6 @@ public sealed class BindingBuilder public int? ContainerPort { get; set; } public string? Host { get; set; } public string? Protocol { get; set; } + public string? Routes { get; set; } } } diff --git a/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs b/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs index 5d6f9bd21..accd00e52 100644 --- a/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs +++ b/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs @@ -12,5 +12,6 @@ public class ConfigServiceBinding public int? ContainerPort { get; set; } public string? Host { get; set; } public string? Protocol { get; set; } + public string? Routes { get; set; } } } diff --git a/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs b/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs index 014bce756..67d61dfa9 100644 --- a/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs +++ b/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs @@ -218,6 +218,9 @@ private static void HandleServiceBindingNameMapping(YamlMappingNode yamlMappingN case "protocol": binding.Protocol = YamlParser.GetScalarValue(key, child.Value); break; + case "routes": + binding.Routes = YamlParser.GetScalarValue(key, child.Value); + break; default: throw new TyeYamlException(child.Key.Start, CoreStrings.FormatUnrecognizedKey(key)); } diff --git a/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor b/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor index 15f1ead23..082631722 100644 --- a/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor +++ b/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor @@ -55,6 +55,11 @@ { var url = GetUrl(b); @url + foreach (var r in b.Routes) + { + var routeUrl = url + r; + @routeUrl + } } else { diff --git a/src/Microsoft.Tye.Hosting/DockerRunner.cs b/src/Microsoft.Tye.Hosting/DockerRunner.cs index f0d27ab28..e929ca038 100644 --- a/src/Microsoft.Tye.Hosting/DockerRunner.cs +++ b/src/Microsoft.Tye.Hosting/DockerRunner.cs @@ -94,6 +94,7 @@ service.Description.RunInfo is IngressRunInfo || Protocol = binding.Protocol }; b.ReplicaPorts.Add(b.Port.Value); + b.Routes.AddRange(binding.Routes); proxyDescription.Bindings.Add(b); } var proxyContainerService = new Service(proxyDescription, ServiceSource.Host); diff --git a/src/Microsoft.Tye.Hosting/Model/ServiceBinding.cs b/src/Microsoft.Tye.Hosting/Model/ServiceBinding.cs index 2adaa4790..286924f26 100644 --- a/src/Microsoft.Tye.Hosting/Model/ServiceBinding.cs +++ b/src/Microsoft.Tye.Hosting/Model/ServiceBinding.cs @@ -17,5 +17,6 @@ public class ServiceBinding public string? IPAddress { get; set; } public string? Protocol { get; set; } public List ReplicaPorts { get; } = new List(); + public List Routes { get; } = new List(); } } diff --git a/src/tye/ApplicationBuilderExtensions.cs b/src/tye/ApplicationBuilderExtensions.cs index 350e860f8..85acefed6 100644 --- a/src/tye/ApplicationBuilderExtensions.cs +++ b/src/tye/ApplicationBuilderExtensions.cs @@ -174,7 +174,7 @@ public static Application ToHostingApplication(this ApplicationBuilder applicati foreach (var binding in service.Bindings) { - description.Bindings.Add(new ServiceBinding() + var sb = new ServiceBinding() { ConnectionString = binding.ConnectionString, Host = binding.Host, @@ -182,7 +182,9 @@ public static Application ToHostingApplication(this ApplicationBuilder applicati Name = binding.Name, Port = binding.Port, Protocol = binding.Protocol, - }); + }; + sb.Routes.AddRange(binding.Routes?.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty()); + description.Bindings.Add(sb); } services.Add(service.Name, new Service(description, service.Source)); From 260a9fa7c0769485c6081c5f45acd08f20432af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Mari=C4=87?= Date: Fri, 15 Oct 2021 15:27:15 +0200 Subject: [PATCH 2/4] Add deserialization unit tests --- test/UnitTests/TyeDeserializationTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/UnitTests/TyeDeserializationTests.cs b/test/UnitTests/TyeDeserializationTests.cs index c03c1713d..74736d2ef 100644 --- a/test/UnitTests/TyeDeserializationTests.cs +++ b/test/UnitTests/TyeDeserializationTests.cs @@ -82,6 +82,7 @@ public void ComprehensionalTest() containerPort: 80 host: localhost protocol: http + routes: /swagger;/graphql - name: appB project: ApplicationB/ApplicationB.csproj replicas: 2 @@ -155,6 +156,7 @@ public void ServicesSetCorrectly() containerPort: 80 host: localhost protocol: http + routes: /swagger;/graphql - name: appB project: ApplicationB/ApplicationB.csproj replicas: 2 From af5e08bd561bb83b6aba20e8c8fe494cbd50dbcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ante=20Mari=C4=87?= Date: Fri, 5 Nov 2021 11:16:01 +0100 Subject: [PATCH 3/4] Change routes from semicolon separated list to an array --- docs/reference/schema.md | 4 ++-- src/Microsoft.Tye.Core/BindingBuilder.cs | 4 +++- .../ConfigModel/ConfigServiceBinding.cs | 4 +++- .../Serialization/ConfigServiceParser.cs | 17 ++++++++++++++++- src/tye/ApplicationBuilderExtensions.cs | 2 +- test/UnitTests/TyeDeserializationTests.cs | 8 ++++++-- 6 files changed, 31 insertions(+), 8 deletions(-) diff --git a/docs/reference/schema.md b/docs/reference/schema.md index 8119c9259..39d7f3f1d 100644 --- a/docs/reference/schema.md +++ b/docs/reference/schema.md @@ -402,9 +402,9 @@ Specifies the protocol used by the binding. The protocol is used in [service dis Specifies the hostname used by the binding. The protocol is used in [service discovery](/docs/reference/service_discovery.md) to construct a URL. It's safe to omit the `host` when localhost should be used for local development. -#### `routes` (string) +#### `routes` (`string[]`) -Specifies the additional routes as semicolon separated list to show in Bindings on the Dashboard for easy access. Example value: /swagger;/graphql +Specifies the list of additional routes to show in Bindings on the Dashboard for easy access. Example route value: /swagger. #### `port` (string) diff --git a/src/Microsoft.Tye.Core/BindingBuilder.cs b/src/Microsoft.Tye.Core/BindingBuilder.cs index 1a10ddad2..3f933eaac 100644 --- a/src/Microsoft.Tye.Core/BindingBuilder.cs +++ b/src/Microsoft.Tye.Core/BindingBuilder.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; + namespace Microsoft.Tye { public sealed class BindingBuilder @@ -12,6 +14,6 @@ public sealed class BindingBuilder public int? ContainerPort { get; set; } public string? Host { get; set; } public string? Protocol { get; set; } - public string? Routes { get; set; } + public List Routes { get; set; } = new List(); } } diff --git a/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs b/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs index accd00e52..52f6464ef 100644 --- a/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs +++ b/src/Microsoft.Tye.Core/ConfigModel/ConfigServiceBinding.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; + namespace Microsoft.Tye.ConfigModel { public class ConfigServiceBinding @@ -12,6 +14,6 @@ public class ConfigServiceBinding public int? ContainerPort { get; set; } public string? Host { get; set; } public string? Protocol { get; set; } - public string? Routes { get; set; } + public List Routes { get; set; } = new List(); } } diff --git a/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs b/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs index 67d61dfa9..c4f1e4a93 100644 --- a/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs +++ b/src/Microsoft.Tye.Core/Serialization/ConfigServiceParser.cs @@ -219,7 +219,12 @@ private static void HandleServiceBindingNameMapping(YamlMappingNode yamlMappingN binding.Protocol = YamlParser.GetScalarValue(key, child.Value); break; case "routes": - binding.Routes = YamlParser.GetScalarValue(key, child.Value); + if (child.Value.NodeType != YamlNodeType.Sequence) + { + throw new TyeYamlException(child.Value.Start, CoreStrings.FormatExpectedYamlSequence(key)); + } + + HandleServiceBindingRoutes((child.Value as YamlSequenceNode)!, binding.Routes); break; default: throw new TyeYamlException(child.Key.Start, CoreStrings.FormatUnrecognizedKey(key)); @@ -574,6 +579,16 @@ private static void HandleServiceTags(YamlSequenceNode yamlSequenceNode, List routes) + { + foreach (var child in yamlSequenceNode!.Children) + { + var route = YamlParser.GetScalarValue(child); + routes.Add(route); + } + } + private static void HandleServiceDockerArgsNameMapping(YamlMappingNode yamlMappingNode, IDictionary dockerArguments) { foreach (var child in yamlMappingNode!.Children) diff --git a/src/tye/ApplicationBuilderExtensions.cs b/src/tye/ApplicationBuilderExtensions.cs index 85acefed6..0eef6831a 100644 --- a/src/tye/ApplicationBuilderExtensions.cs +++ b/src/tye/ApplicationBuilderExtensions.cs @@ -183,7 +183,7 @@ public static Application ToHostingApplication(this ApplicationBuilder applicati Port = binding.Port, Protocol = binding.Protocol, }; - sb.Routes.AddRange(binding.Routes?.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty()); + sb.Routes.AddRange(binding.Routes); description.Bindings.Add(sb); } diff --git a/test/UnitTests/TyeDeserializationTests.cs b/test/UnitTests/TyeDeserializationTests.cs index 74736d2ef..18966cada 100644 --- a/test/UnitTests/TyeDeserializationTests.cs +++ b/test/UnitTests/TyeDeserializationTests.cs @@ -82,7 +82,9 @@ public void ComprehensionalTest() containerPort: 80 host: localhost protocol: http - routes: /swagger;/graphql + routes: + - /swagger + - /graphql - name: appB project: ApplicationB/ApplicationB.csproj replicas: 2 @@ -156,7 +158,9 @@ public void ServicesSetCorrectly() containerPort: 80 host: localhost protocol: http - routes: /swagger;/graphql + routes: + - /swagger + - /graphql - name: appB project: ApplicationB/ApplicationB.csproj replicas: 2 From 6f973b3dd00fa9075e17b85b43394f28c4fe8fd4 Mon Sep 17 00:00:00 2001 From: phoff Date: Wed, 19 Jan 2022 16:20:30 -0800 Subject: [PATCH 4/4] Use blocks for bindings. --- .../Dashboard/Pages/Index.razor | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor b/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor index 082631722..cf06ba18b 100644 --- a/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor +++ b/src/Microsoft.Tye.Hosting/Dashboard/Pages/Index.razor @@ -2,6 +2,12 @@ @inject Application application @implements IDisposable + +

Services

@@ -54,21 +60,21 @@ if (b.Protocol == "http" || b.Protocol == "https") { var url = GetUrl(b); - @url + @url foreach (var r in b.Routes) { var routeUrl = url + r; - @routeUrl + @routeUrl } } else { - @GetUrl(b) + @GetUrl(b) } } else { - @b.ConnectionString + @b.ConnectionString } } }