Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/kitosudv 3312 subscriptions flag #849

Merged
merged 15 commits into from
Nov 21, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ public class StsOrganizationSynchronizationDetails
public bool CanUpdateConnection { get; }
public bool CanDeleteConnection { get; }
public CheckConnectionError? CheckConnectionError { get; }
public bool SubscribesToUpdates { get; }

public StsOrganizationSynchronizationDetails(bool connected, int? synchronizationDepth, bool canCreateConnection, bool canUpdateConnection, bool canDeleteConnection, CheckConnectionError? checkConnectionError)
public StsOrganizationSynchronizationDetails(bool connected, int? synchronizationDepth, bool canCreateConnection, bool canUpdateConnection, bool canDeleteConnection, CheckConnectionError? checkConnectionError, bool subscribesToUpdates)
{
Connected = connected;
SynchronizationDepth = synchronizationDepth;
CanCreateConnection = canCreateConnection;
CanUpdateConnection = canUpdateConnection;
CanDeleteConnection = canDeleteConnection;
CheckConnectionError = checkConnectionError;
SubscribesToUpdates = subscribesToUpdates;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ public interface IStsOrganizationSynchronizationService
/// <param name="levelsToInclude"></param>
/// <returns></returns>
Result<ExternalOrganizationUnit, OperationError> GetStsOrganizationalHierarchy(Guid organizationId, Maybe<int> levelsToInclude);

/// <summary>
/// Connect the organization to "STS Organisation"
/// </summary>
/// <param name="organizationId"></param>
/// <param name="levelsToInclude"></param>
/// <returns></returns>
Maybe<OperationError> Connect(Guid organizationId, Maybe<int> levelsToInclude);
Maybe<OperationError> Connect(Guid organizationId, Maybe<int> levelsToInclude, bool subscribeToUpdates);
/// <summary>
/// Disconnect the KITOS organization from STS Organisation
/// </summary>
Expand All @@ -43,9 +42,7 @@ public interface IStsOrganizationSynchronizationService
/// <summary>
/// Updates the connection to the STS Organization
/// </summary>
/// <param name="organizationId"></param>
/// <param name="levelsToInclude"></param>
/// <returns></returns>
Maybe<OperationError> UpdateConnection(Guid organizationId, Maybe<int> levelsToInclude);
Maybe<OperationError> UpdateConnection(Guid organizationId, Maybe<int> levelsToInclude, bool subscribeToUpdates);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public Result<StsOrganizationSynchronizationDetails, OperationError> GetSynchron
{
var currentConnectionStatus = ValidateConnection(organization);
var isConnected = organization.StsOrganizationConnection?.Connected == true;
var subscribesToUpdates = organization.StsOrganizationConnection?.SubscribeToUpdates == true;
var canCreateConnection = currentConnectionStatus.IsNone && organization.StsOrganizationConnection?.Connected != true;
var canUpdateConnection = currentConnectionStatus.IsNone && isConnected;
return new StsOrganizationSynchronizationDetails
Expand All @@ -65,7 +66,8 @@ public Result<StsOrganizationSynchronizationDetails, OperationError> GetSynchron
canCreateConnection,
canUpdateConnection,
isConnected,
currentConnectionStatus.Match(error => error.Detail, () => default(CheckConnectionError?))
currentConnectionStatus.Match(error => error.Detail, () => default(CheckConnectionError?)),
subscribesToUpdates
);
});
}
Expand All @@ -83,7 +85,7 @@ public Result<ExternalOrganizationUnit, OperationError> GetStsOrganizationalHier
.Bind(root => FilterByRequestedLevels(root, levelsToInclude));
}

public Maybe<OperationError> Connect(Guid organizationId, Maybe<int> levelsToInclude)
public Maybe<OperationError> Connect(Guid organizationId, Maybe<int> levelsToInclude, bool subscribeToUpdates)
{
return Modify(organizationId, organization =>
{
Expand All @@ -92,7 +94,7 @@ public Maybe<OperationError> Connect(Guid organizationId, Maybe<int> levelsToInc
(
importRoot =>
{
var error = organization.ConnectToExternalOrganizationHierarchy(OrganizationUnitOrigin.STS_Organisation, importRoot, levelsToInclude);
var error = organization.ConnectToExternalOrganizationHierarchy(OrganizationUnitOrigin.STS_Organisation, importRoot, levelsToInclude, subscribeToUpdates);
if (error.HasValue)
{
_logger.Error("Failed to import org root {rootId} and subtree into organization with id {orgId}. Failed with: {errorCode}:{errorMessage}", importRoot.Uuid, organization.Id, error.Value.FailureType, error.Value.Message.GetValueOrFallback(""));
Expand Down Expand Up @@ -138,11 +140,11 @@ public Result<OrganizationTreeUpdateConsequences, OperationError> GetConnectionE
);
}

public Maybe<OperationError> UpdateConnection(Guid organizationId, Maybe<int> levelsToInclude)
public Maybe<OperationError> UpdateConnection(Guid organizationId, Maybe<int> levelsToInclude, bool subscribeToUpdates)
{
return Modify(organizationId, organization =>
LoadOrganizationUnits(organization)
.Bind(importRoot => organization.UpdateConnectionToExternalOrganizationHierarchy(OrganizationUnitOrigin.STS_Organisation, importRoot, levelsToInclude))
.Bind(importRoot => organization.UpdateConnectionToExternalOrganizationHierarchy(OrganizationUnitOrigin.STS_Organisation, importRoot, levelsToInclude, subscribeToUpdates))
.Select(consequences =>
{
if (consequences.DeletedExternalUnitsBeingDeleted.Any())
Expand Down
14 changes: 12 additions & 2 deletions Core.DomainModel/Organization/Organization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,11 @@ public Result<OrganizationTreeUpdateConsequences, OperationError> ComputeExterna
return strategy.ComputeUpdate(filteredTree);
}

public Maybe<OperationError> ConnectToExternalOrganizationHierarchy(OrganizationUnitOrigin origin, ExternalOrganizationUnit root, Maybe<int> levelsIncluded)
public Maybe<OperationError> ConnectToExternalOrganizationHierarchy(
OrganizationUnitOrigin origin,
ExternalOrganizationUnit root,
Maybe<int> levelsIncluded,
bool subscribeToUpdates)
{
if (root == null)
{
Expand Down Expand Up @@ -258,6 +262,7 @@ public Maybe<OperationError> ConnectToExternalOrganizationHierarchy(Organization
{
StsOrganizationConnection ??= new StsOrganizationConnection();
StsOrganizationConnection.Connected = true;
StsOrganizationConnection.SubscribeToUpdates = subscribeToUpdates;
StsOrganizationConnection.SynchronizationDepth = levelsIncluded.Match(levels => (int?)levels, () => default);
return Maybe<OperationError>.None;
}
Expand All @@ -282,7 +287,11 @@ public Result<DisconnectOrganizationFromOriginResult, OperationError> Disconnect
}
}

public Result<OrganizationTreeUpdateConsequences, OperationError> UpdateConnectionToExternalOrganizationHierarchy(OrganizationUnitOrigin origin, ExternalOrganizationUnit root, Maybe<int> levelsIncluded)
public Result<OrganizationTreeUpdateConsequences, OperationError> UpdateConnectionToExternalOrganizationHierarchy(
OrganizationUnitOrigin origin,
ExternalOrganizationUnit root,
Maybe<int> levelsIncluded,
bool subscribeToUpdates)
{
if (root == null) throw new ArgumentNullException(nameof(root));

Expand All @@ -306,6 +315,7 @@ public Result<OrganizationTreeUpdateConsequences, OperationError> UpdateConnecti
var childLevelsToInclude = levelsIncluded.Select(levels => levels - 1); //subtract the root level before copying
var filteredTree = root.Copy(childLevelsToInclude);
StsOrganizationConnection.SynchronizationDepth = levelsIncluded.Match(levels => (int?)levels, () => default);
StsOrganizationConnection.SubscribeToUpdates = subscribeToUpdates;

return strategy.PerformUpdate(filteredTree);
}
Expand Down
4 changes: 3 additions & 1 deletion Core.DomainModel/Organization/StsOrganizationConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ public class StsOrganizationConnection : Entity, IOwnedByOrganization
/// Determines the optional synchronization depth used during synchronization from STS Organisation
/// </summary>
public int? SynchronizationDepth { get; set; }

public bool SubscribeToUpdates { get; set; }
//TODO https://os2web.atlassian.net/browse/KITOSUDV-3317 adds the change logs here
//TODO: https://os2web.atlassian.net/browse/KITOSUDV-3312 adds automatic subscription here
public DisconnectOrganizationFromOriginResult Disconnect()
{
var organizationUnits = Organization.OrgUnits.Where(x => x.Origin == OrganizationUnitOrigin.STS_Organisation).ToList();
organizationUnits.ForEach(unit => unit.ConvertToNativeKitosUnit());

Connected = false;
SubscribeToUpdates = false;
SynchronizationDepth = null;
return new DisconnectOrganizationFromOriginResult(organizationUnits);
}
Expand Down
7 changes: 7 additions & 0 deletions Infrastructure.DataAccess/Infrastructure.DataAccess.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,10 @@
<Compile Include="Migrations\202210271249212_Removed_Delegated_SystemUsages.designer.cs">
<DependentUpon>202210271249212_Removed_Delegated_SystemUsages.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\202211181038597_Added_sts_subscription_flag.cs" />
<Compile Include="Migrations\202211181038597_Added_sts_subscription_flag.designer.cs">
<DependentUpon>202211181038597_Added_sts_subscription_flag.cs</DependentUpon>
</Compile>
<Compile Include="Migrations\Configuration.cs" />
<Compile Include="Mapping\TerminationDeadlineTypeMap.cs" />
<Content Include="Migrations\SQLScripts\Manually run scripts to fix staging DB\Delete_Users_Other_Than_Preserved_Users.sql" />
Expand Down Expand Up @@ -1595,6 +1599,9 @@
<EmbeddedResource Include="Migrations\202210271249212_Removed_Delegated_SystemUsages.resx">
<DependentUpon>202210271249212_Removed_Delegated_SystemUsages.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Migrations\202211181038597_Added_sts_subscription_flag.resx">
<DependentUpon>202211181038597_Added_sts_subscription_flag.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Migrations\SQLScripts\Migrate_Contract_Relations.sql" />
<EmbeddedResource Include="Migrations\SQLScripts\Migrate_System_Url.sql" />
<EmbeddedResource Include="Migrations\SQLScripts\Remove_ReadOnly_Role.sql" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public StsOrganizationConnectionMap()
Property(x => x.Connected)
.IsRequired()
.HasIndexAnnotation("IX_Connected");

Property(x => x.SubscribeToUpdates)
.IsRequired()
.HasIndexAnnotation("IX_Required");
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Infrastructure.DataAccess.Migrations
{
using System;
using System.Data.Entity.Migrations;

public partial class Added_sts_subscription_flag : DbMigration
{
public override void Up()
{
AddColumn("dbo.StsOrganizationConnections", "SubscribeToUpdates", c => c.Boolean(nullable: false));
CreateIndex("dbo.StsOrganizationConnections", "SubscribeToUpdates", name: "IX_Required");
}

public override void Down()
{
DropIndex("dbo.StsOrganizationConnections", "IX_Required");
DropColumn("dbo.StsOrganizationConnections", "SubscribeToUpdates");
}
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public HttpResponseMessage GetSynchronizationStatus(Guid organizationId)
.Select(details => new StsOrganizationSynchronizationDetailsResponseDTO
{
Connected = details.Connected,
SubscribesToUpdates = details.SubscribesToUpdates,
SynchronizationDepth = details.SynchronizationDepth,
CanCreateConnection = details.CanCreateConnection,
CanDeleteConnection = details.CanDeleteConnection,
Expand All @@ -64,8 +65,13 @@ public HttpResponseMessage CreateConnection(Guid organizationId, [FromBody] Conn
return BadRequest(ModelState);
}

if (request == null)
{
return BadRequest("Invalid request body");
}

return _stsOrganizationSynchronizationService
.Connect(organizationId, (request?.SynchronizationDepth).FromNullableValueType())
.Connect(organizationId, (request?.SynchronizationDepth).FromNullableValueType(), request.SubscribeToUpdates.GetValueOrDefault(false))
.Match(FromOperationError, Ok);
}

Expand Down Expand Up @@ -102,8 +108,13 @@ public HttpResponseMessage UpdateConnection(Guid organizationId, [FromBody] Conn
return BadRequest(ModelState);
}

if (request == null)
{
return BadRequest("Invalid request body");
}

return _stsOrganizationSynchronizationService
.UpdateConnection(organizationId, (request?.SynchronizationDepth).FromNullableValueType())
.UpdateConnection(organizationId, (request?.SynchronizationDepth).FromNullableValueType(), request.SubscribeToUpdates.GetValueOrDefault(false))
.Match(FromOperationError, Ok);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ public class ConnectToStsOrganizationRequestDTO
{
[Range(1, int.MaxValue)]
public int? SynchronizationDepth { get; set; }
public bool? SubscribeToUpdates { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public class StsOrganizationSynchronizationDetailsResponseDTO
{
public StsOrganizationAccessStatusResponseDTO AccessStatus { get; set; }
public bool Connected { get; set; }
public bool SubscribesToUpdates { get; set; }
public int? SynchronizationDepth { get; set; }
public bool CanCreateConnection { get; set; }
public bool CanUpdateConnection { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
}

export interface IFKOrganisationImportDialogFactory {
open(flow: FKOrganisationImportFlow, organizationUuid: string, synchronizationDepth: number | null): ng.ui.bootstrap.IModalInstanceService
open(flow: FKOrganisationImportFlow, organizationUuid: string, synchronizationDepth: number | null, subscribesToUpdates: boolean): ng.ui.bootstrap.IModalInstanceService
}

export class FKOrganisationImportDialogFactory implements IFKOrganisationImportDialogFactory {
static $inject = ["$uibModal"];
constructor(private readonly $uibModal: ng.ui.bootstrap.IModalService) { }

open(flow: FKOrganisationImportFlow, organizationUuid: string, synchronizationDepth: number | null): ng.ui.bootstrap.IModalInstanceService {
open(flow: FKOrganisationImportFlow, organizationUuid: string, synchronizationDepth: number | null, subscribesToUpdates: boolean): ng.ui.bootstrap.IModalInstanceService {
return this.$uibModal.open({
windowClass: "modal fade in wide-modal",
templateUrl: "app/components/local-config/import/fk-organization-import-config-import-modal.view.html",
Expand All @@ -21,29 +21,33 @@
resolve: {
"flow": [() => flow],
"orgUuid": [() => organizationUuid],
"synchronizationDepth": [() => synchronizationDepth]
"synchronizationDepth": [() => synchronizationDepth],
"subscribesToUpdates": [() => subscribesToUpdates]
},
backdrop: "static", //Make sure accidental click outside the modal does not close it during the import process
});
}
}

class FKOrganisationImportController {
static $inject = ["flow", "orgUuid", "synchronizationDepth", "stsOrganizationSyncService", "$uibModalInstance", "notify"];
static $inject = ["flow", "orgUuid", "synchronizationDepth", "subscribesToUpdates", "stsOrganizationSyncService", "$uibModalInstance", "notify"];
isConsequencesCollapsed: boolean = false;
isHierarchyCollapsed: boolean = false;
busy: boolean = false;
updating: boolean = false;
loadingHierarchy: boolean | null;
subscribesToUpdates: boolean = false;
consequencesAwaitingApproval: Array<Models.Api.Organization.ConnectionUpdateOrganizationUnitConsequenceDTO> | null = null;
fkOrgHierarchy: Kitos.Shared.Components.Organization.IOrganizationTreeComponentOptions | null = null;
constructor(
readonly flow: FKOrganisationImportFlow,
private readonly organizationUuid: string,
initialImportDepth: number | null,
subscribesToUpdates: boolean,
private readonly stsOrganizationSyncService: Services.Organization.IStsOrganizationSyncService,
private readonly $uibModalInstance: ng.ui.bootstrap.IModalServiceInstance,
private readonly notify) {
this.subscribesToUpdates = subscribesToUpdates;
this.fkOrgHierarchy = {
availableLevels: initialImportDepth,
root: null
Expand Down Expand Up @@ -102,11 +106,11 @@
}

private performUpdate() {

this.updating = true;
this.busy = true;

return this.stsOrganizationSyncService.updateConnection(this.organizationUuid, this.fkOrgHierarchy.availableLevels)
return this.stsOrganizationSyncService.updateConnection(this.organizationUuid, this.fkOrgHierarchy.availableLevels, this.subscribesToUpdates)
.then(() => {
this.closeDialog();
}, error => {
Expand All @@ -119,7 +123,7 @@

private createConnection() {
this.stsOrganizationSyncService
.createConnection(this.organizationUuid, this.fkOrgHierarchy.availableLevels)
.createConnection(this.organizationUuid, this.fkOrgHierarchy.availableLevels, this.subscribesToUpdates)
.then(() => {
this.closeDialog();
}, error => {
Expand Down
Loading