-
diff --git a/client/nt.webclient/vue3withtypescript/nt/src/stores/userStore.ts b/client/nt.webclient/vue3withtypescript/nt/src/stores/userStore.ts
index 852eca52..7615ea00 100644
--- a/client/nt.webclient/vue3withtypescript/nt/src/stores/userStore.ts
+++ b/client/nt.webclient/vue3withtypescript/nt/src/stores/userStore.ts
@@ -9,7 +9,8 @@ export const useUserStore = defineStore('UserStore',()=>{
userName : '',
displayName : '',
bio : '',
- token : ''
+ token : '',
+ followers:[]
});
// getters
@@ -17,6 +18,7 @@ export const useUserStore = defineStore('UserStore',()=>{
const DisplayName = computed(() => loggedInUser.value.displayName ? loggedInUser.value.displayName : loggedInUser.value.userName);
const Bio = computed(()=> loggedInUser.value.bio ? loggedInUser.value.bio : '');
const Token = computed(( )=> loggedInUser.value.token)
+ const Followers = computed(()=> loggedInUser.value.followers);
// methods
const SaveUser = (user:LoggedInUser):void=>{
@@ -28,7 +30,8 @@ export const useUserStore = defineStore('UserStore',()=>{
userName : '',
displayName : '',
bio : '',
- token : ''
+ token : '',
+ followers:[]
} as LoggedInUser;
}
@@ -39,6 +42,7 @@ export const useUserStore = defineStore('UserStore',()=>{
DisplayName,
Bio,
Token,
+ Followers,
SaveUser,
Reset
};
diff --git a/client/nt.webclient/vue3withtypescript/nt/src/types/ReviewTypes.ts b/client/nt.webclient/vue3withtypescript/nt/src/types/ReviewTypes.ts
index 5ea8b111..27d96e27 100644
--- a/client/nt.webclient/vue3withtypescript/nt/src/types/ReviewTypes.ts
+++ b/client/nt.webclient/vue3withtypescript/nt/src/types/ReviewTypes.ts
@@ -1,4 +1,10 @@
export interface Review{
title:string,
- description:string
-}
\ No newline at end of file
+ content:string,
+ movieId:string,
+ movieTitle:string,
+ rating:number,
+ userName:string,
+ displayName:string
+}
+
diff --git a/client/nt.webclient/vue3withtypescript/nt/src/types/UserTypes.ts b/client/nt.webclient/vue3withtypescript/nt/src/types/UserTypes.ts
index 359e2ab0..2e77308a 100644
--- a/client/nt.webclient/vue3withtypescript/nt/src/types/UserTypes.ts
+++ b/client/nt.webclient/vue3withtypescript/nt/src/types/UserTypes.ts
@@ -9,4 +9,5 @@ export interface User {
reviews?: Review;
Uprated?: 0;
Downrated?: 0;
+ followers:string[];
}
diff --git a/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/Response.ts b/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/Response.ts
index 9c079fd6..517e1818 100644
--- a/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/Response.ts
+++ b/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/Response.ts
@@ -4,6 +4,4 @@ export interface IResponseBase {
errors?: Array
;
}
-export interface IGraphQlResponseBase{
-
-}
+export interface IGraphQlResponseBase {}
diff --git a/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/Review.ts b/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/Review.ts
new file mode 100644
index 00000000..cb0abde2
--- /dev/null
+++ b/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/Review.ts
@@ -0,0 +1,18 @@
+import { IResponseBase } from './Response';
+
+export interface IRecentReviewForUsersRequest {
+ userIds: string[];
+ count: number;
+}
+
+export interface IRecentReviewsForUsersResponse extends IResponseBase {
+ reviews: IRecentReviewsForUsersResponseItem[];
+}
+
+export interface IRecentReviewsForUsersResponseItem {
+ reviewId: string;
+ movieId: string;
+ content: string;
+ rating: number;
+ author: string;
+}
diff --git a/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/User.ts b/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/User.ts
index 2f3cc71c..8bb1523c 100644
--- a/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/User.ts
+++ b/client/nt.webclient/vue3withtypescript/nt/src/types/apirequestresponsetypes/User.ts
@@ -36,6 +36,7 @@ export interface IValidateUserResponse extends IResponseBase {
userName: string;
displayName?: string;
bio?: string;
+ followers:string[];
};
}
diff --git a/server/Configuration/mockoon-env.json b/server/Configuration/mockoon-env.json
new file mode 100644
index 00000000..7af25717
--- /dev/null
+++ b/server/Configuration/mockoon-env.json
@@ -0,0 +1,148 @@
+{
+ "uuid": "909f1d54-2f9c-47f4-b4bc-bb703cf38706",
+ "lastMigration": 33,
+ "name": "Mockoon env",
+ "endpointPrefix": "",
+ "latency": 0,
+ "port": 3001,
+ "hostname": "",
+ "folders": [],
+ "routes": [
+ {
+ "uuid": "2bf1a054-0c56-4a9b-ba5b-bcead1c8df2b",
+ "type": "http",
+ "documentation": "",
+ "method": "post",
+ "endpoint": "api/User/ValidateUser",
+ "responses": [
+ {
+ "uuid": "f14297ec-c1a0-4de1-ade4-53fe38a3f3d1",
+ "body": "{\n \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImppYS5hbnUiLCJhdWQiOlsibnQudXNlcnNlcnZpY2UuY29tIiwibnQuZ2F0ZXdheS5jb20iLCJudC5hdXRoc2VydmljZXMuY29tIl0sImV4cCI6MTc1MzU4ODE1OCwiaXNzIjoibnQuYXV0aHNlcnZpY2VzLmNvbSJ9.tSVidi03-msD_kQWBhoSoInIJiys_VZJsKoNravLWz8\",\n \"isAuthenticated\": true,\n \"loginTime\": \"0001-01-01T00:00:00\",\n \"userName\": \"jia.anu\",\n \"displayName\": \"Jia Anu\",\n \"bio\": \"I am jia anu\"\n}",
+ "latency": 0,
+ "statusCode": 200,
+ "label": "",
+ "headers": [],
+ "bodyType": "INLINE",
+ "filePath": "",
+ "databucketID": "",
+ "sendFileAsBody": false,
+ "rules": [],
+ "rulesOperator": "OR",
+ "disableTemplating": false,
+ "fallbackTo404": false,
+ "default": true,
+ "crudKey": "id",
+ "callbacks": []
+ }
+ ],
+ "responseMode": null,
+ "streamingMode": null,
+ "streamingInterval": 0
+ },
+ {
+ "uuid": "6c9d107c-3a8f-4e12-8506-e06fb5731ebc",
+ "type": "http",
+ "documentation": "",
+ "method": "post",
+ "endpoint": "movies",
+ "responses": [
+ {
+ "uuid": "910bf483-f271-4caa-bc04-29e4df48f9fe",
+ "body": "{\n \"data\": {\n \"recentMovies\": [\n {\n \"title\": \"Ennu Ninte Moideen\",\n \"movieLanguage\": \"Malayalam\",\n \"releaseDate\": \"2023-08-07T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Prithviraj\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Parvathy\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Saikumar\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n },\n {\n \"title\": \"Argo\",\n \"movieLanguage\": \"English\",\n \"releaseDate\": \"2023-08-06T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Ben Affleck\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Bryan Cranston\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Alan Arkin\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n },\n {\n \"title\": \"The Great Indian Kitchen\",\n \"movieLanguage\": \"Malayalam\",\n \"releaseDate\": \"2023-02-15T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Nimisha Sajayan\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Suraj Venjaramoodu\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Ajitha\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n },\n {\n \"title\": \"Cast Away\",\n \"movieLanguage\": \"English\",\n \"releaseDate\": \"2023-01-08T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Tom Hanks\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Helen Hunt\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Nick Searcy\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n },\n {\n \"title\": \"Premam\",\n \"movieLanguage\": \"Malayalam\",\n \"releaseDate\": \"2022-03-14T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Nivin Pauly\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Sai Pallavi\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Madonna Sebastian\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n },\n {\n \"title\": \"Bangalore Days\",\n \"movieLanguage\": \"Malayalam\",\n \"releaseDate\": \"2022-03-05T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Dulquer Salmaan\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Nivin Pauly\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Nazriya Nazim\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n },\n {\n \"title\": \"Forensic\",\n \"movieLanguage\": \"Malayalam\",\n \"releaseDate\": \"2022-03-03T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Tovino Thomas\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Mamta Mohandas\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Reba Monica John\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n },\n {\n \"title\": \"Arrival\",\n \"movieLanguage\": \"English\",\n \"releaseDate\": \"2022-01-08T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Amy Adams\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Jeremy Renner\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Forest Whitaker\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n },\n {\n \"title\": \"Puzhu\",\n \"movieLanguage\": \"Malayalam\",\n \"releaseDate\": \"2021-12-14T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Mammootty\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Parvathy\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Appunni Sasi\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n },\n {\n \"title\": \"Lincoln\",\n \"movieLanguage\": \"English\",\n \"releaseDate\": \"2021-08-17T18:30:00.000Z\",\n \"cast\": [\n {\n \"name\": \"Daniel Day-Lewis\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Sally Field\",\n \"__typename\": \"PersonType\"\n },\n {\n \"name\": \"Tommy Lee Jones\",\n \"__typename\": \"PersonType\"\n }\n ],\n \"__typename\": \"MovieType\"\n }\n ]\n }\n}",
+ "latency": 0,
+ "statusCode": 200,
+ "label": "",
+ "headers": [],
+ "bodyType": "INLINE",
+ "filePath": "",
+ "databucketID": "",
+ "sendFileAsBody": false,
+ "rules": [],
+ "rulesOperator": "OR",
+ "disableTemplating": false,
+ "fallbackTo404": false,
+ "default": true,
+ "crudKey": "id",
+ "callbacks": []
+ }
+ ],
+ "responseMode": null,
+ "streamingMode": null,
+ "streamingInterval": 0
+ }
+ ],
+ "rootChildren": [
+ {
+ "type": "route",
+ "uuid": "2bf1a054-0c56-4a9b-ba5b-bcead1c8df2b"
+ },
+ {
+ "type": "route",
+ "uuid": "6c9d107c-3a8f-4e12-8506-e06fb5731ebc"
+ }
+ ],
+ "proxyMode": false,
+ "proxyHost": "",
+ "proxyRemovePrefix": false,
+ "tlsOptions": {
+ "enabled": false,
+ "type": "CERT",
+ "pfxPath": "",
+ "certPath": "",
+ "keyPath": "",
+ "caPath": "",
+ "passphrase": ""
+ },
+ "cors": true,
+ "headers": [
+ {
+ "key": "Content-Type",
+ "value": "application/json"
+ },
+ {
+ "key": "Access-Control-Allow-Origin",
+ "value": "*"
+ },
+ {
+ "key": "Access-Control-Allow-Methods",
+ "value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS"
+ },
+ {
+ "key": "Access-Control-Allow-Headers",
+ "value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With, access-control-allow-methods"
+ },
+ {
+ "key": "Access-Control-Allow-Credentials",
+ "value": "true"
+ }
+ ],
+ "proxyReqHeaders": [
+ {
+ "key": "",
+ "value": ""
+ }
+ ],
+ "proxyResHeaders": [
+ {
+ "key": "",
+ "value": ""
+ }
+ ],
+ "data": [
+ {
+ "uuid": "5d8372b2-c418-4fa0-be4d-6091fb918fc4",
+ "id": "yesl",
+ "name": "New data",
+ "documentation": "",
+ "value": "[\n {\n userName:\"jia.anu\",\n password: \"mypass\"\n},\n]"
+ },
+ {
+ "uuid": "ce6f449d-b1a4-4826-b448-61a58e8c4aa5",
+ "id": "59rh",
+ "name": "New data",
+ "documentation": "",
+ "value": "[\n {\"operationName\":\"recentMovieQuery\",\"variables\":{\"count\":10},\"query\":\"query recentMovieQuery($count: Int) {\\n recentMovies(count: $count) {\\n title\\n movieLanguage\\n releaseDate\\n cast {\\n name\\n __typename\\n }\\n __typename\\n }\\n}\"}\n]"
+ }
+ ],
+ "callbacks": []
+}
\ No newline at end of file
diff --git a/server/nt.microservice/infrastructure/nt.gateway/ocelot.json b/server/nt.microservice/infrastructure/nt.gateway/ocelot.json
index a7258985..e7643aec 100644
--- a/server/nt.microservice/infrastructure/nt.gateway/ocelot.json
+++ b/server/nt.microservice/infrastructure/nt.gateway/ocelot.json
@@ -167,6 +167,20 @@
},
+ {
+ "DownstreamPathTemplate": "/api/UserReviews/GetRecentReviewsForUsers",
+ "DownstreamScheme": "http",
+ "RouteIsCaseSensitive": false,
+ "UseServiceDiscovry": true,
+ "ServiceName": "nt.reviewservice.service",
+ "UpstreamPathTemplate": "/reviews/GetRecentReviewsForUsers",
+ "UpstreamHttpMethod": [ "POST" ],
+ "QoSOptions": {
+ "ExceptionsAllowedBeforeBreaking": 10,
+ "DurationOfBreak": 10000,
+ "TimeoutValue": 10000
+ }
+ },
{
"DownstreamPathTemplate": "/{everything}",
diff --git a/server/nt.microservice/infrastructure/nt.helper/Constants.cs b/server/nt.microservice/infrastructure/nt.helper/Constants.cs
index 6d2c350c..51e08aea 100644
--- a/server/nt.microservice/infrastructure/nt.helper/Constants.cs
+++ b/server/nt.microservice/infrastructure/nt.helper/Constants.cs
@@ -30,7 +30,7 @@ public static class Consul
public const string ServiceName = "nt-common-servicediscovery";
public const string ContainerName = "nt.common.servicediscovery";
- public static class Environement
+ public static class Environment
{
public const string Key = "ServiceRegistrationConfig";
public const string ServiceName = $"{Key}__serviceName";
@@ -129,6 +129,15 @@ public static class Database
public static class EnvironmentVariable
{
+ public const string Key = Constants.Infrastructure.Consul.Environment.Key;
+ public const string ServiceName = Constants.Infrastructure.Consul.Environment.ServiceName;
+ public const string ServiceId = Constants.Infrastructure.Consul.Environment.ServiceId;
+ public const string ServiceHost = Constants.Infrastructure.Consul.Environment.ServiceHost;
+ public const string ServicePort = Constants.Infrastructure.Consul.Environment.ServicePort;
+ public const string ServiceHealthCheckUrl = Constants.Infrastructure.Consul.Environment.ServiceHealthCheckUrl;
+ public const string RegistryUri = Constants.Infrastructure.Consul.Environment.RegistryUri;
+ public const string DeregisterAfter = Constants.Infrastructure.Consul.Environment.DeregisterAfter;
+
public const string DbUserNameKey = "MONGO_INITDB_ROOT_USERNAME";
public const string DbPasswordKey = "MONGO_INITDB_ROOT_PASSWORD";
public const string DbName = "MovieDatabase__DatabaseName";
@@ -139,7 +148,7 @@ public static class EnvironmentVariable
public static class ReviewService
{
public const string ServiceName = "nt-reviewservice-service";
-
+ public const string ProfileName = Global.Common.LaunchProfile;
public static class Cache
{
@@ -159,6 +168,15 @@ public static class Database
public static class EnvironmentVariable
{
+ public const string Key = Constants.Infrastructure.Consul.Environment.Key;
+ public const string ServiceName = Constants.Infrastructure.Consul.Environment.ServiceName;
+ public const string ServiceId = Constants.Infrastructure.Consul.Environment.ServiceId;
+ public const string ServiceHost = Constants.Infrastructure.Consul.Environment.ServiceHost;
+ public const string ServicePort = Constants.Infrastructure.Consul.Environment.ServicePort;
+ public const string ServiceHealthCheckUrl = Constants.Infrastructure.Consul.Environment.ServiceHealthCheckUrl;
+ public const string RegistryUri = Constants.Infrastructure.Consul.Environment.RegistryUri;
+ public const string DeregisterAfter = Constants.Infrastructure.Consul.Environment.DeregisterAfter;
+
public const string DbUserNameKey = "MONGO_INITDB_ROOT_USERNAME";
public const string DbPasswordKey = "MONGO_INITDB_ROOT_PASSWORD";
public const string DbName = "ReviewDatabase__DatabaseName";
diff --git a/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/Program.cs b/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/Program.cs
index 82692a89..d2a7f710 100644
--- a/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/Program.cs
+++ b/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/Program.cs
@@ -1,4 +1,3 @@
-using Aspire.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using nt.orchestrator.AppHost.Settings;
@@ -109,13 +108,13 @@
.WaitForAll(authServiceInstances);
var authServiceSideCar = builder.AddProject(Constants.AuthService.Sidecar.InstanceName)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceName, serviceSettings.AuthService.ServiceRegistrationConfig.ServiceName)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceId, serviceSettings.AuthService.ServiceRegistrationConfig.ServiceId)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceHost, serviceSettings.AuthService.ServiceRegistrationConfig.ServiceHost)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServicePort, serviceSettings.AuthService.ServiceRegistrationConfig.ServicePort.ToString())
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceHealthCheckUrl, serviceSettings.AuthService.ServiceRegistrationConfig.HealthCheckUrl)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.RegistryUri, consulServiceDiscovery.GetEndpoint("http"))
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.DeregisterAfter, serviceSettings.AuthService.ServiceRegistrationConfig.DeregisterAfterMinutes.ToString())
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceName, serviceSettings.AuthService.ServiceRegistrationConfig.ServiceName)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceId, serviceSettings.AuthService.ServiceRegistrationConfig.ServiceId)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceHost, serviceSettings.AuthService.ServiceRegistrationConfig.ServiceHost)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServicePort, serviceSettings.AuthService.ServiceRegistrationConfig.ServicePort.ToString())
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceHealthCheckUrl, serviceSettings.AuthService.ServiceRegistrationConfig.HealthCheckUrl)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.RegistryUri, consulServiceDiscovery.GetEndpoint("http"))
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.DeregisterAfter, serviceSettings.AuthService.ServiceRegistrationConfig.DeregisterAfterMinutes.ToString())
.WaitFor(consulServiceDiscovery)
.WaitFor(rabbitmq)
.WaitFor(authServiceLoadBalancer);
@@ -126,11 +125,11 @@
.WithEnvironment(Constants.UserService.Environment.RabbitMqHost, infrastructureSettings.RabbitMq.Host)
.WithEnvironment(Constants.UserService.Environment.RabbitMqUserName, infrastructureSettings.RabbitMq.UserName)
.WithEnvironment(Constants.UserService.Environment.RabbitMqPassword, infrastructureSettings.RabbitMq.Password)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceName, serviceSettings.UserService.ServiceRegistrationConfig.ServiceName)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceId, serviceSettings.UserService.ServiceRegistrationConfig.ServiceId)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceHost, serviceSettings.UserService.ServiceRegistrationConfig.ServiceHost)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.RegistryUri, consulServiceDiscovery.GetEndpoint("http"))
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.DeregisterAfter, serviceSettings.UserService.ServiceRegistrationConfig.DeregisterAfterMinutes.ToString())
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceName, serviceSettings.UserService.ServiceRegistrationConfig.ServiceName)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceId, serviceSettings.UserService.ServiceRegistrationConfig.ServiceId)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceHost, serviceSettings.UserService.ServiceRegistrationConfig.ServiceHost)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.RegistryUri, consulServiceDiscovery.GetEndpoint("http"))
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.DeregisterAfter, serviceSettings.UserService.ServiceRegistrationConfig.DeregisterAfterMinutes.ToString())
.WithEnvironment("BlobConfig__ConnectionString", infrastructureSettings.BlobStorage.blobConfig.ConnectionString)
.WithHttpEndpoint(name:"http")
.WaitFor(blobStorage)
@@ -140,8 +139,8 @@
.WithUrls(c => c.Urls.ForEach(u => u.DisplayText = $"Open API ({u.Endpoint?.Port})"));
-userService.WithEnvironment(Constants.Infrastructure.Consul.Environement.ServicePort, ()=>userService.GetEndpoint("http").Port.ToString())
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceHealthCheckUrl,
+userService.WithEnvironment(Constants.Infrastructure.Consul.Environment.ServicePort, ()=>userService.GetEndpoint("http").Port.ToString())
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceHealthCheckUrl,
()=> $"http://host.docker.internal:{userService.GetEndpoint("http").Port}{serviceSettings.UserService.ServiceRegistrationConfig.HealthCheckUrl}");
var aggregatorService = builder.AddProject(Constants.AggregatorUserIdentityService.ServiceName)
@@ -151,11 +150,11 @@
.WithEnvironment(Constants.AggregatorUserIdentityService.ServiceMappingUserServiceName, serviceSettings.AggregateAuthUserService.ServiceMappingConfig.Services.Single(x => x.Key == "UserService").Name)
.WithEnvironment(Constants.AggregatorUserIdentityService.ServiceMappingAuthServiceKey, serviceSettings.AggregateAuthUserService.ServiceMappingConfig.Services.Single(x => x.Key == "AuthService").Key)
.WithEnvironment(Constants.AggregatorUserIdentityService.ServiceMappingAuthServiceName, serviceSettings.AggregateAuthUserService.ServiceMappingConfig.Services.Single(x => x.Key == "AuthService").Name)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceName, serviceSettings.AggregateAuthUserService.ServiceRegistrationConfig.ServiceName)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceId, serviceSettings.AggregateAuthUserService.ServiceRegistrationConfig.ServiceId)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceHost, serviceSettings.AggregateAuthUserService.ServiceRegistrationConfig.ServiceHost)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.RegistryUri, consulServiceDiscovery.GetEndpoint("http"))
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.DeregisterAfter, serviceSettings.AggregateAuthUserService.ServiceRegistrationConfig.DeregisterAfterMinutes.ToString())
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceName, serviceSettings.AggregateAuthUserService.ServiceRegistrationConfig.ServiceName)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceId, serviceSettings.AggregateAuthUserService.ServiceRegistrationConfig.ServiceId)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceHost, serviceSettings.AggregateAuthUserService.ServiceRegistrationConfig.ServiceHost)
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.RegistryUri, consulServiceDiscovery.GetEndpoint("http"))
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.DeregisterAfter, serviceSettings.AggregateAuthUserService.ServiceRegistrationConfig.DeregisterAfterMinutes.ToString())
//.WithHttpEndpoint(name: "http")
.WaitFor(consulServiceDiscovery)
.WaitFor(authServiceLoadBalancer)
@@ -163,36 +162,47 @@
.WaitFor(userService)
.WithUrls(c => c.Urls.ForEach(u => u.DisplayText = $"Open API ({u.Endpoint?.Port})")); ;
-aggregatorService.WithEnvironment(Constants.Infrastructure.Consul.Environement.ServicePort, () => aggregatorService.GetEndpoint("http").Port.ToString())
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceHealthCheckUrl,
+aggregatorService.WithEnvironment(Constants.Infrastructure.Consul.Environment.ServicePort, () => aggregatorService.GetEndpoint("http").Port.ToString())
+ .WithEnvironment(Constants.Infrastructure.Consul.Environment.ServiceHealthCheckUrl,
() => $"http://host.docker.internal:{aggregatorService.GetEndpoint("http").Port}{serviceSettings.AggregateAuthUserService.ServiceRegistrationConfig.HealthCheckUrl}");
var movieService = builder.AddProject(Constants.MovieService.ServiceName)
.WithEnvironment(Constants.Global.EnvironmentVariables.RunningWithVariable, Constants.Global.EnvironmentVariables.RunningWithValue)
.WithEnvironment(Constants.MovieService.EnvironmentVariable.DbName, serviceSettings.MovieService.DbName)
.WithEnvironment(Constants.MovieService.EnvironmentVariable.DbCollection, serviceSettings.MovieService.MovieCollectionName)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceName, serviceSettings.MovieService.ServiceRegistrationConfig.ServiceName)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceId, serviceSettings.MovieService.ServiceRegistrationConfig.ServiceId)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceHost, serviceSettings.MovieService.ServiceRegistrationConfig.ServiceHost)
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.RegistryUri, consulServiceDiscovery.GetEndpoint("http"))
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.DeregisterAfter, serviceSettings.MovieService.ServiceRegistrationConfig.DeregisterAfterMinutes.ToString())
+ .WithEnvironment(Constants.MovieService.EnvironmentVariable.ServiceName, serviceSettings.MovieService.ServiceRegistrationConfig.ServiceName)
+ .WithEnvironment(Constants.MovieService.EnvironmentVariable.ServiceId, serviceSettings.MovieService.ServiceRegistrationConfig.ServiceId)
+ .WithEnvironment(Constants.MovieService.EnvironmentVariable.ServiceHost, serviceSettings.MovieService.ServiceRegistrationConfig.ServiceHost)
+ .WithEnvironment(Constants.MovieService.EnvironmentVariable.RegistryUri, consulServiceDiscovery.GetEndpoint("http"))
+ .WithEnvironment(Constants.MovieService.EnvironmentVariable.DeregisterAfter, serviceSettings.MovieService.ServiceRegistrationConfig.DeregisterAfterMinutes.ToString())
.WithReference(mongoDbMovie)
.WaitFor(mongoDbMovie)
.WaitFor(consulServiceDiscovery)
.WithUrls(c => c.Urls.ForEach(u => u.DisplayText = $"Open API ({u.Endpoint?.Port})")); ;
-movieService.WithEnvironment(Constants.Infrastructure.Consul.Environement.ServicePort, () => movieService.GetEndpoint("http").Port.ToString())
- .WithEnvironment(Constants.Infrastructure.Consul.Environement.ServiceHealthCheckUrl,
+movieService.WithEnvironment(Constants.MovieService.EnvironmentVariable.ServicePort, () => movieService.GetEndpoint("http").Port.ToString())
+ .WithEnvironment(Constants.MovieService.EnvironmentVariable.ServiceHealthCheckUrl,
() => $"http://host.docker.internal:{movieService.GetEndpoint("http").Port}{serviceSettings.MovieService.ServiceRegistrationConfig.HealthCheckUrl}");
-var reviewService = builder.AddProject("nt-reviewservice-service")
+var reviewService = builder.AddProject(Constants.ReviewService.ServiceName)
.WithEnvironment(Constants.Global.EnvironmentVariables.RunningWithVariable, Constants.Global.EnvironmentVariables.RunningWithValue)
- .WithUrls(c => c.Urls.ForEach(u => u.DisplayText = $"Open API ({u.Endpoint?.EndpointName})"))
+ .WithEnvironment(Constants.ReviewService.EnvironmentVariable.DbName, serviceSettings.ReviewService.DbName)
+ .WithEnvironment(Constants.ReviewService.EnvironmentVariable.DbCollection, serviceSettings.ReviewService.ReviewCollectionName)
+ .WithEnvironment(Constants.ReviewService.EnvironmentVariable.ServiceName, serviceSettings.ReviewService.ServiceRegistrationConfig.ServiceName)
+ .WithEnvironment(Constants.ReviewService.EnvironmentVariable.ServiceId, serviceSettings.ReviewService.ServiceRegistrationConfig.ServiceId)
+ .WithEnvironment(Constants.ReviewService.EnvironmentVariable.ServiceHost, serviceSettings.ReviewService.ServiceRegistrationConfig.ServiceHost)
+ .WithEnvironment(Constants.ReviewService.EnvironmentVariable.RegistryUri, consulServiceDiscovery.GetEndpoint("http"))
+ .WithEnvironment(Constants.ReviewService.EnvironmentVariable.DeregisterAfter, serviceSettings.MovieService.ServiceRegistrationConfig.DeregisterAfterMinutes.ToString())
.WithReference(mongoDbReview)
.WaitFor(mongoDbReview)
.WaitFor(redisReview)
- .WithReference(redisReview);
+ .WaitFor(consulServiceDiscovery)
+ .WithReference(redisReview)
+ .WithUrls(c => c.Urls.ForEach(u => u.DisplayText = $"Open API ({u.Endpoint?.EndpointName})"));
+reviewService.WithEnvironment(Constants.ReviewService.EnvironmentVariable.ServicePort, () => reviewService.GetEndpoint("http").Port.ToString())
+ .WithEnvironment(Constants.ReviewService.EnvironmentVariable.ServiceHealthCheckUrl,
+ () => $"http://host.docker.internal:{reviewService.GetEndpoint("http").Port}{serviceSettings.ReviewService.ServiceRegistrationConfig.HealthCheckUrl}");
var gateway = builder.AddProject(Constants.Gateway.ServiceName, launchProfileName: Constants.Gateway.LaunchProfile)
.WithEnvironment(Constants.Global.EnvironmentVariables.RunningWithVariable, Constants.Global.EnvironmentVariables.RunningWithValue)
diff --git a/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/Settings/InfrastructureSettings.cs b/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/Settings/InfrastructureSettings.cs
index e367ac7e..d427d109 100644
--- a/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/Settings/InfrastructureSettings.cs
+++ b/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/Settings/InfrastructureSettings.cs
@@ -33,6 +33,8 @@ public record ServicesSettings
public UserService UserService { get; set; } = null!;
public MovieService MovieService { get; set; } = null!;
+
+ public ReviewService ReviewService { get; set; } = null!;
}
public record Gateway(string Host);
@@ -80,6 +82,11 @@ public record MovieService(string DbName,string MovieCollectionName)
}
+public record ReviewService(string DbName, string ReviewCollectionName,string ConnectionString)
+{
+ public ServiceRegistrationConfig ServiceRegistrationConfig { get; set; } = null!;
+}
+
public record ServiceRegistrationConfig
{
public string ServiceName { get; set; } = null!;
diff --git a/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/appsettings.json b/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/appsettings.json
index f8900d4c..b69a030f 100644
--- a/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/appsettings.json
+++ b/server/nt.microservice/infrastructure/nt.orchestrator.AppHost/appsettings.json
@@ -109,6 +109,19 @@
"HealthCheckUrl": "/api/healthcheck/health",
"DeregisterAfterMinutes": 5
}
+ },
+ "ReviewService": {
+ "DbName": "ntreviewstore",
+ "ReviewCollectionName": "reviews",
+ "ConnectionString": "mongodb://root:mypass@nt.reviewservice.db:27018/?authSource=admin",
+ "ServiceRegistrationConfig": {
+ "ServiceName": "nt.reviewservice.service",
+ "ServiceId": "reviewservice-1",
+ "ServiceHost": "localhost",
+ "ServiceAddress": "localhost",
+ "HealthCheckUrl": "/api/healthcheck/health",
+ "DeregisterAfterMinutes": 5
+ }
}
}
}
diff --git a/server/nt.microservice/services/MovieService/MovieService.Api/Controllers/BaseController.cs b/server/nt.microservice/services/MovieService/MovieService.Api/Controllers/BaseController.cs
index 37724cdb..b32ca055 100644
--- a/server/nt.microservice/services/MovieService/MovieService.Api/Controllers/BaseController.cs
+++ b/server/nt.microservice/services/MovieService/MovieService.Api/Controllers/BaseController.cs
@@ -3,7 +3,7 @@
namespace MovieService.Api.Controllers
{
- public abstract class BaseController : Controller
+ public abstract class BaseController : ControllerBase
{
public BaseController(ILogger logger)
diff --git a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/BackgroundServices/ConsulServiceRegistrationService.cs b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/BackgroundServices/ConsulServiceRegistrationService.cs
new file mode 100644
index 00000000..92737327
--- /dev/null
+++ b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/BackgroundServices/ConsulServiceRegistrationService.cs
@@ -0,0 +1,52 @@
+using Consul;
+using Microsoft.Extensions.Options;
+using nt.shared.dto.Configurations;
+
+namespace ReviewService.Presenation.Api.BackgroundServices;
+
+public class ConsulServiceRegistrationService : BackgroundService
+{
+ private readonly IConsulClient _consulClient;
+ private readonly ServiceRegistrationConfig _serviceDiscoveryConfiguration;
+ private readonly ILogger _logger;
+ private readonly IHostApplicationLifetime _lifetime;
+ public ConsulServiceRegistrationService(IConsulClient consultClient,
+ IOptions serviceDiscoveryConfigurations,
+ ILogger logger,
+ IHostApplicationLifetime lifetime)
+ {
+ _consulClient = consultClient ?? throw new ArgumentNullException(nameof(consultClient));
+ _serviceDiscoveryConfiguration = serviceDiscoveryConfigurations?.Value ?? throw new ArgumentNullException(nameof(serviceDiscoveryConfigurations));
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ _lifetime = lifetime ?? throw new ArgumentNullException(nameof(lifetime));
+ }
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ var registration = new AgentServiceRegistration
+ {
+ ID = _serviceDiscoveryConfiguration.ServiceId,
+ Name = _serviceDiscoveryConfiguration.ServiceName,
+ Address = _serviceDiscoveryConfiguration.ServiceHost,
+ Port = _serviceDiscoveryConfiguration.ServicePort,
+ Check = new AgentServiceCheck
+ {
+ HTTP = _serviceDiscoveryConfiguration.HealthCheckUrl,
+ Interval = TimeSpan.FromSeconds(10),
+ Timeout = TimeSpan.FromSeconds(5),
+ DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(5)
+ }
+ };
+
+ // Register service with Consul
+ await _consulClient.Agent.ServiceRegister(registration).ConfigureAwait(false);
+ _logger.LogInformation($"User Service registered with Consul successfully with health check url {registration.Check.HTTP}");
+
+
+ _lifetime.ApplicationStopping.Register(async () =>
+ {
+ _logger.LogInformation("Deregistering service from Consul");
+ await _consulClient.Agent.ServiceDeregister(_serviceDiscoveryConfiguration.ServiceId);
+ });
+ }
+}
+
diff --git a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Controllers/HealthCheckController.cs b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Controllers/HealthCheckController.cs
new file mode 100644
index 00000000..323baaaf
--- /dev/null
+++ b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Controllers/HealthCheckController.cs
@@ -0,0 +1,21 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace ReviewService.Presenation.Api.Controllers;
+
+[ApiController]
+[Route("api/healthcheck")]
+public class HealthController : ControllerBase
+{
+ public HealthController(ILogger logger)
+ {
+ }
+
+ [HttpGet]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [Route("health")]
+ public ActionResult Health()
+ {
+ return Ok();
+ }
+}
diff --git a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Controllers/UserReviewsController.cs b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Controllers/UserReviewsController.cs
index 8e332f95..6ba65547 100644
--- a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Controllers/UserReviewsController.cs
+++ b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Controllers/UserReviewsController.cs
@@ -8,7 +8,7 @@
namespace ReviewService.Api.Controllers;
[ApiController]
-[Route("[controller]")]
+[Route("api/[controller]")]
public class UserReviewsController : ControllerBase
{
private readonly ILogger _logger;
diff --git a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Program.cs b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Program.cs
index 12f79df4..029af7c0 100644
--- a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Program.cs
+++ b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Program.cs
@@ -1,9 +1,10 @@
+using Consul;
using Microsoft.Extensions.Options;
-using MongoDB.Driver;
+using nt.shared.dto.Configurations;
using ReviewService.Presenation.Api;
+using ReviewService.Presenation.Api.BackgroundServices;
using ReviewService.Presenation.Api.Helpers;
using ReviewService.Presenation.Api.Options;
-using StackExchange.Redis;
namespace ReviewService.Api;
@@ -13,9 +14,23 @@ public static async Task Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults();
+
+ var corsPolicy = "_ntClientAppsOrigins";
+ builder.Services.AddCors(option => {
+ option.AddPolicy(name: corsPolicy,
+ builder =>
+ {
+ builder.AllowAnyOrigin();
+ builder.AllowAnyMethod();
+ builder.AllowAnyHeader();
+ });
+ });
+
+
builder.Services.Configure(builder.Configuration.GetSection(nameof(DatabaseOptions)));
builder.Services.Configure(builder.Configuration.GetSection(nameof(CacheOptions)));
-
+ builder.Services.Configure(builder.Configuration.GetSection(nameof(ServiceRegistrationConfig)));
+
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
@@ -23,6 +38,19 @@ public static async Task Main(string[] args)
builder.Services.RegisterServices();
builder.Services.AddEndpointsApiExplorer(); // for minimal APIs
builder.Services.AddSwaggerGen(); // generates the Swagger JSON
+
+ builder.Services.AddSingleton(sp =>
+ {
+ var config = sp.GetRequiredService>().Value;
+ var consulConfig = new ConsulClientConfiguration
+ {
+ Address = new Uri(config.RegistryUri)
+ };
+ return new ConsulClient(consulConfig);
+ });
+
+ builder.Services.AddHostedService();
+
var app = builder.Build();
app.MapDefaultEndpoints();
@@ -44,7 +72,8 @@ public static async Task Main(string[] args)
app.UseSwaggerUI(); // serves /swagger
}
- app.UseHttpsRedirection();
+ // app.UseHttpsRedirection();
+ app.UseCors(corsPolicy);
app.UseAuthorization();
app.MapControllers();
diff --git a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Properties/launchSettings.json b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Properties/launchSettings.json
index de516a80..e53f682c 100644
--- a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Properties/launchSettings.json
+++ b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/Properties/launchSettings.json
@@ -6,7 +6,8 @@
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
- "applicationUrl": "http://localhost:5081"
+ "applicationUrl": "http://localhost:5081",
+ "launchUrl": "swagger"
},
"https": {
"commandName": "Project",
@@ -14,7 +15,8 @@
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
- "applicationUrl": "https://localhost:7204;http://localhost:5081"
+ "applicationUrl": "https://localhost:7204;http://localhost:5081",
+ "launchUrl": "swagger"
},
"Container (Dockerfile)": {
"commandName": "Docker",
@@ -26,6 +28,7 @@
"publishAllPorts": true,
"useSSL": true
}
+
},
"$schema": "https://json.schemastore.org/launchsettings.json"
}
\ No newline at end of file
diff --git a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/ReviewService.Presenation.Api.csproj b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/ReviewService.Presenation.Api.csproj
index b7af8bd9..75345000 100644
--- a/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/ReviewService.Presenation.Api.csproj
+++ b/server/nt.microservice/services/ReviewService/ReviewService.Presentation.Api/ReviewService.Presenation.Api.csproj
@@ -13,6 +13,7 @@
+
@@ -23,6 +24,7 @@
+