Skip to content

Commit

Permalink
Merge branch 'master' into MODORDERS-1162
Browse files Browse the repository at this point in the history
  • Loading branch information
BKadirkhodjaev authored Sep 16, 2024
2 parents 4e75140 + 832f66b commit 2afb770
Show file tree
Hide file tree
Showing 17 changed files with 286 additions and 25 deletions.
4 changes: 3 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,9 @@
"pathPattern": "/orders/pieces",
"permissionsRequired": ["orders.pieces.collection.get"],
"modulePermissions": [
"orders-storage.pieces.collection.get"
"orders-storage.pieces.collection.get",
"consortia.user-tenants.collection.get",
"user-tenants.collection.get"
]
},
{
Expand Down
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
2 changes: 1 addition & 1 deletion src/main/java/org/folio/helper/BindHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private Future<Void> removeForbiddenEntities(Piece piece, RequestContext request

private Future<Void> clearTitleBindItemsIfNeeded(String titleId, String bindItemId, RequestContext requestContext) {
String query = String.format("titleId==%s and bindItemId==%s and isBound==true", titleId, bindItemId);
return pieceStorageService.getPieces(0, 0, query, requestContext)
return pieceStorageService.getAllPieces(0, 0, query, requestContext)
.compose(pieceCollection -> {
var totalRecords = pieceCollection.getTotalRecords();
if (totalRecords != 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ private List<Piece> getSuccessfullyProcessedPieces(String poLineId, Map<String,

private Future<List<Piece>> getPiecesByPoLine(String poLineId, RequestContext requestContext) {
String query = String.format("poLineId==%s", poLineId);
return pieceStorageService.getPieces(Integer.MAX_VALUE, 0, query, requestContext)
return pieceStorageService.getAllPieces(query, requestContext)
.map(PieceCollection::getPieces);
}

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 @@ -5,6 +5,8 @@
import java.util.Map;
import java.util.stream.Collectors;

import static org.folio.rest.RestConstants.PATH_PARAM_PLACE_HOLDER;

public class ResourcePathResolver {

private ResourcePathResolver() {
Expand Down Expand Up @@ -53,6 +55,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 +100,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/" + PATH_PARAM_PLACE_HOLDER + "/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,49 @@
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.rest.RestConstants.PATH_PARAM_PLACE_HOLDER;
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 url = CONSORTIA_USER_TENANTS_ENDPOINT.replace(PATH_PARAM_PLACE_HOLDER, consortiumId);
var requestEntry = new RequestEntry(url)
.withOffset(0)
.withLimit(Integer.MAX_VALUE)
.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();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public Future<HoldingSummaryCollection> getHoldingsSummary(String holdingId, Req
var queryForPiece = String.format("?query=holdingId==%s", holdingId);
var queryForLines = String.format("?query=locations=\"holdingId\" : \"%s\"", holdingId);

return pieceStorageService.getPieces(Integer.MAX_VALUE, 0, queryForPiece, requestContext)
return pieceStorageService.getAllPieces(queryForPiece, requestContext)
.map(piecesCollection -> {
Set<String> lineIds = piecesCollection.getPieces().stream()
.map(Piece::getPoLineId)
Expand Down
47 changes: 40 additions & 7 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 @@ -98,29 +107,53 @@ public Future<Void> deletePiecesByIds(List<String> pieceIds, RequestContext requ

public Future<PieceCollection> getExpectedPiecesByLineId(String poLineId, RequestContext requestContext) {
String query = String.format(PIECES_BY_POL_ID_AND_STATUS_QUERY, poLineId, Piece.ReceivingStatus.EXPECTED.value());
return getPieces(Integer.MAX_VALUE, 0, query, requestContext);
return getAllPieces(query, requestContext);
}

public Future<List<Piece>> getPiecesByHoldingId(String holdingId, RequestContext requestContext) {
if (holdingId != null) {
String query = String.format(PIECES_BY_HOLDING_ID_QUERY, holdingId);
return getPieces(Integer.MAX_VALUE, 0, query, requestContext).map(PieceCollection::getPieces);
return getAllPieces(query, requestContext).map(PieceCollection::getPieces);
}
return Future.succeededFuture(Collections.emptyList());
}

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 getAllPieces(limit, offset, query, requestContext)
.compose(piecesCollection -> filterPiecesByUserTenantsIfNecessary(piecesCollection.getPieces(), requestContext)
.map(piecesCollection::withPieces));
}

public Future<PieceCollection> getAllPieces(String query, RequestContext requestContext) {
return getAllPieces(Integer.MAX_VALUE, 0, query, requestContext);
}

public Future<PieceCollection> getAllPieces(int limit, int offset, String query, RequestContext requestContext) {
var requestEntry = new RequestEntry(PIECE_STORAGE_ENDPOINT).withQuery(query).withOffset(offset).withLimit(limit);
return restClient.get(requestEntry, PieceCollection.class, requestContext);
}

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) {
logger.debug("getPiecesByIds:: start to retrieving pieces by ids: {}", pieceIds);
var futures = ofSubLists(new ArrayList<>(pieceIds), MAX_IDS_FOR_GET_RQ_15)
.map(HelperUtils::convertIdsToCqlQuery)
.map(query -> getPieces(Integer.MAX_VALUE, 0, query, requestContext))
.map(query -> getAllPieces(query, requestContext))
.toList();
return collectResultsOnSuccess(futures)
.map(lists -> lists.stream()
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 @@ -69,7 +69,7 @@ void testGetHoldingSummaryById() throws IOException {
when(purchaseOrderLineService.getOrderLines(anyString(), anyInt(), anyInt(), any()))
.thenReturn(Future.succeededFuture(polines));

when(pieceStorageService.getPieces(anyInt(), anyInt(), anyString(), any()))
when(pieceStorageService.getAllPieces(anyString(), any()))
.thenReturn(Future.succeededFuture(pieces));

var hs = holdingsSummaryService.getHoldingsSummary(UUID.randomUUID().toString(), requestContext)
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

0 comments on commit 2afb770

Please sign in to comment.