Skip to content

Commit 21cfb0f

Browse files
added method to start keycloak
1 parent 9b280a1 commit 21cfb0f

8 files changed

Lines changed: 94 additions & 23 deletions

File tree

ClientProxyBase/ClientProxyBase.cs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ protected virtual async Task<Result<TResponse>> SendGetRequest<TResponse>(String
109109
{
110110

111111
HttpRequestMessage requestMessage = new(HttpMethod.Get, uri);
112-
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
112+
if (String.IsNullOrEmpty(accessToken) == false)
113+
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
113114

114115
// Make the Http Call here
115116
HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken);
@@ -129,8 +130,15 @@ protected virtual async Task<Result<TResponse>> SendPostRequest<TRequest, TRespo
129130
{
130131

131132
HttpRequestMessage requestMessage = new(HttpMethod.Post, uri);
132-
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
133-
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
133+
if (String.IsNullOrEmpty(accessToken) == false)
134+
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
135+
if (content.GetType() == typeof(FormUrlEncodedContent)) {
136+
// Treat this specially
137+
requestMessage.Content = content as FormUrlEncodedContent;
138+
}
139+
else {
140+
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
141+
}
134142

135143
// Make the Http Call here
136144
HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken);
@@ -150,8 +158,17 @@ protected virtual async Task<Result<TResponse>> SendPutRequest<TRequest, TRespon
150158
{
151159

152160
HttpRequestMessage requestMessage = new(HttpMethod.Put, uri);
153-
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
154-
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
161+
if (String.IsNullOrEmpty(accessToken) == false)
162+
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
163+
if (content.GetType() == typeof(FormUrlEncodedContent))
164+
{
165+
// Treat this specially
166+
requestMessage.Content = content as FormUrlEncodedContent;
167+
}
168+
else
169+
{
170+
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
171+
}
155172

156173
// Make the Http Call here
157174
HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken);
@@ -171,8 +188,17 @@ protected virtual async Task<Result<TResponse>> SendPatchRequest<TRequest, TResp
171188
{
172189

173190
HttpRequestMessage requestMessage = new(HttpMethod.Patch, uri);
174-
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
175-
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
191+
if (String.IsNullOrEmpty(accessToken) == false)
192+
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
193+
if (content.GetType() == typeof(FormUrlEncodedContent))
194+
{
195+
// Treat this specially
196+
requestMessage.Content = content as FormUrlEncodedContent;
197+
}
198+
else
199+
{
200+
requestMessage.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
201+
}
176202

177203
// Make the Http Call here
178204
HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken);
@@ -192,7 +218,8 @@ protected virtual async Task<Result<TResponse>> SendDeleteRequest<TResponse>(Str
192218
{
193219

194220
HttpRequestMessage requestMessage = new(HttpMethod.Delete, uri);
195-
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
221+
if (String.IsNullOrEmpty(accessToken) == false)
222+
requestMessage.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationSchemes.Bearer, accessToken);
196223

197224
// Make the Http Call here
198225
HttpResponseMessage httpResponse = await this.HttpClient.SendAsync(requestMessage, cancellationToken);

Shared.IntegrationTesting.Tests/GenericSteps.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
namespace Shared.IntegrationTesting.Tests;
1+
using ClientProxyBase;
2+
3+
namespace Shared.IntegrationTesting.Tests;
24

35
using Logger;
6+
using Microsoft.AspNetCore.Http;
47
using NLog;
58
using Reqnroll;
69

@@ -43,15 +46,17 @@ public async Task StartSystem() {
4346
DockerServices services = DockerServices.EventStore | DockerServices.MessagingService | DockerServices.SecurityService |
4447
DockerServices.CallbackHandler | DockerServices.FileProcessor |
4548
DockerServices.TestHost | DockerServices.TransactionProcessor |
46-
DockerServices.TransactionProcessorAcl;
47-
49+
DockerServices.TransactionProcessorAcl | DockerServices.KeyCloak;
50+
4851
this.TestingContext.Logger = logger;
4952
this.TestingContext.Logger.LogInformation("About to Start Containers for Scenario Run");
5053
this.TestingContext.DockerHelper.ScenarioName = scenarioName;
5154
await this.TestingContext.DockerHelper.StartContainersForScenarioRun(scenarioName, services).ConfigureAwait(false);
5255
this.TestingContext.Logger.LogInformation("Containers for Scenario Run Started");
5356
}
5457

58+
59+
5560
[AfterScenario()]
5661
public async Task StopSystem(){
5762
DockerServices sharedDockerServices = DockerServices.SqlServer;

Shared.IntegrationTesting.Tests/Shared.IntegrationTesting.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
</ItemGroup>
2929

3030
<ItemGroup>
31+
<ProjectReference Include="..\ClientProxyBase\ClientProxyBase.csproj" />
3132
<ProjectReference Include="..\Shared.IntegrationTesting\Shared.IntegrationTesting.csproj" />
3233
</ItemGroup>
3334

Shared.IntegrationTesting/BaseDockerHelper.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,12 @@ public abstract class BaseDockerHelper{
106106
protected List<INetworkService> TestNetworks;
107107

108108
protected String TransactionProcessorAclContainerName;
109-
109+
110110
protected Int32 TransactionProcessorAclPort;
111111

112+
protected String KeyCloakContainerName;
113+
protected Int32 KeyCloakPort;
114+
112115
protected String TransactionProcessorContainerName;
113116

114117
protected Int32 TransactionProcessorPort;
@@ -146,6 +149,7 @@ protected BaseDockerHelper(Boolean skipHealthChecks=false) {
146149
this.ImageDetails.Add(ContainerType.TransactionProcessor, ("stuartferguson/transactionprocessorwindows:master", true));
147150
this.ImageDetails.Add(ContainerType.FileProcessor, ("stuartferguson/fileprocessorwindows:master", true));
148151
this.ImageDetails.Add(ContainerType.TransactionProcessorAcl, ("stuartferguson/transactionprocessoraclwindows:master", true));
152+
this.ImageDetails.Add(ContainerType.Keycloak, ("quay.io/keycloak/keycloak:26.4.1", true)); // Note: this may not work...
149153
}
150154
else{
151155
if (FdOs.IsLinux()){
@@ -163,6 +167,7 @@ protected BaseDockerHelper(Boolean skipHealthChecks=false) {
163167
this.ImageDetails.Add(ContainerType.TransactionProcessor, ("stuartferguson/transactionprocessor:master", true));
164168
this.ImageDetails.Add(ContainerType.FileProcessor, ("stuartferguson/fileprocessor:master", true));
165169
this.ImageDetails.Add(ContainerType.TransactionProcessorAcl, ("stuartferguson/transactionprocessoracl:master", true));
170+
this.ImageDetails.Add(ContainerType.Keycloak, ("quay.io/keycloak/keycloak:26.4.1", true));
166171
}
167172

168173
this.HostPorts = new Dictionary<ContainerType, Int32>();
@@ -320,6 +325,7 @@ public virtual void SetupContainerNames(){
320325
this.MessagingServiceContainerName = $"messaging{this.TestId:N}";
321326
this.TransactionProcessorContainerName = $"transaction{this.TestId:N}";
322327
this.TransactionProcessorAclContainerName = $"transactionacl{this.TestId:N}";
328+
this.KeyCloakContainerName= $"keycloak{this.TestId:N}";
323329
}
324330

325331
public virtual ContainerBuilder SetupEventStoreContainer(){
@@ -368,6 +374,22 @@ public virtual ContainerBuilder SetupEventStoreContainer(){
368374
return eventStoreContainerBuilder;
369375
}
370376

377+
public virtual ContainerBuilder SetupKeycloakContainer()
378+
{
379+
this.Trace("About to Start KeyCloak Container");
380+
381+
List<String> environmentVariables = new();
382+
environmentVariables.Add("KC_BOOTSTRAP_ADMIN_USERNAME=admin");
383+
environmentVariables.Add("KC_BOOTSTRAP_ADMIN_PASSWORD=admin");
384+
385+
ContainerBuilder keycloakContainer = new Builder().UseContainer()
386+
.WithName(this.KeyCloakContainerName).WithEnvironment(environmentVariables.ToArray())
387+
.UseImageDetails(this.GetImageDetails(ContainerType.Keycloak).Data).ExposePort(DockerPorts.KeyCloakDockerPort)
388+
.Command("start-dev"); // 👈 equivalent to `docker run ... start-dev`
389+
390+
return keycloakContainer;
391+
}
392+
371393
public virtual ContainerBuilder SetupFileProcessorContainer(){
372394
this.Trace("About to Start File Processor Container");
373395

@@ -934,6 +956,7 @@ protected async Task<IContainerService> StartContainer2(Func<ContainerBuilder> b
934956
DockerServices.TransactionProcessorAcl => ContainerType.TransactionProcessorAcl,
935957
DockerServices.EventStore=> ContainerType.EventStore,
936958
DockerServices.SqlServer => ContainerType.SqlServer,
959+
DockerServices.KeyCloak => ContainerType.Keycloak,
937960
_ => ContainerType.NotSet
938961
};
939962

@@ -1009,6 +1032,9 @@ Int32 GetPort(Int32 dockerPort) =>
10091032
case ContainerType.TransactionProcessorAcl:
10101033
TransactionProcessorAclPort = GetPort(DockerPorts.TransactionProcessorAclDockerPort);
10111034
break;
1035+
case ContainerType.Keycloak:
1036+
this.KeyCloakPort = GetPort(DockerPorts.KeyCloakDockerPort);
1037+
break;
10121038
}
10131039
}
10141040

Shared.IntegrationTesting/ContainerType.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ public enum ContainerType
1111
TransactionProcessor,
1212
FileProcessor,
1313
TransactionProcessorAcl,
14+
Keycloak,
1415
NotSet
1516
}

Shared.IntegrationTesting/DockerHelper.cs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
namespace Shared.IntegrationTesting;
1+
using System.Net.Http;
2+
using System.Text;
3+
using System.Threading;
4+
5+
namespace Shared.IntegrationTesting;
26

3-
using System;
4-
using System.Collections.Generic;
5-
using System.Diagnostics.Metrics;
6-
using System.IO;
7-
using System.Linq;
8-
using System.Runtime.InteropServices;
9-
using System.Threading.Tasks;
107
using Ductus.FluentDocker;
118
using Ductus.FluentDocker.Commands;
129
using Ductus.FluentDocker.Common;
@@ -16,6 +13,14 @@
1613
using Ductus.FluentDocker.Services.Extensions;
1714
using Newtonsoft.Json;
1815
using Shouldly;
16+
using System;
17+
using System.Collections.Generic;
18+
using System.Diagnostics.Metrics;
19+
using System.IO;
20+
using System.Linq;
21+
using System.Runtime.InteropServices;
22+
using System.Text.Json.Serialization;
23+
using System.Threading.Tasks;
1924

2025
[Flags]
2126
public enum DockerServices{
@@ -27,7 +32,9 @@ public enum DockerServices{
2732
TestHost = 32,
2833
TransactionProcessor = 64,
2934
FileProcessor = 128,
30-
TransactionProcessorAcl = 256 }
35+
TransactionProcessorAcl = 256,
36+
KeyCloak = 512
37+
}
3138

3239
public abstract class DockerHelper : BaseDockerHelper
3340
{
@@ -116,7 +123,8 @@ public override async Task StartContainersForScenarioRun(String scenarioName, Do
116123
await StartContainer2(this.SetupTransactionProcessorContainer, networks, DockerServices.TransactionProcessor);
117124
await StartContainer2(this.SetupFileProcessorContainer, networks, DockerServices.FileProcessor);
118125
await StartContainer2(this.SetupTransactionProcessorAclContainer, networks, DockerServices.TransactionProcessorAcl);
119-
126+
await StartContainer2(this.SetupKeycloakContainer, networks, DockerServices.KeyCloak);
127+
120128
await this.LoadEventStoreProjections();
121129

122130
await this.CreateSubscriptions();

Shared.IntegrationTesting/DockerPorts.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ public static class DockerPorts
2121
public static readonly Int32 TransactionProcessorAclDockerPort = 5003;
2222

2323
public static readonly Int32 TransactionProcessorDockerPort = 5002;
24+
25+
public static readonly Int32 KeyCloakDockerPort = 8080;
2426
}

Shared.IntegrationTesting/Shared.IntegrationTesting.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>net9.0</TargetFrameworks>
5-
<DebugType>None</DebugType>
5+
<DebugType>Full</DebugType>
66
</PropertyGroup>
77

88
<ItemGroup>
@@ -19,6 +19,7 @@
1919
</ItemGroup>
2020

2121
<ItemGroup>
22+
<ProjectReference Include="..\ClientProxyBase\ClientProxyBase.csproj" />
2223
<ProjectReference Include="..\Shared\Shared.csproj" />
2324
</ItemGroup>
2425

0 commit comments

Comments
 (0)