diff --git a/pre-registration-booking-service/pom.xml b/pre-registration-booking-service/pom.xml
index 948569ade72..0f714ba5f2d 100644
--- a/pre-registration-booking-service/pom.xml
+++ b/pre-registration-booking-service/pom.xml
@@ -14,6 +14,7 @@
UTF-8
1.4.2
1.4.0-SNAPSHOT
+ 1.4.0-SNAPSHOT
1.4.0-SNAPSHOT
1.4.0-SNAPSHOT
21
@@ -143,6 +144,11 @@
pre-registration-core
${pre.registration.core.version}
+
+ io.mosip.preregistration
+ pre-registration-application-service
+ ${pre.registration.application.service.version}
+
io.mosip.kernel
kernel-core
diff --git a/pre-registration-booking-service/src/main/java/io/mosip/preregistration/booking/service/BookingService.java b/pre-registration-booking-service/src/main/java/io/mosip/preregistration/booking/service/BookingService.java
index c4ac2fe0a94..3b8c2072cac 100644
--- a/pre-registration-booking-service/src/main/java/io/mosip/preregistration/booking/service/BookingService.java
+++ b/pre-registration-booking-service/src/main/java/io/mosip/preregistration/booking/service/BookingService.java
@@ -45,6 +45,7 @@
import io.mosip.preregistration.booking.exception.RecordNotFoundException;
import io.mosip.preregistration.booking.exception.util.BookingExceptionCatcher;
import io.mosip.preregistration.booking.repository.impl.BookingDAO;
+import io.mosip.preregistration.application.service.ApplicationIdentityMigrationService;
import io.mosip.preregistration.booking.service.util.BookingLock;
import io.mosip.preregistration.booking.service.util.BookingServiceUtil;
import io.mosip.preregistration.core.code.AuditLogVariables;
@@ -83,6 +84,9 @@ public class BookingService implements BookingServiceIntf {
@Autowired
BookingServiceUtil serviceUtil;
+ @Autowired
+ private ApplicationIdentityMigrationService applicationIdentityMigrationService;
+
/**
* Reference for ${preregistration.availability.sync} from property file
*/
@@ -641,8 +645,9 @@ public BookingStatusDTO book(String preRegistrationId, BookingRequestDTO booking
" and Date and Time " + availableEntity.getRegDate() + " " + availableEntity.getFromTime());
if (serviceUtil.isKiosksAvailable(availableEntity)) {
/* Updating booking */
- bookingDAO.saveRegistrationEntityForBooking(
+ RegistrationBookingEntity bookingEntity = bookingDAO.saveRegistrationEntityForBooking(
serviceUtil.bookingEntitySetter(preRegistrationId, bookingRequestDTO));
+ applicationIdentityMigrationService.migrateRawUserToEffectiveUser(preRegistrationId, bookingEntity.getCrBy());
/* Reduce Availability */
availableEntity.setAvailableKiosks(availableEntity.getAvailableKiosks() - 1);
AvailibityEntity availableUpdate = bookingDAO.updateAvailibityEntity(availableEntity);
@@ -704,6 +709,10 @@ public CancelBookingResponseDTO cancelBooking(String preRegistrationId, boolean
serviceUtil.timeSpanCheckForCancle(bookedDateTime);
}
+ String effectiveUserId = applicationIdentityMigrationService
+ .resolveEffectiveUserId(bookingEntity.getCrBy());
+ applicationIdentityMigrationService.migrateRawUserToEffectiveUser(preRegistrationId,
+ effectiveUserId);
/* Deleting the canceled booking */
// bookingDAO.deleteRegistrationEntity(bookingEntity);
bookingDAO.deleteByPreRegistrationId(preRegistrationId);
@@ -765,6 +774,9 @@ public MainResponseDTO deleteBooking(String preregId) {
if (validationUtil.requstParamValidator(requestParamMap)
&& serviceUtil.checkApplicationStatus(preregId)) {
RegistrationBookingEntity registrationEntityList = bookingDAO.findByPreRegistrationId(preregId);
+ String effectiveUserId = applicationIdentityMigrationService
+ .resolveEffectiveUserId(registrationEntityList.getCrBy());
+ applicationIdentityMigrationService.migrateRawUserToEffectiveUser(preregId, effectiveUserId);
String str = registrationEntityList.getRegDate() + " " + registrationEntityList.getSlotFromTime();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime bookedDateTime = LocalDateTime.parse(str, formatter);
@@ -782,7 +794,7 @@ public MainResponseDTO deleteBooking(String preregId) {
bookingDAO.updateAvailibityEntity(availableEntity);
deleteDto.setPreRegistrationId(registrationEntityList.getPreregistrationId());
- deleteDto.setDeletedBy(registrationEntityList.getCrBy());
+ deleteDto.setDeletedBy(effectiveUserId);
deleteDto.setDeletedDateTime(new Date(System.currentTimeMillis()));
}
diff --git a/pre-registration-booking-service/src/main/java/io/mosip/preregistration/booking/service/util/BookingServiceUtil.java b/pre-registration-booking-service/src/main/java/io/mosip/preregistration/booking/service/util/BookingServiceUtil.java
index 2090c2d9346..96ba3a81822 100644
--- a/pre-registration-booking-service/src/main/java/io/mosip/preregistration/booking/service/util/BookingServiceUtil.java
+++ b/pre-registration-booking-service/src/main/java/io/mosip/preregistration/booking/service/util/BookingServiceUtil.java
@@ -19,6 +19,7 @@
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
+import java.util.UUID;
import jakarta.annotation.PostConstruct;
@@ -69,6 +70,7 @@
import io.mosip.preregistration.booking.exception.BookingPreIdNotFoundException;
import io.mosip.preregistration.booking.exception.BookingRegistrationCenterIdNotFoundException;
import io.mosip.preregistration.booking.exception.BookingTimeSlotNotSeletectedException;
+import io.mosip.preregistration.booking.exception.AppointmentBookingFailedException;
import io.mosip.preregistration.booking.exception.DemographicGetStatusException;
import io.mosip.preregistration.booking.exception.InvalidDateTimeFormatException;
import io.mosip.preregistration.booking.exception.RecordNotFoundException;
@@ -81,12 +83,16 @@
import io.mosip.preregistration.core.common.dto.RequestWrapper;
import io.mosip.preregistration.core.common.dto.ResponseWrapper;
import io.mosip.preregistration.core.common.entity.RegistrationBookingEntity;
+import io.mosip.preregistration.core.common.entity.UserDetails;
import io.mosip.preregistration.core.config.LoggerConfiguration;
import io.mosip.preregistration.core.exception.MasterDataNotAvailableException;
import io.mosip.preregistration.core.exception.NotificationException;
import io.mosip.preregistration.core.exception.RestCallException;
import io.mosip.preregistration.core.util.UUIDGeneratorUtil;
import io.mosip.preregistration.core.util.ValidationUtil;
+import io.mosip.preregistration.core.common.service.UserDetailsService;
+import io.mosip.preregistration.core.exception.UserLookupException;
+import io.mosip.preregistration.core.util.GenericUtil;
/**
* This class provides the utility methods for Booking application.
@@ -107,6 +113,9 @@ public class BookingServiceUtil {
@Autowired
private RestTemplate restTemplate;
+ @Autowired
+ private UserDetailsService userDetailsService;
+
/**
* Reference for ${regCenter.url} from property file
*/
@@ -140,6 +149,9 @@ public class BookingServiceUtil {
@Value("${mosip.notification.timezone}")
private String specificZoneId;
+ @Value("${mosip.prereg.pii.backward.compatibility}")
+ private boolean piiBackwardCompatibility;
+
/**
* ObjectMapper global object creation
*/
@@ -535,7 +547,8 @@ public RegistrationBookingEntity bookingEntitySetter(String preRegistrationId,
entity.setRegistrationCenterId(bookingRequestDTO.getRegistrationCenterId());
entity.setId(UUIDGeneratorUtil.generateId());
entity.setLangCode("12L");
- entity.setCrBy(authUserDetails().getUserId());
+ String userId = authUserDetails().getUserId();
+ entity.setCrBy(resolveEffectiveCrBy(userId));
entity.setCrDate(DateUtils2.parseDateToLocalDateTime(new Date()));
entity.setRegDate(LocalDate.parse(bookingRequestDTO.getRegDate()));
entity.setSlotFromTime(LocalTime.parse(bookingRequestDTO.getSlotFromTime()));
@@ -544,6 +557,24 @@ public RegistrationBookingEntity bookingEntitySetter(String preRegistrationId,
return entity;
}
+ private String resolveEffectiveCrBy(String userId) {
+ String maskedUserId = GenericUtil.maskIdentifier(userId);
+ try {
+ String effectiveCrBy = userDetailsService.getOrCreateInternalUserId(userId);
+ boolean canonicalApplied = effectiveCrBy != null && !effectiveCrBy.isBlank()
+ && !effectiveCrBy.trim().equals(userId == null ? "" : userId.trim());
+ log.info("sessionId", "idType", "id",
+ "Resolved effective user id for booking write. maskedUserId=" + maskedUserId
+ + ", canonicalApplied=" + canonicalApplied);
+ return effectiveCrBy;
+ } catch (UserLookupException ex) {
+ log.warn("sessionId", "idType", "id",
+ "Failed to resolve effective booking user id for " + maskedUserId);
+ throw new AppointmentBookingFailedException(ErrorCodes.PRG_BOOK_RCI_005.getCode(),
+ ErrorMessages.APPOINTMENT_BOOKING_FAILED.getMessage());
+ }
+ }
+
/**
*
* @param notificationDTO
@@ -734,3 +765,4 @@ public MainResponseDTO getApplicationStatus(String applicationId) {
// }
}
+
diff --git a/pre-registration-booking-service/src/main/resources/bootstrap.properties b/pre-registration-booking-service/src/main/resources/bootstrap.properties
index 46f53f8cdac..54351b9d9a4 100644
--- a/pre-registration-booking-service/src/main/resources/bootstrap.properties
+++ b/pre-registration-booking-service/src/main/resources/bootstrap.properties
@@ -15,6 +15,7 @@ server.port=9095
health.config.enabled=false
mosip.preregistration.booking.id.book=mosip.pre-registration.booking.book
mosip.id.preregistration.booking.book=mosip.pre-registration.booking.book
+mosip.prereg.pii.backward.compatibility=false
#disabling health check so that client doesnt try to load properties from sprint config server every
# 5 minutes (should not be done in production)
diff --git a/pre-registration-booking-service/src/test/java/io/mosip/preregistration/booking/test/service/util/BookingServiceUtilTest.java b/pre-registration-booking-service/src/test/java/io/mosip/preregistration/booking/test/service/util/BookingServiceUtilTest.java
index 4b15de71e79..31c72ac39ff 100644
--- a/pre-registration-booking-service/src/test/java/io/mosip/preregistration/booking/test/service/util/BookingServiceUtilTest.java
+++ b/pre-registration-booking-service/src/test/java/io/mosip/preregistration/booking/test/service/util/BookingServiceUtilTest.java
@@ -13,7 +13,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
+import io.mosip.preregistration.booking.exception.*;
+import io.mosip.preregistration.core.exception.UserLookupException;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -32,6 +33,7 @@
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -51,15 +53,6 @@
import io.mosip.preregistration.booking.dto.RegistrationCenterResponseDto;
import io.mosip.preregistration.booking.dto.SlotDto;
import io.mosip.preregistration.booking.entity.AvailibityEntity;
-import io.mosip.preregistration.booking.exception.AppointmentReBookingFailedException;
-import io.mosip.preregistration.booking.exception.AvailablityNotFoundException;
-import io.mosip.preregistration.booking.exception.BookingDateNotSeletectedException;
-import io.mosip.preregistration.booking.exception.BookingPreIdNotFoundException;
-import io.mosip.preregistration.booking.exception.BookingRegistrationCenterIdNotFoundException;
-import io.mosip.preregistration.booking.exception.BookingTimeSlotNotSeletectedException;
-import io.mosip.preregistration.booking.exception.InvalidDateTimeFormatException;
-import io.mosip.preregistration.booking.exception.RecordNotFoundException;
-import io.mosip.preregistration.booking.exception.TimeSpanException;
import io.mosip.preregistration.booking.repository.BookingAvailabilityRepository;
import io.mosip.preregistration.booking.repository.RegistrationBookingRepository;
import io.mosip.preregistration.booking.repository.impl.BookingDAO;
@@ -68,6 +61,8 @@
import io.mosip.preregistration.core.common.dto.MainRequestDTO;
import io.mosip.preregistration.core.common.dto.NotificationDTO;
import io.mosip.preregistration.core.common.dto.ResponseWrapper;
+import io.mosip.preregistration.core.common.entity.RegistrationBookingEntity;
+import io.mosip.preregistration.core.common.service.UserDetailsService;
import io.mosip.preregistration.core.exception.MasterDataNotAvailableException;
import io.mosip.preregistration.core.exception.RestCallException;
import io.mosip.preregistration.core.util.RequestValidator;
@@ -97,6 +92,9 @@ public class BookingServiceUtilTest {
@MockBean
private BookingDAO bookingDAO;
+ @MockBean
+ private UserDetailsService userDetailsService;
+
@Mock
private AuthUserDetails authUserDetails;
@@ -139,6 +137,9 @@ public void setup() throws Exception {
Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);
Mockito.when(SecurityContextHolder.getContext().getAuthentication().getPrincipal()).thenReturn(applicationUser);
+ Mockito.when(applicationUser.getUserId()).thenReturn("test-user");
+ Mockito.when(userDetailsService.getOrCreateInternalUserId("test-user"))
+ .thenReturn("00000000-0000-0000-0000-000000000001");
centerDto.setId("10001");
centerDto.setLangCode("eng");
centerDto.setCenterStartTime(startTime);
@@ -568,6 +569,44 @@ public void emailNotificationTest() throws JsonProcessingException {
@Test
public void bookingEntitySetterTest() {
+ ReflectionTestUtils.setField(serviceUtil, "piiBackwardCompatibility", false);
+ BookingRequestDTO bookingRequestDTO = new BookingRequestDTO();
+ bookingRequestDTO.setRegistrationCenterId("1");
+ bookingRequestDTO.setSlotFromTime("09:00");
+ bookingRequestDTO.setSlotToTime("09:13");
+ bookingRequestDTO.setRegDate("2018-12-06");
+ serviceUtil.bookingEntitySetter("1234568687844744", bookingRequestDTO);
+ }
+
+ @Test
+ public void bookingEntitySetterLegacyCrByTest() {
+ ReflectionTestUtils.setField(serviceUtil, "piiBackwardCompatibility", false);
+ BookingRequestDTO bookingRequestDTO = new BookingRequestDTO();
+ bookingRequestDTO.setRegistrationCenterId("1");
+ bookingRequestDTO.setSlotFromTime("09:00");
+ bookingRequestDTO.setSlotToTime("09:13");
+ bookingRequestDTO.setRegDate("2018-12-06");
+ RegistrationBookingEntity entity = serviceUtil.bookingEntitySetter("1234568687844744", bookingRequestDTO);
+ assertEquals("00000000-0000-0000-0000-000000000001", entity.getCrBy());
+ }
+
+ @Test
+ public void bookingEntitySetterWithCompatibilityModeWritesUuidTest() {
+ ReflectionTestUtils.setField(serviceUtil, "piiBackwardCompatibility", true);
+ BookingRequestDTO bookingRequestDTO = new BookingRequestDTO();
+ bookingRequestDTO.setRegistrationCenterId("1");
+ bookingRequestDTO.setSlotFromTime("09:00");
+ bookingRequestDTO.setSlotToTime("09:13");
+ bookingRequestDTO.setRegDate("2018-12-06");
+ RegistrationBookingEntity entity = serviceUtil.bookingEntitySetter("1234568687844744", bookingRequestDTO);
+ assertEquals("00000000-0000-0000-0000-000000000001", entity.getCrBy());
+ }
+
+ @Test(expected = AppointmentBookingFailedException.class)
+ public void bookingEntitySetterThrowsOnUuidResolutionFailureTest() {
+ ReflectionTestUtils.setField(serviceUtil, "piiBackwardCompatibility", false);
+ Mockito.when(userDetailsService.getOrCreateInternalUserId("test-user"))
+ .thenThrow(new UserLookupException("PRG_CORE_REQ_024", "Failed to resolve internal user ID"));
BookingRequestDTO bookingRequestDTO = new BookingRequestDTO();
bookingRequestDTO.setRegistrationCenterId("1");
bookingRequestDTO.setSlotFromTime("09:00");
@@ -646,3 +685,5 @@ public void timeSpanCheckForRebook1() {
}
}
+
+
diff --git a/pre-registration-booking-service/src/test/resources/application.properties b/pre-registration-booking-service/src/test/resources/application.properties
index 4c5991c7926..ad94dc47102 100644
--- a/pre-registration-booking-service/src/test/resources/application.properties
+++ b/pre-registration-booking-service/src/test/resources/application.properties
@@ -26,6 +26,7 @@ preregistration.rebook.timespan = 24
preregistration.cancel.timespan = 24
preregistration.timespan.cancel=24
preregistration.timespan.rebook=24
+mosip.prereg.pii.backward.compatibility=false
service.version=v1.0
master.service.env=masterdata