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

[MODORDERS-1174] Filter pieces based on user affiliations #1017

Merged
merged 5 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
2 changes: 1 addition & 1 deletion ramls/acq-models
Submodule acq-models updated 0 files
12 changes: 10 additions & 2 deletions src/main/java/org/folio/config/ApplicationConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.folio.service.caches.InventoryCache;
import org.folio.service.configuration.ConfigurationEntriesService;
import org.folio.service.consortium.ConsortiumConfigurationService;
import org.folio.service.consortium.ConsortiumUserTenantsRetriever;
import org.folio.service.consortium.SharingInstanceService;
import org.folio.service.exchange.ExchangeRateProviderResolver;
import org.folio.service.exchange.FinanceExchangeRateService;
Expand Down Expand Up @@ -521,8 +522,10 @@ PieceChangeReceiptStatusPublisher receiptStatusPublisher() {
}

@Bean
PieceStorageService pieceStorageService(RestClient restClient) {
return new PieceStorageService(restClient);
PieceStorageService pieceStorageService(ConsortiumConfigurationService consortiumConfigurationService,
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever,
RestClient restClient) {
return new PieceStorageService(consortiumConfigurationService, consortiumUserTenantsRetriever, restClient);
}

@Bean
Expand Down Expand Up @@ -848,6 +851,11 @@ ConsortiumConfigurationService consortiumConfigurationService(RestClient restCli
return new ConsortiumConfigurationService(restClient);
}

@Bean
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever(RestClient restClient) {
return new ConsortiumUserTenantsRetriever(restClient);
}

@Bean
SharingInstanceService sharingInstanceService(RestClient restClient) {
return new SharingInstanceService(restClient);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/folio/orders/utils/RequestContextUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ public static RequestContext createContextWithNewTenantId(RequestContext request
return new RequestContext(requestContext.getContext(), modifiedHeaders);
}

public static String getUserIdFromContext(RequestContext requestContext) {
return requestContext.getHeaders().get(XOkapiHeaders.USER_ID);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ private ResourcePathResolver() {
public static final String ROUTING_LISTS = "routingLists";
public static final String ORDER_SETTINGS = "orderSettings";
public static final String USERS = "users";
public static final String CONSORTIA_USER_TENANTS = "consortia.user-tenants";


private static final Map<String, String> SUB_OBJECT_ITEM_APIS;
private static final Map<String, String> SUB_OBJECT_COLLECTION_APIS;
Expand Down Expand Up @@ -96,6 +98,7 @@ private ResourcePathResolver() {
apis.put(EXPORT_HISTORY, "/orders-storage/export-history");
apis.put(TAGS, "/tags");
apis.put(USERS, "/users");
apis.put(CONSORTIA_USER_TENANTS, "/consortia/:id/user-tenants");
apis.put(ORDER_SETTINGS, "/orders-storage/settings");
apis.put(ROUTING_LISTS, "/orders-storage/routing-lists");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.folio.service.consortium;

import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import org.folio.rest.core.RestClient;
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.core.models.RequestEntry;

import java.util.List;
import java.util.stream.IntStream;

import static org.folio.orders.utils.RequestContextUtil.getUserIdFromContext;
import static org.folio.orders.utils.ResourcePathResolver.CONSORTIA_USER_TENANTS;
import static org.folio.orders.utils.ResourcePathResolver.resourcesPath;
import static org.folio.service.pieces.util.UserTenantFields.COLLECTION_USER_TENANTS;
import static org.folio.service.pieces.util.UserTenantFields.TENANT_ID;
import static org.folio.service.pieces.util.UserTenantFields.USER_ID;

public class ConsortiumUserTenantsRetriever {

private static final String CONSORTIA_USER_TENANTS_ENDPOINT = resourcesPath(CONSORTIA_USER_TENANTS);

private final RestClient restClient;

public ConsortiumUserTenantsRetriever(RestClient restClient) {
this.restClient = restClient;
}

public Future<List<String>> getUserTenants(String consortiumId, RequestContext requestContext) {
var userId = getUserIdFromContext(requestContext);
var requestEntry = new RequestEntry(CONSORTIA_USER_TENANTS_ENDPOINT)
.withOffset(0)
.withLimit(Integer.MAX_VALUE)
.withId(consortiumId)
.withQueryParameter(USER_ID.getValue(), userId);
return restClient.getAsJsonObject(requestEntry, requestContext)
.map(this::extractTenantIds);
}

private List<String> extractTenantIds(JsonObject userTenantCollection) {
var userTenants = userTenantCollection.getJsonArray(COLLECTION_USER_TENANTS.getValue());
return IntStream.range(0, userTenants.size())
.mapToObj(userTenants::getJsonObject)
.map(userTenant -> userTenant.getString(TENANT_ID.getValue()))
.toList();
}

}
35 changes: 30 additions & 5 deletions src/main/java/org/folio/service/pieces/PieceStorageService.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.logging.log4j.LogManager;
Expand All @@ -24,6 +25,8 @@
import org.folio.rest.jaxrs.model.PieceCollection;

import io.vertx.core.Future;
import org.folio.service.consortium.ConsortiumUserTenantsRetriever;
import org.folio.service.consortium.ConsortiumConfigurationService;

public class PieceStorageService {
private static final Logger logger = LogManager.getLogger(PieceStorageService.class);
Expand All @@ -33,9 +36,15 @@ public class PieceStorageService {
private static final String PIECE_STORAGE_ENDPOINT = resourcesPath(PIECES_STORAGE);
private static final String PIECE_STORAGE_BY_ID_ENDPOINT = PIECE_STORAGE_ENDPOINT + "/{id}";

private final ConsortiumConfigurationService consortiumConfigurationService;
private final ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever;
private final RestClient restClient;

public PieceStorageService(RestClient restClient) {
public PieceStorageService(ConsortiumConfigurationService consortiumConfigurationService,
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever,
RestClient restClient) {
this.consortiumConfigurationService = consortiumConfigurationService;
this.consortiumUserTenantsRetriever = consortiumUserTenantsRetriever;
this.restClient = restClient;
}

Expand Down Expand Up @@ -110,10 +119,26 @@ public Future<List<Piece>> getPiecesByHoldingId(String holdingId, RequestContext
}

public Future<PieceCollection> getPieces(int limit, int offset, String query, RequestContext requestContext) {
RequestEntry requestEntry = new RequestEntry(PIECE_STORAGE_ENDPOINT).withQuery(query)
.withOffset(offset)
.withLimit(limit);
return restClient.get(requestEntry, PieceCollection.class, requestContext);
var requestEntry = new RequestEntry(PIECE_STORAGE_ENDPOINT).withQuery(query).withOffset(offset).withLimit(limit);
return restClient.get(requestEntry, PieceCollection.class, requestContext)
.compose(piecesCollection -> filterPiecesByUserTenantsIfNecessary(piecesCollection.getPieces(), requestContext))
.map(pieces -> new PieceCollection().withPieces(pieces).withTotalRecords(pieces.size()));
SerhiiNosko marked this conversation as resolved.
Show resolved Hide resolved
}

private Future<List<Piece>> filterPiecesByUserTenantsIfNecessary(List<Piece> pieces, RequestContext requestContext) {
return consortiumConfigurationService.getConsortiumConfiguration(requestContext)
.compose(consortiumConfiguration -> consortiumConfiguration
.map(configuration -> consortiumUserTenantsRetriever.getUserTenants(configuration.consortiumId(), requestContext)
.map(userTenants -> filterPiecesByUserTenants(pieces, userTenants)))
.orElse(Future.succeededFuture(pieces)));
}

private List<Piece> filterPiecesByUserTenants(List<Piece> pieces, List<String> userTenants) {
return pieces.stream()
.filter(piece -> Optional.ofNullable(piece.getReceivingTenantId())
.map(userTenants::contains)
.orElse(true))
.toList();
}

public Future<List<Piece>> getPiecesByIds(List<String> pieceIds, RequestContext requestContext) {
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/org/folio/service/pieces/util/UserTenantFields.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.folio.service.pieces.util;

public enum UserTenantFields {

USER_ID("userId"),
TENANT_ID("tenantId"),
COLLECTION_USER_TENANTS("userTenants");

private final String value;

UserTenantFields(String value) {
this.value = value;
}

public String getValue() {
return value;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.core.models.RequestEntry;
import org.folio.rest.jaxrs.model.PieceCollection;
import org.folio.service.consortium.ConsortiumConfigurationService;
import org.folio.service.consortium.ConsortiumUserTenantsRetriever;
import org.folio.service.pieces.PieceStorageService;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
Expand Down Expand Up @@ -235,15 +237,27 @@ public RestClient restClient() {
}

@Bean
public PieceStorageService pieceStorageService(RestClient restClient) {
return spy(new PieceStorageService(restClient));
public PieceStorageService pieceStorageService(ConsortiumConfigurationService consortiumConfigurationService,
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever,
RestClient restClient) {
return spy(new PieceStorageService(consortiumConfigurationService, consortiumUserTenantsRetriever, restClient));
}

@Bean
public CirculationRequestsRetriever circulationRequestsRetriever(PieceStorageService pieceStorageService, RestClient restClient) {
return new CirculationRequestsRetriever(pieceStorageService, restClient);
}

@Bean
ConsortiumConfigurationService consortiumConfigurationService(RestClient restClient) {
return new ConsortiumConfigurationService(restClient);
}

@Bean
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever(RestClient restClient) {
return new ConsortiumUserTenantsRetriever(restClient);
}

}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.folio.service.caches.InventoryCache;
import org.folio.service.configuration.ConfigurationEntriesService;
import org.folio.service.consortium.ConsortiumConfigurationService;
import org.folio.service.consortium.ConsortiumUserTenantsRetriever;
import org.folio.service.consortium.SharingInstanceService;
import org.folio.service.inventory.InventoryHoldingManager;
import org.folio.service.inventory.InventoryItemManager;
Expand Down Expand Up @@ -221,19 +222,30 @@ static class ContextConfiguration {
return new ProtectionService(acquisitionsUnitsService);
}

@Bean PieceStorageService pieceStorageService(RestClient restClient) {
return new PieceStorageService(restClient);
@Bean PieceStorageService pieceStorageService(ConsortiumConfigurationService consortiumConfigurationService,
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever,
RestClient restClient) {
return new PieceStorageService(consortiumConfigurationService, consortiumUserTenantsRetriever, restClient);
}

@Bean InventoryService inventoryService (RestClient restClient) {
return new InventoryService(restClient);
}

@Bean SharingInstanceService sharingInstanceService (RestClient restClient) {
return new SharingInstanceService(restClient);
}
@Bean ConsortiumConfigurationService consortiumConfigurationService (RestClient restClient) {

@Bean
ConsortiumConfigurationService consortiumConfigurationService(RestClient restClient) {
return new ConsortiumConfigurationService(restClient);
}

@Bean
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever(RestClient restClient) {
return new ConsortiumUserTenantsRetriever(restClient);
}

@Bean PurchaseOrderStorageService purchaseOrderStorageService () {
return mock(PurchaseOrderStorageService.class);
}
Expand Down
Loading
Loading