From 09fa922dd7688ad6359ee2b9411b6e16c8f0490e Mon Sep 17 00:00:00 2001 From: meof-coding Date: Sun, 26 Nov 2023 17:29:18 +0700 Subject: [PATCH 1/9] init project --- SimpleServer/SimpleServer.sln | 7 ++++ .../Movie.API/Properties/launchSettings.json | 4 +- .../Controllers/WeatherForecastController.cs | 33 +++++++++++++++ .../Watchlist.API/Entity/UserWatchList.cs | 10 +++++ .../WatchlistService/Watchlist.API/Program.cs | 26 ++++++++++++ .../Properties/launchSettings.json | 41 +++++++++++++++++++ .../Watchlist.API/Watchlist.API.csproj | 16 ++++++++ .../appsettings.Development.json | 9 ++++ .../Watchlist.API/appsettings.json | 10 +++++ 9 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WeatherForecastController.cs create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Properties/launchSettings.json create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.Development.json create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.json diff --git a/SimpleServer/SimpleServer.sln b/SimpleServer/SimpleServer.sln index 9ac80e2..375db30 100644 --- a/SimpleServer/SimpleServer.sln +++ b/SimpleServer/SimpleServer.sln @@ -49,6 +49,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Payment.API", "src\Services EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.Grpc", "src\Services\Identity\Identity.Grpc\Identity.Grpc.csproj", "{D4025862-FCFB-4FC4-BDDA-42127817C5B0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Watchlist.API", "src\Services\WatchlistService\Watchlist.API\Watchlist.API.csproj", "{19FC313F-7235-41E9-9B3E-46D8736051D2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -103,6 +105,10 @@ Global {D4025862-FCFB-4FC4-BDDA-42127817C5B0}.Debug|Any CPU.Build.0 = Debug|Any CPU {D4025862-FCFB-4FC4-BDDA-42127817C5B0}.Release|Any CPU.ActiveCfg = Release|Any CPU {D4025862-FCFB-4FC4-BDDA-42127817C5B0}.Release|Any CPU.Build.0 = Release|Any CPU + {19FC313F-7235-41E9-9B3E-46D8736051D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19FC313F-7235-41E9-9B3E-46D8736051D2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19FC313F-7235-41E9-9B3E-46D8736051D2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19FC313F-7235-41E9-9B3E-46D8736051D2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -129,6 +135,7 @@ Global {B28B8B14-5D5E-4F71-8D29-8F4FA518E63B} = {5DB32E24-821A-4265-8866-5FA3DD7E5E54} {A2136994-728F-4D71-87F9-E11E6DD78790} = {D6B1FD89-8AD1-46A3-A89C-6A73DEFE7D81} {D4025862-FCFB-4FC4-BDDA-42127817C5B0} = {96C41B3F-C50A-499A-8341-6BDC36B37389} + {19FC313F-7235-41E9-9B3E-46D8736051D2} = {EBA29E1D-1833-43D8-9B09-A2D80787B656} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C9B02C29-4D8B-4687-AB7D-9DF5642002D9} diff --git a/SimpleServer/src/Services/Movie/Movie.API/Properties/launchSettings.json b/SimpleServer/src/Services/Movie/Movie.API/Properties/launchSettings.json index 061fdc8..01913fd 100644 --- a/SimpleServer/src/Services/Movie/Movie.API/Properties/launchSettings.json +++ b/SimpleServer/src/Services/Movie/Movie.API/Properties/launchSettings.json @@ -42,8 +42,8 @@ "launchBrowser": true, "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", "environmentVariables": {}, - "useSSL": true, - "publishAllPorts": true + "publishAllPorts": true, + "useSSL": true } } } \ No newline at end of file diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WeatherForecastController.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..73e4b2e --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WeatherForecastController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Watchlist.API.Controllers; + +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase +{ + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } +} + diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs new file mode 100644 index 0000000..dc42e1c --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs @@ -0,0 +1,10 @@ +using System; + +namespace Watchlist.API.Entity +{ + public class UserWatchList + { + public string UserId { get; set; } + public List SavedMovies { get; set; } + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs new file mode 100644 index 0000000..62b4262 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs @@ -0,0 +1,26 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); + diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Properties/launchSettings.json b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Properties/launchSettings.json new file mode 100644 index 0000000..1bb99d7 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:12245", + "sslPort": 44377 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5013", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true + }, + "https": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7085;http://localhost:5013", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj new file mode 100644 index 0000000..f9b7250 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj @@ -0,0 +1,16 @@ + + + + net7.0 + enable + enable + + + + + + + + + + diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.Development.json b/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.Development.json new file mode 100644 index 0000000..ce16a2e --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} + diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.json b/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.json new file mode 100644 index 0000000..af0538f --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} + From bf6690032a1c96dd4931c8be342b8b47ef83c4c7 Mon Sep 17 00:00:00 2001 From: meof-coding Date: Sun, 26 Nov 2023 18:00:05 +0700 Subject: [PATCH 2/9] add entity model --- .../Watchlist.API/Entity/UnfinishedMovies.cs | 14 ++++++++++++++ .../Watchlist.API/Entity/UserUnfinishedMovies.cs | 9 +++++++++ .../Watchlist.API/Entity/UserWatchList.cs | 7 +++---- 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UnfinishedMovies.cs create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserUnfinishedMovies.cs diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UnfinishedMovies.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UnfinishedMovies.cs new file mode 100644 index 0000000..83e2eb7 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UnfinishedMovies.cs @@ -0,0 +1,14 @@ + +namespace Watchlist.API.Entity +{ + public class UnfinishedMovies + { + public string MovieId { get; set; } = string.Empty; + + // total duration (in minutes) + public int ProgressDuarion { get; set; } + + // Last watched + public DateTime LastWatched { get; set; } + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserUnfinishedMovies.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserUnfinishedMovies.cs new file mode 100644 index 0000000..d60d74d --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserUnfinishedMovies.cs @@ -0,0 +1,9 @@ +namespace Watchlist.API.Entity +{ + public class UserUnfinishedMovies + { + public string UserId { get; set; } = string.Empty; + + public List UnfinishedMoviesList { get; set; } = new(); + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs index dc42e1c..464964e 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs @@ -1,10 +1,9 @@ -using System; - namespace Watchlist.API.Entity { public class UserWatchList { - public string UserId { get; set; } - public List SavedMovies { get; set; } + public string UserId { get; set; } = string.Empty, + + public List SavedMovieIds { get; set; } = new() } } From 11d71b34e70bba75df87352ccd1467d196c26bd8 Mon Sep 17 00:00:00 2001 From: meof-coding Date: Sun, 26 Nov 2023 18:02:04 +0700 Subject: [PATCH 3/9] Update UserWatchList.cs --- .../WatchlistService/Watchlist.API/Entity/UserWatchList.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs index 464964e..a737f70 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Entity/UserWatchList.cs @@ -2,8 +2,8 @@ namespace Watchlist.API.Entity { public class UserWatchList { - public string UserId { get; set; } = string.Empty, + public string UserId { get; set; } = string.Empty; - public List SavedMovieIds { get; set; } = new() - } + public List SavedMovieIds { get; set; } = new(); + }; } From 98077cca4628d2a849527b7b678f51d19e7f57e7 Mon Sep 17 00:00:00 2001 From: meof-coding Date: Sun, 26 Nov 2023 19:36:22 +0700 Subject: [PATCH 4/9] add db context infrastructure --- .../Infrastructure/Data/IWatchListContext.cs | 11 ++++++++ .../Infrastructure/Data/WatchListContext.cs | 26 +++++++++++++++++++ .../WatchlistService/Watchlist.API/Program.cs | 20 +++++++++++++- .../Watchlist.API/Watchlist.API.csproj | 9 +++++++ .../appsettings.Development.json | 5 ++++ 5 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/IWatchListContext.cs create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/WatchListContext.cs diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/IWatchListContext.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/IWatchListContext.cs new file mode 100644 index 0000000..46b6adb --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/IWatchListContext.cs @@ -0,0 +1,11 @@ +using MongoDB.Driver; +using Watchlist.API.Entity; + +namespace Watchlist.API.Infrastructure.Data +{ + public interface IWatchListContext + { + IMongoCollection WatchLists { get; } + IMongoCollection UnfinishedMovies { get; } + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/WatchListContext.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/WatchListContext.cs new file mode 100644 index 0000000..b09e7c0 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/WatchListContext.cs @@ -0,0 +1,26 @@ +using System; +using MongoDB.Driver; +using Watchlist.API.Entity; + +namespace Watchlist.API.Infrastructure.Data +{ + public class WatchListContext : IWatchListContext + { + public WatchListContext(IConfiguration configuration) + { + var client = new MongoClient(configuration.GetValue("DatabaseSettings:ConnectionString")); + var database = client.GetDatabase(configuration.GetValue("DatabaseSettings:DatabaseName")); + WatchLists = database.GetCollection("userWatchList"); + UnfinishedMovies = database.GetCollection("userUnfinishedMovies"); + } + + public WatchListContext() + { + } + + + public IMongoCollection WatchLists { get; } + + public IMongoCollection UnfinishedMovies { get; } + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs index 62b4262..6a75060 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs @@ -1,12 +1,28 @@ -var builder = WebApplication.CreateBuilder(args); +using Watchlist.API.Infrastructure.Data; +using Watchlist.API.Repository.WatchList; + +var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); + +builder.Services.AddAuthentication("Bearer") + .AddJwtBearer("Bearer", options => + { + options.RequireHttpsMetadata = false; + options.Authority = builder.Configuration["IdentityUrl"]; + options.Audience = "watchlist"; + }); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +// DI for DbContext and Repository +builder.Services.AddScoped(); +builder.Services.AddScoped(); + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -18,9 +34,11 @@ app.UseHttpsRedirection(); +app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run(); +public partial class Program { } \ No newline at end of file diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj index f9b7250..7328f88 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj @@ -10,7 +10,16 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.Development.json b/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.Development.json index ce16a2e..9ab341d 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.Development.json +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/appsettings.Development.json @@ -4,6 +4,11 @@ "Default": "Information", "Microsoft.AspNetCore": "Warning" } + }, + "IdentityUrl":"https://localhost:7096", + "DatabaseSettings": { + "ConnectionString": "mongodb://localhost:27017", + "DatabaseName": "userWwatchListDB" } } From 1ff600e21fadf058b136500e14d18b8dbb92d83e Mon Sep 17 00:00:00 2001 From: meof-coding Date: Sun, 26 Nov 2023 19:50:28 +0700 Subject: [PATCH 5/9] add logic handle user watchlist --- .../WatchList/IWatchListRepository.cs | 14 +++++++ .../WatchList/WatchListRepository.cs | 38 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/IWatchListRepository.cs create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/WatchListRepository.cs diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/IWatchListRepository.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/IWatchListRepository.cs new file mode 100644 index 0000000..aba09b5 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/IWatchListRepository.cs @@ -0,0 +1,14 @@ +using System; + +namespace Watchlist.API.Repository.WatchList +{ + public interface IWatchListRepository + { + // Add movie to watchlist + Task InsertToWatchedListAsync(string userId, string movieId); + // Remove movie from watchlist + Task RemoveFromWatchedListAsync(string userId, string movieId); + // Get watchlist + Task> GetWatchListAsync(string userId); + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/WatchListRepository.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/WatchListRepository.cs new file mode 100644 index 0000000..8939ea0 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/WatchListRepository.cs @@ -0,0 +1,38 @@ +using MongoDB.Driver; +using Watchlist.API.Entity; +using Watchlist.API.Infrastructure.Data; + +namespace Watchlist.API.Repository.WatchList +{ + public class WatchListRepository : IWatchListRepository + { + private readonly IWatchListContext _context; + + public WatchListRepository(IWatchListContext context) + { + _context = context ?? throw new ArgumentNullException(nameof(context)); + } + + public async Task> GetWatchListAsync(string userId) + { + // Get all watch lists from database where userId == userId + return (await _context.WatchLists.FindAsync(x => x.UserId == userId)) + .FirstOrDefault()?.SavedMovieIds ?? new List(); + } + + public async Task InsertToWatchedListAsync(string userId, string movieId) + { + await _context.WatchLists.UpdateOneAsync( + x => x.UserId == userId, + Builders.Update.AddToSet(x => x.SavedMovieIds, movieId), + new UpdateOptions { IsUpsert = true }); + } + + public async Task RemoveFromWatchedListAsync(string userId, string movieId) + { + await _context.WatchLists.UpdateOneAsync( + x => x.UserId == userId, + Builders.Update.Pull(x => x.SavedMovieIds, movieId)); + } + } +} From 696e40d566595e071b5f1a43729ba40aad5acecd Mon Sep 17 00:00:00 2001 From: meof-coding Date: Sun, 26 Nov 2023 19:50:38 +0700 Subject: [PATCH 6/9] add watchList api endpoint --- .../Controllers/WatchListController.cs | 53 +++++++++++++++++++ .../Controllers/WeatherForecastController.cs | 33 ------------ 2 files changed, 53 insertions(+), 33 deletions(-) create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WatchListController.cs delete mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WeatherForecastController.cs diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WatchListController.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WatchListController.cs new file mode 100644 index 0000000..e180d22 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WatchListController.cs @@ -0,0 +1,53 @@ +using System; +using System.Security.Claims; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Watchlist.API.Repository.WatchList; + +namespace Watchlist.API.Controllers +{ + //[Authorize(Roles = "Member")] + [Route("api/watchList")] + public class WatchListController : Controller + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IWatchListRepository _watchListService; + private readonly ILogger _logger; + + public WatchListController(IWatchListRepository watchListService, ILogger logger, IHttpContextAccessor httpContextAccessor) + { + _watchListService = watchListService; + _logger = logger; + _httpContextAccessor = httpContextAccessor; + } + + [HttpGet] + public async Task>> GetWatchListAsync() + { + var userId = GetUserId(); + return Ok(await _watchListService.GetWatchListAsync(userId)); + } + + private string GetUserId() + { + return _httpContextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value + ?? throw new ArgumentNullException("User not found"); + } + + [HttpPost] + public async Task AddMovieToWatchListAsync([FromBody] string movieId) + { + var userId = GetUserId(); + await _watchListService.InsertToWatchedListAsync(userId, movieId); + return Ok(); + } + + [HttpDelete("{movieId}")] + public async Task RemoveMovieFromWatchListAsync(string movieId) + { + var userId = GetUserId(); + await _watchListService.RemoveFromWatchedListAsync(userId, movieId); + return Ok(); + } + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WeatherForecastController.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WeatherForecastController.cs deleted file mode 100644 index 73e4b2e..0000000 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WeatherForecastController.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace Watchlist.API.Controllers; - -[ApiController] -[Route("[controller]")] -public class WeatherForecastController : ControllerBase -{ - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" - }; - - private readonly ILogger _logger; - - public WeatherForecastController(ILogger logger) - { - _logger = logger; - } - - [HttpGet(Name = "GetWeatherForecast")] - public IEnumerable Get() - { - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = Summaries[Random.Shared.Next(Summaries.Length)] - }) - .ToArray(); - } -} - From 06898970c3a7f9d31f43881bb5f38effd2098d2f Mon Sep 17 00:00:00 2001 From: meof-coding Date: Sun, 26 Nov 2023 19:52:29 +0700 Subject: [PATCH 7/9] Update Watchlist.API.csproj --- .../WatchlistService/Watchlist.API/Watchlist.API.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj index 7328f88..60cd906 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Watchlist.API.csproj @@ -10,9 +10,9 @@ - - runtime; build; native; contentfiles; analyzers; buildtransitive - all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all From 8757e268b1d5ff0b7bc638d4ee9211892294125c Mon Sep 17 00:00:00 2001 From: meof-coding Date: Sun, 26 Nov 2023 20:04:33 +0700 Subject: [PATCH 8/9] chore: refactor watchList to savedList and init code for unwatchedList --- ...Controller.cs => SavedWatchListController.cs} | 8 ++++---- .../Controllers/UnfinishedWatchListController.cs | 13 +++++++++++++ .../Infrastructure/Data/IWatchListContext.cs | 2 +- .../Infrastructure/Data/WatchListContext.cs | 4 ++-- .../WatchlistService/Watchlist.API/Program.cs | 4 +++- .../SavedMovies/ISavedWatchListRepository.cs | 14 ++++++++++++++ .../SavedWatchListRepository.cs} | 16 ++++++++-------- .../UnfinishedList/FinishedListRepository.cs | 9 +++++++++ .../UnfinishedList/IFinishedListRepository.cs | 9 +++++++++ .../Repository/WatchList/IWatchListRepository.cs | 14 -------------- 10 files changed, 63 insertions(+), 30 deletions(-) rename SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/{WatchListController.cs => SavedWatchListController.cs} (82%) create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/UnfinishedWatchListController.cs create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/SavedMovies/ISavedWatchListRepository.cs rename SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/{WatchList/WatchListRepository.cs => SavedMovies/SavedWatchListRepository.cs} (58%) create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/UnfinishedList/FinishedListRepository.cs create mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/UnfinishedList/IFinishedListRepository.cs delete mode 100644 SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/IWatchListRepository.cs diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WatchListController.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/SavedWatchListController.cs similarity index 82% rename from SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WatchListController.cs rename to SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/SavedWatchListController.cs index e180d22..bb0dcf4 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/WatchListController.cs +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/SavedWatchListController.cs @@ -6,15 +6,15 @@ namespace Watchlist.API.Controllers { - //[Authorize(Roles = "Member")] + [Authorize(Roles = "Member")] [Route("api/watchList")] - public class WatchListController : Controller + public class SavedWatchListController : Controller { private readonly IHttpContextAccessor _httpContextAccessor; private readonly IWatchListRepository _watchListService; - private readonly ILogger _logger; + private readonly ILogger _logger; - public WatchListController(IWatchListRepository watchListService, ILogger logger, IHttpContextAccessor httpContextAccessor) + public SavedWatchListController(IWatchListRepository watchListService, ILogger logger, IHttpContextAccessor httpContextAccessor) { _watchListService = watchListService; _logger = logger; diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/UnfinishedWatchListController.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/UnfinishedWatchListController.cs new file mode 100644 index 0000000..787485e --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Controllers/UnfinishedWatchListController.cs @@ -0,0 +1,13 @@ +using System; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Watchlist.API.Controllers +{ + [Authorize(Roles = "Member")] + [Route("api/unfinishedWatchList")] + public class UnfinishedWatchListController : Controller + { + + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/IWatchListContext.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/IWatchListContext.cs index 46b6adb..11b532a 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/IWatchListContext.cs +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/IWatchListContext.cs @@ -5,7 +5,7 @@ namespace Watchlist.API.Infrastructure.Data { public interface IWatchListContext { - IMongoCollection WatchLists { get; } + IMongoCollection SavedMovies { get; } IMongoCollection UnfinishedMovies { get; } } } diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/WatchListContext.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/WatchListContext.cs index b09e7c0..c132bdb 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/WatchListContext.cs +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Infrastructure/Data/WatchListContext.cs @@ -10,7 +10,7 @@ public WatchListContext(IConfiguration configuration) { var client = new MongoClient(configuration.GetValue("DatabaseSettings:ConnectionString")); var database = client.GetDatabase(configuration.GetValue("DatabaseSettings:DatabaseName")); - WatchLists = database.GetCollection("userWatchList"); + SavedMovies = database.GetCollection("userSavedList"); UnfinishedMovies = database.GetCollection("userUnfinishedMovies"); } @@ -19,7 +19,7 @@ public WatchListContext() } - public IMongoCollection WatchLists { get; } + public IMongoCollection SavedMovies { get; } public IMongoCollection UnfinishedMovies { get; } } diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs index 6a75060..e4fcc1d 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Program.cs @@ -1,4 +1,5 @@ using Watchlist.API.Infrastructure.Data; +using Watchlist.API.Repository.UnfinishedList; using Watchlist.API.Repository.WatchList; var builder = WebApplication.CreateBuilder(args); @@ -21,7 +22,8 @@ // DI for DbContext and Repository builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); var app = builder.Build(); diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/SavedMovies/ISavedWatchListRepository.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/SavedMovies/ISavedWatchListRepository.cs new file mode 100644 index 0000000..e18dc41 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/SavedMovies/ISavedWatchListRepository.cs @@ -0,0 +1,14 @@ +using System; + +namespace Watchlist.API.Repository.WatchList +{ + public interface ISavedWatchListRepository + { + // Add movie to watchlist + Task InsertToSavedWatchedListAsync(string userId, string movieId); + // Remove movie from watchlist + Task RemoveFromSavedWatchedListAsync(string userId, string movieId); + // Get watchlist + Task> GetSavedWatchListAsync(string userId); + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/WatchListRepository.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/SavedMovies/SavedWatchListRepository.cs similarity index 58% rename from SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/WatchListRepository.cs rename to SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/SavedMovies/SavedWatchListRepository.cs index 8939ea0..81a81dd 100644 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/WatchListRepository.cs +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/SavedMovies/SavedWatchListRepository.cs @@ -4,33 +4,33 @@ namespace Watchlist.API.Repository.WatchList { - public class WatchListRepository : IWatchListRepository + public class SavedWatchListRepository : ISavedWatchListRepository { private readonly IWatchListContext _context; - public WatchListRepository(IWatchListContext context) + public SavedWatchListRepository(IWatchListContext context) { _context = context ?? throw new ArgumentNullException(nameof(context)); } - public async Task> GetWatchListAsync(string userId) + public async Task> GetSavedWatchListAsync(string userId) { // Get all watch lists from database where userId == userId - return (await _context.WatchLists.FindAsync(x => x.UserId == userId)) + return (await _context.SavedMovies.FindAsync(x => x.UserId == userId)) .FirstOrDefault()?.SavedMovieIds ?? new List(); } - public async Task InsertToWatchedListAsync(string userId, string movieId) + public async Task InsertToSavedWatchedListAsync(string userId, string movieId) { - await _context.WatchLists.UpdateOneAsync( + await _context.SavedMovies.UpdateOneAsync( x => x.UserId == userId, Builders.Update.AddToSet(x => x.SavedMovieIds, movieId), new UpdateOptions { IsUpsert = true }); } - public async Task RemoveFromWatchedListAsync(string userId, string movieId) + public async Task RemoveFromSavedWatchedListAsync(string userId, string movieId) { - await _context.WatchLists.UpdateOneAsync( + await _context.SavedMovies.UpdateOneAsync( x => x.UserId == userId, Builders.Update.Pull(x => x.SavedMovieIds, movieId)); } diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/UnfinishedList/FinishedListRepository.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/UnfinishedList/FinishedListRepository.cs new file mode 100644 index 0000000..3ea0a63 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/UnfinishedList/FinishedListRepository.cs @@ -0,0 +1,9 @@ +using System; + +namespace Watchlist.API.Repository.UnfinishedList +{ + public class FinishedListRepository : IFinishedListRepository + { + + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/UnfinishedList/IFinishedListRepository.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/UnfinishedList/IFinishedListRepository.cs new file mode 100644 index 0000000..99a24e3 --- /dev/null +++ b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/UnfinishedList/IFinishedListRepository.cs @@ -0,0 +1,9 @@ +using System; + +namespace Watchlist.API.Repository.UnfinishedList +{ + public interface IFinishedListRepository + { + + } +} diff --git a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/IWatchListRepository.cs b/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/IWatchListRepository.cs deleted file mode 100644 index aba09b5..0000000 --- a/SimpleServer/src/Services/WatchlistService/Watchlist.API/Repository/WatchList/IWatchListRepository.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace Watchlist.API.Repository.WatchList -{ - public interface IWatchListRepository - { - // Add movie to watchlist - Task InsertToWatchedListAsync(string userId, string movieId); - // Remove movie from watchlist - Task RemoveFromWatchedListAsync(string userId, string movieId); - // Get watchlist - Task> GetWatchListAsync(string userId); - } -} From a48259bee155a2f07197a51dbf397608ab42f5c4 Mon Sep 17 00:00:00 2001 From: meof-coding Date: Mon, 27 Nov 2023 18:11:05 +0700 Subject: [PATCH 9/9] add reverse proxy for watch list --- .../OcelotApiGw/ocelot.Development.json | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/SimpleServer/src/ApiGateways/Web.Bff.SimpleNetflix/OcelotApiGw/ocelot.Development.json b/SimpleServer/src/ApiGateways/Web.Bff.SimpleNetflix/OcelotApiGw/ocelot.Development.json index 32d0ad6..85df62e 100644 --- a/SimpleServer/src/ApiGateways/Web.Bff.SimpleNetflix/OcelotApiGw/ocelot.Development.json +++ b/SimpleServer/src/ApiGateways/Web.Bff.SimpleNetflix/OcelotApiGw/ocelot.Development.json @@ -261,6 +261,28 @@ "movies" ] } + }, + { + "DownstreamPathTemplate": "/api/watchList/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 5013 + } + ], + "UpstreamPathTemplate": "/watchList/{everything}", + "UpstreamHttpMethod": [ + "GET", + "POST", + "DELETE" + ], + "AuthenticationOptions": { + "AuthenticationProviderKey": "IdentityApiKey", + "AllowedScopes": [ + "watchlist" + ] + } } ] } \ No newline at end of file