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

CIRCSTORE-527 Merge ecs-tlr-feature branch into master #496

Merged
merged 18 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
2d74a75
[CIRCSTORE-502] Add ecsRequestPhase field to request schema (#462)
roman-barannyk Apr 22, 2024
81c55e3
CIRCSTORE-509: Create CRUD API for storing circulation settings (#466)
MagzhanArtykov Jun 11, 2024
49d2d1e
Merge branch 'master' into ecs-tlr-feature
alexanderkurash Jun 19, 2024
81c9932
CIRCSTORE- 519 Update instead save with the same name circ settings. …
AntonAntonich Aug 16, 2024
8a2462f
Merge branch 'master' of github.com:folio-org/mod-circulation-storage…
roman-barannyk Aug 19, 2024
46fe4c6
CIRCSTORE-519 fixed unit test
AntonAntonich Aug 19, 2024
738f093
CIRCSTORE-519 removed comments test
AntonAntonich Aug 20, 2024
c860953
Merge branch 'refs/heads/master' into ecs-tlr-feature
AntonAntonich Aug 22, 2024
58effff
CIRCSTORE-525 implementation
AntonAntonich Aug 27, 2024
a7c1910
Merge pull request #486 from folio-org/CIRCSTORE-525
OleksandrVidinieiev Aug 29, 2024
b35fa1d
[CIRCSTORE-521] Publish request batch event when requests are reorder…
roman-barannyk Aug 29, 2024
078733e
[CIRCSTORE-526] Add ILR support for publishing batch request update e…
roman-barannyk Sep 16, 2024
5591f35
Merge branch 'master' of github.com:folio-org/mod-circulation-storage…
roman-barannyk Oct 18, 2024
af2d0bd
Merge branch 'master' of github.com:folio-org/mod-circulation-storage…
roman-barannyk Oct 25, 2024
b39d10e
Merge branch 'master' of github.com:folio-org/mod-circulation-storage…
AntonAntonich Oct 25, 2024
5851ec8
Fixed StaffSlipsApiTest
AntonAntonich Oct 25, 2024
8517254
Merge branch 'ecs-tlr-feature' of github.com:folio-org/mod-circulatio…
roman-barannyk Oct 25, 2024
e39ab64
Merge branch 'master' of github.com:folio-org/mod-circulation-storage…
roman-barannyk Nov 6, 2024
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
35 changes: 35 additions & 0 deletions ramls/request-queue-reordering.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Requests batch update",
"description": "List of ids reordered requests",
"type": "object",
"properties": {
"instanceId": {
"description": "Instance ID of reordered requests",
"type": "string",
"$ref": "raml-util/schemas/uuid.schema"
},
"itemId": {
"description": "Item ID of reordered requests",
"type": "string",
"$ref": "raml-util/schemas/uuid.schema"
},
"requestLevel": {
"description": "Level of the request - Item or Title",
"type": "string",
"enum": ["Item", "Title"]
},
"requestIds": {
"description": "Array of requests ids",
"type": "array",
"items": {
"type": "string",
"$ref": "raml-util/schemas/uuid.schema"
}
}
},
"additionalProperties": false,
"required": [
"requestLevel"
]
}
1 change: 1 addition & 0 deletions ramls/request-storage-batch.raml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ documentation:
types:
requests-batch: !include requests-batch.json
errors: !include raml-util/schemas/errors.schema
request-queue-reordering: !include request-queue-reordering.json

traits:
validate: !include raml-util/traits/validation.raml
Expand Down
5 changes: 5 additions & 0 deletions ramls/request.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
"type": "string",
"enum": ["Hold", "Recall", "Page"]
},
"ecsRequestPhase": {
"description": "Stage in ECS request process, absence of this field means this is a single-tenant request",
"type": "string",
"enum": ["Primary", "Secondary"]
},
"requestDate": {
"description": "Date the request was made",
"type": "string",
Expand Down
18 changes: 9 additions & 9 deletions src/main/java/org/folio/rest/impl/CirculationSettingsAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,28 @@ public void getCirculationSettingsStorageCirculationSettingsByCirculationSetting
String circulationSettingsId, Map<String, String> okapiHeaders,
Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {

new CirculationSettingsService(vertxContext, okapiHeaders)
.findById(circulationSettingsId)
.onComplete(asyncResultHandler);
new CirculationSettingsService(vertxContext, okapiHeaders)
.findById(circulationSettingsId)
.onComplete(asyncResultHandler);
}

@Override
public void putCirculationSettingsStorageCirculationSettingsByCirculationSettingsId(
String circulationSettingsId, CirculationSetting entity, Map<String, String> okapiHeaders,
Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {

new CirculationSettingsService(vertxContext, okapiHeaders)
.update(circulationSettingsId, entity)
.onComplete(asyncResultHandler);
new CirculationSettingsService(vertxContext, okapiHeaders)
.update(circulationSettingsId, entity)
.onComplete(asyncResultHandler);
}

@Override
public void deleteCirculationSettingsStorageCirculationSettingsByCirculationSettingsId(
String circulationSettingsId, Map<String, String> okapiHeaders,
Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {

new CirculationSettingsService(vertxContext, okapiHeaders)
.delete(circulationSettingsId)
.onComplete(asyncResultHandler);
new CirculationSettingsService(vertxContext, okapiHeaders)
.delete(circulationSettingsId)
.onComplete(asyncResultHandler);
}
}
25 changes: 8 additions & 17 deletions src/main/java/org/folio/rest/impl/RequestsBatchAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@
import static org.folio.rest.jaxrs.resource.RequestStorageBatch.PostRequestStorageBatchRequestsResponse.respond201;
import static org.folio.rest.jaxrs.resource.RequestStorageBatch.PostRequestStorageBatchRequestsResponse.respond422WithApplicationJson;
import static org.folio.rest.jaxrs.resource.RequestStorageBatch.PostRequestStorageBatchRequestsResponse.respond500WithTextPlain;
import static org.folio.rest.tools.utils.TenantTool.tenantId;

import java.util.Map;

import javax.ws.rs.core.Response;
import org.folio.rest.annotations.Validate;
import org.folio.rest.jaxrs.model.RequestsBatch;
import org.folio.rest.jaxrs.resource.RequestStorageBatch;
import org.folio.rest.persist.PgUtil;
import org.folio.rest.tools.utils.MetadataUtil;
import org.folio.service.BatchResourceService;
import org.folio.service.request.RequestBatchResourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -26,7 +23,7 @@
import io.vertx.core.Handler;

public class RequestsBatchAPI implements RequestStorageBatch {
private static final Logger LOG = LoggerFactory.getLogger(RequestsBatchAPI.class);
private static final Logger log = LoggerFactory.getLogger(RequestsBatchAPI.class);

@Validate
@Override
Expand All @@ -38,36 +35,30 @@ public void postRequestStorageBatchRequests(
MetadataUtil.populateMetadata(entity.getRequests(), okapiHeaders);
} catch (Throwable e) {
String msg = "Cannot populate metadata of request list elements: " + e.getMessage();
LOG.error(msg, e);
log.error(msg, e);
asyncResultHandler.handle(succeededFuture(respond500WithTextPlain(msg)));
return;
}

BatchResourceService batchUpdateService = new BatchResourceService(
PgUtil.postgresClient(context, okapiHeaders)
);

RequestBatchResourceService requestBatchUpdateService =
new RequestBatchResourceService(tenantId(okapiHeaders), batchUpdateService);

requestBatchUpdateService.executeRequestBatchUpdate(entity.getRequests(),
updateResult -> {
log.info("postRequestStorageBatchRequests:: requests: {}", entity.getRequests());
new RequestBatchResourceService(context, okapiHeaders)
.executeRequestBatchUpdate(entity.getRequests(), updateResult -> {
// Successfully updated
if (updateResult.succeeded()) {
LOG.debug("Batch update executed successfully");
log.debug("Batch update executed successfully");
asyncResultHandler.handle(succeededFuture(respond201()));
return;
}

// Update failed due to can not have more then one request in the same position
if (hasSamePositionConstraintViolated(updateResult.cause())) {
LOG.warn("Same position constraint violated", updateResult.cause());
log.warn("Same position constraint violated", updateResult.cause());
asyncResultHandler.handle(succeededFuture(
respond422WithApplicationJson(samePositionInQueueError(null, null))
));
} else {
// Other failure occurred
LOG.warn("Unhandled error occurred during update", updateResult.cause());
log.warn("Unhandled error occurred during update", updateResult.cause());
asyncResultHandler.handle(succeededFuture(
respond500WithTextPlain(updateResult.cause().getMessage())
));
Expand Down
40 changes: 27 additions & 13 deletions src/main/java/org/folio/service/BatchResourceService.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import io.vertx.sqlclient.RowSet;

public class BatchResourceService {
private static final Logger LOG = LoggerFactory.getLogger(BatchResourceService.class);
private static final Logger log = LoggerFactory.getLogger(BatchResourceService.class);
private static final String WHERE_CLAUSE = "WHERE id = '%s'";

private final PostgresClient postgresClient;
Expand All @@ -38,14 +38,17 @@ public BatchResourceService(PostgresClient postgresClient) {
* @param batchFactories - Factory to create a batch update chunk.
* @param onFinishHandler - Callback.
*/
public void executeBatchUpdate(
public Future<Void> executeBatchUpdate(
List<Function<SQLConnection, Future<RowSet<Row>>>> batchFactories,
Handler<AsyncResult<Void>> onFinishHandler) {

Promise<Void> promise = Promise.promise();

postgresClient.startTx(connectionResult -> {
if (connectionResult.failed()) {
LOG.warn("Can not start transaction", connectionResult.cause());
log.warn("Cannot start transaction", connectionResult.cause());
onFinishHandler.handle(failedFuture(connectionResult.cause()));
promise.fail(connectionResult.cause());
return;
}

Expand All @@ -60,21 +63,32 @@ public void executeBatchUpdate(
// Handle overall update result and decide on whether to commit or rollback transaction
lastUpdate.onComplete(updateResult -> {
if (updateResult.failed()) {
LOG.warn("Batch update rejected", updateResult.cause());
log.warn("Batch update rejected", updateResult.cause());

// Rollback transaction and keep original cause.
postgresClient.rollbackTx(connectionResult,
rollback -> onFinishHandler.handle(failedFuture(updateResult.cause()))
);
postgresClient.rollbackTx(connectionResult, rollback -> {
onFinishHandler.handle(failedFuture(updateResult.cause()));
promise.fail(updateResult.cause());
});
} else {
LOG.debug("Update successful, committing transaction");

postgresClient.endTx(connectionResult, onFinishHandler);
log.debug("Update successful, committing transaction");

postgresClient.endTx(connectionResult, commitResult -> {
if (commitResult.succeeded()) {
onFinishHandler.handle(succeededFuture());
promise.complete();
} else {
log.warn("Failed to commit transaction", commitResult.cause());
onFinishHandler.handle(failedFuture(commitResult.cause()));
promise.fail(commitResult.cause());
}
});
}
});
});
}

return promise.future();
}
/**
* Creates update single entity batch function.
*
Expand All @@ -92,7 +106,7 @@ public <T> Function<SQLConnection, Future<RowSet<Row>>> updateSingleEntityBatchF
final Promise<RowSet<Row>> promise = promise();
final Future<SQLConnection> connectionResult = succeededFuture(connection);

LOG.debug("Updating entity {} with id {}", entity, id);
log.debug("Updating entity {} with id {}", entity, id);

postgresClient.update(connectionResult, tableName, entity, "jsonb",
String.format(WHERE_CLAUSE, id), false, promise);
Expand All @@ -113,7 +127,7 @@ public Function<SQLConnection, Future<RowSet<Row>>> queryWithParamsBatchFactory(
String query, Collection<?> params) {

return connection -> {
LOG.debug("Executing SQL [{}], got [{}] parameters", query, params.size());
log.debug("Executing SQL [{}], got [{}] parameters", query, params.size());

final Promise<RowSet<Row>> promise = promise();
final Future<SQLConnection> connectionResult = succeededFuture(connection);
Expand Down
18 changes: 11 additions & 7 deletions src/main/java/org/folio/service/CirculationSettingsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,21 @@ public Future<Response> findById(String circulationSettingsId) {
GetCirculationSettingsStorageCirculationSettingsByCirculationSettingsIdResponse.class);
}

public Future<Response> update(String circulationSettingsId, CirculationSetting circulationSetting) {
return PgUtil.put(CIRCULATION_SETTINGS_TABLE, circulationSetting, circulationSettingsId, okapiHeaders, vertxContext,
public Future<Response> update(String circulationSettingsId,
CirculationSetting circulationSetting) {

return PgUtil.put(CIRCULATION_SETTINGS_TABLE, circulationSetting, circulationSettingsId,
okapiHeaders, vertxContext,
PutCirculationSettingsStorageCirculationSettingsByCirculationSettingsIdResponse.class)
.compose(eventPublisher.publishUpdated(circulationSetting));
}

public Future<Response> delete(String circulationSettingsId) {
return repository.getById(circulationSettingsId).compose (
circulationSetting -> PgUtil.deleteById(CIRCULATION_SETTINGS_TABLE, circulationSettingsId, okapiHeaders, vertxContext,
DeleteCirculationSettingsStorageCirculationSettingsByCirculationSettingsIdResponse.class)
.compose(eventPublisher.publishRemoved(circulationSetting))
return repository.getById(circulationSettingsId)
.compose(circulationSetting -> PgUtil.deleteById(CIRCULATION_SETTINGS_TABLE,
circulationSettingsId, okapiHeaders, vertxContext,
DeleteCirculationSettingsStorageCirculationSettingsByCirculationSettingsIdResponse.class)
.compose(eventPublisher.publishRemoved(circulationSetting))
);
}

Expand Down Expand Up @@ -109,4 +113,4 @@ private Future<List<CirculationSetting>> getSettingsByName(String settingsName)

return repository.get(filter);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static org.folio.support.kafka.topic.CirculationStorageKafkaTopic.CIRCULATION_SETTINGS;
import static org.folio.support.kafka.topic.CirculationStorageKafkaTopic.LOAN;
import static org.folio.support.kafka.topic.CirculationStorageKafkaTopic.REQUEST;
import static org.folio.support.kafka.topic.CirculationStorageKafkaTopic.REQUEST_QUEUE_REORDERING;
import static org.folio.support.kafka.topic.CirculationStorageKafkaTopic.RULES;

import java.util.Map;
Expand All @@ -19,6 +20,7 @@
import org.folio.rest.jaxrs.model.CirculationSetting;
import org.folio.rest.jaxrs.model.Loan;
import org.folio.rest.jaxrs.model.Request;
import org.folio.rest.jaxrs.model.RequestQueueReordering;

import io.vertx.core.Context;
import lombok.extern.log4j.Log4j2;
Expand Down Expand Up @@ -53,6 +55,15 @@ public static EntityChangedEventPublisher<String, Request> requestEventPublisher
new RequestRepository(vertxContext, okapiHeaders));
}

public static EntityChangedEventPublisher<String, RequestQueueReordering>
requestBatchEventPublisher(Context vertxContext, Map<String, String> okapiHeaders) {

return new EntityChangedEventPublisher<>(okapiHeaders, RequestQueueReordering::getInstanceId,
NULL_ID, new EntityChangedEventFactory<>(), new DomainEventPublisher<>(vertxContext,
REQUEST_QUEUE_REORDERING.fullTopicName(tenantId(okapiHeaders)),
FailureHandler.noOperation()), null);
}

public static EntityChangedEventPublisher<String, CheckIn> checkInEventPublisher(
Context vertxContext, Map<String, String> okapiHeaders) {

Expand Down
Loading