This is an automated email from the ASF dual-hosted git repository. dgriffon pushed a commit to branch unomi-1.9.x in repository https://gitbox.apache.org/repos/asf/unomi.git
commit 8ec27b851ca981f3dc182a481c3b4982f8623a2b Author: jsinovassin <58434978+jsinovas...@users.noreply.github.com> AuthorDate: Fri Jul 28 08:40:27 2023 +0200 Unomi 785 fix npe (#637) * UNOMI-785 : create new profile in case session profile not existing anymore * UNOMI-785 : add integration tests --- .../org/apache/unomi/itests/ContextServletIT.java | 51 ++++++++++++++++++++++ .../unomi/rest/endpoints/ContextJsonEndpoint.java | 18 ++++---- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java b/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java index 4e5943ffd..ac7252203 100644 --- a/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java @@ -595,6 +595,57 @@ public class ContextServletIT extends BaseIT { /* We can see we still have old control group check stored in the session too */ false); } + @Test() + public void testEventSessionWithNotExistingProfile_Success() throws IOException, InterruptedException { + + //Arrange + String profileId = "profile-to-be-removed"; + Profile profile = new Profile(profileId); + profileService.save(profile); + + String sessionWithDeletedProfileId = "session-with-delete-profile"; + String scope = "test-scope"; + Session session = new Session(sessionWithDeletedProfileId, profile, new Date(), scope); + profileService.saveSession(session); + + refreshPersistence(Profile.class, Session.class); + keepTrying("Profile not saved in time", + () -> persistenceService.load(profileId, Profile.class), Objects::nonNull, + 1000, 10); + keepTrying("Session not saved in time", + () -> persistenceService.load(sessionWithDeletedProfileId, Session.class), Objects::nonNull, + 1000, 10); + + profileService.delete(profileId, false); + refreshPersistence(Profile.class); + waitForNullValue("Profile not deleted in time", + () -> persistenceService.load(profileId, Profile.class), + 1000, 10); + + String eventId = "test-event-id-" + System.currentTimeMillis(); + String eventType = "test-event-type"; + Event event = new Event(); + event.setEventType(eventType); + event.setItemId(eventId); + event.setSessionId(sessionWithDeletedProfileId); + + ContextRequest contextRequest = new ContextRequest(); + contextRequest.setEvents(Arrays.asList(event)); + contextRequest.setSessionId(sessionWithDeletedProfileId); + + HttpPost request = new HttpPost(URL + CONTEXT_URL); + request.addHeader(THIRD_PARTY_HEADER_NAME, UNOMI_KEY); + request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.create("application/json"))); + TestUtils.executeContextJSONRequest(request); + refreshPersistence(Profile.class, Session.class); + Thread.sleep(2000); //Making sure event is updated in DB + + //Assert + keepTrying("Session should not the deleted profile", + () -> persistenceService.load(sessionWithDeletedProfileId, Session.class), persistedSession -> !persistedSession.getProfileId().equals(profileId), + 1000, 10); + } + private void performPersonalizationWithControlGroup(Map<String, String> controlGroupConfig, List<String> expectedVariants, boolean expectedControlGroupInfoInPersoResult, boolean expectedControlGroupValueInPersoResult, Boolean expectedControlGroupValueInProfile, Boolean expectedControlGroupValueInSession) throws Exception { diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java index a7ebea0da..38f8de4bb 100644 --- a/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java +++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/ContextJsonEndpoint.java @@ -50,14 +50,7 @@ import javax.ws.rs.*; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; @WebService @Consumes(MediaType.APPLICATION_JSON) @@ -232,7 +225,14 @@ public class ContextJsonEndpoint { // Session user has been switched, profile id in cookie is not up to date // We must reload the profile with the session ID as some properties could be missing from the session profile // #personalIdentifier - profile = profileService.load(sessionProfile.getItemId()); + Profile persistedProfile = profileService.load(sessionProfile.getItemId()); + if (persistedProfile == null){ + logger.error("Profile with id {} stored in session {} not existing anymore in profile index. A new profile will be created", sessionProfile.getItemId(), session.getItemId()); + profile = createNewProfile(null, timestamp); + profileCreated = true; + } else { + profile = persistedProfile; + } } // Handle anonymous situation