Skip to content

Commit

Permalink
chore: adjust process worker workflow (#276)
Browse files Browse the repository at this point in the history
* fix(n2n): create process steps on submit
* feat(n2n): move submit endpoint to registration service
* chore: adjust copyright header
---------
Refs: CPLP-3197
Co-authored-by: Norbert Truchsess <[email protected]>
Reviewed-by: Norbert Truchsess <[email protected]>
  • Loading branch information
Phil91 authored Oct 10, 2023
1 parent 502bbae commit 8caaca3
Show file tree
Hide file tree
Showing 18 changed files with 829 additions and 519 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/********************************************************************************
* Copyright (c) 2021, 2023 BMW Group AG
* Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
Expand All @@ -26,7 +25,5 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLog
public interface INetworkBusinessLogic
{
Task HandlePartnerRegistration(PartnerRegistrationData data);

Task RetriggerProcessStep(Guid externalId, ProcessStepTypeId processStepTypeId);
Task Submit(PartnerSubmitData submitData, CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/********************************************************************************
* Copyright (c) 2021, 2023 BMW Group AG
* Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
Expand Down Expand Up @@ -33,7 +32,6 @@
using Org.Eclipse.TractusX.Portal.Backend.Processes.NetworkRegistration.Library;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Models;
using Org.Eclipse.TractusX.Portal.Backend.Provisioning.Library.Service;
using System.Collections.Immutable;
using System.Text.RegularExpressions;

namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.BusinessLogic;
Expand Down Expand Up @@ -307,72 +305,4 @@ private static void ValidateUsers(UserDetailData user)
throw new ControllerArgumentException("Lastname does not match expected format");
}
}

public async Task Submit(PartnerSubmitData submitData, CancellationToken cancellationToken)
{
var companyId = _identityService.IdentityData.CompanyId;
var userId = _identityService.IdentityData.UserId;
var userRoleIds = await _portalRepositories.GetInstance<IUserRolesRepository>()
.GetUserRoleIdsUntrackedAsync(_settings.InitialRoles)
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
var data = await _portalRepositories.GetInstance<INetworkRepository>()
.GetSubmitData(companyId, userId, userRoleIds)
.ConfigureAwait(false);
if (!data.Exists)
{
throw new NotFoundException($"Company {companyId} not found");
}

if (!data.IsUserInRole)
{
throw new ForbiddenException($"User must be in role {string.Join(",", _settings.InitialRoles.SelectMany(x => x.UserRoleNames))}");
}

if (data.CompanyApplications.Count() != 1)
{
throw new ConflictException($"Company {companyId} has no or more than one application");
}

if (data.ProcessId == null)
{
throw new ConflictException("There must be an process");
}

var companyApplication = data.CompanyApplications.Single();
if (companyApplication.CompanyApplicationStatusId != CompanyApplicationStatusId.CREATED)
{
throw new ConflictException($"Application {companyApplication.CompanyApplicationId} is not in state CREATED");
}

submitData.Agreements.Where(x => x.ConsentStatusId != ConsentStatusId.ACTIVE).IfAny(inactive =>
throw new ControllerArgumentException($"All agreements must be agreed to. Agreements that are not active: {string.Join(",", inactive.Select(x => x.AgreementId))}", nameof(submitData.Agreements)));

data.CompanyRoleAgreementIds
.ExceptBy(submitData.CompanyRoles, x => x.CompanyRoleId)
.IfAny(missing =>
throw new ControllerArgumentException($"CompanyRoles {string.Join(",", missing.Select(x => x.CompanyRoleId))} are missing", nameof(submitData.CompanyRoles)));

var requiredAgreementIds = data.CompanyRoleAgreementIds
.SelectMany(x => x.AgreementIds)
.Distinct().ToImmutableList();

requiredAgreementIds.Except(submitData.Agreements.Where(x => x.ConsentStatusId == ConsentStatusId.ACTIVE).Select(x => x.AgreementId))
.IfAny(missing =>
throw new ControllerArgumentException($"All Agreements for the company roles must be agreed to, missing agreementIds: {string.Join(",", missing)}", nameof(submitData.Agreements)));

_portalRepositories.GetInstance<IConsentRepository>()
.CreateConsents(requiredAgreementIds.Select(agreementId => (agreementId, companyId, userId, ConsentStatusId.ACTIVE)));

var processId = _portalRepositories.GetInstance<IProcessStepRepository>().CreateProcess(ProcessTypeId.APPLICATION_CHECKLIST).Id;
_portalRepositories.GetInstance<IApplicationRepository>().AttachAndModifyCompanyApplication(companyApplication.CompanyApplicationId,
ca =>
{
ca.ApplicationStatusId = CompanyApplicationStatusId.SUBMITTED;
ca.ChecklistProcessId = processId;
});
_portalRepositories.GetInstance<IProcessStepRepository>().CreateProcessStepRange(Enumerable.Repeat(new ValueTuple<ProcessStepTypeId, ProcessStepStatusId, Guid>(ProcessStepTypeId.TRIGGER_CALLBACK_OSP_SUBMITTED, ProcessStepStatusId.TODO, data.ProcessId.Value), 1));

await _portalRepositories.SaveAsync().ConfigureAwait(false);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/********************************************************************************
* Copyright (c) 2021, 2023 BMW Group AG
* Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
Expand Down Expand Up @@ -70,7 +69,7 @@ public async Task<OkResult> PartnerRegister([FromBody] PartnerRegistrationData d
/// <response code="204">Empty response on success.</response>
/// <response code="404">No registration found for the externalId.</response>
[HttpPost]
//[Authorize(Roles = "tbd")]
[Authorize(Roles = "approve_new_partner")]
[Authorize(Policy = PolicyTypes.CompanyUser)]
[Route("{externalId}/retrigger-synchronize-users")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
Expand All @@ -82,28 +81,6 @@ public async Task<NoContentResult> RetriggerSynchronizeUser([FromRoute] Guid ext
return NoContent();
}

/// <summary>
/// Submits the application
/// </summary>
/// <param name="data">The agreements for the companyRoles</param>
/// <param name="cancellationToken">Cancellation Token</param>
/// <returns>NoContent</returns>
/// Example: POST: api/administration/registration/network/partnerRegistration/submit
/// <response code="204">Empty response on success.</response>
/// <response code="404">No registration found for the externalId.</response>
[HttpPost]
[Authorize(Roles = "submit_registration")]
[Authorize(Policy = PolicyTypes.CompanyUser)]
[Route("partnerRegistration/submit")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
public async Task<NoContentResult> Submit([FromBody] PartnerSubmitData data, CancellationToken cancellationToken)
{
await _logic.Submit(data, cancellationToken).ConfigureAwait(false);
return NoContent();
}

/// <summary>
/// Retriggers the last failed step
/// </summary>
Expand All @@ -113,7 +90,7 @@ public async Task<NoContentResult> Submit([FromBody] PartnerSubmitData data, Can
/// <response code="204">Empty response on success.</response>
/// <response code="404">No registration found for the externalId.</response>
[HttpPost]
//[Authorize(Roles = "tbd")]
[Authorize(Roles = "approve_new_partner")]
[Authorize(Policy = PolicyTypes.CompanyUser)]
[Route("{externalId}/retrigger-callback-osp-approve")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
Expand Down Expand Up @@ -155,7 +132,7 @@ public async Task<NoContentResult> RetriggerCallbackOspDecline([FromRoute] Guid
/// <response code="204">Empty response on success.</response>
/// <response code="404">No registration found for the externalId.</response>
[HttpPost]
//[Authorize(Roles = "tbd")]
[Authorize(Roles = "approve_new_partner")]
[Authorize(Policy = PolicyTypes.CompanyUser)]
[Route("{externalId}/retrigger-callback-osp-submitted")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ public interface INetworkRepository
Task<bool> CheckExternalIdExists(Guid externalId, Guid onboardingServiceProviderId);
Task<Guid> GetNetworkRegistrationDataForProcessIdAsync(Guid processId);
Task<(bool RegistrationIdExists, VerifyProcessData processData)> IsValidRegistration(Guid externalId, IEnumerable<ProcessStepTypeId> processStepTypeIds);
Task<(bool Exists, IEnumerable<(Guid CompanyApplicationId, CompanyApplicationStatusId CompanyApplicationStatusId, string? CallbackUrl)> CompanyApplications, bool IsUserInRole, IEnumerable<(CompanyRoleId CompanyRoleId, IEnumerable<Guid> AgreementIds)> CompanyRoleAgreementIds, Guid? ProcessId)> GetSubmitData(Guid companyId, Guid userId, IEnumerable<Guid> roleIds);
Task<(bool Exists, IEnumerable<(Guid CompanyApplicationId, CompanyApplicationStatusId CompanyApplicationStatusId, string? CallbackUrl)> CompanyApplications, IEnumerable<(CompanyRoleId CompanyRoleId, IEnumerable<Guid> AgreementIds)> CompanyRoleAgreementIds, Guid? ProcessId)> GetSubmitData(Guid companyId);
Task<(OspDetails? OspDetails, Guid? ExternalId, string? Bpn, Guid ApplicationId, IEnumerable<string> Comments)> GetCallbackData(Guid networkRegistrationId, ProcessStepTypeId processStepTypeId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,18 @@ public Task<Guid> GetNetworkRegistrationDataForProcessIdAsync(Guid processId) =>
))
.SingleOrDefaultAsync();

public Task<(bool Exists, IEnumerable<(Guid CompanyApplicationId, CompanyApplicationStatusId CompanyApplicationStatusId, string? CallbackUrl)> CompanyApplications, bool IsUserInRole, IEnumerable<(CompanyRoleId CompanyRoleId, IEnumerable<Guid> AgreementIds)> CompanyRoleAgreementIds, Guid? ProcessId)> GetSubmitData(Guid companyId, Guid userId, IEnumerable<Guid> roleIds) =>
public Task<(bool Exists, IEnumerable<(Guid CompanyApplicationId, CompanyApplicationStatusId CompanyApplicationStatusId, string? CallbackUrl)> CompanyApplications, IEnumerable<(CompanyRoleId CompanyRoleId, IEnumerable<Guid> AgreementIds)> CompanyRoleAgreementIds, Guid? ProcessId)> GetSubmitData(Guid companyId) =>
_context.Companies
.AsSplitQuery()
.Where(x => x.Id == companyId)
.Select(x => new ValueTuple<bool, IEnumerable<(Guid, CompanyApplicationStatusId, string?)>, bool, IEnumerable<(CompanyRoleId, IEnumerable<Guid>)>, Guid?>(
.Select(x => new ValueTuple<bool, IEnumerable<(Guid, CompanyApplicationStatusId, string?)>, IEnumerable<(CompanyRoleId, IEnumerable<Guid>)>, Guid?>(
true,
x.CompanyApplications
.Where(ca => ca.CompanyApplicationTypeId == CompanyApplicationTypeId.EXTERNAL)
.Select(ca => new ValueTuple<Guid, CompanyApplicationStatusId, string?>(
ca.Id,
ca.ApplicationStatusId,
ca.OnboardingServiceProvider!.OnboardingServiceProviderDetail!.CallbackUrl)),
x.Identities
.Any(i => i.Id == userId && i.IdentityAssignedRoles.Any(roles => roleIds.Any(r => r == roles.UserRoleId))),
x.CompanyAssignedRoles.Select(assigned => new ValueTuple<CompanyRoleId, IEnumerable<Guid>>(
assigned.CompanyRoleId,
assigned.CompanyRole!.AgreementAssignedCompanyRoles.Select(a => a.AgreementId))),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,16 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Processes.ApplicationChecklist.Con

public static class ApplicationChecklistExtensions
{
public static IServiceCollection AddApplicationChecklist(this IServiceCollection services, IConfigurationSection section)
{
return services
public static IServiceCollection AddApplicationChecklist(this IServiceCollection services, IConfigurationSection section) =>
services
.AddTransient<ITokenService, TokenService>()
.AddTransient<IApplicationChecklistService, ApplicationChecklistService>()
.AddBpdmService(section.GetSection("Bpdm"))
.AddCustodianService(section.GetSection("Custodian"))
.AddClearinghouseService(section.GetSection("Clearinghouse"))
.AddSdFactoryService(section.GetSection("SdFactory"));
}

public static IServiceCollection AddApplicationChecklistCreation(this IServiceCollection services)
{
return services
public static IServiceCollection AddApplicationChecklistCreation(this IServiceCollection services) =>
services
.AddTransient<IApplicationChecklistCreationService, ApplicationChecklistCreationService>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/********************************************************************************
* Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Org.Eclipse.TractusX.Portal.Backend.Registration.Service.Model;

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

public interface INetworkBusinessLogic
{
Task Submit(PartnerSubmitData submitData, CancellationToken cancellationToken);
}
Loading

0 comments on commit 8caaca3

Please sign in to comment.