Skip to content

Commit

Permalink
Merge branch 'master' into CIRCSTORE-520-vertx-4.5.9
Browse files Browse the repository at this point in the history
  • Loading branch information
julianladisch authored Aug 20, 2024
2 parents ed629f9 + 2775310 commit 739bc35
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 56 deletions.
6 changes: 5 additions & 1 deletion src/main/java/org/folio/persist/AbstractRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ protected AbstractRepository(PostgresClient postgresClient, String tableName,
this.recordType = recordType;
}

public Future<T> saveAndReturnUpdatedEntity(String id, T entity) {
return postgresClient.saveAndReturnUpdatedEntity(tableName, id, entity);
}

public Future<String> save(String id, T entity) {
return postgresClient.save(tableName, id, entity);
}
Expand Down Expand Up @@ -119,4 +123,4 @@ public Future<RowSet<Row>> deleteById(String id) {
return postgresClient.delete(tableName, id);
}

}
}
10 changes: 9 additions & 1 deletion src/main/java/org/folio/rest/impl/CirculationSettingsAPI.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package org.folio.rest.impl;

import static io.vertx.core.Future.succeededFuture;
import static org.folio.rest.jaxrs.resource.CirculationSettingsStorage.PostCirculationSettingsStorageCirculationSettingsResponse.headersFor201;
import static org.folio.rest.jaxrs.resource.CirculationSettingsStorage.PostCirculationSettingsStorageCirculationSettingsResponse.respond201WithApplicationJson;
import static org.folio.rest.jaxrs.resource.CirculationSettingsStorage.PostCirculationSettingsStorageCirculationSettingsResponse.respond500WithTextPlain;

import java.util.Map;

import javax.ws.rs.core.Response;
Expand All @@ -21,7 +26,10 @@ public void postCirculationSettingsStorageCirculationSettings(String lang,

new CirculationSettingsService(vertxContext, okapiHeaders)
.create(circulationSettings)
.onComplete(asyncResultHandler);
.onSuccess(response -> asyncResultHandler.handle(
succeededFuture(respond201WithApplicationJson(circulationSettings, headersFor201()))))
.onFailure(throwable -> asyncResultHandler.handle(
succeededFuture(respond500WithTextPlain(throwable.getMessage()))));
}

@Override
Expand Down
54 changes: 48 additions & 6 deletions src/main/java/org/folio/service/CirculationSettingsService.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
package org.folio.service;

import static org.folio.rest.tools.utils.ValidationHelper.isDuplicate;
import static org.folio.service.event.EntityChangedEventPublisherFactory.circulationSettingsEventPublisher;
import static org.folio.support.ModuleConstants.CIRCULATION_SETTINGS_TABLE;

import java.util.List;
import java.util.Map;

import javax.ws.rs.core.Response;

import lombok.extern.log4j.Log4j2;
import org.folio.persist.CirculationSettingsRepository;
import org.folio.rest.jaxrs.model.CirculationSetting;
import org.folio.rest.jaxrs.model.CirculationSettings;
import org.folio.rest.jaxrs.resource.CirculationSettingsStorage.DeleteCirculationSettingsStorageCirculationSettingsByCirculationSettingsIdResponse;
import org.folio.rest.jaxrs.resource.CirculationSettingsStorage.GetCirculationSettingsStorageCirculationSettingsByCirculationSettingsIdResponse;
import org.folio.rest.jaxrs.resource.CirculationSettingsStorage.GetCirculationSettingsStorageCirculationSettingsResponse;
import org.folio.rest.jaxrs.resource.CirculationSettingsStorage.PostCirculationSettingsStorageCirculationSettingsResponse;
import org.folio.rest.jaxrs.resource.CirculationSettingsStorage.PutCirculationSettingsStorageCirculationSettingsByCirculationSettingsIdResponse;
import org.folio.rest.persist.Criteria.Criteria;
import org.folio.rest.persist.Criteria.Criterion;
import org.folio.rest.persist.PgUtil;
import org.folio.service.event.EntityChangedEventPublisher;

import io.vertx.core.Context;
import io.vertx.core.Future;

@Log4j2
public class CirculationSettingsService {

private final Context vertxContext;
Expand All @@ -42,10 +47,11 @@ public Future<Response> getAll(int offset, int limit, String query) {
GetCirculationSettingsStorageCirculationSettingsResponse.class);
}

public Future<Response> create(CirculationSetting circulationSetting) {
return PgUtil.post(CIRCULATION_SETTINGS_TABLE, circulationSetting, okapiHeaders, vertxContext,
PostCirculationSettingsStorageCirculationSettingsResponse.class)
.compose(eventPublisher.publishCreated());
public Future<CirculationSetting> create(CirculationSetting circulationSetting) {
log.debug("create:: trying to save circulationSetting: {}", circulationSetting);
return repository.saveAndReturnUpdatedEntity(circulationSetting.getId(),
circulationSetting)
.recover(throwable -> updateSettingsValue(circulationSetting, throwable));
}

public Future<Response> findById(String circulationSettingsId) {
Expand All @@ -67,4 +73,40 @@ public Future<Response> delete(String circulationSettingsId) {
.compose(eventPublisher.publishRemoved(circulationSetting))
);
}
}

private Future<CirculationSetting> updateSettingsValue(CirculationSetting circulationSetting,
Throwable throwable) {

if (!isDuplicate(throwable.getMessage())) {
log.warn("updateSettingsValue:: error during saving circulation setting: {}",
circulationSetting, throwable);
return Future.failedFuture(throwable);
}

log.info("updateSettingsValue:: setting with name: {} already exists.",
circulationSetting.getName());

return getSettingsByName(circulationSetting.getName())
.compose(settings -> updateSettings(settings, circulationSetting));
}

private Future<CirculationSetting> updateSettings(List<CirculationSetting> settings,
CirculationSetting circulationSetting) {

settings.forEach(setting -> setting.setValue(circulationSetting.getValue()));
log.debug("updateSettings:: updating {} setting(s) with name '{}'",
settings::size, circulationSetting::getName);
return repository.update(settings)
.map(circulationSetting);
}

private Future<List<CirculationSetting>> getSettingsByName(String settingsName) {
log.debug("getSettingsByName:: trying to fetch setting by name: {}", settingsName);
Criterion filter = new Criterion(new Criteria()
.addField("'name'")
.setOperation("=")
.setVal(settingsName));

return repository.get(filter);
}
}
9 changes: 8 additions & 1 deletion src/main/resources/templates/db_scripts/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,14 @@
{
"tableName": "circulation_settings",
"withMetadata": true,
"withAuditing": false
"withAuditing": false,
"uniqueIndex": [
{
"fieldName": "name",
"tOps": "ADD",
"caseSensitive": false
}
]
},
{
"tableName": "request",
Expand Down
146 changes: 99 additions & 47 deletions src/test/java/org/folio/rest/api/CirculationSettingsAPITest.java
Original file line number Diff line number Diff line change
@@ -1,95 +1,147 @@
package org.folio.rest.api;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.junit.MatcherAssert.assertThat;

import java.net.MalformedURLException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

import io.vertx.core.json.JsonObject;
import lombok.SneakyThrows;
import org.folio.rest.support.ApiTests;
import org.folio.rest.support.http.AssertingRecordClient;
import org.folio.rest.support.http.InterfaceUrls;
import org.junit.Before;
import org.junit.Test;

import io.vertx.core.json.JsonObject;
import java.util.UUID;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.junit.MatcherAssert.assertThat;

public class CirculationSettingsAPITest extends ApiTests {
private static final String ID_KEY = "id";
private static final String NAME_KEY = "name";
private static final String VALUE_KEY = "value";
private static final String SAMPLE_VALUE = "sample";
private static final String SAMPLE_KEY = "sample";
private static final String INITIAL_VALUE = "OK";
private static final String UPDATED_VALUE = "OK1";
private static final String TABLE_NAME = "circulation_settings";
private static final String CIRCULATION_SETTINGS_PROPERTY = "circulation-settings";
private static final int NOT_FOUND_STATUS = 404;
private static final String REQUEST_PRINT_SETTING = "Enable Request Print";

private final AssertingRecordClient circulationSettingsClient =
new AssertingRecordClient(
client, StorageTestSuite.TENANT_ID, InterfaceUrls::circulationSettingsUrl,
"circulation-settings");
client, StorageTestSuite.TENANT_ID, InterfaceUrls::circulationSettingsUrl,
CIRCULATION_SETTINGS_PROPERTY);

@Test
public void canCreateAndRetrieveCirculationSettings() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
@Before
public void beforeEach() {
StorageTestSuite.cleanUpTable(TABLE_NAME);
}

@Test
@SneakyThrows
public void updateInsteadCreateWithTheSameName() {
String id = UUID.randomUUID().toString();
JsonObject circulationSettingsJson = getCirculationSetting(id);
JsonObject circulationSettingsResponse =
circulationSettingsClient.create(circulationSettingsJson).getJson();
JsonObject circulationSettingsJsonUpdated = getUpdatedSettingsJson();
circulationSettingsClient.create(circulationSettingsJsonUpdated);
JsonObject circulationSettingsById = circulationSettingsClient.getById(id).getJson();

assertThat(circulationSettingsResponse.getString("id"), is(id));
assertThat(circulationSettingsById.getString("id"), is(id));
assertThat(circulationSettingsById.getJsonObject("value"), is(
circulationSettingsJson.getJsonObject("value")));
assertThatCorrectCreation(circulationSettingsResponse, circulationSettingsJson);
assertThat(circulationSettingsClient.getAll().getTotalRecords(), is(1));
assertThat(getValue(circulationSettingsJsonUpdated), is(getValue(circulationSettingsById)));
}

@Test
public void canUpdateCirculationSettings() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
@SneakyThrows
public void canCreateAndRetrieveCirculationSettings() {
String id = UUID.randomUUID().toString();
JsonObject circulationSettingsJson = getCirculationSetting(id);
JsonObject circulationSettingsResponse =
circulationSettingsClient.create(circulationSettingsJson).getJson();
JsonObject circulationSettingsById = circulationSettingsClient.getById(id).getJson();

assertThat(circulationSettingsResponse.getString(ID_KEY), is(id));
assertThat(circulationSettingsById.getString(ID_KEY), is(id));
assertThat(circulationSettingsById.getJsonObject(VALUE_KEY), is(
circulationSettingsJson.getJsonObject(VALUE_KEY)));
}

@Test
@SneakyThrows
public void canUpdateCirculationSettings() {
String id = UUID.randomUUID().toString();
JsonObject circulationSettingsJson = getCirculationSetting(id);
circulationSettingsClient.create(circulationSettingsJson).getJson();
circulationSettingsClient.attemptPutById(
circulationSettingsJson.put("value", new JsonObject().put("sample", "DONE")));
circulationSettingsJson.put(VALUE_KEY, new JsonObject().put(SAMPLE_KEY, "DONE")));
JsonObject updatedCirculationSettings = circulationSettingsClient.getById(id).getJson();

assertThat(updatedCirculationSettings.getString("id"), is(id));
assertThat(updatedCirculationSettings.getJsonObject("value"), is(
circulationSettingsJson.getJsonObject("value")));
assertThat(updatedCirculationSettings.getString(ID_KEY), is(id));
assertThat(updatedCirculationSettings.getJsonObject(VALUE_KEY), is(
circulationSettingsJson.getJsonObject(VALUE_KEY)));
}

@Test
public void canDeleteCirculationSettings() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {

@SneakyThrows
public void canDeleteCirculationSettings() {
UUID id = UUID.randomUUID();
circulationSettingsClient.create(getCirculationSetting(id.toString())).getJson();
circulationSettingsClient.deleteById(id);
var deletedCirculationSettings = circulationSettingsClient.attemptGetById(id);
assertThat(deletedCirculationSettings.getStatusCode(), is(404));
}

private JsonObject getCirculationSetting(String id) {
return new JsonObject()
.put("id", id)
.put("name", "sample")
.put("value", new JsonObject().put("sample", "OK"));
assertThat(deletedCirculationSettings.getStatusCode(), is(NOT_FOUND_STATUS));
}

@Test
public void canCreateAndRetrieveEnableRequestPrintDetailsSetting() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
@SneakyThrows
public void canCreateAndRetrieveEnableRequestPrintDetailsSetting() {
String id = UUID.randomUUID().toString();
JsonObject enableRequestPrintDetailsSettingJson = new JsonObject();
enableRequestPrintDetailsSettingJson.put("id", id);
enableRequestPrintDetailsSettingJson.put("name", "Enable Request Print");
enableRequestPrintDetailsSettingJson.put("value", new JsonObject().put("Enable Request Print", true));
enableRequestPrintDetailsSettingJson.put(ID_KEY, id);
enableRequestPrintDetailsSettingJson.put(NAME_KEY, REQUEST_PRINT_SETTING);
JsonObject enablePrintSettingJson = new JsonObject().put(REQUEST_PRINT_SETTING, true);
enableRequestPrintDetailsSettingJson.put(VALUE_KEY, enablePrintSettingJson);

JsonObject circulationSettingsResponse =
circulationSettingsClient.create(enableRequestPrintDetailsSettingJson).getJson();
JsonObject circulationSettingsById = circulationSettingsClient.getById(id).getJson();

assertThat(circulationSettingsResponse.getString("id"), is(id));
assertThat(circulationSettingsResponse.getString("name"),
is(enableRequestPrintDetailsSettingJson.getString("name")));
assertThat(circulationSettingsById.getString("id"), is(id));
assertThat(circulationSettingsById.getJsonObject("value"),
is(enableRequestPrintDetailsSettingJson.getJsonObject("value")));
assertThat(circulationSettingsResponse.getString(ID_KEY), is(id));
assertThat(circulationSettingsResponse.getString(NAME_KEY),
is(enableRequestPrintDetailsSettingJson.getString(NAME_KEY)));
assertThat(circulationSettingsById.getString(ID_KEY), is(id));
assertThat(circulationSettingsById.getJsonObject(VALUE_KEY),
is(enableRequestPrintDetailsSettingJson.getJsonObject(VALUE_KEY)));
}

private static String getValue(JsonObject circulationSettingsById) {
return circulationSettingsById.getJsonObject(VALUE_KEY).getString(SAMPLE_KEY);
}

private JsonObject getCirculationSetting(String id) {
return new JsonObject()
.put(ID_KEY, id)
.put(NAME_KEY, SAMPLE_VALUE)
.put(VALUE_KEY, new JsonObject().put(SAMPLE_KEY, INITIAL_VALUE));
}

private static void assertThatCorrectCreation(JsonObject circulationSettingsResponse,
JsonObject circulationSettingsJson) {

String actualCreatedId = circulationSettingsResponse.getString(ID_KEY);
String expectedCreatedId = circulationSettingsJson.getString(ID_KEY);
String actualCreatedName = circulationSettingsResponse.getString(NAME_KEY);
String expectedCreatedName = circulationSettingsJson.getString(NAME_KEY);

assertThat(actualCreatedId, is(expectedCreatedId));
assertThat(actualCreatedName, is(expectedCreatedName));
}

private JsonObject getUpdatedSettingsJson() {
String updatedId = UUID.randomUUID().toString();
JsonObject circulationSettingsJsonUpdated = getCirculationSetting(updatedId);
JsonObject updatedValue = new JsonObject().put(SAMPLE_KEY, UPDATED_VALUE);
circulationSettingsJsonUpdated.put(VALUE_KEY, updatedValue);
return circulationSettingsJsonUpdated;
}
}
}

0 comments on commit 739bc35

Please sign in to comment.