Skip to content

Commit

Permalink
feat(processes): adjust retriggers
Browse files Browse the repository at this point in the history
* add missing endpoints to retrigger failed steps
* add retrigger steps and endpoints for process steps which miss a retrigger step

Refs: #912
  • Loading branch information
Phil91 authored and ntruchsess committed Sep 12, 2024
1 parent 4e3958c commit c56f530
Show file tree
Hide file tree
Showing 56 changed files with 10,485 additions and 231 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@ public interface IInvitationBusinessLogic
Task RetriggerEnableCentralIdp(Guid processId);
Task RetriggerCreateDatabaseIdp(Guid processId);
Task RetriggerInvitationCreateUser(Guid processId);
Task RetriggerAddRealmRole(Guid processId);
Task RetriggerInviteSharedClient(Guid processId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
public interface IMailBusinessLogic
{
Task SendMail(MailData mailData);
Task RetriggerSendMail(Guid processId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ public interface IServiceAccountBusinessLogic
IAsyncEnumerable<UserRoleWithDescription> GetServiceAccountRolesAsync(string? languageShortName);
Task HandleServiceAccountCreationCallback(Guid processId, AuthenticationDetail callbackData);
Task HandleServiceAccountDeletionCallback(Guid processId);
Task RetriggerDimTechnicalUser(Guid processId, ProcessStepTypeId processStepTypeId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ public interface ISubscriptionConfigurationBusinessLogic
/// <param name="offerSubscriptionId">Id of the offer subscription</param>
Task RetriggerProviderCallback(Guid offerSubscriptionId);

/// <summary>
/// Retriggers the process step
/// </summary>
/// <param name="offerSubscriptionId">Id of the offer subscription</param>
Task RetriggerCreateDimTechnicalUser(Guid offerSubscriptionId);

/// <summary>
/// Gets the process steps for the given offer subscription id
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Extensions;
using Org.Eclipse.TractusX.Portal.Backend.Processes.Library;

namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic;
Expand Down Expand Up @@ -72,40 +73,16 @@ private async Task ExecuteInvitationInternalAsync(CompanyInvitationData invitati
await _portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}

public Task RetriggerCreateCentralIdp(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_CENTRAL_IDP);
public Task RetriggerCreateSharedIdpServiceAccount(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_IDP_SERVICE_ACCOUNT);
public Task RetriggerUpdateCentralIdpUrls(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_UPDATE_CENTRAL_IDP_URLS);
public Task RetriggerCreateCentralIdpOrgMapper(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_CENTRAL_IDP_ORG_MAPPER);
public Task RetriggerCreateSharedRealmIdpClient(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_REALM);
public Task RetriggerEnableCentralIdp(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_ENABLE_CENTRAL_IDP);
public Task RetriggerCreateDatabaseIdp(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_DATABASE_IDP);
public Task RetriggerInvitationCreateUser(Guid processId) => TriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_USER);
public Task RetriggerCreateCentralIdp(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_CENTRAL_IDP.TriggerProcessStep(processId, _portalRepositories);
public Task RetriggerCreateSharedIdpServiceAccount(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_IDP_SERVICE_ACCOUNT.TriggerProcessStep(processId, _portalRepositories);
public Task RetriggerAddRealmRole(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_ADD_REALM_ROLE.TriggerProcessStep(processId, _portalRepositories);

private async Task TriggerProcessStepInternal(Guid processId, ProcessStepTypeId stepToTrigger)
{
var nextStep = stepToTrigger switch
{
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_CENTRAL_IDP => ProcessStepTypeId.INVITATION_CREATE_CENTRAL_IDP,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_IDP_SERVICE_ACCOUNT => ProcessStepTypeId.INVITATION_CREATE_SHARED_IDP_SERVICE_ACCOUNT,
ProcessStepTypeId.RETRIGGER_INVITATION_UPDATE_CENTRAL_IDP_URLS => ProcessStepTypeId.INVITATION_UPDATE_CENTRAL_IDP_URLS,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_CENTRAL_IDP_ORG_MAPPER => ProcessStepTypeId.INVITATION_CREATE_CENTRAL_IDP_ORG_MAPPER,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_REALM => ProcessStepTypeId.INVITATION_CREATE_SHARED_REALM,
ProcessStepTypeId.RETRIGGER_INVITATION_ENABLE_CENTRAL_IDP => ProcessStepTypeId.INVITATION_ENABLE_CENTRAL_IDP,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_USER => ProcessStepTypeId.INVITATION_CREATE_USER,
ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_DATABASE_IDP => ProcessStepTypeId.INVITATION_CREATE_DATABASE_IDP,
_ => throw new UnexpectedConditionException($"Step {stepToTrigger} is not retriggerable")
};

var (validProcessId, processData) = await _portalRepositories.GetInstance<IProcessStepRepository>().IsValidProcess(processId, ProcessTypeId.INVITATION, Enumerable.Repeat(stepToTrigger, 1)).ConfigureAwait(ConfigureAwaitOptions.None);
if (!validProcessId)
{
throw new NotFoundException($"process {processId} does not exist");
}

var context = processData.CreateManualProcessData(stepToTrigger, _portalRepositories, () => $"processId {processId}");
public Task RetriggerInviteSharedClient(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_CLIENT.TriggerProcessStep(processId, _portalRepositories);

context.ScheduleProcessSteps(Enumerable.Repeat(nextStep, 1));
context.FinalizeProcessStep();
await _portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}
public Task RetriggerUpdateCentralIdpUrls(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_UPDATE_CENTRAL_IDP_URLS.TriggerProcessStep(processId, _portalRepositories);
public Task RetriggerCreateCentralIdpOrgMapper(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_CENTRAL_IDP_ORG_MAPPER.TriggerProcessStep(processId, _portalRepositories);
public Task RetriggerCreateSharedRealmIdpClient(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_SHARED_REALM.TriggerProcessStep(processId, _portalRepositories);
public Task RetriggerEnableCentralIdp(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_ENABLE_CENTRAL_IDP.TriggerProcessStep(processId, _portalRepositories);
public Task RetriggerCreateDatabaseIdp(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_DATABASE_IDP.TriggerProcessStep(processId, _portalRepositories);
public Task RetriggerInvitationCreateUser(Guid processId) => ProcessStepTypeId.RETRIGGER_INVITATION_CREATE_USER.TriggerProcessStep(processId, _portalRepositories);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@
using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using Org.Eclipse.TractusX.Portal.Backend.Processes.Library;
using Org.Eclipse.TractusX.Portal.Backend.Processes.Mailing.Library;
using System.Collections.Immutable;

namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic;

public class MailBusinessLogic(IPortalRepositories portalRepositories, IMailingProcessCreation mailingProcessCreation)
public class MailBusinessLogic(
IPortalRepositories portalRepositories,
IMailingProcessCreation mailingProcessCreation)
: IMailBusinessLogic
{
private static readonly IEnumerable<string> ValidTemplates =
Expand Down Expand Up @@ -56,4 +60,6 @@ public async Task SendMail(MailData mailData)
await portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}
}

public Task RetriggerSendMail(Guid processId) => ProcessStepTypeId.RETRIGGER_SEND_MAIL.TriggerProcessStep(processId, portalRepositories);
}
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ public async Task ApproveRegistrationVerification(Guid applicationId)
applicationId,
ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION,
[ApplicationChecklistEntryStatusId.TO_DO],
ProcessStepTypeId.VERIFY_REGISTRATION,
ProcessStepTypeId.MANUAL_VERIFY_REGISTRATION,
[ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER],
[CreateWalletStep()])
.ConfigureAwait(ConfigureAwaitOptions.None);
Expand Down Expand Up @@ -516,12 +516,12 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com
applicationId,
ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION,
[ApplicationChecklistEntryStatusId.TO_DO, ApplicationChecklistEntryStatusId.DONE],
ProcessStepTypeId.DECLINE_APPLICATION,
ProcessStepTypeId.MANUAL_DECLINE_APPLICATION,
null,
[ProcessStepTypeId.VERIFY_REGISTRATION,])
[ProcessStepTypeId.MANUAL_VERIFY_REGISTRATION,])
.ConfigureAwait(ConfigureAwaitOptions.None);

checklistService.SkipProcessSteps(context, [ProcessStepTypeId.VERIFY_REGISTRATION]);
checklistService.SkipProcessSteps(context, [ProcessStepTypeId.MANUAL_VERIFY_REGISTRATION]);

var identityProviderRepository = portalRepositories.GetInstance<IIdentityProviderRepository>();
var userRepository = portalRepositories.GetInstance<IUserRepository>();
Expand Down Expand Up @@ -672,37 +672,8 @@ private async Task<Guid> GetApplicationIdByBpn(IssuerResponseData data, Cancella
return result.Single();
}

public Task RetriggerDeleteIdpSharedRealm(Guid processId) => RetriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_DELETE_IDP_SHARED_REALM);

/// <inheritdoc />
public Task RetriggerDeleteIdpSharedServiceAccount(Guid processId) => RetriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_DELETE_IDP_SHARED_SERVICEACCOUNT);

/// <inheritdoc />
public Task RetriggerDeleteCentralIdentityProvider(Guid processId) => RetriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_DELETE_CENTRAL_IDENTITY_PROVIDER);

public Task RetriggerDeleteCentralUser(Guid processId) => RetriggerProcessStepInternal(processId, ProcessStepTypeId.RETRIGGER_DELETE_CENTRAL_USER);

private async Task RetriggerProcessStepInternal(Guid processId, ProcessStepTypeId stepToTrigger)
{
var (processType, nextStep) = stepToTrigger switch
{
ProcessStepTypeId.RETRIGGER_DELETE_IDP_SHARED_REALM => (ProcessTypeId.IDENTITYPROVIDER_PROVISIONING, ProcessStepTypeId.DELETE_IDP_SHARED_REALM),
ProcessStepTypeId.RETRIGGER_DELETE_IDP_SHARED_SERVICEACCOUNT => (ProcessTypeId.IDENTITYPROVIDER_PROVISIONING, ProcessStepTypeId.DELETE_IDP_SHARED_SERVICEACCOUNT),
ProcessStepTypeId.RETRIGGER_DELETE_CENTRAL_IDENTITY_PROVIDER => (ProcessTypeId.IDENTITYPROVIDER_PROVISIONING, ProcessStepTypeId.DELETE_CENTRAL_IDENTITY_PROVIDER),
ProcessStepTypeId.RETRIGGER_DELETE_CENTRAL_USER => (ProcessTypeId.USER_PROVISIONING, ProcessStepTypeId.DELETE_CENTRAL_USER),
_ => throw new UnexpectedConditionException($"Step {stepToTrigger} is not retriggerable")
};

var (validProcessId, processData) = await portalRepositories.GetInstance<IProcessStepRepository>().IsValidProcess(processId, processType, Enumerable.Repeat(stepToTrigger, 1)).ConfigureAwait(false);
if (!validProcessId)
{
throw new NotFoundException($"process {processId} does not exist");
}

var context = processData.CreateManualProcessData(stepToTrigger, portalRepositories, () => $"processId {processId}");

context.ScheduleProcessSteps(Enumerable.Repeat(nextStep, 1));
context.FinalizeProcessStep();
await portalRepositories.SaveAsync().ConfigureAwait(false);
}
public Task RetriggerDeleteIdpSharedRealm(Guid processId) => ProcessStepTypeId.RETRIGGER_DELETE_IDP_SHARED_REALM.TriggerProcessStep(processId, portalRepositories);
public Task RetriggerDeleteIdpSharedServiceAccount(Guid processId) => ProcessStepTypeId.RETRIGGER_DELETE_IDP_SHARED_SERVICEACCOUNT.TriggerProcessStep(processId, portalRepositories);
public Task RetriggerDeleteCentralIdentityProvider(Guid processId) => ProcessStepTypeId.RETRIGGER_DELETE_CENTRAL_IDENTITY_PROVIDER.TriggerProcessStep(processId, portalRepositories);
public Task RetriggerDeleteCentralUser(Guid processId) => ProcessStepTypeId.RETRIGGER_DELETE_CENTRAL_USER.TriggerProcessStep(processId, portalRepositories);
}
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ public async Task HandleServiceAccountCreationCallback(Guid processId, Authentic

if (processData.ProcessTypeId == ProcessTypeId.OFFER_SUBSCRIPTION)
{
context.ScheduleProcessSteps([ProcessStepTypeId.TRIGGER_ACTIVATE_SUBSCRIPTION]);
context.ScheduleProcessSteps([ProcessStepTypeId.MANUAL_TRIGGER_ACTIVATE_SUBSCRIPTION]);
}
context.FinalizeProcessStep();
await portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
Expand Down Expand Up @@ -368,7 +368,7 @@ public async Task HandleServiceAccountDeletionCallback(Guid processId)
[ProcessStepTypeId.AWAIT_CREATE_DIM_TECHNICAL_USER_RESPONSE])
.ConfigureAwait(ConfigureAwaitOptions.None);

var context = processData.ProcessData.CreateManualProcessData(ProcessStepTypeId.AWAIT_DELETE_DIM_TECHNICAL_USER,
var context = processData.ProcessData.CreateManualProcessData(ProcessStepTypeId.AWAIT_DELETE_DIM_TECHNICAL_USER_RESPONSE,
portalRepositories, () => $"externalId {processId}");

portalRepositories.GetInstance<IUserRepository>().AttachAndModifyIdentity(
Expand All @@ -382,4 +382,6 @@ public async Task HandleServiceAccountDeletionCallback(Guid processId)
context.FinalizeProcessStep();
await portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}

public Task RetriggerDimTechnicalUser(Guid processId, ProcessStepTypeId processStepTypeId) => processStepTypeId.TriggerProcessStep(processId, portalRepositories);
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ public Task RetriggerCreateTechnicalUser(Guid offerSubscriptionId) =>
public Task RetriggerProviderCallback(Guid offerSubscriptionId) =>
TriggerProcessStep(offerSubscriptionId, ProcessStepTypeId.RETRIGGER_PROVIDER_CALLBACK, false);

/// <inheritdoc />
public Task RetriggerCreateDimTechnicalUser(Guid offerSubscriptionId) =>
TriggerProcessStep(offerSubscriptionId, ProcessStepTypeId.RETRIGGER_OFFERSUBSCRIPTION_CREATE_DIM_TECHNICAL_USER, true);

/// <inheritdoc />
private async Task TriggerProcessStep(Guid offerSubscriptionId, ProcessStepTypeId stepToTrigger, bool mustBePending)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,27 @@ public async Task<NoContentResult> RetriggerCreateSharedIdpServiceAccount([FromR
return NoContent();
}

/// <summary>
/// Retriggers the last failed step
/// </summary>
/// <param name="processId" example="251e4596-5ff0-4176-b544-840b04ebeb93">Id of the process that should be triggered</param>
/// <returns>NoContent</returns>
/// Example: POST: api/administration/invitation/{processId}/retrigger-add-realm-role
/// <response code="204">Empty response on success.</response>
/// <response code="404">No registration found for the externalId.</response>
[HttpPost]
[Authorize(Roles = "invite_new_partner")]
[Authorize(Policy = PolicyTypes.CompanyUser)]
[Route("{processId}/retrigger-add-realm-role")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
public async Task<NoContentResult> RetriggerAddRealmRole([FromRoute] Guid processId)
{
await _logic.RetriggerAddRealmRole(processId).ConfigureAwait(ConfigureAwaitOptions.None);
return NoContent();
}

/// <summary>
/// Retriggers the last failed step
/// </summary>
Expand Down Expand Up @@ -218,6 +239,27 @@ public async Task<NoContentResult> RetriggerCreateDatabaseIdp([FromRoute] Guid p
return NoContent();
}

/// <summary>
/// Retriggers the last failed step
/// </summary>
/// <param name="processId" example="251e4596-5ff0-4176-b544-840b04ebeb93">Id of the process that should be triggered</param>
/// <returns>NoContent</returns>
/// Example: POST: api/administration/invitation/{processId}/retrigger-invite-shared-client
/// <response code="204">Empty response on success.</response>
/// <response code="404">No registration found for the externalId.</response>
[HttpPost]
[Authorize(Roles = "invite_new_partner")]
[Authorize(Policy = PolicyTypes.CompanyUser)]
[Route("{processId}/retrigger-invite-shared-client")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
public async Task<NoContentResult> RetriggerInviteSharedClient([FromRoute] Guid processId)
{
await _logic.RetriggerInviteSharedClient(processId).ConfigureAwait(ConfigureAwaitOptions.None);
return NoContent();
}

/// <summary>
/// Retriggers the last failed step
/// </summary>
Expand Down
Loading

0 comments on commit c56f530

Please sign in to comment.