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

Cors 2075 new saga le sa #394

Merged
merged 34 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6e596c4
CORS-2074: new restructured model for LE and SA for new bootstrap engine
minasharifi Nov 21, 2023
eae8971
CORS-2074: new restructured model for LE and SA for new bootstrap engine
minasharifi Nov 22, 2023
3687047
CORS-2074: new restructured model for LE and SA for new bootstrap engine
minasharifi Nov 22, 2023
cca966e
CORS-2074: new restructured model for LE and SA for new bootstrap engine
minasharifi Nov 23, 2023
ca75e81
CORS-2075: added new LE saga class
minasharifi Nov 24, 2023
bc3191f
CORS-2075: added new LE saga class
minasharifi Nov 27, 2023
e4a32f3
CORS-2075: added new LE saga class
minasharifi Nov 28, 2023
809e1c4
CORS-2075: added new LE saga class
minasharifi Nov 29, 2023
1f7510e
CORS-2139 - add mappers for LegalEntityV2 and ServiceAgreementV2 to m…
olenac87 Nov 29, 2023
14ba83b
Merge remote-tracking branch 'origin/CORS-2075-new-saga-LE-SA' into C…
olenac87 Nov 29, 2023
d4ed4ac
CORS-2139 - add mappers for LegalEntityV2 and ServiceAgreementV2 to m…
olenac87 Nov 29, 2023
fba1daa
CORS-2139 - add mappers for LegalEntityV2 and ServiceAgreementV2 to m…
olenac87 Nov 29, 2023
e11cfdb
CORS-2075: added new LE saga class
minasharifi Nov 30, 2023
3fcf7c8
CORS-2075: added new LE saga class
minasharifi Nov 30, 2023
2bd3dba
CORS-2075: added new LE saga class
minasharifi Nov 30, 2023
41756c6
CORS-2139 - fix MSA creating in ServiceAgreementSagaV2
olenac87 Nov 30, 2023
531fd92
Merge remote-tracking branch 'origin/CORS-2075-new-saga-LE-SA' into C…
olenac87 Nov 30, 2023
909ac46
CORS-2075: added new LE saga class
minasharifi Nov 30, 2023
5504637
CORS-2075: fixed some small things in SA saga
minasharifi Dec 1, 2023
d5dd83f
CORS-2139 - add ServiceAgreementSagaV2Test
olenac87 Dec 4, 2023
d221b97
Merge remote-tracking branch 'origin/CORS-2075-new-saga-LE-SA' into C…
olenac87 Dec 4, 2023
6319928
CORS-2075: fixed some small things in SA saga
minasharifi Dec 4, 2023
5d98dfd
CORS-2139 - amendments to ServiceAgreementSagaV2
olenac87 Dec 6, 2023
dafffe4
CORS-2139 - fix tests for ServiceAgreementSagaV2
olenac87 Dec 7, 2023
c82917e
CORS-2075: used SA saga in LE new saga
minasharifi Dec 8, 2023
c70d0e5
Merge remote-tracking branch 'origin/CORS-2075-new-saga-LE-SA' into C…
minasharifi Dec 8, 2023
9bbf14b
CORS-2139 - move jobProfileUsers to SA level instead of participants …
olenac87 Dec 11, 2023
375f379
CORS-2075: fixed SA saga issues
minasharifi Dec 14, 2023
7a4a98f
CORS-2075: removed SA saga in LE saga
minasharifi Dec 15, 2023
d2bbc4c
Merge remote-tracking branch 'origin/master' into CORS-2075-new-saga-…
minasharifi Jan 2, 2024
a550bc1
CORS-2075: fixed changelog file
minasharifi Jan 2, 2024
b3160a3
CORS-2075: remove unused methods and imports
minasharifi Jan 2, 2024
3eca0dd
CORS-2075: added more info in the changelog
minasharifi Jan 2, 2024
47a575a
CORS-2075: added more info in the changelog
minasharifi Jan 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog
All notable changes to this project will be documented in this file.

## [3.71.0](https://github.com/Backbase/stream-services/compare/3.70.0...3.71.0)
### Added
- Added new models for LE and SA to cover requirements in the new bootstrap. In the new structure, LE supports just master service agreement and custom service agreement has been dropped. Product groups, limits, job profile users, reference job roles, contacts were moved from LE to new SA model. In the new bootstrap, LE and SA are now separated and can be defined in the different JSON files and independently ingested.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good! Just a reminder that limits can be ingested at different levels, you can have SA limits, LE limits and User limits, so removing it from the LE model will create limitations on the saga.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@uesleilima you're right, just removed the limits in the changelog. we have limits for both new SA and LE


## [3.70.0](https://github.com/Backbase/stream-services/compare/3.69.0...3.70.0)
### Added
- Support to Events via Azure Service Bus for the Stream Composition Services
Expand Down
149 changes: 148 additions & 1 deletion api/stream-legal-entity/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ openapi: 3.0.1
info:
title: Ingest Legal Entity API
description: Ingestion Saga for Legal Entities and their products
version: 2.3.2
version: 2.4.0
x-logo:
url: "http://www.backbase.com/wp-content/uploads/2017/04/backbase-logo-png.png"
backgroundColor: "#FFFFFF"
Expand Down Expand Up @@ -1132,6 +1132,69 @@ components:
- legalEntityType
- administrators
- jobProfile

LegalEntityV2:
title: Legal Entity v2
description: |
(This Legal Entity is the restructured one)
A Legal Entity is any personal or non-personal entity that is involved in a transaction or an product with the bank. Both the bank and its customers are legal entities

A Legal Entity:
* Has one or more users that act on its behalf.
* A legal entity hierarchy is a collection of parent-child relationships. For example, within the same deployment, this allows you to:
* Set up a holding structure for a corporate customer of the bank.
* Set up a structure within the bank to support country and regional offices.
type: object
properties:
name:
type: string
activateSingleServiceAgreement:
type: boolean
internalId:
$ref: '#/components/schemas/InternalIdentifier'
externalId:
$ref: '#/components/schemas/ExternalIdentifier'
legalEntityType:
$ref: '#/components/schemas/LegalEntityType'
customerCategory:
$ref: '#/components/schemas/CustomerCategory'
realmName:
type: string
description: Realm to which the Legal Entity should be mapped.
parentExternalId:
$ref: '#/components/schemas/ExternalIdentifier'
parentInternalId:
$ref: '#/components/schemas/InternalIdentifier'
subsidiaries:
type: array
items:
$ref: '#/components/schemas/LegalEntityV2'
limit:
$ref: '#/components/schemas/Limit'
administrators:
type: array
items:
$ref: '#/components/schemas/User'
users:
type: array
items:
$ref: '#/components/schemas/User'
masterServiceAgreement:
$ref: '#/components/schemas/ServiceAgreementV2'
contacts:
type: array
items:
$ref: '#/components/schemas/ExternalContact'
additions:
type: object
additionalProperties:
type: string
required:
- name
- external
- legalEntityType
- administrators

JobProfileUser:
type: object
properties:
Expand Down Expand Up @@ -1607,6 +1670,89 @@ components:
type: object
additionalProperties:
type: string

ServiceAgreementV2:
title: Service Agreement
description: |
The formal vehicle that allows users of one entity to access products of that or other entities
A Service agreement is:
- A contract that includes one or more legal entities. A legal entity that is participating in a service agreement can allow a subset of its users to act through that service agreement and/or allow a subset of its products to be accessed through the service agreement. Within each service agreement, permissions to perform specific tasks are granted to users, including access to products shared by one or more legal entities (participating in that service agreement). As such, a service agreement is a way to give third party users specific access to your products.
- A special kind of service agreement is called the master service agreement. This service agreement has one legal entity participant and once configured, the participant cannot be changed. Important to know is that once the user is granted with administrative permissions (e.g. manage account groups), he or she has the power to execute the task in any service agreement lower in the hierarchy. For example, if the user of the bank is assigned with manage account groups permission in the master service agreement of the bank, the user can manage account groups in any service agreement lower in the hierarchy.
- A service agreement may be restricted in time, by setting a time bound. Permissions granted to users in the time-restricted service agreement, are active and may be consumed, only while the time bound is valid.
properties:
internalId:
$ref: '#/components/schemas/InternalIdentifier'
externalId:
$ref: '#/components/schemas/ExternalIdentifier'
name:
maxLength: 128
minLength: 1
pattern: ^\S(.*(\S))?$
type: string
description: The service agreement name
description:
maxLength: 255
minLength: 1
pattern: ^(\S|\n)((.|\n)*(\S|\n))?$
type: string
description: Description
jobProfileUsers:
type: array
items:
$ref: '#/components/schemas/JobProfileUser'
participants:
type: array
description: Participants of the service agreement
items:
$ref: '#/components/schemas/LegalEntityParticipant'
validFromDate:
type: string
format: date
description: Start date of the service agreement.
validFromTime:
type: string
description: Start time of the service agreement.
validUntilDate:
type: string
format: date
description: End date of the service agreement.
validUntilTime:
type: string
description: End time of the service agreement.
status:
$ref: '#/components/schemas/LegalEntityStatus'
isMaster:
type: boolean
description: Master flag
regularUserAps:
$ref: '#/components/schemas/ApsIdentifiers'
adminUserAps:
$ref: '#/components/schemas/ApsIdentifiers'
jobRoles:
type: array
items:
$ref: '#/components/schemas/JobRole'
referenceJobRoles:
type: array
items:
$ref: '#/components/schemas/ReferenceJobRole'
creatorLegalEntity:
$ref: '#/components/schemas/ExternalIdentifier'
limit:
$ref: '#/components/schemas/Limit'
contacts:
type: array
items:
$ref: '#/components/schemas/ExternalContact'
productGroups:
type: array
items:
$ref: "#/components/schemas/ProductGroup"
additions:
type: object
additionalProperties:
type: string

ApsIdentifiers:
type: object
properties:
Expand Down Expand Up @@ -1652,6 +1798,7 @@ components:
- "REMOVE"
limit:
$ref: '#/components/schemas/Limit'

LegalEntityStatus:
type: string
description: Status of the entity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.backbase.stream.legalentity.model.LegalEntityParticipant;
import com.backbase.stream.legalentity.model.Privilege;
import com.backbase.stream.legalentity.model.ServiceAgreement;
import com.backbase.stream.legalentity.model.ServiceAgreementV2;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
Expand All @@ -29,6 +30,9 @@ public interface AccessGroupMapper {
@Mapping(source = "id", target = "internalId")
ServiceAgreement toStream(ServiceAgreementItemQuery getServiceAgreement);

@Mapping(source = "id", target = "internalId")
ServiceAgreementV2 toStreamV2(ServiceAgreementItemQuery getServiceAgreement);

@Mapping(source = "id", target = "internalId")
ServiceAgreement toStream(ServiceAgreementItem serviceAgreementItem);

Expand All @@ -37,6 +41,9 @@ public interface AccessGroupMapper {
@Mapping(source = "participants", target = "participantsToIngest")
ServicesAgreementIngest toPresentation(ServiceAgreement serviceAgreement);

@Mapping(source = "participants", target = "participantsToIngest")
ServicesAgreementIngest toPresentation(ServiceAgreementV2 serviceAgreement);

ServiceAgreementPut toPresentationPut(ServiceAgreement serviceAgreement);

// Initialize users list to workaround https://backbase.atlassian.net/browse/MAINT-10442
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import com.backbase.dbs.accesscontrol.api.service.v3.model.LegalEntityPut;
import com.backbase.dbs.accesscontrol.api.service.v3.model.LegalEntityType;
import com.backbase.stream.legalentity.model.LegalEntity;
import com.backbase.stream.legalentity.model.LegalEntityV2;
import com.backbase.stream.legalentity.model.ServiceAgreement;
import com.backbase.stream.legalentity.model.ServiceAgreementV2;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

Expand All @@ -18,15 +20,27 @@ public interface LegalEntityMapper {
@Mapping(source = "legalEntityType", target = "type")
LegalEntityCreateItem toPresentation(LegalEntity legalEntity);

@Mapping(source = "legalEntityType", target = "type")
LegalEntityCreateItem toPresentation(LegalEntityV2 legalEntity);

@Mapping(source = "type", target = "legalEntityType")
@Mapping(source = "id", target = "internalId")
LegalEntity toStream(LegalEntityItemBase legalEntityItemBase);

@Mapping(source = "type", target = "legalEntityType")
@Mapping(source = "id", target = "internalId")
LegalEntityV2 toStreamV2(LegalEntityItemBase legalEntityItemBase);

@Mapping(source = "type", target = "legalEntityType")
@Mapping(source = "id", target = "internalId")
@Mapping(source = "parentId", target = "parentInternalId")
LegalEntity toStream(LegalEntityItem legalEntityItem);

@Mapping(source = "type", target = "legalEntityType")
@Mapping(source = "id", target = "internalId")
@Mapping(source = "parentId", target = "parentInternalId")
LegalEntityV2 toStreamV2(LegalEntityItem legalEntityItem);

com.backbase.stream.legalentity.model.LegalEntityType map(LegalEntityType legalEntityType);

@Mapping(source = "type", target = "legalEntityType")
Expand All @@ -35,6 +49,9 @@ public interface LegalEntityMapper {
@Mapping(source = "id", target = "internalId")
ServiceAgreement toStream(GetServiceAgreement getServiceAgreement);

@Mapping(source = "id", target = "internalId")
ServiceAgreementV2 toStreamV2(GetServiceAgreement getServiceAgreement);

@Mapping(source = "additions", target = "newValues.additions")
@Mapping(source = "externalId", target = "newValues.externalId")
@Mapping(source = "name", target = "newValues.name")
Expand All @@ -44,4 +61,14 @@ public interface LegalEntityMapper {
@Mapping(source = "activateSingleServiceAgreement", target = "newValues.activateSingleServiceAgreement")
@Mapping(source = "externalId", target = "currentExternalId")
LegalEntityPut toLegalEntityPut(LegalEntity legalEntity);

@Mapping(source = "additions", target = "newValues.additions")
@Mapping(source = "externalId", target = "newValues.externalId")
@Mapping(source = "name", target = "newValues.name")
@Mapping(source = "legalEntityType", target = "newValues.type")
@Mapping(source = "customerCategory", target = "newValues.customerCategory")
@Mapping(source = "parentExternalId", target = "newValues.parentExternalId")
@Mapping(source = "activateSingleServiceAgreement", target = "newValues.activateSingleServiceAgreement")
@Mapping(source = "externalId", target = "currentExternalId")
LegalEntityPut toLegalEntityPut(LegalEntityV2 legalEntity);
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import com.backbase.stream.legalentity.model.ReferenceJobRole;
import com.backbase.stream.legalentity.model.ServiceAgreement;
import com.backbase.stream.legalentity.model.ServiceAgreementUserAction;
import com.backbase.stream.legalentity.model.ServiceAgreementV2;
import com.backbase.stream.legalentity.model.User;
import com.backbase.stream.mapper.AccessGroupMapper;
import com.backbase.stream.mapper.ParticipantMapper;
Expand Down Expand Up @@ -455,6 +456,14 @@ private BiFunction<IdItem, ServiceAgreement, ServiceAgreement> storeIdInServiceA
};
}

private BiFunction<IdItem, ServiceAgreementV2, ServiceAgreementV2> storeIdInServiceAgreementV2() {
return (idItem, serviceAgreement1) -> {
serviceAgreement1.setInternalId(idItem.getId());
log.info("Created Service Agreement: {} with id: {}", serviceAgreement1.getName(), idItem.getId());
return serviceAgreement1;
};
}

public Mono<LegalEntity> setAdministrators(LegalEntity legalEntity) {

List<PresentationServiceAgreementUserPair> userPairs = legalEntity.getAdministrators().stream().map(user -> {
Expand Down Expand Up @@ -537,9 +546,9 @@ public Mono<BatchProductGroupTask> assignPermissionsBatch(BatchProductGroupTask
.dataGroupIdentifiers(
usersPermissions.get(user).get(bfg).stream()
.map(pg -> mapDataGroupId(pg.getInternalId()))
.collect(Collectors.toList())))
.collect(Collectors.toList())))
.collect(Collectors.toList());
.toList()))
.toList()))
.toList();

return Mono.just(request)
.flatMap(userPermissionsRequest -> {
Expand Down Expand Up @@ -1086,6 +1095,38 @@ public Mono<Void> deleteAdmins(ServiceAgreement serviceAgreement) {
});
}

public Mono<Void> deleteAdmins(ServiceAgreementV2 serviceAgreement) {
log.debug("Removing admins for Service Agreement {}", serviceAgreement.getName());
return serviceAgreementsApi.getServiceAgreementAdmins(serviceAgreement.getInternalId())
.flatMapMany(admins -> Flux.fromIterable(admins.getAdmins()))
// get External ID for each admin.
// We need to get the user by using the internal id to facilitate the delete for issue #46
.flatMap(userId -> usersApi.getUserById(userId, true)).map(GetUser::getExternalId)
.collectList()
.doOnNext(adminIds -> log.debug("Found admins: {}", adminIds))
.map(adminsExternalIds -> adminsExternalIds.stream()
.map(adminId -> new PresentationServiceAgreementUserPair()
.externalServiceAgreementId(serviceAgreement.getExternalId())
.externalUserId(adminId))
.collect(Collectors.toList()))
.flatMap(admins -> {
if (CollectionUtils.isEmpty(admins)) {
return Mono.empty();
} else {
return serviceAgreementsApi.putPresentationServiceAgreementAdminsBatchUpdate(
new PresentationServiceAgreementUsersBatchUpdate()
.action(PresentationAction.REMOVE)
.users(admins))
.map(r -> batchResponseUtils.checkBatchResponseItem(r, "Delete Admin", r.getStatus().getValue(), r.getResourceId(), r.getErrors()))
.collectList()
.onErrorResume(WebClientResponseException.class, e -> {
log.error("Failed to delete admin: {}", e.getResponseBodyAsString(), e);
return Mono.error(e);
}).then();
}
});
}

/**
* Get internal identifiers of all arrangements mentioned in all Data Groups for specified Service Agreement.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,4 @@ public Mono<LegalEntity> putLegalEntity(LegalEntity legalEntity) {
.onErrorStop()
.then(getLegalEntityByExternalId(legalEntityPut.getNewValues().getExternalId()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class LegalEntityMapperTest {

@Test
void toPresentationWithNullArg() {
assertNull(mapper.toPresentation(null));
assertNull(mapper.toPresentation((LegalEntity) null));
}

@Test
Expand Down Expand Up @@ -174,7 +174,7 @@ void toStreamFromGetServiceAgreementShouldCopyAllAttributes() {

@Test
void testToLegalEntityPutWithNullArg() {
assertNull(mapper.toLegalEntityPut(null));
assertNull(mapper.toLegalEntityPut((LegalEntity) null));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ public LegalEntitySaga(LegalEntityService legalEntityService,
UserService userService,
UserProfileService userProfileService,
AccessGroupService accessGroupService,
ProductIngestionSaga productIngestionSaga,
BatchProductIngestionSaga batchProductIngestionSaga,
LimitsSaga limitsSaga,
ContactsSaga contactsSaga,
Expand Down
Loading
Loading