diff --git a/.cfignore b/.cfignore
new file mode 100644
index 0000000..a9d96f9
--- /dev/null
+++ b/.cfignore
@@ -0,0 +1,18 @@
+# DotNet
+bin/
+obj/
+
+# user-specific state
+*.user
+
+# VS Code
+.vscode/
+*.code-workspace
+
+# Visual Studio
+.vs/
+
+# Common files that don't need to be pushed
+manifest*.yml
+*.md
+launchSettings.json
diff --git a/.gitignore b/.gitignore
index cd42ee3..547a964 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
bin/
obj/
+.vs/
+*.user
diff --git a/Cook.csproj b/Cook.csproj
index 0a95df4..30c332a 100644
--- a/Cook.csproj
+++ b/Cook.csproj
@@ -5,11 +5,11 @@
cook project
enable
enable
- SA1402;SA1600;SA0001;SA1633
+ SA1101;SA1204;SA1402;SA1600;SA0001;SA1633
- 4.0.*-*
+ 4.0.*
diff --git a/Cook.slnx b/Cook.slnx
index a8b1ea3..d463273 100644
--- a/Cook.slnx
+++ b/Cook.slnx
@@ -1,3 +1,3 @@
-
+
diff --git a/Program.cs b/Program.cs
index 380bf6e..8570a98 100644
--- a/Program.cs
+++ b/Program.cs
@@ -22,16 +22,6 @@
return secretMenu;
});
-app.MapGet("/restaurant/dessert-menu", async (Cook.ResourceService resourceService) =>
-{
- try
- {
- return await resourceService.GetContentAsync("dessert.json");
- }
- catch (Exception ex)
- {
- return $"Error fetching resource: {ex.Message}";
- }
-});
+app.MapGet("/restaurant/dessert-menu", async (Cook.ResourceService resourceService) => await resourceService.GetContentAsync("dessert.json"));
app.Run();
diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json
index 9025d31..cda6b0e 100644
--- a/Properties/launchSettings.json
+++ b/Properties/launchSettings.json
@@ -5,20 +5,20 @@
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
- "launchUrl": "swagger",
+ "launchUrl": "restaurant",
"applicationUrl": "http://localhost:8080",
"environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
+ "ASPNETCORE_ENVIRONMENT": "development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
- "launchUrl": "swagger",
+ "launchUrl": "restaurant",
"applicationUrl": "https://localhost:7053;http://localhost:8080",
"environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
+ "ASPNETCORE_ENVIRONMENT": "development"
}
}
}
diff --git a/ResourceService.cs b/ResourceService.cs
index bb65f8b..d2d0cfb 100644
--- a/ResourceService.cs
+++ b/ResourceService.cs
@@ -3,97 +3,84 @@ namespace Cook;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.Json.Serialization;
+using Microsoft.Extensions.Options;
+using Steeltoe.Common;
+using Steeltoe.Configuration.ConfigServer;
-public class ResourceService
+public class ResourceService(IOptionsSnapshot configServerOptions, HttpClient httpClient)
{
- private readonly IConfiguration configuration;
- private readonly HttpClient httpClient;
private OAuth2TokenResponse? cachedToken;
- public ResourceService(IConfiguration configuration, HttpClient httpClient)
- {
- this.configuration = configuration;
- this.httpClient = httpClient;
- }
-
public async Task GetContentAsync(string name)
{
- try
- {
- var configServerUri = this.configuration["spring:cloud:config:uri"];
+ var configServerUri = configServerOptions.Value.Uri;
+ var appName = configServerOptions.Value.Name;
+ var profile = configServerOptions.Value.Environment;
+ var label = configServerOptions.Value.Label ?? "main";
- var appName = this.configuration["spring:application:name"] ?? "application";
- var profile = this.configuration["spring:cloud:config:env"] ?? "default";
- var label = this.configuration["spring:cloud:config:label"] ?? "main";
+ var request = new HttpRequestMessage(HttpMethod.Get, $"{configServerUri}/{appName}/{profile}/{label}/{name}");
- var accessToken = await this.GetOrRefreshAccessTokenAsync();
-
- var request = new HttpRequestMessage(HttpMethod.Get, $"{configServerUri}/{appName}/{profile}/{label}/{name}");
+ if (Platform.IsCloudFoundry)
+ {
+ var accessToken = await GetOrRefreshAccessTokenAsync();
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
-
- var response = await this.httpClient.SendAsync(request);
- if (response.IsSuccessStatusCode)
- {
- return await response.Content.ReadAsStringAsync();
- }
- else
- {
- throw new HttpRequestException($"Failed to fetch resource: {response.StatusCode} - {response.ReasonPhrase}");
- }
}
- catch (Exception ex)
+
+ var response = await httpClient.SendAsync(request);
+ if (response.IsSuccessStatusCode)
{
- throw new InvalidOperationException($"Error fetching resource: {ex.Message}", ex);
+ return await response.Content.ReadAsStringAsync();
}
+
+ throw new HttpRequestException($"Failed to fetch resource: {response.StatusCode} - {response.ReasonPhrase}");
}
private async Task GetOrRefreshAccessTokenAsync()
{
- if (this.cachedToken != null && DateTime.UtcNow < this.cachedToken.ExpirationTime)
+ if (cachedToken != null && DateTime.UtcNow < cachedToken.ExpirationTime)
{
- return this.cachedToken.AccessToken;
+ return cachedToken.AccessToken;
}
- var clientId = this.configuration["spring:cloud:config:clientId"];
- var clientSecret = this.configuration["spring:cloud:config:clientSecret"];
- var accessTokenUri = this.configuration["spring:cloud:config:accessTokenUri"];
+ var clientId = configServerOptions.Value.ClientId;
+ var clientSecret = configServerOptions.Value.ClientSecret;
+ var accessTokenUri = configServerOptions.Value.AccessTokenUri;
if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret) || string.IsNullOrEmpty(accessTokenUri))
{
throw new InvalidOperationException("OAuth2 credentials not configured");
}
- var tokenRequest = new FormUrlEncodedContent(new[]
- {
+ var tokenRequest = new FormUrlEncodedContent([
new KeyValuePair("grant_type", "client_credentials"),
new KeyValuePair("client_id", clientId),
- new KeyValuePair("client_secret", clientSecret),
- });
+ new KeyValuePair("client_secret", clientSecret)
+ ]);
- var tokenResponse = await this.httpClient.PostAsync(accessTokenUri, tokenRequest);
+ var tokenResponse = await httpClient.PostAsync(accessTokenUri, tokenRequest);
if (!tokenResponse.IsSuccessStatusCode)
{
throw new HttpRequestException($"Failed to get access token: {tokenResponse.StatusCode} - {tokenResponse.ReasonPhrase}");
}
- this.cachedToken = this.ExtractTokenData(await tokenResponse.Content.ReadAsStringAsync());
+ cachedToken = ExtractTokenData(await tokenResponse.Content.ReadAsStringAsync());
- return this.cachedToken.AccessToken;
+ return cachedToken.AccessToken;
}
- private OAuth2TokenResponse ExtractTokenData(string tokenResponse)
+ private static OAuth2TokenResponse ExtractTokenData(string tokenResponse)
{
return JsonSerializer.Deserialize(tokenResponse) ?? new OAuth2TokenResponse();
}
-}
-public class OAuth2TokenResponse
-{
- [JsonPropertyName("access_token")]
- public string AccessToken { get; set; } = string.Empty;
+ private class OAuth2TokenResponse
+ {
+ [JsonPropertyName("access_token")]
+ public string AccessToken { get; init; } = string.Empty;
- [JsonPropertyName("expires_in")]
- public int ExpiresIn { get; set; } = 3600;
+ [JsonPropertyName("expires_in")]
+ public int ExpiresIn { get; init; } = 3600;
- public DateTime ExpirationTime => DateTime.UtcNow.AddSeconds(this.ExpiresIn - 10); // Subtract 10 seconds for safety
+ public DateTime ExpirationTime => DateTime.UtcNow.AddSeconds(ExpiresIn - 10); // Subtract 10 seconds for safety
+ }
}
diff --git a/app.config b/app.config
deleted file mode 100644
index ea5ce6b..0000000
--- a/app.config
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/appsettings.Development.json b/appsettings.Development.json
new file mode 100644
index 0000000..5ed5153
--- /dev/null
+++ b/appsettings.Development.json
@@ -0,0 +1,16 @@
+{
+ "$schema": "https://steeltoe.io/schema/latest/schema.json",
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "Spring": {
+ "Cloud": {
+ "Config": {
+ "Uri": "http://localhost:8888"
+ }
+ }
+ }
+}
diff --git a/appsettings.json b/appsettings.json
index 56a7121..5b4d310 100644
--- a/appsettings.json
+++ b/appsettings.json
@@ -1,20 +1,14 @@
{
+ "$schema": "https://steeltoe.io/schema/latest/schema.json",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
- "spring": {
- "application": {
- "name": "cook"
- },
- "cloud": {
- "config": {
- "uri": "http://localhost:8888",
- "env": "development",
- "label": "main"
- }
+ "Spring": {
+ "Application": {
+ "Name": "cook"
}
}
}
diff --git a/manifest.yml b/manifest.yml
index 9897363..9e35f29 100644
--- a/manifest.yml
+++ b/manifest.yml
@@ -6,4 +6,6 @@ applications:
services:
- cook-config-server
env:
- SPRING__CLOUD__CONFIG__ENV: production
+ ASPNETCORE_ENVIRONMENT: production
+ DOTNET_CLI_TELEMETRY_OPTOUT: "true"
+ DOTNET_NOLOGO: "true"
\ No newline at end of file