Skip to content

Commit b3d145d

Browse files
authored
Merge branch 'develop' into 2168-watchkube
2 parents da71b90 + 1cf5597 commit b3d145d

File tree

9 files changed

+717
-676
lines changed

9 files changed

+717
-676
lines changed

src/Ocelot.Provider.Consul/ConsulProviderFactory.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,16 @@ public static class ConsulProviderFactory // TODO : IServiceDiscoveryProviderFac
2525
public static ServiceDiscoveryFinderDelegate Get { get; } = CreateProvider;
2626
private static IServiceDiscoveryProvider CreateProvider(IServiceProvider provider, ServiceProviderConfiguration config, DownstreamRoute route)
2727
{
28+
// Singleton services
2829
var factory = provider.GetService<IOcelotLoggerFactory>();
2930
var consulFactory = provider.GetService<IConsulClientFactory>();
3031
var contextAccessor = provider.GetService<IHttpContextAccessor>();
3132

33+
// Scoped services
34+
var context = contextAccessor.HttpContext;
3235
var configuration = new ConsulRegistryConfiguration(config.Scheme, config.Host, config.Port, route.ServiceName, config.Token); // TODO Why not to pass 2 args only: config, route? LoL
33-
contextAccessor.HttpContext.Items[nameof(ConsulRegistryConfiguration)] = configuration; // initialize data
34-
var serviceBuilder = provider.GetService<IConsulServiceBuilder>(); // consume data in default/custom builder
36+
context.Items[nameof(ConsulRegistryConfiguration)] = configuration; // initialize data
37+
var serviceBuilder = context.RequestServices.GetService<IConsulServiceBuilder>(); // consume data in default/custom builder
3538

3639
var consulProvider = new Consul(configuration, factory, consulFactory, serviceBuilder); // TODO It must be added to DI-container!
3740

test/Ocelot.AcceptanceTests/AggregateTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ public void Should_return_response_200_with_user_forwarding()
578578
.And(x => x.GivenServiceIsRunning(1, port2, "/", 200, "{Hello from Tom}"))
579579
.And(x => auth.GivenIHaveAToken(identityServerUrl))
580580
.And(x => auth.GivenThereIsAConfiguration(configuration))
581-
.And(x => auth.GivenOcelotIsRunningWithServices(configureServices, configureApp))
581+
.And(x => auth.GivenOcelotIsRunningWithServices(configureServices, configureApp, true))
582582
.And(x => auth.GivenIHaveAddedATokenToMyRequest())
583583
.When(x => auth.WhenIGetUrlOnTheApiGateway("/"))
584584
.Then(x => auth.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
Original file line numberDiff line numberDiff line change
@@ -1,180 +1,215 @@
1+
using CacheManager.Core;
12
using Consul;
23
using IdentityServer4.Extensions;
34
using Microsoft.AspNetCore.Builder;
45
using Microsoft.AspNetCore.Hosting;
56
using Microsoft.AspNetCore.Http;
7+
using Microsoft.AspNetCore.TestHost;
8+
using Microsoft.Extensions.Configuration;
69
using Microsoft.Extensions.Hosting;
710
using Newtonsoft.Json;
11+
using Ocelot.AcceptanceTests.Caching;
12+
using Ocelot.Cache.CacheManager;
813
using Ocelot.Configuration.File;
14+
using Ocelot.DependencyInjection;
15+
using Ocelot.Middleware;
16+
using Ocelot.Provider.Consul;
917
using System.Text;
1018

11-
namespace Ocelot.AcceptanceTests.Configuration
19+
namespace Ocelot.AcceptanceTests.Configuration;
20+
21+
public sealed class ConfigurationInConsulTests : Steps, IDisposable
1222
{
13-
public class ConfigurationInConsulTests : IDisposable
23+
private IHost _builder;
24+
private IHost _fakeConsulBuilder;
25+
private FileConfiguration _config;
26+
private readonly List<ServiceEntry> _consulServices;
27+
28+
public ConfigurationInConsulTests()
1429
{
15-
private IHost _builder;
16-
private readonly Steps _steps;
17-
private IHost _fakeConsulBuilder;
18-
private FileConfiguration _config;
19-
private readonly List<ServiceEntry> _consulServices;
30+
_consulServices = new List<ServiceEntry>();
31+
}
2032

21-
public ConfigurationInConsulTests()
22-
{
23-
_consulServices = new List<ServiceEntry>();
24-
_steps = new Steps();
25-
}
33+
public override void Dispose()
34+
{
35+
_builder?.Dispose();
36+
_fakeConsulBuilder?.Dispose();
37+
base.Dispose();
38+
}
2639

27-
[Fact]
28-
public void should_return_response_200_with_simple_url_when_using_jsonserialized_cache()
29-
{
30-
var consulPort = PortFinder.GetRandomPort();
31-
var servicePort = PortFinder.GetRandomPort();
40+
[Fact]
41+
public void Should_return_response_200_with_simple_url_when_using_jsonserialized_cache()
42+
{
43+
var consulPort = PortFinder.GetRandomPort();
44+
var servicePort = PortFinder.GetRandomPort();
3245

33-
var configuration = new FileConfiguration
34-
{
35-
Routes = new List<FileRoute>
46+
var configuration = new FileConfiguration
47+
{
48+
Routes = new List<FileRoute>
49+
{
50+
new()
3651
{
37-
new()
52+
DownstreamPathTemplate = "/",
53+
DownstreamScheme = "http",
54+
DownstreamHostAndPorts = new List<FileHostAndPort>
3855
{
39-
DownstreamPathTemplate = "/",
40-
DownstreamScheme = "http",
41-
DownstreamHostAndPorts = new List<FileHostAndPort>
56+
new()
4257
{
43-
new()
44-
{
45-
Host = "localhost",
46-
Port = servicePort,
47-
},
58+
Host = "localhost",
59+
Port = servicePort,
4860
},
49-
UpstreamPathTemplate = "/",
50-
UpstreamHttpMethod = new List<string> { "Get" },
5161
},
62+
UpstreamPathTemplate = "/",
63+
UpstreamHttpMethod = new List<string> { "Get" },
5264
},
53-
GlobalConfiguration = new FileGlobalConfiguration
65+
},
66+
GlobalConfiguration = new FileGlobalConfiguration
67+
{
68+
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
5469
{
55-
ServiceDiscoveryProvider = new FileServiceDiscoveryProvider
56-
{
57-
Scheme = "http",
58-
Host = "localhost",
59-
Port = consulPort,
60-
},
70+
Scheme = "http",
71+
Host = "localhost",
72+
Port = consulPort,
6173
},
62-
};
63-
64-
var fakeConsulServiceDiscoveryUrl = $"http://localhost:{consulPort}";
65-
66-
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl, string.Empty))
67-
.And(x => x.GivenThereIsAServiceRunningOn($"http://localhost:{servicePort}", string.Empty, 200, "Hello from Laura"))
68-
.And(x => _steps.GivenThereIsAConfiguration(configuration))
69-
.And(x => _steps.GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache())
70-
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
71-
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
72-
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
73-
.BDDfy();
74-
}
74+
},
75+
};
76+
77+
var fakeConsulServiceDiscoveryUrl = DownstreamUrl(consulPort);
78+
79+
this.Given(x => GivenThereIsAFakeConsulServiceDiscoveryProvider(fakeConsulServiceDiscoveryUrl, string.Empty))
80+
.And(x => x.GivenThereIsAServiceRunningOn(DownstreamUrl(servicePort), string.Empty, 200, "Hello from Laura"))
81+
.And(x => GivenThereIsAConfiguration(configuration))
82+
.And(x => x.GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache())
83+
.When(x => WhenIGetUrlOnTheApiGateway("/"))
84+
.Then(x => ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
85+
.And(x => ThenTheResponseBodyShouldBe("Hello from Laura"))
86+
.BDDfy();
87+
}
7588

76-
private Task GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
77-
{
78-
_fakeConsulBuilder = Host.CreateDefaultBuilder()
79-
.ConfigureWebHost(webBuilder =>
80-
{
81-
webBuilder.UseUrls(url)
82-
.UseKestrel()
83-
.UseContentRoot(Directory.GetCurrentDirectory())
84-
.UseIISIntegration()
85-
.UseUrls(url)
86-
.Configure(app =>
89+
private void GivenOcelotIsRunningUsingConsulToStoreConfigAndJsonSerializedCache()
90+
{
91+
_webHostBuilder = new WebHostBuilder()
92+
.UseDefaultServiceProvider(_ => _.ValidateScopes = true)
93+
.ConfigureAppConfiguration((hostingContext, config) =>
94+
{
95+
config.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath);
96+
var env = hostingContext.HostingEnvironment;
97+
config.AddJsonFile("appsettings.json", true, false)
98+
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, false);
99+
config.AddJsonFile(_ocelotConfigFileName, true, false);
100+
config.AddEnvironmentVariables();
101+
})
102+
.ConfigureServices(s =>
103+
{
104+
s.AddOcelot()
105+
.AddCacheManager(x => x
106+
.WithMicrosoftLogging(_ => { /*log.AddConsole(LogLevel.Debug);*/ })
107+
.WithJsonSerializer()
108+
.WithHandle(typeof(InMemoryJsonHandle<>)))
109+
.AddConsul()
110+
.AddConfigStoredInConsul();
111+
})
112+
.Configure(app => app.UseOcelot().GetAwaiter().GetResult()); // Turning as async/await some tests got broken
113+
114+
_ocelotServer = new TestServer(_webHostBuilder);
115+
_ocelotClient = _ocelotServer.CreateClient();
116+
}
117+
118+
private Task GivenThereIsAFakeConsulServiceDiscoveryProvider(string url, string serviceName)
119+
{
120+
_fakeConsulBuilder = Host.CreateDefaultBuilder()
121+
.ConfigureWebHost(webBuilder =>
122+
{
123+
webBuilder.UseUrls(url)
124+
.UseKestrel()
125+
.UseContentRoot(Directory.GetCurrentDirectory())
126+
.UseIISIntegration()
127+
.UseUrls(url)
128+
.Configure(app =>
129+
{
130+
app.Run(async context =>
87131
{
88-
app.Run(async context =>
132+
if (context.Request.Method.ToLower() == "get" && context.Request.Path.Value == "/v1/kv/InternalConfiguration")
89133
{
90-
if (context.Request.Method.ToLower() == "get" && context.Request.Path.Value == "/v1/kv/InternalConfiguration")
91-
{
92-
var json = JsonConvert.SerializeObject(_config);
134+
var json = JsonConvert.SerializeObject(_config);
93135

94-
var bytes = Encoding.UTF8.GetBytes(json);
136+
var bytes = Encoding.UTF8.GetBytes(json);
95137

96-
var base64 = Convert.ToBase64String(bytes);
138+
var base64 = Convert.ToBase64String(bytes);
97139

98-
var kvp = new FakeConsulGetResponse(base64);
140+
var kvp = new FakeConsulGetResponse(base64);
99141

100-
await context.Response.WriteJsonAsync(new[] { kvp });
101-
}
102-
else if (context.Request.Method.ToLower() == "put" && context.Request.Path.Value == "/v1/kv/InternalConfiguration")
142+
await context.Response.WriteJsonAsync(new[] { kvp });
143+
}
144+
else if (context.Request.Method.ToLower() == "put" && context.Request.Path.Value == "/v1/kv/InternalConfiguration")
145+
{
146+
try
103147
{
104-
try
105-
{
106-
var reader = new StreamReader(context.Request.Body);
148+
var reader = new StreamReader(context.Request.Body);
107149

108-
// Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
109-
// var json = reader.ReadToEnd();
110-
var json = await reader.ReadToEndAsync();
150+
// Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
151+
// var json = reader.ReadToEnd();
152+
var json = await reader.ReadToEndAsync();
111153

112-
_config = JsonConvert.DeserializeObject<FileConfiguration>(json);
154+
_config = JsonConvert.DeserializeObject<FileConfiguration>(json);
113155

114-
var response = JsonConvert.SerializeObject(true);
156+
var response = JsonConvert.SerializeObject(true);
115157

116-
await context.Response.WriteAsync(response);
117-
}
118-
catch (Exception e)
119-
{
120-
Console.WriteLine(e);
121-
throw;
122-
}
158+
await context.Response.WriteAsync(response);
123159
}
124-
else if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
160+
catch (Exception e)
125161
{
126-
await context.Response.WriteJsonAsync(_consulServices);
162+
Console.WriteLine(e);
163+
throw;
127164
}
128-
});
165+
}
166+
else if (context.Request.Path.Value == $"/v1/health/service/{serviceName}")
167+
{
168+
await context.Response.WriteJsonAsync(_consulServices);
169+
}
129170
});
130-
}).Build();
131-
return _fakeConsulBuilder.StartAsync();
132-
}
171+
});
172+
}).Build();
173+
return _fakeConsulBuilder.StartAsync();
174+
}
133175

134-
public class FakeConsulGetResponse
176+
public class FakeConsulGetResponse
177+
{
178+
public FakeConsulGetResponse(string value)
135179
{
136-
public FakeConsulGetResponse(string value)
137-
{
138-
Value = value;
139-
}
140-
141-
public int CreateIndex => 100;
142-
public int ModifyIndex => 200;
143-
public int LockIndex => 200;
144-
public string Key => "InternalConfiguration";
145-
public int Flags => 0;
146-
public string Value { get; }
147-
public string Session => "adf4238a-882b-9ddc-4a9d-5b6758e4159e";
180+
Value = value;
148181
}
149182

150-
private Task GivenThereIsAServiceRunningOn(string url, string basePath, int statusCode, string responseBody)
151-
{
152-
_builder = Host.CreateDefaultBuilder()
153-
.ConfigureWebHost(webBuilder =>
183+
public int CreateIndex => 100;
184+
public int ModifyIndex => 200;
185+
public int LockIndex => 200;
186+
public string Key => "InternalConfiguration";
187+
public int Flags => 0;
188+
public string Value { get; }
189+
public string Session => "adf4238a-882b-9ddc-4a9d-5b6758e4159e";
190+
}
191+
192+
private Task GivenThereIsAServiceRunningOn(string url, string basePath, int statusCode, string responseBody)
193+
{
194+
_builder = Host.CreateDefaultBuilder()
195+
.ConfigureWebHost(webBuilder =>
196+
{
197+
webBuilder.UseUrls(url)
198+
.UseKestrel()
199+
.UseContentRoot(Directory.GetCurrentDirectory())
200+
.UseIISIntegration()
201+
.UseUrls(url)
202+
.Configure(app =>
154203
{
155-
webBuilder.UseUrls(url)
156-
.UseKestrel()
157-
.UseContentRoot(Directory.GetCurrentDirectory())
158-
.UseIISIntegration()
159-
.UseUrls(url)
160-
.Configure(app =>
204+
app.UsePathBase(basePath);
205+
app.Run(async context =>
161206
{
162-
app.UsePathBase(basePath);
163-
app.Run(async context =>
164-
{
165-
context.Response.StatusCode = statusCode;
166-
await context.Response.WriteAsync(responseBody);
167-
});
207+
context.Response.StatusCode = statusCode;
208+
await context.Response.WriteAsync(responseBody);
168209
});
169-
})
170-
.Build();
171-
return _builder.StartAsync();
172-
}
173-
174-
public void Dispose()
175-
{
176-
_builder?.Dispose();
177-
_steps.Dispose();
178-
}
210+
});
211+
})
212+
.Build();
213+
return _builder.StartAsync();
179214
}
180215
}

0 commit comments

Comments
 (0)