diff --git a/src/main/java/org/folio/rest/impl/OrdersSettingsAPI.java b/src/main/java/org/folio/rest/impl/OrdersSettingsAPI.java index 6e554b65..d1251697 100644 --- a/src/main/java/org/folio/rest/impl/OrdersSettingsAPI.java +++ b/src/main/java/org/folio/rest/impl/OrdersSettingsAPI.java @@ -1,12 +1,16 @@ package org.folio.rest.impl; +import static io.vertx.core.json.JsonObject.mapFrom; + import java.util.Map; import javax.ws.rs.core.Response; import org.folio.rest.annotations.Validate; +import org.folio.rest.core.BaseApi; import org.folio.rest.jaxrs.model.Setting; import org.folio.rest.jaxrs.resource.OrdersStorageSettings; +import org.folio.rest.persist.HelperUtils; import org.folio.services.setting.SettingService; import org.folio.spring.SpringContextUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -16,7 +20,7 @@ import io.vertx.core.Handler; import io.vertx.core.Vertx; -public class OrdersSettingsAPI implements OrdersStorageSettings { +public class OrdersSettingsAPI extends BaseApi implements OrdersStorageSettings { @Autowired private SettingService settingService; @@ -29,7 +33,10 @@ public OrdersSettingsAPI() { @Validate public void getOrdersStorageSettings(String query, String totalRecords, int offset, int limit, Map okapiHeaders, Handler> asyncResultHandler, Context vertxContext) { - settingService.getSettings(query, offset, limit, okapiHeaders, asyncResultHandler, vertxContext); + settingService.getSettings(query, offset, limit, okapiHeaders, vertxContext) + .onComplete(ar -> asyncResultHandler.handle(ar.succeeded() + ? buildOkResponse(ar.result()) + : buildErrorResponse(ar.cause()))); } @Override @@ -60,5 +67,10 @@ public void deleteOrdersStorageSettingsById(String id, Map okapi settingService.deleteSetting(id, okapiHeaders, asyncResultHandler, vertxContext); } + @Override + protected String getEndpoint(Object entity) { + return HelperUtils.getEndpoint(OrdersStorageSettings.class) + mapFrom(entity).getString("id"); + } + } diff --git a/src/main/java/org/folio/services/setting/SettingService.java b/src/main/java/org/folio/services/setting/SettingService.java index 558dd397..27f53be9 100644 --- a/src/main/java/org/folio/services/setting/SettingService.java +++ b/src/main/java/org/folio/services/setting/SettingService.java @@ -6,13 +6,14 @@ import javax.ws.rs.core.Response; import java.util.Map; import java.util.Optional; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.folio.rest.jaxrs.model.Setting; import org.folio.rest.jaxrs.model.SettingCollection; import org.folio.rest.jaxrs.resource.OrdersStorageSettings; +import org.folio.rest.jaxrs.resource.OrdersStorageSettings.GetOrdersStorageSettingsResponse; import org.folio.rest.persist.PgUtil; import org.folio.rest.tools.utils.TenantTool; import org.folio.services.setting.util.SettingKey; @@ -37,9 +38,9 @@ public class SettingService { private static final String SETTINGS_TABLE = "settings"; private static final String SETTINGS_BY_KEY_QUERY = "key==%s"; - private static final String SETTINGS_CACHE_KEY = "%s.%s"; + private static final String SETTINGS_CACHE_KEY = "%s.%s.%s.%s"; - private AsyncCache> asyncCache; + private AsyncCache asyncCache; @Value("${orders-storage.cache.setting-data.expiration.time.seconds:60}") private long cacheExpirationTime; @@ -53,33 +54,27 @@ void init() { } public Future> getSettingByKey(SettingKey settingKey, Map okapiHeaders, Context vertxContext) { + return getSettings(SETTINGS_BY_KEY_QUERY.formatted(settingKey.getName()), 0, 1, okapiHeaders, vertxContext) + .map(SettingService::extractSettingIfExistsAndIsUnique); + } + + public Future getSettings(String query, int offset, int limit, Map okapiHeaders, Context vertxContext) { + if (StringUtils.isBlank(query)) { + return getSettingsCollection(query, offset, limit, okapiHeaders, vertxContext); + } try { - var settingCacheKey = String.format(SETTINGS_CACHE_KEY, TenantTool.tenantId(okapiHeaders), settingKey.getName()); + var settingCacheKey = SETTINGS_CACHE_KEY.formatted(TenantTool.tenantId(okapiHeaders), query, offset, limit); return Future.fromCompletionStage(asyncCache.get(settingCacheKey, (key, executor) -> - getSettingByKeyFromDB(settingKey, okapiHeaders, vertxContext))); + getSettingsCollection(query, offset, limit, okapiHeaders, vertxContext).toCompletionStage().toCompletableFuture())); } catch (Exception e) { - log.error("Error when retrieving setting with key: '{}'", settingKey.getName(), e); + log.error("Error when retrieving settings by query: '{}'", query, e); return Future.failedFuture(e); } } - private CompletableFuture> getSettingByKeyFromDB(SettingKey settingKey, Map okapiHeaders, Context vertxContext) { - var query = String.format(SETTINGS_BY_KEY_QUERY, settingKey.getName()); - return getSettings(query, 0, 1, okapiHeaders, vertxContext) - .map(response -> convertResponseToEntity(response, SettingCollection.class)) - .map(SettingService::extractSettingIfExistsAndIsUnique) - .toCompletionStage().toCompletableFuture(); - } - - public void getSettings(String query, int offset, int limit, Map okapiHeaders, - Handler> asyncResultHandler, Context vertxContext) { - getSettings(query, offset, limit, okapiHeaders, vertxContext) - .onComplete(asyncResultHandler); - } - - public Future getSettings(String query, int offset, int limit, Map okapiHeaders, Context vertxContext) { - return PgUtil.get(SETTINGS_TABLE, Setting.class, SettingCollection.class, query, offset, limit, okapiHeaders, vertxContext, - OrdersStorageSettings.GetOrdersStorageSettingsResponse.class); + private Future getSettingsCollection(String query, int offset, int limit, Map okapiHeaders, Context vertxContext) { + return PgUtil.get(SETTINGS_TABLE, Setting.class, SettingCollection.class, query, offset, limit, okapiHeaders, vertxContext, GetOrdersStorageSettingsResponse.class) + .compose(response -> convertResponseToEntity(response, SettingCollection.class)); } public void createSetting(Setting entity, Map okapiHeaders, diff --git a/src/main/java/org/folio/util/DbUtils.java b/src/main/java/org/folio/util/DbUtils.java index a03bf296..e3a7ecb5 100644 --- a/src/main/java/org/folio/util/DbUtils.java +++ b/src/main/java/org/folio/util/DbUtils.java @@ -7,6 +7,7 @@ import java.util.List; import org.apache.commons.collections4.IteratorUtils; +import org.folio.HttpStatus; import org.folio.rest.persist.Conn; import org.folio.rest.persist.Criteria.Criterion; import org.folio.rest.persist.DBClient; @@ -72,12 +73,15 @@ public static long getRowSetAsCount(RowSet rowSet) { .findFirst().orElse(0L); } - public static T convertResponseToEntity(Response response, Class entityClass) { + public static Future convertResponseToEntity(Response response, Class entityClass) { + if (response.getStatus() != HttpStatus.HTTP_OK.toInt()) { + return Future.failedFuture(new HttpException(response.getStatus(), response.getEntity().toString())); + } try { - return JsonObject.mapFrom(response.getEntity()).mapTo(entityClass); + return Future.succeededFuture(JsonObject.mapFrom(response.getEntity()).mapTo(entityClass)); } catch (RuntimeException e) { - throw new IllegalStateException(String.format("Cannot convert response '%s' to entity '%s' - error message: %s", - response.getEntity(), entityClass.getName(), e.getMessage())); + return Future.failedFuture(new IllegalStateException(String.format("Cannot convert response '%s' to entity '%s' - error message: %s", + response.getEntity(), entityClass.getName(), e.getMessage()))); } } diff --git a/src/test/java/org/folio/event/handler/InventoryCreateAsyncRecordHandlerTest.java b/src/test/java/org/folio/event/handler/InventoryCreateAsyncRecordHandlerTest.java index a5861952..5c6fe9ea 100644 --- a/src/test/java/org/folio/event/handler/InventoryCreateAsyncRecordHandlerTest.java +++ b/src/test/java/org/folio/event/handler/InventoryCreateAsyncRecordHandlerTest.java @@ -81,7 +81,7 @@ public void initMocks() throws Exception { void positive_shouldProcessInventoryCreate(String tenantId) { var eventObject = createResourceEvent(DIKU_TENANT, CREATE); var record = createKafkaRecord(eventObject, DIKU_TENANT); - doReturn(Future.succeededFuture(Response.ok(createSettingCollection(createSetting("true"))).build())) + doReturn(Future.succeededFuture(createSettingCollection(createSetting("true")))) .when(settingService).getSettings(anyString(), anyInt(), anyInt(), anyMap(), any(Context.class)); doReturn(Future.succeededFuture(Optional.of(new ConsortiumConfiguration(tenantId, CONSORTIUM_ID)))) .when(consortiumConfigurationService).getConsortiumConfiguration(any()); @@ -118,7 +118,7 @@ void positive_shouldSkipInventoryCreateEventIfCentralOrderingIsDisabled() { var eventObject = createResourceEvent(DIKU_TENANT, CREATE); var record = createKafkaRecord(eventObject, DIKU_TENANT); var emptySettings = new SettingCollection().withTotalRecords(0); - doReturn(Future.succeededFuture(Response.ok(emptySettings).build())) + doReturn(Future.succeededFuture(emptySettings)) .when(settingService).getSettings(anyString(), anyInt(), anyInt(), anyMap(), any(Context.class)); doReturn(Future.succeededFuture(Optional.of(new ConsortiumConfiguration(DIKU_TENANT, CONSORTIUM_ID)))) .when(consortiumConfigurationService).getConsortiumConfiguration(any());