Skip to content
This repository was archived by the owner on Apr 11, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,24 @@ services:
- "5102:80"
- "5581:5001"

courseregistration.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionStrings=Server=sql.data;Database=OpenCodeFoundation.CourseRegistrationDb;User Id=sa;Password=Pass@word
ports:
- "5103:80"
- "5582:5001"

webstatus:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80
- ConnectionStrings=Server=sql.data;Database=OpenCodeFoundation.WebStatusDb;User Id=sa;Password=Pass@word
- HealthChecksUI__HealthChecks__0__Name=Enrolling HTTP Check
- HealthChecksUI__HealthChecks__0__Uri=http://enrolling.api/hc
- HealthChecksUI__HealthChecks__1__Name=CourseRegistration HTTP Check
- HealthChecksUI__HealthChecks__1__Uri=http://courseregistration.api/hc
ports:
- "5107:80"

Expand Down
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ services:
depends_on:
- sql.data

courseregistration.api:
image: ${REGISTRY:-eschool}/courseregistration.api:${TAG:-latest}
build:
context: .
dockerfile: src/Services/CourseRegistration/CourseRegistration.API/Dockerfile
depends_on:
- sql.data

webstatus:
image: ${REGISTRY:-eschool}/webstatus:${TAG:-latest}
build:
Expand Down
78 changes: 78 additions & 0 deletions eSchool.sln
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Frontend.Blazor.Server", "s
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Frontend.Blazor.Shared", "src\Web\Frontend.Blazor\Frontend.Blazor.Shared\Frontend.Blazor.Shared.csproj", "{4EB86635-CF79-4D15-909E-C41C98B0B586}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CourseRegistration", "CourseRegistration", "{F5B40B9B-057F-4D22-B34E-946F7F6E7B86}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CourseRegistration.API", "src\Services\CourseRegistration\CourseRegistration.API\CourseRegistration.API.csproj", "{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CourseRegistration.Domain", "src\Services\CourseRegistration\CourseRegistration.Domain\CourseRegistration.Domain.csproj", "{21012592-FADD-4457-93F5-8B3F7B265ED4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CourseRegistration.FunctionalTests", "src\Services\CourseRegistration\CourseRegistration.FunctionalTests\CourseRegistration.FunctionalTests.csproj", "{D1F9863A-DEC3-42CC-86DF-E81E2570D063}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CourseRegistration.Infrastructure", "src\Services\CourseRegistration\CourseRegistration.Infrastructure\CourseRegistration.Infrastructure.csproj", "{60584837-1CE9-4EF2-899C-EF3982FAA4B0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CourseRegistration.UnitTests", "src\Services\CourseRegistration\CourseRegistration.UnitTests\CourseRegistration.UnitTests.csproj", "{2982CB50-A029-4C8E-938F-F70ADA4DF207}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -195,6 +207,66 @@ Global
{4EB86635-CF79-4D15-909E-C41C98B0B586}.Release|x64.Build.0 = Release|Any CPU
{4EB86635-CF79-4D15-909E-C41C98B0B586}.Release|x86.ActiveCfg = Release|Any CPU
{4EB86635-CF79-4D15-909E-C41C98B0B586}.Release|x86.Build.0 = Release|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Debug|x64.ActiveCfg = Debug|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Debug|x64.Build.0 = Debug|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Debug|x86.ActiveCfg = Debug|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Debug|x86.Build.0 = Debug|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Release|Any CPU.Build.0 = Release|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Release|x64.ActiveCfg = Release|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Release|x64.Build.0 = Release|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Release|x86.ActiveCfg = Release|Any CPU
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D}.Release|x86.Build.0 = Release|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Debug|x64.ActiveCfg = Debug|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Debug|x64.Build.0 = Debug|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Debug|x86.ActiveCfg = Debug|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Debug|x86.Build.0 = Debug|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Release|Any CPU.Build.0 = Release|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Release|x64.ActiveCfg = Release|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Release|x64.Build.0 = Release|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Release|x86.ActiveCfg = Release|Any CPU
{21012592-FADD-4457-93F5-8B3F7B265ED4}.Release|x86.Build.0 = Release|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Debug|x64.ActiveCfg = Debug|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Debug|x64.Build.0 = Debug|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Debug|x86.ActiveCfg = Debug|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Debug|x86.Build.0 = Debug|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Release|Any CPU.Build.0 = Release|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Release|x64.ActiveCfg = Release|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Release|x64.Build.0 = Release|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Release|x86.ActiveCfg = Release|Any CPU
{D1F9863A-DEC3-42CC-86DF-E81E2570D063}.Release|x86.Build.0 = Release|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Debug|x64.ActiveCfg = Debug|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Debug|x64.Build.0 = Debug|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Debug|x86.ActiveCfg = Debug|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Debug|x86.Build.0 = Debug|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Release|Any CPU.Build.0 = Release|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Release|x64.ActiveCfg = Release|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Release|x64.Build.0 = Release|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Release|x86.ActiveCfg = Release|Any CPU
{60584837-1CE9-4EF2-899C-EF3982FAA4B0}.Release|x86.Build.0 = Release|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Debug|x64.ActiveCfg = Debug|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Debug|x64.Build.0 = Debug|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Debug|x86.ActiveCfg = Debug|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Debug|x86.Build.0 = Debug|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Release|Any CPU.Build.0 = Release|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Release|x64.ActiveCfg = Release|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Release|x64.Build.0 = Release|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Release|x86.ActiveCfg = Release|Any CPU
{2982CB50-A029-4C8E-938F-F70ADA4DF207}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -217,6 +289,12 @@ Global
{53F4E6F9-6B91-45F9-97F9-F6EFA0EBEFCE} = {0C00A596-0FE3-4FA6-B54B-FE2BE83371EF}
{3BABD4D9-56A1-4BA3-B30C-30E6765AB389} = {0C00A596-0FE3-4FA6-B54B-FE2BE83371EF}
{4EB86635-CF79-4D15-909E-C41C98B0B586} = {0C00A596-0FE3-4FA6-B54B-FE2BE83371EF}
{F5B40B9B-057F-4D22-B34E-946F7F6E7B86} = {1C120673-72F4-4679-AC4C-68286E9091A5}
{09BD4566-E6F2-4FD0-A8AE-D3663BF7184D} = {F5B40B9B-057F-4D22-B34E-946F7F6E7B86}
{21012592-FADD-4457-93F5-8B3F7B265ED4} = {F5B40B9B-057F-4D22-B34E-946F7F6E7B86}
{D1F9863A-DEC3-42CC-86DF-E81E2570D063} = {F5B40B9B-057F-4D22-B34E-946F7F6E7B86}
{60584837-1CE9-4EF2-899C-EF3982FAA4B0} = {F5B40B9B-057F-4D22-B34E-946F7F6E7B86}
{2982CB50-A029-4C8E-938F-F70ADA4DF207} = {F5B40B9B-057F-4D22-B34E-946F7F6E7B86}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E418719F-3193-403E-AF58-9BE9F94FD8BE}
Expand Down
6 changes: 6 additions & 0 deletions src/ApiGateways/eSchool.GraphQL/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ COPY "src/Services/Enrolling/Enrolling.Infrastructure/Enrolling.Infrastructure.c
COPY "src/Services/Enrolling/Enrolling.UnitTests/Enrolling.UnitTests.csproj" "src/Services/Enrolling/Enrolling.UnitTests/Enrolling.UnitTests.csproj"
COPY "src/Services/Enrolling/Enrolling.FunctionalTests/Enrolling.FunctionalTests.csproj" "src/Services/Enrolling/Enrolling.FunctionalTests/Enrolling.FunctionalTests.csproj"

COPY "src/Services/CourseRegistration/CourseRegistration.API/CourseRegistration.API.csproj" "src/Services/CourseRegistration/CourseRegistration.API/CourseRegistration.API.csproj"
COPY "src/Services/CourseRegistration/CourseRegistration.Domain/CourseRegistration.Domain.csproj" "src/Services/CourseRegistration/CourseRegistration.Domain/CourseRegistration.Domain.csproj"
COPY "src/Services/CourseRegistration/CourseRegistration.Infrastructure/CourseRegistration.Infrastructure.csproj" "src/Services/CourseRegistration/CourseRegistration.Infrastructure/CourseRegistration.Infrastructure.csproj"
COPY "src/Services/CourseRegistration/CourseRegistration.UnitTests/CourseRegistration.UnitTests.csproj" "src/Services/CourseRegistration/CourseRegistration.UnitTests/Enrolling.UnitTests.csproj"
COPY "src/Services/CourseRegistration/CourseRegistration.FunctionalTests/CourseRegistration.FunctionalTests.csproj" "src/Services/CourseRegistration/CourseRegistration.FunctionalTests/CourseRegistration.FunctionalTests.csproj"

COPY "src/Libraries/OpenTelemetry/OpenTelemetry.csproj" "src/Libraries/OpenTelemetry/OpenTelemetry.csproj"

COPY "src/Web/WebStatus/WebStatus.csproj" "src/Web/WebStatus/WebStatus.csproj"
Expand Down
7 changes: 6 additions & 1 deletion src/ApiGateways/eSchool.GraphQL/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace OpenCodeFoundation.ESchool.ApiGateways.ESchool.GraphQL
public class Startup
{
public const string Enrolling = "enrolling";
public const string CourseRegistration = "courseregistration";

// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
Expand All @@ -22,9 +23,13 @@ public void ConfigureServices(IServiceCollection services)
services.AddHttpClient(Enrolling, c =>
c.BaseAddress = new Uri("http://enrolling.api/graphql"));

services.AddHttpClient(CourseRegistration, c =>
c.BaseAddress = new Uri("http://courseregistration.api/graphql"));

services
.AddGraphQLServer()
.AddRemoteSchema(Enrolling);
.AddRemoteSchema(Enrolling)
.AddRemoteSchema(CourseRegistration);

services.AddOpenTelemetryIntegration();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Microsoft.Extensions.Logging;

namespace CourseRegistration.API.Application.Behaviors
{
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{

private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;

public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger)
{
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
}

public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
_logger.LogInformation("Handling request {RequestName} ({@Request})", request.GetType().Name, request);

var response = await next();

_logger.LogInformation(
"Request {RequestName} handled. Response: {@Response}",
request.GetType().Name,
response);

return response;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using MediatR;

namespace CourseRegistration.API.Application.Commands
{
public class CourseRegistrationCommand : IRequest<bool>
{
public string CourseCode { get; set; }
public string CourseName { get; set; }
public string Description { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CourseRegistration.Infrastructure;
using MediatR;
using Microsoft.Extensions.Logging;

namespace CourseRegistration.API.Application.Commands
{
public class CourseRegistrationCommandHandler : IRequestHandler<CourseRegistrationCommand, bool>
{
private readonly ILogger<CourseRegistrationCommandHandler> _logger;
private readonly CourseRegistrationContext _context;

public CourseRegistrationCommandHandler(CourseRegistrationContext context,
ILogger<CourseRegistrationCommandHandler> logger)
{
_context = context ?? throw new ArgumentException(nameof(context));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public async Task<bool> Handle(CourseRegistrationCommand command, CancellationToken cancellationToken)
{
var courseRegistration = new CourseRegistration.Domain.AggregatesModel.CourseRegistrationAggregate.CourseRegistration(command.CourseCode, command.CourseName, command.Description);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do one of choosing different aggregate root name or changing the service name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is your suggestion for the name? We should follow a common convention.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mahedee: We have decided use suffix Service for namespace. So the namespace of this class will be CourseRegistrationService.API.Application.Commands. This way we can create the Aggregate with the name CourseRegistration without any issue.

_context.CourseRegistrations.Add(courseRegistration);
await _context.SaveChangesAsync();
return true;

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CourseRegistration.Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace CourseRegistration.API.Application.Queries
{
public class FindAllCourseRegistrationHandler
: IRequestHandler<FindAllCourseRegistrationQuery, IEnumerable<CourseRegistration.Domain.AggregatesModel.CourseRegistrationAggregate.CourseRegistration>>
{
private readonly CourseRegistrationContext _context;


public FindAllCourseRegistrationHandler(CourseRegistrationContext context)
{
_context = context ?? throw new System.ArgumentNullException(nameof(context));
}


public async Task<IEnumerable<Domain.AggregatesModel.CourseRegistrationAggregate.CourseRegistration>> Handle(FindAllCourseRegistrationQuery request, CancellationToken cancellationToken)
{
return await _context.CourseRegistrations.ToListAsync();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MediatR;

namespace CourseRegistration.API.Application.Queries
{
public class FindAllCourseRegistrationQuery
:IRequest<IEnumerable<CourseRegistration.Domain.AggregatesModel.CourseRegistrationAggregate.CourseRegistration>>
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CourseRegistration.API.Application.Commands;
using CourseRegistration.API.Application.Queries;
using MediatR;
using Microsoft.AspNetCore.Mvc;

namespace CourseRegistration.API.Controllers
{
[ApiController]
[Route("[controller]")]
public class CourseRegistrationController : Controller
{
private readonly IMediator _mediator;

public CourseRegistrationController(IMediator mediator)
{
_mediator = mediator;
}

[HttpGet]
public async Task<IEnumerable<CourseRegistration.Domain.AggregatesModel.CourseRegistrationAggregate.CourseRegistration>> Get()
=> await _mediator.Send(new FindAllCourseRegistrationQuery());

[HttpPost]
public async Task<IActionResult> Post([FromBody] CourseRegistrationCommand command)
{
await _mediator.Send(command);
return Ok();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace CourseRegistration.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<WeatherForecastController> _logger;

public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}

[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
}
Loading