-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add ops console + ticket console + first input-output result
* feat: add skeleton * chore: code skeleton * refactor: program * refactor: processing records in console * feat: add ticket.console * chore: don't write header record when file exists * chore: add api key + log failed actions * chore: add input-output context --------- Co-authored-by: ArneD <[email protected]>
- Loading branch information
Showing
18 changed files
with
693 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
namespace Ops.Console | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Net.Http; | ||
using IdentityModel; | ||
using IdentityModel.Client; | ||
using Microsoft.Extensions.Configuration; | ||
|
||
public sealed class AcmIdmService | ||
{ | ||
private static readonly object LockObject = new object(); | ||
private static AcmIdmService? _instance = null; | ||
|
||
private const string RequiredScopes = | ||
"dv_ar_adres_beheer dv_ar_adres_uitzonderingen dv_gr_geschetstgebouw_beheer dv_gr_geschetstgebouw_uitzonderingen dv_gr_ingemetengebouw_uitzonderingen"; | ||
|
||
private readonly string? _tokenEndpoint; | ||
private readonly string? _clientId; | ||
private readonly string? _clientSecret; | ||
|
||
private AccessToken? _accessToken; | ||
|
||
private AcmIdmService(IConfiguration configuration) | ||
{ | ||
_clientId = configuration.GetSection("AuthOptions").GetValue<string>("ClientId"); | ||
_clientSecret = configuration.GetSection("AuthOptions").GetValue<string>("ClientSecret"); | ||
_tokenEndpoint = configuration.GetSection("AuthOptions").GetValue<string>("TokenEndpoint"); | ||
} | ||
|
||
public static AcmIdmService GetInstance(IConfiguration configuration) | ||
{ | ||
if (_instance == null) | ||
{ | ||
lock (LockObject) | ||
{ | ||
if (_instance == null) | ||
{ | ||
_instance = new AcmIdmService(configuration); | ||
} | ||
} | ||
} | ||
|
||
return _instance; | ||
} | ||
|
||
public string GetAccessToken() | ||
{ | ||
lock (LockObject) | ||
{ | ||
if (_accessToken is not null && !_accessToken.IsExpired) | ||
{ | ||
return _accessToken.Token; | ||
} | ||
|
||
var tokenClient = new TokenClient( | ||
() => new HttpClient(), | ||
new TokenClientOptions | ||
{ | ||
Address = _tokenEndpoint, | ||
ClientId = _clientId!, | ||
ClientSecret = _clientSecret, | ||
Parameters = new Parameters(new[] { new KeyValuePair<string, string>("scope", RequiredScopes) }) | ||
}); | ||
|
||
var response = tokenClient.RequestTokenAsync(OidcConstants.GrantTypes.ClientCredentials).GetAwaiter().GetResult(); | ||
|
||
_accessToken = new AccessToken(response.AccessToken!, response.ExpiresIn); | ||
|
||
return _accessToken.Token; | ||
} | ||
} | ||
|
||
private sealed class AccessToken | ||
{ | ||
private readonly DateTime _expiresAt; | ||
|
||
public string Token { get; } | ||
|
||
// Let's regard it as expired 10 seconds before it actually expires. | ||
public bool IsExpired => _expiresAt < DateTime.Now.Add(TimeSpan.FromSeconds(10)); | ||
|
||
public AccessToken(string token, int expiresIn) | ||
{ | ||
_expiresAt = DateTime.Now.AddSeconds(expiresIn); | ||
Token = token; | ||
} | ||
} | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
|
||
# Gebouweenheden status incorrect tegenover gebouw | ||
|
||
https://vlaamseoverheid.atlassian.net/browse/GAWR-6413 | ||
|
||
## Context | ||
We hebben twee problemen gedetecteerd die niet werden opgelost bij migratie vanuit CRAB. | ||
|
||
1. Er waren gebouweenheden met status `gerealiseerd`, maar het gebouw had nog (maar) status `gepland` of `inAanbouw`. | ||
|
||
``` | ||
select bu.BuildingUnitPersistentLocalId As Id from [building-registry].buildingregistrylegacy.BuildingDetailsV2 b | ||
inner join [building-registry].BuildingRegistryLegacy.BuildingUnitDetailsV2 bu on b.PersistentLocalId = bu.BuildingPersistentLocalId | ||
where b.Status in ('Planned', 'UnderConstruction') and bu.Status in ('Realized') and bu.IsRemoved = 0 and bu.[Function] = 'Unknown' | ||
``` | ||
|
||
2. Er waren gebouweenheden met status `gepland` of `gerealiseerd` in een `nietGerealiseerd` gebouw. | ||
|
||
``` | ||
select bu.BuildingUnitPersistentLocalId As Id from [building-registry].buildingregistrylegacy.BuildingDetailsV2 b | ||
inner join [building-registry].BuildingRegistryLegacy.BuildingUnitDetailsV2 bu on b.PersistentLocalId = bu.BuildingPersistentLocalId | ||
where b.Status in ('NotRealized') and bu.Status in ('Realized', 'Planned') and bu.IsRemoved = 0 and bu.[Function] = 'Unknown' | ||
``` | ||
|
||
## Oplossing probleem 1 | ||
|
||
Gebouweenheden met status `gerealiseerd` corrigeren naar `gepland`. | ||
|
||
* input_prd_gerealiseerd_naar_gepland.csv | ||
* output_prd_gerealiseerd_naar_gepland.csv | ||
|
||
## Oplossing probleem 2 | ||
|
||
Gebouweenheden met status `gerealiseerd` corrigeren naar `gepland`. | ||
|
||
Daarna gebouweenheden met status `gepland` niet-realiseren. | ||
|
||
* input_prd_gerealiseerd_naar_gepland_naar_nietGerealiseerd.csv | ||
* output_prd_gerealiseerd_naar_gepland_naar_nietGerealiseerd_stap1.csv | ||
* output_prd_gerealiseerd_naar_gepland_naar_nietGerealiseerd_stap2.csv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace Ops.Console | ||
{ | ||
using CsvHelper.Configuration; | ||
|
||
public sealed class InputRecord | ||
{ | ||
public string Id { get; init; } | ||
|
||
protected InputRecord() | ||
{ } | ||
} | ||
|
||
public sealed class InputRecordMap : ClassMap<InputRecord> | ||
{ | ||
public InputRecordMap() | ||
{ | ||
Map(m => m.Id).Name("Id"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<Import Project="..\..\packages\Be.Vlaanderen.Basisregisters.Build.Pipeline\Content\Be.Vlaanderen.Basisregisters.Build.Pipeline.Settings.App.props" /> | ||
|
||
<PropertyGroup> | ||
<!-- Error NETSDK1152: https://docs.microsoft.com/en-us/dotnet/core/compatibility/sdk/6.0/duplicate-files-in-output --> | ||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles> | ||
<ServerGarbageCollection>true</ServerGarbageCollection> | ||
<EnableDefaultContentItems>false</EnableDefaultContentItems> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Content Include="appsettings.json" CopyToOutputDirectory="Always" /> | ||
<Content Include="appsettings.*.json" CopyToOutputDirectory="Always" /> | ||
</ItemGroup> | ||
|
||
<Import Project="..\..\.paket\Paket.Restore.targets" /> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
namespace Ops.Console | ||
{ | ||
using CsvHelper.Configuration; | ||
|
||
public sealed class ProcessedRecord | ||
{ | ||
public string Id { get; init; } | ||
public string TicketUrl { get; init; } | ||
|
||
protected ProcessedRecord() | ||
{ | ||
} | ||
|
||
public ProcessedRecord(string id, string ticketUrl) | ||
{ | ||
Id = id; | ||
TicketUrl = ticketUrl; | ||
} | ||
} | ||
|
||
public sealed class ProcessedRecordMap : ClassMap<ProcessedRecord> | ||
{ | ||
public ProcessedRecordMap() | ||
{ | ||
Map(m => m.Id).Name("Id"); | ||
Map(m => m.TicketUrl).Name("Ticket"); | ||
} | ||
} | ||
} |
Oops, something went wrong.