Skip to content

Commit

Permalink
[MODCONSKC-21] - Implement sharing of role capabilities (#87)
Browse files Browse the repository at this point in the history
* [MODCONSKC-21] - Implement sharing of role capabilities

* Fix unit test

* Fix descriptor for role-capabilities endpoint

* Refactored Duplicate unit tests

* Remove custom query, rely on spring jpa

* Fix method names

* Remove duplication

* Update diagram for Sharing Role

* Minor update

* Fix variable name
  • Loading branch information
azizbekxm authored Aug 30, 2024
1 parent 39e949b commit 670041c
Show file tree
Hide file tree
Showing 37 changed files with 1,331 additions and 970 deletions.
47 changes: 45 additions & 2 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@
{
"id": "policies",
"version": "1.1"
},
{
"id": "role-capability-sets",
"version": "1.1"
},
{
"id": "role-capabilities",
"version": "1.0"
}
],
"optional": [
Expand Down Expand Up @@ -408,6 +416,26 @@
"consortia.sharing-roles-capability-sets.item.delete"
],
"modulePermissions": []
},
{
"methods": [
"POST"
],
"pathPattern": "/consortia/{consortiumId}/sharing/roles/capabilities",
"permissionsRequired": [
"consortia.sharing-roles-capabilities.item.post"
],
"modulePermissions": []
},
{
"methods": [
"DELETE"
],
"pathPattern": "/consortia/{consortiumId}/sharing/roles/{roleId}/capabilities",
"permissionsRequired": [
"consortia.sharing-roles-capabilities.item.delete"
],
"modulePermissions": []
}
]
},
Expand Down Expand Up @@ -486,7 +514,9 @@
"consortia.sharing-roles.item.post",
"consortia.sharing-roles.item.delete",
"consortia.sharing-roles-capability-sets.item.post",
"consortia.sharing-roles-capability-sets.item.delete"
"consortia.sharing-roles-capability-sets.item.delete",
"consortia.sharing-roles-capabilities.item.post",
"consortia.sharing-roles-capabilities.item.delete"
]
},
{
Expand Down Expand Up @@ -651,6 +681,16 @@
"permissionName": "consortia.sharing-roles-capability-sets.item.delete",
"displayName": "delete sharing role capability sets",
"description": "Delete sharing role capability sets"
},
{
"permissionName": "consortia.sharing-roles-capabilities.item.post",
"displayName": "post sharing role capabilities",
"description": "Create sharing role capabilities"
},
{
"permissionName": "consortia.sharing-roles-capabilities.item.delete",
"displayName": "delete sharing role capabilities",
"description": "Delete sharing role capabilities"
}
],
"metadata": {
Expand Down Expand Up @@ -762,7 +802,10 @@
"policies.item.delete",
"role-capabilities.collection.post",
"role-capabilities.collection.put",
"role-capabilities.collection.delete"
"role-capabilities.collection.delete",
"role-capability-sets.collection.post",
"role-capability-sets.collection.put",
"role-capability-sets.collection.delete"
]
}
},
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ participant "mod-roles-keycloak" as mrk

user -> mck: Initiate deleting role capability sets action
note right
DELETE /consortia/<consortiumId>/sharing/role-capability-sets/<roleId>
DELETE /consortia/<consortiumId>/sharing/roles/<roleId>/capability-sets
{
"roleId": "<UUID>",
"url": "string"
}
end note
activate mck

mck -> mck_db: Retrieve tenants associated with the roleId from role_capability_sets table using is_capability_sets_shared flag true
mck -> mck_db: Retrieve tenants associated with the roleId from sharing_role table using is_capability_sets_shared flag true
note bottom
| tenant_id | role_id | is_capability_sets_shared |
| "tenant A" | <UUID1> | true |
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ participant "mod-roles-keycloak" as mrk

user -> mck: Initiate sharing role capability sets action
note right
POST /consortia/<consortiumId>/sharing/role-capability-sets
POST /consortia/<consortiumId>/sharing/roles/capability-sets
{
"roleId": "<UUID>",
"url": "string",
Expand All @@ -27,7 +27,7 @@ POST /consortia/<consortiumId>/sharing/role-capability-sets
end note
activate mck

mck -> mck_db: Retrieve tenants associated with the roleId from role_capability_sets table using is_capability_sets_shared flag true
mck -> mck_db: Retrieve tenants associated with the roleId from sharing_role table using is_capability_sets_shared flag true
note bottom
| tenant_id | role_id | is_capability_sets_shared |
| "tenant A" | <UUID1> | true |
Expand Down
61 changes: 61 additions & 0 deletions docs/sharing-feature-sequence-dagram/sharing-role-delete.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
@startuml

!pragma teoz true
!theme cerulean

autonumber

actor "user" as user

participant "mod-consortia-keycloak" as mck
database "mod-consortia-keycloak DB" as mck_db
participant "mod-consortia-publish-coordinator" as mc_pc
participant "mod-login-keycloak" as ml
participant "mod-roles-keycloak" as mrk

user -> mck: Initiate deleting role action
note right
DELETE /consortia/<consortiumId>/sharing/roles/<roleId>
{
"roleId": "<UUID>",
"url": "string"
}
end note
activate mck

mck -> mck_db: Retrieve tenants associated with the roleId from sharing_role table using roleId
note bottom
| tenant_id | role_id |
| "tenant A" | <UUID1> |
end note
note right
| tenant_id | role_id |
| "tenant A" | <UUID1> |
| "tenant B" | <UUID2> |
end note

loop tenants where role is exists
mck -> mck: Add tenant to DELETE Role Publish Coordinator tenants list
end

mck -> mck_db: Remove record with "roleId" and "tenant A" variables

mck -> ml: Login via consortia-system-user
ml --> mck: Return system user's token

mck -> mc_pc: Initiate PC request with DELETE HTTP method to delete a role
mc_pc -> mrk: Send HTTP DELETE request to delete role
mrk --> mc_pc: Return response
mc_pc --> mck: Return Publish Coordinator id

mck --> user: Return response with PC id
note right
Response payload:
{
"deleteRolePCId": "<UUID>"
}
end note

user -> mck: Check if DELETE PC completed: /consortia/<UUID>/publications/<UUID>

@enduml
82 changes: 82 additions & 0 deletions docs/sharing-feature-sequence-dagram/sharing-role-start.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
@startuml

!pragma teoz true
!theme cerulean

autonumber

actor "user" as user

participant "mod-consortia-keycloak" as mck
database "mod-consortia-keycloak DB" as mck_db
participant "mod-consortia-publish-coordinator" as mc_pc
participant "mod-login-keycloak" as ml
participant "mod-roles-keycloak" as mrk

user -> mck: Initiate sharing role action
note right
POST /consortia/<consortiumId>/sharing/roles
{
"roleId": "<UUID>",
"url": "string",
"payload": {
"id": "<UUID>",
"name": "<String>",
"description": "<String>"
}
}
end note
activate mck

mck -> mck_db: Retrieve tenants associated with the roleId from sharing_role table
note bottom
| tenant_id | role_id |
| "tenant A" | <UUID1> |
end note
note right
| tenant_id | role_id |
| "tenant A" | <UUID1> |
end note
mck -> mck_db: Retrieve all tenants list

loop tenants size count
alt #E8F3E1 tenant id does not exist in role_capability_sets table
mck -> mck: Add tenant to POST Role Publish Coordinator tenants list
mck -> mck_db: Create new entity
note right
| tenant_id | role_id |
| "tenant B" | <UUID2> |
end note
else #F3E1E2 tenant id exists
mck -> mck: Add tenant to PUT Role Publish Coordinator tenants list
end
end

mck -> mck: Set source as Consortium for all role (Create and Update)

mck -> ml: Login via consortia-system-user
ml --> mck: Return system user's token

mck -> mc_pc: Initiate PC request with POST HTTP method to create role
mc_pc -> mrk: Send HTTP POST request to create role
mrk --> mc_pc: Return response
mc_pc --> mck: Return Publish Coordinator id

mck -> mc_pc: Initiate PC request with PUT HTTP method to update role
mc_pc -> mrk: Send HTTP POST request to create role
mrk --> mc_pc: Return response
mc_pc --> mck: Return Publish Coordinator id

mck --> user: Return response with both PC ids
note right
Response payload:
{
"createRolePCId": "<UUID>",
"updateRolePCId": "<UUID>"
}
end note

user -> mck: Check if POST PC completed: /consortia/<UUID>/publications/<UUID>
user -> mck: Check if PUT PC completed: /consortia/<UUID>/publications/<UUID>

@enduml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.folio.consortia.controller;

import lombok.RequiredArgsConstructor;
import org.folio.consortia.domain.dto.SharingRoleCapabilityDeleteResponse;
import org.folio.consortia.domain.dto.SharingRoleCapabilityRequest;
import org.folio.consortia.domain.dto.SharingRoleCapabilityResponse;
import org.folio.consortia.rest.resource.RoleCapabilitiesApi;
import org.folio.consortia.service.impl.SharingRoleCapabilityService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.OK;

@RestController
@RequestMapping("/consortia/{consortiumId}/sharing")
@RequiredArgsConstructor
public class SharingRoleCapabilityController implements RoleCapabilitiesApi {

private final SharingRoleCapabilityService sharingRoleCapabilityService;

@Override
public ResponseEntity<SharingRoleCapabilityResponse> startSharingRoleCapabilities(UUID consortiumId,
SharingRoleCapabilityRequest request) {
return ResponseEntity
.status(CREATED)
.body(sharingRoleCapabilityService.start(consortiumId, request));
}

@Override
public ResponseEntity<SharingRoleCapabilityDeleteResponse> deleteSharingRoleCapabilities(UUID consortiumId,
UUID roleId,
SharingRoleCapabilityRequest request) {
return ResponseEntity
.status(OK)
.body(sharingRoleCapabilityService.delete(consortiumId, roleId, request));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ public interface SharingRoleRepository extends JpaRepository<SharingRoleEntity,
@Query("SELECT sr.tenantId FROM SharingRoleEntity sr WHERE sr.roleId = ?1")
Set<String> findTenantsByRoleId(UUID roleId);

@Query("SELECT sr.tenantId FROM SharingRoleEntity sr " +
"WHERE sr.roleId = ?1 AND sr.isCapabilitySetsShared = true")
Set<String> findTenantsByRoleIdAndSharedCapabilitySets(UUID roleId);
Set<String> findTenantsByRoleIdAndIsCapabilitySetsSharedTrue(UUID roleId);

Set<String> findTenantsByRoleIdAndIsCapabilitiesSharedTrue(UUID roleId);

boolean existsByRoleId(UUID roleId);

@Modifying
@Query("DELETE FROM SharingRoleEntity sr WHERE sr.roleId = ?1")
void deleteByRoleId(UUID roleId);
}
21 changes: 15 additions & 6 deletions src/main/java/org/folio/consortia/service/BaseSharingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
import static org.folio.spring.scope.FolioExecutionScopeExecutionContextManager.getRunnableWithCurrentFolioContext;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
Expand Down Expand Up @@ -68,8 +68,8 @@ public TResponse start(UUID consortiumId, TRequest sharingConfigRequest) {
Set<String> sharingConfigTenants = findTenantsForConfig(sharingConfigRequest);
TenantCollection allTenants = tenantService.getAll(consortiumId);

var publicationPostRequest = createPublicationRequest(sharingConfigRequest, HttpMethod.POST.toString());
var publicationPutRequest = createPublicationRequest(sharingConfigRequest, HttpMethod.PUT.toString());
var publicationPostRequest = createPublicationRequest(sharingConfigRequest, HttpMethod.POST);
var publicationPutRequest = createPublicationRequest(sharingConfigRequest, HttpMethod.PUT);

List<TEntity> sharingConfigEntityList = linkTenantsToPublicationPutPostRequestAndEntity(allTenants,
sharingConfigRequest, sharingConfigTenants, publicationPutRequest, publicationPostRequest);
Expand Down Expand Up @@ -104,7 +104,7 @@ public TDeleteResponse delete(UUID consortiumId, UUID configId, TRequest sharing

Set<String> sharingConfigTenants = findTenantsForConfig(sharingConfigRequest);
TenantCollection allTenants = tenantService.getAll(consortiumId);
var publicationDeleteRequest = createPublicationRequest(sharingConfigRequest, HttpMethod.DELETE.toString());
var publicationDeleteRequest = createPublicationRequest(sharingConfigRequest, HttpMethod.DELETE);
linkTenantsToPublicationDeleteRequest(allTenants, sharingConfigRequest, sharingConfigTenants, publicationDeleteRequest);
log.info("delete:: Tenants with size: {} successfully added to appropriate DELETE publication " +
"request for {}: {}", allTenants.getTotalRecords(), configName, configId);
Expand Down Expand Up @@ -273,7 +273,7 @@ private void updateFailedConfigsToLocalSource(UUID consortiumId, TRequest sharin
failedTenantList.size(), getClassName(sharingConfigRequest));
ObjectNode updatedPayload = updatePayload(sharingConfigRequest, SourceValues.USER.getValue());

PublicationRequest publicationPutRequest = createPublicationRequest(sharingConfigRequest, HttpMethod.PUT.toString());
PublicationRequest publicationPutRequest = createPublicationRequest(sharingConfigRequest, HttpMethod.PUT);
publicationPutRequest.setPayload(updatedPayload);
publicationPutRequest.setTenants(failedTenantList);

Expand All @@ -282,16 +282,25 @@ private void updateFailedConfigsToLocalSource(UUID consortiumId, TRequest sharin
publishRequest(consortiumId, publicationPutRequest);
}

private PublicationRequest createPublicationRequest(TRequest sharingConfigRequest, HttpMethod method) {
String urlForRequest = getUrl(sharingConfigRequest, method);
return new PublicationRequest()
.method(method.toString())
.url(urlForRequest)
.payload(getPayload(sharingConfigRequest))
.tenants(new HashSet<>());
}

protected abstract UUID getConfigId(TRequest sharingConfigRequest);
protected abstract Object getPayload(TRequest sharingConfigRequest);
protected abstract String getPayloadId(ObjectNode payload);
protected abstract String getUrl(TRequest sharingConfigRequest, HttpMethod httpMethod);
protected abstract void validateSharingConfigRequestOrThrow(UUID configId, TRequest sharingConfigRequest);

protected abstract Set<String> findTenantsForConfig(TRequest request);
protected abstract void saveSharingConfig(List<TEntity> sharingConfigEntityList);
protected abstract void deleteSharingConfig(UUID configId);

protected abstract PublicationRequest createPublicationRequest(TRequest sharingConfigRequest, String httpMethod);
protected abstract TEntity createSharingConfigEntityFromRequest(TRequest sharingConfigRequest, String tenantId);
protected abstract TResponse createSharingConfigResponse(UUID createConfigsPcId, UUID updateConfigsPcId);
protected abstract TDeleteResponse createSharingConfigResponse(UUID publishRequestId);
Expand Down
Loading

0 comments on commit 670041c

Please sign in to comment.