Skip to content

Commit

Permalink
Merge branch 'master' into MODCON-81
Browse files Browse the repository at this point in the history
  • Loading branch information
SinghAdes authored Aug 7, 2023
2 parents a350b8d + 2e4945b commit 88449fc
Show file tree
Hide file tree
Showing 15 changed files with 269 additions and 45 deletions.
20 changes: 18 additions & 2 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,16 @@
"consortia.sharing-settings.item.post"
],
"modulePermissions": []
},
{
"methods": [
"DELETE"
],
"pathPattern": "/consortia/{consortiumId}/sharing/settings/{settingId}",
"permissionsRequired": [
"consortia.sharing-settings.item.delete"
],
"modulePermissions": []
}
]
},
Expand Down Expand Up @@ -361,7 +371,8 @@
"consortia.publications.item.get",
"consortia.publications.item.delete",
"consortia.publications-results.item.get",
"consortia.sharing-settings.item.post"
"consortia.sharing-settings.item.post",
"consortia.sharing-settings.item.delete"
]
},
{
Expand Down Expand Up @@ -467,7 +478,12 @@
{
"permissionName": "consortia.sharing-settings.item.post",
"displayName": "post sharing setting",
"description": "create sharing setting"
"description": "Create sharing setting"
},
{
"permissionName": "consortia.sharing-settings.item.delete",
"displayName": "delete sharing setting",
"description": "Delete sharing setting"
}
],
"launchDescriptor": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.util.UUID;

import org.folio.consortia.domain.dto.SharingSettingDeleteResponse;
import org.folio.consortia.domain.dto.SharingSettingRequest;
import org.folio.consortia.domain.dto.SharingSettingResponse;
import org.folio.consortia.rest.resource.SettingsApi;
Expand All @@ -25,4 +26,10 @@ public class SharingSettingController implements SettingsApi {
public ResponseEntity<SharingSettingResponse> startSharingSetting(UUID consortiumId, SharingSettingRequest sharingSettingRequest) {
return ResponseEntity.status(CREATED).body(sharingSettingService.start(consortiumId, sharingSettingRequest));
}

@Override
public ResponseEntity<SharingSettingDeleteResponse> deleteSharingSetting(UUID consortiumId, UUID settingId,
SharingSettingRequest sharingSettingRequest) {
return ResponseEntity.ok(sharingSettingService.delete(consortiumId, settingId, sharingSettingRequest));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@

import org.folio.consortia.domain.entity.SharingSettingEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

@Repository
public interface SharingSettingRepository extends JpaRepository<SharingSettingEntity, UUID>{
@Query("SELECT st.tenantId FROM SharingSettingEntity st WHERE st.settingId = ?1")
Set<String> findTenantsBySettingId(UUID settingId);

boolean existsBySettingId(UUID settingId);

@Modifying
@Query("DELETE FROM SharingSettingEntity st where st.settingId = ?1")
void deleteBySettingId(UUID settingId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ public PublicationHttpResponse performRequest(String url, HttpMethod httpMethod,
var absUrl = folioExecutionContext.getOkapiUrl() + url;
log.debug("performRequest:: folio context header TENANT = {}" , folioExecutionContext.getOkapiHeaders().get(XOkapiHeaders.TENANT).iterator().next());

var responseEntity = restTemplate.exchange(absUrl, httpMethod, httpEntity, Object.class);
var responseEntity = switch (httpMethod.toString()) {
case "GET" -> restTemplate.exchange(absUrl, httpMethod, httpEntity, Object.class);
case "POST", "PUT", "DELETE" -> restTemplate.exchange(absUrl, httpMethod, httpEntity, String.class);
default -> throw new IllegalStateException("Unexpected value: " + httpMethod);
};

return new PublicationHttpResponse(objectMapper.writeValueAsString(responseEntity.getBody()), responseEntity.getStatusCode());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.UUID;

import org.folio.consortia.domain.dto.SharingSettingDeleteResponse;
import org.folio.consortia.domain.dto.SharingSettingRequest;
import org.folio.consortia.domain.dto.SharingSettingResponse;

Expand All @@ -15,4 +16,12 @@ public interface SharingSettingService {
*/
SharingSettingResponse start(UUID consortiumId, SharingSettingRequest sharingSettingRequest);

/**
* Delete sharing setting for all tenants
* @param consortiumId ID of consortium
* @param settingId ID of setting
* @param sharingSettingRequest the sharingSettingDTO (data transfer object)
* @return Sharing setting response for delete operation
*/
SharingSettingDeleteResponse delete(UUID consortiumId, UUID settingId, SharingSettingRequest sharingSettingRequest);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
import org.apache.commons.lang3.ObjectUtils;
import org.folio.consortia.config.FolioExecutionContextHelper;
import org.folio.consortia.domain.dto.PublicationRequest;
import org.folio.consortia.domain.dto.SharingSettingDeleteResponse;
import org.folio.consortia.domain.dto.SharingSettingRequest;
import org.folio.consortia.domain.dto.SharingSettingResponse;
import org.folio.consortia.domain.dto.Tenant;
import org.folio.consortia.domain.dto.TenantCollection;
import org.folio.consortia.domain.entity.SharingSettingEntity;
import org.folio.consortia.exception.ResourceNotFoundException;
import org.folio.consortia.repository.SharingSettingRepository;
import org.folio.consortia.service.ConsortiumService;
import org.folio.consortia.service.PublicationService;
Expand All @@ -34,13 +36,13 @@
import com.fasterxml.jackson.databind.node.TextNode;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;

@Service
@Log4j2
@RequiredArgsConstructor
public class SharingSettingServiceImpl implements SharingSettingService {

private final SharingSettingRepository sharingSettingRepository;
private final TenantService tenantService;
private final ConsortiumService consortiumService;
Expand Down Expand Up @@ -99,6 +101,46 @@ public SharingSettingResponse start(UUID consortiumId, SharingSettingRequest sha
}
}

@Override
@Transactional
@SneakyThrows
public SharingSettingDeleteResponse delete(UUID consortiumId, UUID settingId, SharingSettingRequest sharingSettingRequest) {
log.debug("start:: Trying to delete sharing setting with consortiumId: {}, sharing settingId: {}", consortiumId, settingId);
validateSharingSettingRequestOrThrow(settingId, sharingSettingRequest);
consortiumService.checkConsortiumExistsOrThrow(consortiumId);
Set<String> settingTenants = sharingSettingRepository.findTenantsBySettingId(settingId);
TenantCollection allTenants = tenantService.getAll(consortiumId);
PublicationRequest publicationDeleteRequest = createPublicationRequestForSetting(sharingSettingRequest, HttpMethod.DELETE.toString());

// By traverse through all tenants in db,
// we will add tenant to delete request publication tenant list, if it exists in setting tenant associations
for (Tenant tenant : allTenants.getTenants()) {
if (settingTenants.contains(tenant.getId())) {
publicationDeleteRequest.getTenants().add(tenant.getId());
log.info("start:: tenant={} added to publication delete request for setting={}", tenant.getId(), settingId);
}
}
log.info("start:: tenants with size: {} successfully added to appropriate publication request for setting: {}", allTenants.getTotalRecords(), settingId);
sharingSettingRepository.deleteBySettingId(settingId);
log.info("start:: The Sharing Settings for settingId '{}' and '{}' unique tenant(s) were successfully deleted from the database", sharingSettingRequest.getSettingId(), publicationDeleteRequest.getTenants().size());

// we create PC request with POST and PUT Http method to create settings as a consortia-system-user
try (var ignored = new FolioExecutionContextSetter(contextHelper.getSystemUserFolioExecutionContext(folioExecutionContext.getTenantId()))) {
UUID pcId = publishRequest(consortiumId, publicationDeleteRequest);
return new SharingSettingDeleteResponse()
.pcId(pcId);
}
}

private void validateSharingSettingRequestOrThrow(UUID settingId, SharingSettingRequest sharingSettingRequest) {
if (ObjectUtils.notEqual(sharingSettingRequest.getSettingId(), settingId)) {
throw new IllegalArgumentException("Mismatch id in path to settingId in request body");
}
if (!sharingSettingRepository.existsBySettingId(settingId)) {
throw new ResourceNotFoundException("settingId", String.valueOf(settingId));
}
}

private UUID publishRequest(UUID consortiumId, PublicationRequest publicationRequest) {
if (CollectionUtils.isNotEmpty(publicationRequest.getTenants())) {
return publicationService.publishRequest(consortiumId, publicationRequest).getId();
Expand All @@ -111,7 +153,7 @@ private void checkEqualsOfPayloadIdWithSettingId(SharingSettingRequest sharingSe
String sharingSettingId = String.valueOf(sharingSettingRequest.getSettingId());
String payloadId = getPayloadId(sharingSettingRequest.getPayload());
if (ObjectUtils.notEqual(sharingSettingId, payloadId)) {
throw new IllegalArgumentException("id in payload is not equal to settingId");
throw new IllegalArgumentException("Mismatch id in payload with settingId");
}
}

Expand All @@ -124,8 +166,8 @@ private PublicationRequest createPublicationRequestForSetting(SharingSettingRequ
PublicationRequest publicationRequest = new PublicationRequest();
publicationRequest.setMethod(httpMethod);
String url = sharingSettingRequest.getUrl();
if (httpMethod.equals(HttpMethod.PUT.toString())) {
url += "/" + getPayloadId(sharingSettingRequest.getPayload());
if (httpMethod.equals(HttpMethod.PUT.toString()) || httpMethod.equals(HttpMethod.DELETE.toString())) {
url += "/" + sharingSettingRequest.getSettingId();
}
publicationRequest.setUrl(url);
publicationRequest.setPayload(sharingSettingRequest.getPayload());
Expand Down
17 changes: 17 additions & 0 deletions src/main/resources/permissions/system-user-permissions.csv
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,52 @@ consortia.sync-primary-affiliations.item.post
consortia.create-primary-affiliations.item.post
departments.item.post
departments.item.put
departments.item.delete
usergroups.item.post
usergroups.item.put
usergroups.item.delete
inventory-storage.material-types.item.post
inventory-storage.material-types.item.put
inventory-storage.material-types.item.delete
inventory-storage.loan-types.item.post
inventory-storage.loan-types.item.put
inventory-storage.loan-types.item.delete
inventory-storage.item-note-types.item.post
inventory-storage.item-note-types.item.put
inventory-storage.item-note-types.item.delete
inventory-storage.electronic-access-relationships.item.post
inventory-storage.electronic-access-relationships.item.put
inventory-storage.electronic-access-relationships.item.delete
inventory-storage.statistical-codes.item.post
inventory-storage.statistical-codes.item.put
inventory-storage.statistical-codes.item.delete
inventory-storage.statistical-code-types.item.post
inventory-storage.statistical-code-types.item.put
inventory-storage.statistical-code-types.item.delete
inventory-storage.identifier-types.item.post
inventory-storage.identifier-types.item.put
inventory-storage.identifier-types.item.delete
inventory-storage.nature-of-content-terms.item.post
inventory-storage.nature-of-content-terms.item.put
inventory-storage.nature-of-content-terms.item.delete
inventory-storage.modes-of-issuance.item.post
inventory-storage.modes-of-issuance.item.put
inventory-storage.modes-of-issuance.item.delete
inventory-storage.instance-statuses.item.post
inventory-storage.instance-statuses.item.put
inventory-storage.instance-statuses.item.delete
inventory-storage.instance-note-types.item.post
inventory-storage.instance-note-types.item.put
inventory-storage.instance-note-types.item.delete
inventory-storage.instance-formats.item.post
inventory-storage.instance-formats.item.put
inventory-storage.instance-formats.item.delete
inventory-storage.contributor-types.item.post
inventory-storage.contributor-types.item.put
inventory-storage.contributor-types.item.delete
inventory-storage.alternative-title-types.item.post
inventory-storage.alternative-title-types.item.put
inventory-storage.alternative-title-types.item.delete
circulation-storage.cancellation-reasons.item.post
circulation-storage.cancellation-reasons.item.put
circulation-storage.cancellation-reasons.item.delete
13 changes: 12 additions & 1 deletion src/main/resources/swagger.api/schemas/sharingSetting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ SharingSettingRequest:
type: object
additionalProperties: false
required:
- id
- settingId
- url

SharingSettingResponse:
Expand All @@ -31,3 +31,14 @@ SharingSettingResponse:
required:
- createSettingsPCId
- updateSettingsPCId

SharingSettingDeleteResponse:
description: "A JSON schema for the Sharing settings object response for delete request"
type: object
properties:
pcId:
type: string
format: uuid
additionalProperties: false
required:
- pcId
54 changes: 35 additions & 19 deletions src/main/resources/swagger.api/sharing_settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,30 @@ paths:
$ref: "#/components/responses/Conflict"
"500":
$ref: "#/components/responses/InternalServerError"
/settings/{settingId}:
delete:
summary: delete sharing setting
operationId: deleteSharingSetting
parameters:
- $ref: "#/components/parameters/consortiumId"
- $ref: "#/components/parameters/settingId"
requestBody:
$ref: "#/components/requestBodies/SharingSettingBody"
responses:
"200":
$ref: "#/components/responses/SharingSettingDeleteResponse"
"400":
$ref: "#/components/responses/BadRequest"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/Conflict"
"422":
$ref: "#/components/responses/Conflict"
"500":
$ref: "#/components/responses/InternalServerError"
components:
requestBodies:
SharingInstanceBody:
description: Sharing Instance object
required: true
content:
application/json:
schema:
$ref: "schemas/sharingInstance.yaml#/SharingInstance"
SharingSettingBody:
description: Sharing settings object
required: true
Expand All @@ -44,24 +59,18 @@ components:
schema:
$ref: "schemas/sharingSetting.yaml#/SharingSettingRequest"
responses:
SharingInstance:
description: Returns a sharing instance object object
content:
application/json:
schema:
$ref: "schemas/sharingInstance.yaml#/SharingInstance"
SharingInstanceCollection:
description: Returns list of sharing instances
SharingSettingResponse:
description: Returns a sharing setting object response for post operation
content:
application/json:
schema:
$ref: "schemas/sharingInstance.yaml#/SharingInstanceCollection"
SharingSettingResponse:
description: Returns a sharing instance object object
$ref: "schemas/sharingSetting.yaml#/SharingSettingResponse"
SharingSettingDeleteResponse:
description: Returns a sharing setting response for delete operation
content:
application/json:
schema:
$ref: "schemas/sharingSetting.yaml#/SharingSettingResponse"
$ref: "schemas/sharingSetting.yaml#/SharingSettingDeleteResponse"
NoContent:
description: No content
Conflict:
Expand Down Expand Up @@ -107,3 +116,10 @@ components:
$ref: "schemas/common.yaml#/uuid"
required: true
description: The ID of consortium
settingId:
in: path
name: settingId
schema:
$ref: "schemas/common.yaml#/uuid"
required: true
description: The ID of setting
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,10 @@ void parallelTenantRequestsTest(int tenantsAmount, int chunkSize) throws JsonPro
.map(val -> "tenant_" + val)
.toList();

ResponseEntity<Object> restTemplateResponse = new ResponseEntity<>(ptreAsString, HttpStatusCode.valueOf(201));
ResponseEntity<String> restTemplateResponse = new ResponseEntity<>(ptreAsString, HttpStatusCode.valueOf(201));

ArgumentCaptor<HttpEntity<Object>> entityCaptor = ArgumentCaptor.forClass(HttpEntity.class);
when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), entityCaptor.capture(), eq(Object.class))).thenReturn(restTemplateResponse);
when(restTemplate.exchange(anyString(), eq(HttpMethod.POST), entityCaptor.capture(), eq(String.class))).thenReturn(restTemplateResponse);

// split list of tenants into chunks and make parallel API calls
StreamEx.ofSubLists(listOfTenantNames, chunkSize)
Expand Down Expand Up @@ -282,7 +282,7 @@ void parallelTenantRequestsTest(int tenantsAmount, int chunkSize) throws JsonPro
.sorted()
.toList();

verify(restTemplate, times(listOfTenantNames.size())).exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(Object.class));
verify(restTemplate, times(listOfTenantNames.size())).exchange(anyString(), eq(HttpMethod.POST), any(HttpEntity.class), eq(String.class));
// check if all 'x-okapi-tenant' values match with the initial list of expected tenant names
Assertions.assertTrue(CollectionUtils.isEqualCollection(capturedTenantHeaders, listOfTenantNames));
}
Expand Down
Loading

0 comments on commit 88449fc

Please sign in to comment.