diff --git a/src/Ocelot.Library/Infrastructure/Configuration/ConfigurationValidationResult.cs b/src/Ocelot.Library/Infrastructure/Configuration/ConfigurationValidationResult.cs new file mode 100644 index 00000000..976279ca --- /dev/null +++ b/src/Ocelot.Library/Infrastructure/Configuration/ConfigurationValidationResult.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Ocelot.Library.Infrastructure.Configuration +{ + public class ConfigurationValidationResult + { + } +} diff --git a/src/Ocelot.Library/Infrastructure/Configuration/ConfigurationValidator.cs b/src/Ocelot.Library/Infrastructure/Configuration/ConfigurationValidator.cs new file mode 100644 index 00000000..bcb6b0bb --- /dev/null +++ b/src/Ocelot.Library/Infrastructure/Configuration/ConfigurationValidator.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Ocelot.Library.Infrastructure.Responses; + +namespace Ocelot.Library.Infrastructure.Configuration +{ + public class ConfigurationValidator : IConfigurationValidator + { + public Response IsValid(Configuration configuration) + { + var duplicateUpstreamTemplates = configuration.ReRoutes + .Select(r => r.DownstreamTemplate) + .GroupBy(r => r) + .Where(r => r.Count() > 1) + .Select(r => r.Key) + .ToList(); + + if (duplicateUpstreamTemplates.Count <= 0) + { + return new OkResponse(new ConfigurationValidationResult()); + } + + var errors = new List(); + + foreach (var duplicateUpstreamTemplate in duplicateUpstreamTemplates) + { + var error = new DownstreamTemplateAlreadyUsedError(string.Format("Duplicate DownstreamTemplate: {0}", + duplicateUpstreamTemplate)); + errors.Add(error); + } + + return new ErrorResponse(errors); + } + } +} diff --git a/src/Ocelot.Library/Infrastructure/Configuration/DownstreamTemplateAlreadyUsedError.cs b/src/Ocelot.Library/Infrastructure/Configuration/DownstreamTemplateAlreadyUsedError.cs new file mode 100644 index 00000000..3992cb4e --- /dev/null +++ b/src/Ocelot.Library/Infrastructure/Configuration/DownstreamTemplateAlreadyUsedError.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Ocelot.Library.Infrastructure.Responses; + +namespace Ocelot.Library.Infrastructure.Configuration +{ + public class DownstreamTemplateAlreadyUsedError : Error + { + public DownstreamTemplateAlreadyUsedError(string message) : base(message) + { + } + } +} diff --git a/src/Ocelot.Library/Infrastructure/Configuration/IConfigurationValidator.cs b/src/Ocelot.Library/Infrastructure/Configuration/IConfigurationValidator.cs new file mode 100644 index 00000000..595ea21f --- /dev/null +++ b/src/Ocelot.Library/Infrastructure/Configuration/IConfigurationValidator.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Ocelot.Library.Infrastructure.Responses; + +namespace Ocelot.Library.Infrastructure.Configuration +{ + public interface IConfigurationValidator + { + Response IsValid(Configuration configuration); + } +} diff --git a/test/Ocelot.UnitTests/ConfigurationValidationTests.cs b/test/Ocelot.UnitTests/ConfigurationValidationTests.cs new file mode 100644 index 00000000..1a65e3db --- /dev/null +++ b/test/Ocelot.UnitTests/ConfigurationValidationTests.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using Ocelot.Library.Infrastructure.Configuration; +using Ocelot.Library.Infrastructure.Responses; +using Shouldly; +using TestStack.BDDfy; +using Xunit; + +namespace Ocelot.UnitTests +{ + public class ConfigurationValidationTests + { + private Configuration _configuration; + private readonly IConfigurationValidator _configurationValidator; + private Response _result; + + public ConfigurationValidationTests() + { + _configurationValidator = new ConfigurationValidator(); + } + + [Fact] + public void configuration_is_valid_with_one_reroute() + { + this.Given(x => x.GivenAConfiguration(new Configuration() + { + ReRoutes = new List + { + new ReRoute + { + DownstreamTemplate = "http://www.bbc.co.uk", + UpstreamTemplate = "http://asdf.com" + } + } + })) + .When(x => x.WhenIValidateTheConfiguration()) + .Then(x => x.ThenTheResultIsValid()) + .BDDfy(); + } + + [Fact] + public void configuration_is_not_valid_with_duplicate_reroutes() + { + this.Given(x => x.GivenAConfiguration(new Configuration() + { + ReRoutes = new List + { + new ReRoute + { + DownstreamTemplate = "http://www.bbc.co.uk", + UpstreamTemplate = "http://asdf.com" + }, + new ReRoute + { + DownstreamTemplate = "http://www.bbc.co.uk", + UpstreamTemplate = "http://lol.com" + } + } + })) + .When(x => x.WhenIValidateTheConfiguration()) + .Then(x => x.ThenTheResultIsNotValid()) + .BDDfy(); + } + + private void GivenAConfiguration(Configuration configuration) + { + _configuration = configuration; + } + + private void WhenIValidateTheConfiguration() + { + _result = _configurationValidator.IsValid(_configuration); + } + + private void ThenTheResultIsValid() + { + _result.IsError.ShouldBeFalse(); + } + + private void ThenTheResultIsNotValid() + { + _result.IsError.ShouldBeTrue(); + } + } +}