Skip to content

Commit

Permalink
Merge pull request #92 from folio-org/bugfix-release-1.0.3
Browse files Browse the repository at this point in the history
Bugfix release v1.0.3 (Ramsons R2 2024 Bug Fix)
  • Loading branch information
OleksandrVidinieiev authored Dec 30, 2024
2 parents 7081542 + 5be1f26 commit 60c5142
Show file tree
Hide file tree
Showing 27 changed files with 896 additions and 166 deletions.
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.0.3 2024-12-30
* DCB transaction status synchronization (MODTLR-112)
* Resolve central tenant ID dynamically (MODTLR-118)
*
## 1.0.2 2024-12-12
* Copy Secure Patron name when cloning users (MODTLR-116)
* Support for intermediate requests (MODTLR-98)
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<groupId>org.folio</groupId>
<artifactId>mod-tlr</artifactId>
<name>mod-tlr</name>
<version>1.0.3-SNAPSHOT</version>
<version>1.0.4-SNAPSHOT</version>
<description>FOLIO mod-tlr module</description>
<packaging>jar</packaging>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.folio.client.feign;

import org.folio.domain.dto.ConsortiaConfiguration;
import org.folio.spring.config.FeignClientConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(name = "consortia-configuration", url = "consortia-configuration", configuration = FeignClientConfiguration.class)
public interface ConsortiaConfigurationClient {

@GetMapping
ConsortiaConfiguration getConfiguration();
}
13 changes: 0 additions & 13 deletions src/main/java/org/folio/domain/Constants.java

This file was deleted.

99 changes: 50 additions & 49 deletions src/main/java/org/folio/listener/kafka/KafkaEventListener.java
Original file line number Diff line number Diff line change
@@ -1,114 +1,115 @@
package org.folio.listener.kafka;

import static org.folio.domain.Constants.CENTRAL_TENANT_ID;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Optional;

import org.folio.domain.dto.Loan;
import org.folio.domain.dto.Request;
import org.folio.domain.dto.RequestsBatchUpdate;
import org.folio.domain.dto.User;
import org.folio.domain.dto.UserGroup;
import org.folio.exception.KafkaEventDeserializationException;
import org.folio.service.ConsortiaService;
import org.folio.service.KafkaEventHandler;
import org.folio.service.impl.LoanEventHandler;
import org.folio.service.impl.RequestBatchUpdateEventHandler;
import org.folio.service.impl.RequestEventHandler;
import org.folio.service.impl.UserEventHandler;
import org.folio.service.impl.UserGroupEventHandler;
import org.folio.spring.DefaultFolioExecutionContext;
import org.folio.spring.FolioExecutionContext;
import org.folio.spring.FolioModuleMetadata;
import org.folio.spring.integration.XOkapiHeaders;
import org.folio.spring.scope.FolioExecutionContextSetter;
import org.folio.spring.service.SystemUserScopedExecutionService;
import org.folio.support.KafkaEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;

@Component
@Log4j2
@RequiredArgsConstructor
public class KafkaEventListener {
private static final ObjectMapper objectMapper = new ObjectMapper();
private final RequestEventHandler requestEventHandler;
private final LoanEventHandler loanEventHandler;
private final UserGroupEventHandler userGroupEventHandler;
private final UserEventHandler userEventHandler;
private final SystemUserScopedExecutionService systemUserScopedExecutionService;
private final RequestBatchUpdateEventHandler requestBatchEventHandler;

public KafkaEventListener(@Autowired RequestEventHandler requestEventHandler,
@Autowired RequestBatchUpdateEventHandler requestBatchEventHandler,
@Autowired SystemUserScopedExecutionService systemUserScopedExecutionService,
@Autowired UserGroupEventHandler userGroupEventHandler,
@Autowired UserEventHandler userEventHandler) {

this.requestEventHandler = requestEventHandler;
this.systemUserScopedExecutionService = systemUserScopedExecutionService;
this.userGroupEventHandler = userGroupEventHandler;
this.requestBatchEventHandler = requestBatchEventHandler;
this.userEventHandler = userEventHandler;
}
private final ConsortiaService consortiaService;
private final FolioModuleMetadata folioModuleMetadata;

@KafkaListener(
topicPattern = "${folio.environment}\\.\\w+\\.circulation\\.request",
groupId = "${spring.kafka.consumer.group-id}"
)
public void handleRequestEvent(String eventString, MessageHeaders messageHeaders) {
log.debug("handleRequestEvent:: event: {}", () -> eventString);
KafkaEvent<Request> event = deserialize(eventString, messageHeaders, Request.class);
log.info("handleRequestEvent:: event received: {}", event::getId);
handleEvent(event, requestEventHandler);
log.info("handleRequestEvent:: event consumed: {}", event::getId);
public void handleRequestEvent(String eventString, @Headers Map<String, Object> messageHeaders) {
handleEvent(eventString, requestEventHandler, messageHeaders, Request.class);
}

@KafkaListener(
topicPattern = "${folio.environment}\\.\\w+\\.circulation\\.request-queue-reordering",
topicPattern = "${folio.environment}\\.\\w+\\.circulation\\.loan",
groupId = "${spring.kafka.consumer.group-id}"
)
public void handleRequestBatchUpdateEvent(String eventString, MessageHeaders messageHeaders) {
log.debug("handleRequestBatchUpdateEvent:: event: {}", () -> eventString);
KafkaEvent<RequestsBatchUpdate> event = deserialize(eventString, messageHeaders, RequestsBatchUpdate.class);
log.info("handleRequestBatchUpdateEvent:: event received: {}", event::getId);
handleEvent(event, requestBatchEventHandler);
log.info("handleRequestBatchUpdateEvent:: event consumed: {}", event::getId);
public void handleLoanEvent(String eventString, @Headers Map<String, Object> messageHeaders) {
handleEvent(eventString, loanEventHandler, messageHeaders, Loan.class);
}

private <T> void handleEvent(KafkaEvent<T> event, KafkaEventHandler<T> handler) {
try {
systemUserScopedExecutionService.executeAsyncSystemUserScoped(CENTRAL_TENANT_ID,
() -> handler.handle(event));
} catch (Exception e) {
log.error("handleEvent:: Failed to handle Kafka event in tenant {}", CENTRAL_TENANT_ID);
}
@KafkaListener(
topicPattern = "${folio.environment}\\.\\w+\\.circulation\\.request-queue-reordering",
groupId = "${spring.kafka.consumer.group-id}"
)
public void handleRequestBatchUpdateEvent(String eventString, @Headers Map<String, Object> messageHeaders) {
handleEvent(eventString, requestBatchEventHandler, messageHeaders, RequestsBatchUpdate.class);
}

@KafkaListener(
topicPattern = "${folio.environment}\\.\\w+\\.users\\.userGroup",
groupId = "${spring.kafka.consumer.group-id}"
)
public void handleUserGroupEvent(String eventString, MessageHeaders messageHeaders) {
KafkaEvent<UserGroup> event = deserialize(eventString, messageHeaders, UserGroup.class);

log.info("handleUserGroupEvent:: event received: {}", event::getId);
log.debug("handleUserGroupEvent:: event: {}", () -> event);
handleEvent(event, userGroupEventHandler);
public void handleUserGroupEvent(String eventString, @Headers Map<String, Object> messageHeaders) {
handleEvent(eventString, userGroupEventHandler, messageHeaders, UserGroup.class);
}

@KafkaListener(
topicPattern = "${folio.environment}\\.\\w+\\.users\\.users",
groupId = "${spring.kafka.consumer.group-id}"
)
public void handleUserEvent(String eventString, MessageHeaders messageHeaders) {
KafkaEvent<User> event = deserialize(eventString, messageHeaders, User.class);
public void handleUserEvent(String eventString, @Headers Map<String, Object> messageHeaders) {
handleEvent(eventString, userEventHandler, messageHeaders, User.class);
}

private <T> void handleEvent(String eventString, KafkaEventHandler<T> handler,
Map<String, Object> messageHeaders, Class<T> payloadType) {

log.info("handleUserEvent:: event received: {}", event::getId);
handleEvent(event, userEventHandler);
log.debug("handleEvent:: event: {}", () -> eventString);
KafkaEvent<T> event = deserialize(eventString, messageHeaders, payloadType);
log.info("handleEvent:: event received: {}", event::getId);

FolioExecutionContext context = DefaultFolioExecutionContext.fromMessageHeaders(
folioModuleMetadata, messageHeaders);

try (FolioExecutionContextSetter contextSetter = new FolioExecutionContextSetter(context)) {
String centralTenantId = consortiaService.getCentralTenantId();
systemUserScopedExecutionService.executeAsyncSystemUserScoped(centralTenantId,
() -> handler.handle(event));
} catch (Exception e) {
log.error("handleEvent:: failed to handle event {}", event.getId(), e);
}
log.info("handleEvent:: event consumed: {}", event::getId);
}

private static <T> KafkaEvent<T> deserialize(String eventString, MessageHeaders messageHeaders,
private static <T> KafkaEvent<T> deserialize(String eventString, Map<String, Object> messageHeaders,
Class<T> dataType) {

try {
Expand All @@ -125,7 +126,7 @@ private static <T> KafkaEvent<T> deserialize(String eventString, MessageHeaders
}
}

private static String getHeaderValue(MessageHeaders headers, String headerName) {
private static String getHeaderValue(Map<String, Object> headers, String headerName) {
log.debug("getHeaderValue:: headers: {}, headerName: {}", () -> headers, () -> headerName);
var headerValue = headers.get(headerName);
var value = headerValue == null
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/folio/repository/EcsTlrRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ public interface EcsTlrRepository extends JpaRepository<EcsTlrEntity, UUID> {
Optional<EcsTlrEntity> findByPrimaryRequestId(UUID primaryRequestId);
Optional<EcsTlrEntity> findByInstanceId(UUID instanceId);
List<EcsTlrEntity> findByPrimaryRequestIdIn(List<UUID> primaryRequestIds);
List<EcsTlrEntity> findByItemId(UUID itemId);
}
1 change: 1 addition & 0 deletions src/main/java/org/folio/service/ConsortiaService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
public interface ConsortiaService {
TenantCollection getAllConsortiumTenants(String consortiumId);
Collection<Tenant> getAllConsortiumTenants();
String getCentralTenantId();
}
5 changes: 3 additions & 2 deletions src/main/java/org/folio/service/DcbService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public interface DcbService {
void createBorrowerTransaction(EcsTlrEntity ecsTlr, Request request);
void createBorrowingPickupTransaction(EcsTlrEntity ecsTlr, Request request);
void createPickupTransaction(EcsTlrEntity ecsTlr, Request request);
void updateTransactionStatuses(TransactionStatus.StatusEnum newStatus, EcsTlrEntity ecsTlr);
TransactionStatusResponse getTransactionStatus(UUID transactionId, String tenantId);
TransactionStatusResponse updateTransactionStatus(UUID transactionId,
TransactionStatus.StatusEnum newStatus, String tenantId);
void updateTransactionStatus(UUID transactionId, TransactionStatus.StatusEnum newStatus,
String tenantId);
}
13 changes: 13 additions & 0 deletions src/main/java/org/folio/service/impl/ConsortiaServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import java.util.Optional;

import org.folio.client.feign.ConsortiaClient;
import org.folio.client.feign.ConsortiaConfigurationClient;
import org.folio.domain.dto.ConsortiaConfiguration;
import org.folio.domain.dto.Tenant;
import org.folio.domain.dto.TenantCollection;
import org.folio.domain.dto.UserTenant;
Expand All @@ -21,6 +23,7 @@
@RequiredArgsConstructor
public class ConsortiaServiceImpl implements ConsortiaService {
private final ConsortiaClient consortiaClient;
private final ConsortiaConfigurationClient consortiaConfigurationClient;
private final UserTenantsService userTenantsService;

@Override
Expand All @@ -40,4 +43,14 @@ public Collection<Tenant> getAllConsortiumTenants() {
log.info("getAllConsortiumTenants:: found {} consortium tenants", tenants::size);
return tenants;
}

@Override
public String getCentralTenantId() {
log.info("getCentralTenantId:: resolving central tenant ID");
String centralTenantId = Optional.ofNullable(consortiaConfigurationClient.getConfiguration())
.map(ConsortiaConfiguration::getCentralTenantId)
.orElseThrow();
log.info("getCentralTenantId:: central tenant ID: {}", centralTenantId);
return centralTenantId;
}
}
Loading

0 comments on commit 60c5142

Please sign in to comment.