Skip to content

Commit

Permalink
feat: Remove old bemanning and integrate with Vibes
Browse files Browse the repository at this point in the history
  • Loading branch information
nikolaia committed Feb 15, 2024
1 parent f4dcb83 commit cc516ec
Show file tree
Hide file tree
Showing 14 changed files with 134 additions and 141 deletions.
8 changes: 0 additions & 8 deletions src/ApplicationCore/Interfaces/IBemanningRepository.cs

This file was deleted.

7 changes: 0 additions & 7 deletions src/ApplicationCore/Models/BemanningEmployee.cs

This file was deleted.

15 changes: 15 additions & 0 deletions src/Infrastructure/ApiClients/DTOs/VibesEmploymentDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Infrastructure.ApiClients.DTOs;

public class VibesEmploymentDTO
{
public VibesEmploymentDTO(string email, DateTime? startDate, DateTime? endDate)
{
this.email = email;
this.startDate = startDate;
this.endDate = endDate;
}

public string email { get; set; }
public DateTime? startDate { get; set; }
public DateTime? endDate { get; set; }
}
7 changes: 7 additions & 0 deletions src/Infrastructure/ApiClients/DTOs/VibesOrganisationDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Infrastructure.ApiClients.DTOs;

public class VibesOrganisationDTO
{
public string Name { get; set; }

Check warning on line 5 in src/Infrastructure/ApiClients/DTOs/VibesOrganisationDTO.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public string UrlKey { get; set; }

Check warning on line 6 in src/Infrastructure/ApiClients/DTOs/VibesOrganisationDTO.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'UrlKey' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}
14 changes: 14 additions & 0 deletions src/Infrastructure/ApiClients/IVibesApiClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Infrastructure.ApiClients.DTOs;
using Refit;

namespace Infrastructure.ApiClients;

[Headers("Authorization: Bearer")]
public interface IVibesApiClient
{
[Get("/v0/organisations")]
Task<IEnumerable<VibesOrganisationDTO>> GetOrganisations();

[Get("/v0/{companyCountry}/consultants/employment")]
Task<IEnumerable<VibesEmploymentDTO>> GetEmploymentDates(string companyCountry);
}
31 changes: 16 additions & 15 deletions src/Infrastructure/OrchestratorService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using ApplicationCore.Models;
using ApplicationCore.Services;

using Infrastructure.ApiClients;
using Infrastructure.ApiClients.DTOs;
using Infrastructure.Repositories;

Expand All @@ -17,21 +18,21 @@ public class OrchestratorService
{
private readonly IEmployeesRepository _employeesRepository;
private readonly CvPartnerRepository _cvPartnerRepository;
private readonly IBemanningRepository _bemanningRepository;
private readonly VibesRepository _vibesRepository;
private readonly BlobStorageService _blobStorageService;
private readonly ILogger<OrchestratorService> _logger;
private readonly FilteredUids _filteredUids;

public OrchestratorService(CvPartnerRepository cvPartnerRepository,
IBemanningRepository bemanningRepository,
VibesRepository vibesRepository,
IEmployeesRepository employeesRepository,
BlobStorageService blobStorageService,
FilteredUids filteredUids,
ILogger<OrchestratorService> logger)
{
_employeesRepository = employeesRepository;
_cvPartnerRepository = cvPartnerRepository;
_bemanningRepository = bemanningRepository;
_vibesRepository = vibesRepository;
_blobStorageService = blobStorageService;
_logger = logger;
_filteredUids = filteredUids;
Expand All @@ -40,14 +41,14 @@ public OrchestratorService(CvPartnerRepository cvPartnerRepository,
public async Task FetchMapAndSaveEmployeeData()
{
_logger.LogInformation("OrchestratorRepository: FetchMapAndSaveEmployeeData: Started");
var bemanningEntries = await _bemanningRepository.GetBemanningDataForEmployees();
var bemanningEntries = await _vibesRepository.GetEmployment();
var cvEntries = await _cvPartnerRepository.GetAllEmployees();

var phoneNumberUtil = PhoneNumberUtil.GetInstance();

foreach (var bemanning in bemanningEntries.Where(IsActiveEmployee))
{
var cv = cvEntries.Find(cv => cv.email.ToLower().Trim() == bemanning.Email.ToLower().Trim());
var cv = cvEntries.Find(cv => cv.email.ToLower().Trim() == bemanning.email.ToLower().Trim());

if (cv != null)
{
Expand All @@ -72,8 +73,8 @@ await _employeesRepository.AddOrUpdateEmployeeInformation(new Employee
? await _blobStorageService.SaveToBlob(cv.user_id, cv.image.url)
: null,
OfficeName = cv.office_name,
StartDate = bemanning.StartDate,
EndDate = bemanning.EndDate,
StartDate = bemanning.startDate ?? new DateTime(2018,08,01),
EndDate = bemanning.endDate,
CountryCode = countryCode
}
});
Expand All @@ -83,8 +84,8 @@ await _employeesRepository.AddOrUpdateEmployeeInformation(new Employee
// If the employee does not exist in CV Partner, only in Bemanning, we should ensure the employee is not in the database.
_logger.LogInformation(
"Deleting employee with email {BemanningEmail} from database, since it does not exist in CV Partner",
bemanning.Email);
var blobUrlToBeDeleted = await _employeesRepository.EnsureEmployeeIsDeleted(bemanning.Email);
bemanning.email);
var blobUrlToBeDeleted = await _employeesRepository.EnsureEmployeeIsDeleted(bemanning.email);
if (blobUrlToBeDeleted == null)
{
continue;
Expand All @@ -105,8 +106,8 @@ await _employeesRepository.AddOrUpdateEmployeeInformation(new Employee
// StartDate in bemanning wasn't set properly when orchestrating. Covering an edge case
_logger.LogInformation(
"Deleting employee with email {BemanningEmail} from database, since they haven't started yet",
bemanning.Email);
blobUrlsToBeDeleted.Add(await _employeesRepository.EnsureEmployeeIsDeleted(bemanning.Email));
bemanning.email);
blobUrlsToBeDeleted.Add(await _employeesRepository.EnsureEmployeeIsDeleted(bemanning.email));
}

// Remove all potential images from both past employees and future employees
Expand All @@ -122,14 +123,14 @@ await _employeesRepository.AddOrUpdateEmployeeInformation(new Employee
_logger.LogInformation("OrchestratorRepository: FetchMapAndSaveEmployeeData: Finished");
}

private static bool IsActiveEmployee(BemanningEmployee bemanning)
private static bool IsActiveEmployee(VibesEmploymentDTO employmentDto)
{
return DateTime.Now >= bemanning.StartDate && (bemanning.EndDate == null || DateTime.Now <= bemanning.EndDate);
return DateTime.Now >= employmentDto.startDate && (employmentDto.endDate == null || DateTime.Now <= employmentDto.endDate);
}

private static bool IsFutureEmployee(BemanningEmployee bemanning)
private static bool IsFutureEmployee(VibesEmploymentDTO employmentDto)
{
return bemanning.StartDate > DateTime.Now;
return employmentDto.startDate > DateTime.Now;
}

public async Task FetchMapAndSaveCvData()
Expand Down
93 changes: 0 additions & 93 deletions src/Infrastructure/Repositories/BemanningRepository.cs

This file was deleted.

31 changes: 31 additions & 0 deletions src/Infrastructure/Repositories/VibesRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Infrastructure.ApiClients;
using Infrastructure.ApiClients.DTOs;

using Microsoft.Extensions.Logging;

namespace Infrastructure.Repositories;

public class VibesRepository
{
private readonly IVibesApiClient _vibesApiClient;
private readonly ILogger<VibesRepository> _logger;

public VibesRepository(IVibesApiClient vibesApiClient, ILogger<VibesRepository> logger)
{
_vibesApiClient = vibesApiClient;
_logger = logger;
}
public async Task<List<VibesEmploymentDTO>> GetEmployment()
{
_logger.LogInformation("VibesRepository.GetEmployment: Fetching employee start and end dates from Vibes/Bemanning");

var organisationResponse = await _vibesApiClient.GetOrganisations();

var getEmploymentTasks = organisationResponse.Select(async organisationDto =>
await _vibesApiClient.GetEmploymentDates(organisationDto.UrlKey));

var apiResponses = await Task.WhenAll(getEmploymentTasks);

return apiResponses.SelectMany(response => response).ToList();
}
}
8 changes: 7 additions & 1 deletion src/Shared/AppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ public record BlobStorageConfig
public bool UseDevelopmentStorage { get; set; } = false;
}

public record VibesConfig
{
public Uri BaseUri { get; set; }

Check warning on line 23 in src/Shared/AppSettings.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'BaseUri' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public string Scope { get; set; }

Check warning on line 24 in src/Shared/AppSettings.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Scope' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}

public record AppSettings
{
public Uri AzureAppConfigUri { get; set; } = null!;
public bool UseAzureAppConfig { get; set; }
public Healthcheck Healthcheck { get; set; } = null!;
public CvPartnerConfig CvPartner { get; set; } = null!;
public VibesConfig Vibes { get; set; }

Check warning on line 33 in src/Shared/AppSettings.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Vibes' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public string FilteredUids { get; set; } = null!;
public string BemanningConnectionString { get; set; } = null!;
public BlobStorageConfig BlobStorage { get; set; } = null!;
}
24 changes: 24 additions & 0 deletions src/Shared/AzureIdentity/RefitBearerTokenHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Net.Http.Headers;

using Azure.Core;

namespace Shared.AzureIdentity;

public class RefitBearerTokenHandler : DelegatingHandler
{
private readonly TokenCredential _credential;
private readonly string _scope;

public RefitBearerTokenHandler(TokenCredential credential, string scope)
{
_credential = credential ?? throw new ArgumentNullException(nameof(credential));
_scope = scope ?? throw new ArgumentNullException(nameof(scope));
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var token = await _credential.GetTokenAsync(new TokenRequestContext(new[] { _scope }), cancellationToken);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Token);
return await base.SendAsync(request, cancellationToken);
}
}
11 changes: 5 additions & 6 deletions src/Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,13 @@
.AddJsonFile("appsettings.Local.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();


// Bind configuration "TestApp:Settings" section to the Settings object
var appSettingsSection = builder.Configuration
.GetSection("AppSettings");
var initialAppSettings = appSettingsSection.Get<AppSettings>();

if (initialAppSettings == null) throw new Exception("Unable to load app settings");


builder.Services.AddScoped<IBemanningRepository, BemanningRepository>();
builder.Services.AddScoped<BemanningRepository>();

builder.Services.AddScoped<BlobStorageService>();
builder.Services.AddScoped<IBlobStorageRepository, BlobStorageRepository>();

Expand All @@ -115,14 +110,18 @@

builder.Services.AddScoped<FilteredUids>();
builder.Services.AddScoped<CvPartnerRepository>();
builder.Services.AddScoped<VibesRepository>();

// ApplicationCore
builder.Services.AddScoped<OrchestratorService>();

// Refit
builder.Services.AddRefitClient<ICvPartnerApiClient>()
.ConfigureHttpClient(c => c.BaseAddress = initialAppSettings.CvPartner.Uri);

builder.Services.AddRefitClient<IVibesApiClient>()
.ConfigureHttpClient(c => c.BaseAddress = initialAppSettings.Vibes.BaseUri)
.AddHttpMessageHandler(() => new RefitBearerTokenHandler(new DefaultAzureCredential(), initialAppSettings.Vibes.Scope));

if (initialAppSettings.UseAzureAppConfig)
{
builder.Services.AddAzureAppConfiguration();
Expand Down
5 changes: 4 additions & 1 deletion src/Web/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
"AppSettings": {
"AzureAppConfigUri": "https://chewie-appcfg-ld2ijhpvmb34c.azconfig.io",
"UseAzureAppConfig": true,
"BemanningConnectionString": "replace_me_on_deploy",
"Vibes": {
"BaseUri": "https://vibes-backend-prod.azurewebsites.net",
"Scope": "api://480d5a12-76d8-4909-81fb-14c4898f8764/.default"
},
"CvPartner": {
"Uri": "https://variant.cvpartner.com/api",
"Token": "replace_me_on_deploy"
Expand Down
Loading

0 comments on commit cc516ec

Please sign in to comment.