Repository: incubator-unomi Updated Branches: refs/heads/master a171e3d8f -> 38ddefc48
UNOMI-199 fix integration test, increase reliability, add integration test to test multiple visitor login on same browser Project: http://git-wip-us.apache.org/repos/asf/incubator-unomi/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-unomi/commit/38ddefc4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-unomi/tree/38ddefc4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-unomi/diff/38ddefc4 Branch: refs/heads/master Commit: 38ddefc48522977ddbbf93ccc08c9cea12362cad Parents: a171e3d Author: dgaillard <[email protected]> Authored: Fri Sep 21 16:49:16 2018 +0200 Committer: dgaillard <[email protected]> Committed: Fri Sep 21 16:49:16 2018 +0200 ---------------------------------------------------------------------- itests/pom.xml | 11 +- .../java/org/apache/unomi/itests/AllITs.java | 2 +- .../java/org/apache/unomi/itests/BaseIT.java | 19 +- .../java/org/apache/unomi/itests/BasicIT.java | 314 +++++++++++++++++-- .../apache/unomi/itests/ModifyConsentIT.java | 4 +- .../unomi/itests/ProfileImportActorsIT.java | 6 +- .../unomi/itests/ProfileImportBasicIT.java | 75 ++--- .../unomi/itests/ProfileImportRankingIT.java | 6 +- .../unomi/itests/ProfileImportSurfersIT.java | 8 +- .../java/org/apache/unomi/itests/TestUtils.java | 7 +- itests/src/test/resources/1-basic-test.csv | 6 +- itests/src/test/resources/testLogin.json | 34 ++ .../test/resources/testLoginEventCondition.json | 23 ++ .../apache/unomi/lifecycle/BundleWatcher.java | 2 +- .../resources/OSGI-INF/blueprint/blueprint.xml | 6 + 15 files changed, 435 insertions(+), 88 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/pom.xml ---------------------------------------------------------------------- diff --git a/itests/pom.xml b/itests/pom.xml index eb42ba2..2e9b6fc 100644 --- a/itests/pom.xml +++ b/itests/pom.xml @@ -56,7 +56,13 @@ <version>${project.version}</version> <scope>test</scope> </dependency> - + <dependency> + <groupId>org.apache.unomi</groupId> + <artifactId>unomi-lifecycle-watcher</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.apache.karaf.features</groupId> <artifactId>standard</artifactId> @@ -171,12 +177,13 @@ <groupId>com.github.alexcojocaru</groupId> <artifactId>elasticsearch-maven-plugin</artifactId> <!-- REPLACE THE FOLLOWING WITH THE PLUGIN VERSION YOU NEED --> - <version>5.7</version> + <version>5.6</version> <configuration> <clusterName>contextElasticSearchITests</clusterName> <transportPort>9500</transportPort> <httpPort>9400</httpPort> <version>${elasticsearch.version}</version> + <autoCreateIndex>true</autoCreateIndex> </configuration> <executions> <!-- http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/java/org/apache/unomi/itests/AllITs.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/AllITs.java b/itests/src/test/java/org/apache/unomi/itests/AllITs.java index 923ef71..aa39424 100644 --- a/itests/src/test/java/org/apache/unomi/itests/AllITs.java +++ b/itests/src/test/java/org/apache/unomi/itests/AllITs.java @@ -28,7 +28,7 @@ import org.junit.runners.Suite.SuiteClasses; */ @RunWith(Suite.class) @SuiteClasses({ - //BasicIT.class, + BasicIT.class, ConditionEvaluatorIT.class, ConditionESQueryBuilderIT.class, SegmentIT.class, http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/java/org/apache/unomi/itests/BaseIT.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java index 5849e4c..3d3e610 100644 --- a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java @@ -18,6 +18,7 @@ package org.apache.unomi.itests; import org.ops4j.pax.exam.Configuration; +import org.ops4j.pax.exam.CoreOptions; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel; import org.ops4j.pax.exam.options.MavenArtifactUrlReference; @@ -42,8 +43,10 @@ public abstract class BaseIT { protected static final String KARAF_DIR = "target/exam"; + protected static final String UNOMI_KEY = "670c26d1cc413346c3b2fd9ce65dab41"; + @Configuration - public Option[] config() { + public Option[] config() throws InterruptedException { MavenArtifactUrlReference karafUrl = maven() .groupId("org.apache.karaf") .artifactId("apache-karaf") @@ -86,15 +89,17 @@ public abstract class BaseIT { .classifier("features") .type("xml") .versionAsInProject(); - + return new Option[]{ - debugConfiguration("5005", false), + debugConfiguration("5006", false), karafDistributionConfiguration() .frameworkUrl(karafUrl) .unpackDirectory(new File(KARAF_DIR)) .useDeployFolder(true), replaceConfigurationFile("etc/org.apache.unomi.router.cfg", new File( "src/test/resources/org.apache.unomi.router.cfg")), + replaceConfigurationFile("data/tmp/1-basic-test.csv", new File( + "src/test/resources/1-basic-test.csv")), replaceConfigurationFile("data/tmp/recurrent_import/2-surfers-test.csv", new File( "src/test/resources/2-surfers-test.csv")), replaceConfigurationFile("data/tmp/recurrent_import/3-surfers-overwrite-test.csv", new File( @@ -105,6 +110,10 @@ public abstract class BaseIT { "src/test/resources/5-ranking-test.csv")), replaceConfigurationFile("data/tmp/recurrent_import/6-actors-test.csv", new File( "src/test/resources/6-actors-test.csv")), + replaceConfigurationFile("data/tmp/testLogin.json", new File( + "src/test/resources/testLogin.json")), + replaceConfigurationFile("data/tmp/testLoginEventCondition.json", new File( + "src/test/resources/testLoginEventCondition.json")), keepRuntimeFolder(), configureConsole().ignoreLocalConsole(), logLevel(LogLevel.INFO), @@ -121,7 +130,9 @@ public abstract class BaseIT { features(karafCxfRepo, "cxf"), features(karafCellarRepo, "cellar"), features(contextServerRepo, "unomi-kar"), - features(routerRepo, "unomi-router-karaf-feature") + features(routerRepo, "unomi-router-karaf-feature"), + CoreOptions.bundleStartLevel(100), + CoreOptions.frameworkStartLevel(100) }; } } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/java/org/apache/unomi/itests/BasicIT.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/BasicIT.java b/itests/src/test/java/org/apache/unomi/itests/BasicIT.java index cc91fed..14c524d 100644 --- a/itests/src/test/java/org/apache/unomi/itests/BasicIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/BasicIT.java @@ -27,28 +27,86 @@ import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; -import org.apache.unomi.api.ContextRequest; -import org.apache.unomi.api.ContextResponse; +import org.apache.unomi.api.*; +import org.apache.unomi.api.conditions.ConditionType; +import org.apache.unomi.api.rules.Rule; +import org.apache.unomi.api.services.DefinitionsService; +import org.apache.unomi.api.services.ProfileService; +import org.apache.unomi.api.services.RulesService; +import org.apache.unomi.lifecycle.BundleWatcher; +import org.apache.unomi.persistence.spi.CustomObjectMapper; import org.junit.Assert; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; import org.ops4j.pax.exam.spi.reactors.PerSuite; +import org.ops4j.pax.exam.util.Filter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import javax.inject.Inject; +import java.io.File; import java.io.IOException; +import java.util.*; @RunWith(PaxExam.class) @ExamReactorStrategy(PerSuite.class) public class BasicIT extends BaseIT { + private final static Logger LOGGER = LoggerFactory.getLogger(BasicIT.class); + private static final String JSON_MYME_TYPE = "application/json"; private ObjectMapper objectMapper = new ObjectMapper(); + private static final String SESSION_ID_0 = "aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d0"; + private static final String SESSION_ID_1 = "aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d1"; + private static final String SESSION_ID_2 = "aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d2"; + private static final String SESSION_ID_3 = "aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d3"; + private static final String SESSION_ID_4 = "aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d4"; + + private static final String EVENT_TYPE_LOGIN = "login"; + private static final String EVENT_TYPE_VIEW = "view"; + private static final String TEST_SCOPE = "testScope"; + + private static final String ITEM_TYPE_SITE = "site"; + private static final String ITEM_ID_SITE = "/test/site"; + private static final String ITEM_TYPE_VISITOR = "VISITOR"; + private static final String ITEM_ID_PAGE_1 = "/test/site/page1"; + private static final String ITEM_TYPE_PAGE = "page"; + + private static final String FIRST_NAME = "firstName"; + private static final String LAST_NAME = "lastName"; + private static final String EMAIL = "email"; + + private static final String FIRST_NAME_VISITOR_1 = "firstNameVisitor1"; + private static final String FIRST_NAME_VISITOR_2 = "firstNameVisitor2"; + private static final String LAST_NAME_VISITOR_1 = "lastNameVisitor1"; + private static final String LAST_NAME_VISITOR_2 = "lastNameVisitor2"; + private static final String EMAIL_VISITOR_1 = "[email protected]"; + private static final String EMAIL_VISITOR_2 = "[email protected]"; + + @Inject @Filter(timeout = 60000) + protected RulesService rulesService; + @Inject @Filter(timeout = 60000) + protected ProfileService profileService; + @Inject @Filter(timeout = 60000) + protected DefinitionsService definitionsService; + @Inject @Filter(timeout = 60000) + protected BundleWatcher bundleWatcher; + + @Before + public void setUp() throws InterruptedException { + while (!bundleWatcher.isStartupComplete()) { + Thread.sleep(1000); + } + } + @Test public void testContextJS() throws IOException { - HttpUriRequest request = new HttpGet(URL + "/context.js?sessionId=aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d9"); - CloseableHttpResponse response = HttpClientBuilder.create().build().execute(request); + LOGGER.info("Start test testContextJS"); + HttpUriRequest request = new HttpGet(URL + "/context.js?sessionId=" + SESSION_ID_0); // The underlying HTTP connection is still held by the response object // to allow the response content to be streamed directly from the network socket. // In order to ensure correct deallocation of system resources @@ -56,32 +114,197 @@ public class BasicIT extends BaseIT { // Please note that if response content is not fully consumed the underlying // connection cannot be safely re-used and will be shut down and discarded // by the connection manager. - String responseContent = null; - try { + String responseContent; + try (CloseableHttpResponse response = HttpClientBuilder.create().build().execute(request)) { System.out.println(response.getStatusLine()); HttpEntity entity = response.getEntity(); // do something useful with the response body // and ensure it is fully consumed responseContent = EntityUtils.toString(entity); - } finally { - response.close(); } - Assert.assertTrue("Response should contain context object", responseContent.contains("window.digitalData = window.digitalData || {};")); - // @todo we should check the validity of the context object, but this is rather complex since it would - // potentially require parsing the Javascript ! + Assert.assertTrue("Response should contain context object", responseContent.contains("window.digitalData = window.digitalData || {};\n")); + // @todo we should check the validity of the context object, but this is rather complex since it would potentially require parsing the Javascript ! + LOGGER.info("End test testContextJS"); + } + + @Test + public void testContextJSONWithUrlParameter() throws IOException, InterruptedException { + LOGGER.info("Start test testContextJSONWithUrlParameter"); + ContextRequest contextRequest = new ContextRequest(); + HttpPost request = new HttpPost(URL + "/context.json?sessionId=" + SESSION_ID_1); + request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.create("application/json"))); + + executeContextJSONRequest(request, SESSION_ID_1); + LOGGER.info("End test testContextJSONWithUrlParameter"); } @Test - public void testContextJSON() throws IOException { - String sessionId = "aa3b04bd-8f4d-4a07-8e96-d33ffa04d3d9"; + public void testContextJSON() throws IOException, InterruptedException { + LOGGER.info("Start test testContextJSON"); ContextRequest contextRequest = new ContextRequest(); -// contextRequest.setSource(new EventSource()); -// contextRequest.getSource().setId("af6f393a-a537-4586-991b-8521b9c7b05b"); - HttpPost request = new HttpPost(URL + "/context.json?sessionId=" + sessionId); + contextRequest.setSessionId(SESSION_ID_2); + HttpPost request = new HttpPost(URL + "/context.json"); request.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequest), ContentType.create("application/json"))); - CloseableHttpResponse response = HttpClientBuilder.create().build().execute(request); - try { + executeContextJSONRequest(request, SESSION_ID_2); + LOGGER.info("End test testContextJSON"); + } + + @Test + public void testMultipleLoginOnSameBrowser() throws IOException, InterruptedException { + LOGGER.info("Start test testMultipleLoginOnSameBrowser"); + // Add login event condition + ConditionType conditionType = CustomObjectMapper.getObjectMapper().readValue( + new File("data/tmp/testLoginEventCondition.json").toURI().toURL(), ConditionType.class); + definitionsService.setConditionType(conditionType); + Thread.sleep(2000); + // Add login rule + Rule rule = CustomObjectMapper.getObjectMapper().readValue(new File("data/tmp/testLogin.json").toURI().toURL(), + Rule.class); + rulesService.setRule(rule); + Thread.sleep(2000); + + CustomItem sourceSite = new CustomItem(ITEM_ID_SITE, ITEM_TYPE_SITE); + sourceSite.setScope(TEST_SCOPE); + + // First page view with the first visitor aka VISITOR_1 and SESSION_ID_3 + ContextRequest contextRequestPageViewSession1 = getContextRequestWithPageViewEvent(sourceSite, SESSION_ID_3); + HttpPost requestPageView1 = new HttpPost(URL + "/context.json"); + requestPageView1.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequestPageViewSession1), + ContentType.create("application/json"))); + RequestResponse requestResponsePageView1 = executeContextJSONRequest(requestPageView1, SESSION_ID_3); + String profileIdVisitor1 = requestResponsePageView1.getContextResponse().getProfileId(); + Thread.sleep(1000); + + // Initialize VISITOR_1 properties + Map<String, Object> loginEventPropertiesVisitor1 = new HashMap<>(); + loginEventPropertiesVisitor1.put(FIRST_NAME, FIRST_NAME_VISITOR_1); + loginEventPropertiesVisitor1.put(LAST_NAME, LAST_NAME_VISITOR_1); + loginEventPropertiesVisitor1.put(EMAIL, EMAIL_VISITOR_1); + + // Create login event with VISITOR_1 + ContextRequest contextRequestLoginVisitor1 = getContextRequestWithLoginEvent(sourceSite, loginEventPropertiesVisitor1, + EMAIL_VISITOR_1, SESSION_ID_3); + HttpPost requestLoginVisitor1 = new HttpPost(URL + "/context.json"); + requestLoginVisitor1.addHeader("Cookie", requestResponsePageView1.getCookieHeaderValue()); + requestLoginVisitor1.addHeader("X-Unomi-Peer", UNOMI_KEY); + requestLoginVisitor1.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequestLoginVisitor1), + ContentType.create("application/json"))); + RequestResponse requestResponseLoginVisitor1 = executeContextJSONRequest(requestLoginVisitor1, SESSION_ID_3); + Assert.assertEquals("Context profile id should be the same", profileIdVisitor1, + requestResponseLoginVisitor1.getContextResponse().getProfileId()); + checkVisitor1ResponseProperties(requestResponseLoginVisitor1.getContextResponse().getProfileProperties()); + Thread.sleep(1000); + + // Lets add a page view with VISITOR_1 to simulate reloading the page after login and be able to check the profile properties + HttpPost requestPageView2 = new HttpPost(URL + "/context.json"); + requestPageView2.addHeader("Cookie", requestResponsePageView1.getCookieHeaderValue()); + requestPageView2.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequestPageViewSession1), + ContentType.create("application/json"))); + RequestResponse requestResponsePageView2 = executeContextJSONRequest(requestPageView2, SESSION_ID_3); + Assert.assertEquals("Context profile id should be the same", profileIdVisitor1, + requestResponsePageView2.getContextResponse().getProfileId()); + checkVisitor1ResponseProperties(requestResponsePageView2.getContextResponse().getProfileProperties()); + Thread.sleep(1000); + + // Lets simulate a logout by requesting the context with a new page view event and a new session id + // but we will send the cookie of the profile id from VISITOR_1 + ContextRequest contextRequestPageViewSession2 = getContextRequestWithPageViewEvent(sourceSite, SESSION_ID_4); + HttpPost requestPageView3 = new HttpPost(URL + "/context.json"); + requestPageView3.addHeader("Cookie", requestResponsePageView1.getCookieHeaderValue()); + requestPageView3.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequestPageViewSession2), + ContentType.create("application/json"))); + RequestResponse requestResponsePageView3 = executeContextJSONRequest(requestPageView3, SESSION_ID_4); + Assert.assertEquals("Context profile id should be the same", profileIdVisitor1, + requestResponsePageView3.getContextResponse().getProfileId()); + checkVisitor1ResponseProperties(requestResponsePageView3.getContextResponse().getProfileProperties()); + Thread.sleep(1000); + + // Initialize VISITOR_2 properties + Map<String, Object> loginEventPropertiesVisitor2 = new HashMap<>(); + loginEventPropertiesVisitor2.put(FIRST_NAME, FIRST_NAME_VISITOR_2); + loginEventPropertiesVisitor2.put(LAST_NAME, LAST_NAME_VISITOR_2); + loginEventPropertiesVisitor2.put(EMAIL, EMAIL_VISITOR_2); + + // Create login event with VISITOR_2 + ContextRequest contextRequestLoginVisitor2 = getContextRequestWithLoginEvent(sourceSite, loginEventPropertiesVisitor2, + EMAIL_VISITOR_2, SESSION_ID_4); + HttpPost requestLoginVisitor2 = new HttpPost(URL + "/context.json"); + requestLoginVisitor2.addHeader("Cookie", requestResponsePageView1.getCookieHeaderValue()); + requestLoginVisitor2.addHeader("X-Unomi-Peer", UNOMI_KEY); + requestLoginVisitor2.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequestLoginVisitor2), + ContentType.create("application/json"))); + RequestResponse requestResponseLoginVisitor2 = executeContextJSONRequest(requestLoginVisitor2, SESSION_ID_4); + // We should have a new profile id so the session should have been moved from VISITOR_1 to VISITOR_2 + String profileIdVisitor2 = requestResponseLoginVisitor2.getContextResponse().getProfileId(); + Assert.assertNotEquals("Context profile id should not be the same", profileIdVisitor1, + profileIdVisitor2); + checkVisitor2ResponseProperties(requestResponseLoginVisitor2.getContextResponse().getProfileProperties()); + Thread.sleep(1000); + + // Lets add a page view with VISITOR_2 to simulate reloading the page after login + HttpPost requestPageView4 = new HttpPost(URL + "/context.json"); + requestPageView4.addHeader("Cookie", requestResponseLoginVisitor2.getCookieHeaderValue()); + requestPageView4.setEntity(new StringEntity(objectMapper.writeValueAsString(contextRequestPageViewSession2), + ContentType.create("application/json"))); + RequestResponse requestResponsePageView4 = executeContextJSONRequest(requestPageView4, SESSION_ID_4); + Assert.assertEquals("Context profile id should be the same", profileIdVisitor2, + requestResponsePageView4.getContextResponse().getProfileId()); + checkVisitor2ResponseProperties(requestResponsePageView4.getContextResponse().getProfileProperties()); + Thread.sleep(1000); + + // Check both visitor profile at the end by loading them directly + Profile profileVisitor1 = profileService.load(profileIdVisitor1); + checkVisitor1ResponseProperties(profileVisitor1.getProperties()); + Profile profileVisitor2 = profileService.load(profileIdVisitor2); + checkVisitor2ResponseProperties(profileVisitor2.getProperties()); + LOGGER.info("End test testMultipleLoginOnSameBrowser"); + } + + private ContextRequest getContextRequestWithLoginEvent(CustomItem sourceSite, Map<String, Object> loginEventProperties, + String visitorId, String sessionId) { + + CustomItem loginEventTarget = new CustomItem(visitorId, ITEM_TYPE_VISITOR); + loginEventTarget.setProperties(loginEventProperties); + + Event loginEvent = new Event(EVENT_TYPE_LOGIN, null, new Profile(""), TEST_SCOPE, + null, loginEventTarget, new Date()); + + ContextRequest contextRequest = new ContextRequest(); + contextRequest.setSource(sourceSite); + contextRequest.setRequireSegments(false); + contextRequest.setEvents(Collections.singletonList(loginEvent)); + contextRequest.setRequiredProfileProperties(Arrays.asList(FIRST_NAME, LAST_NAME, EMAIL)); + contextRequest.setSessionId(sessionId); + return contextRequest; + } + + private ContextRequest getContextRequestWithPageViewEvent(CustomItem sourceSite, String sessionId) { + CustomItem customPageItem = new CustomItem(ITEM_ID_PAGE_1, ITEM_TYPE_PAGE); + customPageItem.setScope(TEST_SCOPE); + Map<String, Object> pageInfo = new HashMap<>(); + pageInfo.put("referringURL", "http://localhost:8080"); + + Map<String, Object> properties = new HashMap<>(); + properties.put("pageInfo", pageInfo); + + customPageItem.setProperties(properties); + + // Create page view event to mock a connection to a site + Event pageViewEvent = new Event(EVENT_TYPE_VIEW, null, new Profile(""), TEST_SCOPE, sourceSite, customPageItem, new Date()); + + // Initialize context like if you display the first page on the website + ContextRequest contextRequest = new ContextRequest(); + contextRequest.setSessionId(sessionId); + contextRequest.setSource(customPageItem); + contextRequest.setRequireSegments(false); + contextRequest.setEvents(Collections.singletonList(pageViewEvent)); + contextRequest.setRequiredProfileProperties(Arrays.asList(FIRST_NAME, LAST_NAME, EMAIL)); + return contextRequest; + } + + private RequestResponse executeContextJSONRequest(HttpPost request, String sessionId) throws IOException, InterruptedException { + try (CloseableHttpResponse response = HttpClientBuilder.create().build().execute(request)) { // validate mimeType String mimeType = ContentType.getOrDefault(response.getEntity()).getMimeType(); Assert.assertEquals("Response content type should be " + JSON_MYME_TYPE, JSON_MYME_TYPE, mimeType); @@ -90,10 +313,59 @@ public class BasicIT extends BaseIT { ContextResponse context = TestUtils.retrieveResourceFromResponse(response, ContextResponse.class); Assert.assertNotNull("Context should not be null", context); Assert.assertNotNull("Context profileId should not be null", context.getProfileId()); - Assert.assertEquals("Context sessionId should be the same as the sessionId used to request the context", sessionId, context.getSessionId()); - } finally { - response.close(); + Assert.assertEquals("Context sessionId should be the same as the sessionId used to request the context", sessionId, + context.getSessionId()); + + String cookieHeader = null; + if (response.containsHeader("Set-Cookie")) { + cookieHeader = response.getHeaders("Set-Cookie")[0].toString().substring(12); + } + return new RequestResponse(context, cookieHeader); } } + private void checkVisitor1ResponseProperties(Map<String, Object> profileProperties) { + checkVisitorResponseProperties(profileProperties, FIRST_NAME_VISITOR_1, LAST_NAME_VISITOR_1, EMAIL_VISITOR_1); + } + + private void checkVisitor2ResponseProperties(Map<String, Object> profileProperties) { + checkVisitorResponseProperties(profileProperties, FIRST_NAME_VISITOR_2, LAST_NAME_VISITOR_2, EMAIL_VISITOR_2); + } + + private void checkVisitorResponseProperties(Map<String, Object> profileProperties, String firstNameVisitor, + String lastNameVisitor, String emailVisitor) { + Assert.assertNotNull("Context profile properties should not be null", profileProperties); + + Assert.assertTrue("Context profile properties should contains the entry " + FIRST_NAME, + profileProperties.containsKey(FIRST_NAME)); + Assert.assertTrue("Context profile properties should contains the entry " + LAST_NAME, + profileProperties.containsKey(LAST_NAME)); + Assert.assertTrue("Context profile properties should contains the entry " + EMAIL, + profileProperties.containsKey(EMAIL)); + + Assert.assertEquals("Context profile properties " + FIRST_NAME + " should be equal to " + firstNameVisitor, + profileProperties.get(FIRST_NAME), firstNameVisitor); + Assert.assertEquals("Context profile properties " + LAST_NAME + " should be equal to " + lastNameVisitor, + profileProperties.get(LAST_NAME), lastNameVisitor); + Assert.assertEquals("Context profile properties " + EMAIL + " should be equal to " + emailVisitor, + profileProperties.get(EMAIL), emailVisitor); + } + + private class RequestResponse { + private ContextResponse contextResponse; + private String cookieHeaderValue; + + public RequestResponse(ContextResponse contextResponse, String cookieHeaderValue) { + this.contextResponse = contextResponse; + this.cookieHeaderValue = cookieHeaderValue; + } + + public ContextResponse getContextResponse() { + return contextResponse; + } + + public String getCookieHeaderValue() { + return cookieHeaderValue; + } + } } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/java/org/apache/unomi/itests/ModifyConsentIT.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/ModifyConsentIT.java b/itests/src/test/java/org/apache/unomi/itests/ModifyConsentIT.java index a602dcb..6b53d79 100644 --- a/itests/src/test/java/org/apache/unomi/itests/ModifyConsentIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/ModifyConsentIT.java @@ -66,7 +66,7 @@ public class ModifyConsentIT extends BaseIT { public void testConsentGrant() throws InterruptedException { Profile profile = profileService.load(PROFILE_TEST_ID); Assert.assertNotNull(profile); - Assert.assertTrue(profile.getConsents().size() == 0); + Assert.assertEquals(0, profile.getConsents().size()); Event modifyConsentEvent = new Event("modifyConsent", null, profile, null, null, profile, new Date()); modifyConsentEvent.setPersistent(false); @@ -92,7 +92,7 @@ public class ModifyConsentIT extends BaseIT { profile = profileService.load(PROFILE_TEST_ID); - Assert.assertTrue(profile.getConsents().size() == 2); + Assert.assertEquals(2, profile.getConsents().size()); } } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/java/org/apache/unomi/itests/ProfileImportActorsIT.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/ProfileImportActorsIT.java b/itests/src/test/java/org/apache/unomi/itests/ProfileImportActorsIT.java index a25fbd1..308009a 100644 --- a/itests/src/test/java/org/apache/unomi/itests/ProfileImportActorsIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/ProfileImportActorsIT.java @@ -43,11 +43,9 @@ import java.util.*; @ExamReactorStrategy(PerSuite.class) public class ProfileImportActorsIT extends BaseIT { - @Inject - @Filter("(configDiscriminator=IMPORT)") + @Inject @Filter(value="(configDiscriminator=IMPORT)", timeout = 60000) protected ImportExportConfigurationService<ImportConfiguration> importConfigurationService; - - @Inject + @Inject @Filter(timeout = 60000) protected ProfileService profileService; @Test http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/java/org/apache/unomi/itests/ProfileImportBasicIT.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/ProfileImportBasicIT.java b/itests/src/test/java/org/apache/unomi/itests/ProfileImportBasicIT.java index 7aad069..e2b1898 100644 --- a/itests/src/test/java/org/apache/unomi/itests/ProfileImportBasicIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/ProfileImportBasicIT.java @@ -33,10 +33,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -47,21 +47,19 @@ import java.util.Map; @RunWith(PaxExam.class) @ExamReactorStrategy(PerSuite.class) public class ProfileImportBasicIT extends BaseIT { - private Logger logger = LoggerFactory.getLogger(ProfileImportBasicIT.class); - @Inject - @Filter("(configDiscriminator=IMPORT)") + @Inject @Filter(value="(configDiscriminator=IMPORT)", timeout = 60000) protected ImportExportConfigurationService<ImportConfiguration> importConfigurationService; - @Inject + @Inject @Filter(timeout = 60000) protected ProfileService profileService; @Test public void testImportBasic() throws IOException, InterruptedException { - /*** Basic Test ***/ ImportConfiguration importConfiguration = new ImportConfiguration(); - importConfiguration.setItemId("1-basic-test"); + String itemId = "1-basic-test"; + importConfiguration.setItemId(itemId); importConfiguration.setConfigType(RouterConstants.IMPORT_EXPORT_CONFIG_TYPE_ONESHOT); importConfiguration.setMergingProperty("email"); importConfiguration.setOverwriteExistingProfiles(true); @@ -70,49 +68,52 @@ public class ProfileImportBasicIT extends BaseIT { mapping.put("email", 0); mapping.put("firstName", 1); mapping.put("lastName", 2); + mapping.put("city", 3); importConfiguration.getProperties().put("mapping", mapping); importConfiguration.setActive(true); - logger.info("Save import config oneshot with ID : {}.", importConfiguration.getItemId()); - + logger.info("Save import config oneshot with ID : {}.", itemId); importConfigurationService.save(importConfiguration, false); - //Wait for the csv to be processed + // Wait for the config to be processed Thread.sleep(5000); - logger.info("Check import config oneshot with ID : {}.", importConfiguration.getItemId()); - + logger.info("Check import config oneshot with ID : {}.", itemId); List<ImportConfiguration> importConfigurations = importConfigurationService.getAll(); Assert.assertEquals(1, importConfigurations.size()); - String content = "[email protected],Basic1,User1\n" + - "[email protected],Basic2,User2\n" + - "[email protected],Basic3,User3"; - File basicFile = new File("data/tmp/unomi_oneshot_import_configs/1-basic-test.csv"); - basicFile.getParentFile().mkdirs(); - BufferedWriter out = new BufferedWriter(new FileWriter(basicFile)); - out.write(content); - out.close(); - - logger.info("Write the file {}.", "data/tmp/unomi_oneshot_import_configs/1-basic-test.csv"); - - //Wait for the csv to be processed - Thread.sleep(75000); - - //Check saved profiles - PartialList<Profile> profiles = profileService.findProfilesByPropertyValue("properties.email", "[email protected]", 0, 10, null); - Assert.assertEquals(3, profileService.getAllProfilesCount()); - Assert.assertEquals(1, profiles.getList().size()); - Assert.assertNotNull(profiles.get(0)); - Assert.assertEquals("Basic1", profiles.get(0).getProperty("firstName")); - Assert.assertEquals("User1", profiles.get(0).getProperty("lastName")); - - //Check import config status - importConfiguration = importConfigurationService.load("1-basic-test"); + // Move the file to the import folder so the import can start + File basicFile = new File("data/tmp/1-basic-test.csv"); + Files.copy(basicFile.toPath(), new File("data/tmp/unomi_oneshot_import_configs/1-basic-test.csv").toPath(), StandardCopyOption.REPLACE_EXISTING); + + // Wait for the csv to be processed + boolean isDone = false; + while (!isDone) { + importConfiguration = importConfigurationService.load(itemId); + if (importConfiguration != null && importConfiguration.getStatus() != null) { + isDone = importConfiguration.getStatus().equals(RouterConstants.CONFIG_STATUS_COMPLETE_SUCCESS); + } + Thread.sleep(1000); + } + // Check import config status Assert.assertEquals(RouterConstants.CONFIG_STATUS_COMPLETE_SUCCESS, importConfiguration.getStatus()); Assert.assertEquals(1, importConfiguration.getExecutions().size()); + // Check saved profiles + PartialList<Profile> profiles = profileService.findProfilesByPropertyValue("properties.city", "oneShotImportCity", 0, 10, null); + Assert.assertEquals(3, profiles.getList().size()); + + checkProfiles(1); + checkProfiles(2); + checkProfiles(3); } + private void checkProfiles(int profileNumber) { + String propertyValue = "basic" + profileNumber + "@test.com"; + PartialList<Profile> profiles = profileService.findProfilesByPropertyValue("properties.email", propertyValue, 0, 10, null); + Assert.assertNotNull(profiles.get(0)); + Assert.assertEquals("Basic" + profileNumber, profiles.get(0).getProperty("firstName")); + Assert.assertEquals("User" + profileNumber, profiles.get(0).getProperty("lastName")); + } } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/java/org/apache/unomi/itests/ProfileImportRankingIT.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/ProfileImportRankingIT.java b/itests/src/test/java/org/apache/unomi/itests/ProfileImportRankingIT.java index a2f0f39..b4663ec 100644 --- a/itests/src/test/java/org/apache/unomi/itests/ProfileImportRankingIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/ProfileImportRankingIT.java @@ -46,11 +46,9 @@ import java.util.Map; @ExamReactorStrategy(PerSuite.class) public class ProfileImportRankingIT extends BaseIT { - @Inject - @Filter("(configDiscriminator=IMPORT)") + @Inject @Filter(value="(configDiscriminator=IMPORT)", timeout = 60000) protected ImportExportConfigurationService<ImportConfiguration> importConfigurationService; - - @Inject + @Inject @Filter(timeout = 60000) protected ProfileService profileService; @Test http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/java/org/apache/unomi/itests/ProfileImportSurfersIT.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/ProfileImportSurfersIT.java b/itests/src/test/java/org/apache/unomi/itests/ProfileImportSurfersIT.java index 082ffaf..a845206 100644 --- a/itests/src/test/java/org/apache/unomi/itests/ProfileImportSurfersIT.java +++ b/itests/src/test/java/org/apache/unomi/itests/ProfileImportSurfersIT.java @@ -49,14 +49,12 @@ import java.util.Map; @RunWith(PaxExam.class) @ExamReactorStrategy(PerSuite.class) public class ProfileImportSurfersIT extends BaseIT { + private Logger logger = LoggerFactory.getLogger(ProfileImportSurfersIT.class); - @Inject - @Filter("(configDiscriminator=IMPORT)") + @Inject @Filter(value="(configDiscriminator=IMPORT)", timeout = 60000) protected ImportExportConfigurationService<ImportConfiguration> importConfigurationService; - - @Inject + @Inject @Filter(timeout = 60000) protected ProfileService profileService; - private Logger logger = LoggerFactory.getLogger(ProfileImportSurfersIT.class); @Test public void testImportSurfers() throws IOException, InterruptedException { http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/java/org/apache/unomi/itests/TestUtils.java ---------------------------------------------------------------------- diff --git a/itests/src/test/java/org/apache/unomi/itests/TestUtils.java b/itests/src/test/java/org/apache/unomi/itests/TestUtils.java index 72f2d98..d98d394 100644 --- a/itests/src/test/java/org/apache/unomi/itests/TestUtils.java +++ b/itests/src/test/java/org/apache/unomi/itests/TestUtils.java @@ -25,11 +25,10 @@ import org.apache.http.util.EntityUtils; import java.io.IOException; public class TestUtils { - public static <T> T retrieveResourceFromResponse(HttpResponse response, Class<T> clazz) - throws IOException { + + public static <T> T retrieveResourceFromResponse(HttpResponse response, Class<T> clazz) throws IOException { String jsonFromResponse = EntityUtils.toString(response.getEntity()); - ObjectMapper mapper = new ObjectMapper(). - configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return mapper.readValue(jsonFromResponse, clazz); } } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/resources/1-basic-test.csv ---------------------------------------------------------------------- diff --git a/itests/src/test/resources/1-basic-test.csv b/itests/src/test/resources/1-basic-test.csv index 337940f..520b217 100644 --- a/itests/src/test/resources/1-basic-test.csv +++ b/itests/src/test/resources/1-basic-test.csv @@ -1,3 +1,3 @@ [email protected],Basic1,User1 [email protected],Basic2,User2 [email protected],Basic3,User3 \ No newline at end of file [email protected],Basic1,User1,oneShotImportCity [email protected],Basic2,User2,oneShotImportCity [email protected],Basic3,User3,oneShotImportCity \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/resources/testLogin.json ---------------------------------------------------------------------- diff --git a/itests/src/test/resources/testLogin.json b/itests/src/test/resources/testLogin.json new file mode 100644 index 0000000..e5a3511 --- /dev/null +++ b/itests/src/test/resources/testLogin.json @@ -0,0 +1,34 @@ +{ + "metadata": { + "id": "testLogin", + "name": "Test Login", + "description": "Copy event properties to profile properties on login" + }, + "condition": { + "parameterValues": { + "subConditions": [ + { + "parameterValues": { + }, + "type": "loginEventCondition" + } + ], + "operator": "and" + }, + "type": "booleanCondition" + }, + "actions": [ + { + "parameterValues": { + "mergeProfilePropertyValue": "eventProperty::target.properties(email)", + "mergeProfilePropertyName": "mergeIdentifier" + }, + "type": "mergeProfilesOnPropertyAction" + }, + { + "parameterValues": { + }, + "type": "allEventToProfilePropertiesAction" + } + ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/itests/src/test/resources/testLoginEventCondition.json ---------------------------------------------------------------------- diff --git a/itests/src/test/resources/testLoginEventCondition.json b/itests/src/test/resources/testLoginEventCondition.json new file mode 100644 index 0000000..5b248ce --- /dev/null +++ b/itests/src/test/resources/testLoginEventCondition.json @@ -0,0 +1,23 @@ +{ + "metadata": { + "id": "loginEventCondition", + "name": "loginEventCondition", + "description": "", + "systemTags": [ + "profileTags", + "event", + "condition", + "eventCondition" + ], + "readOnly": true + }, + "parentCondition": { + "type": "eventTypeCondition", + "parameterValues": { + "eventTypeId": "login" + } + }, + + "parameters": [ + ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java ---------------------------------------------------------------------- diff --git a/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java b/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java index 3f4ab5a..828a288 100644 --- a/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java +++ b/lifecycle-watcher/src/main/java/org/apache/unomi/lifecycle/BundleWatcher.java @@ -176,7 +176,7 @@ public class BundleWatcher implements SynchronousBundleListener, ServiceListener } } - private boolean isStartupComplete() { + public boolean isStartupComplete() { if (unomiStartedBundleCount < requiredStartedBundleCount) { return false; } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/38ddefc4/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml ---------------------------------------------------------------------- diff --git a/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml index 01112a3..3fe88cf 100644 --- a/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/lifecycle-watcher/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -36,4 +36,10 @@ <property name="requiredStartedBundleCount" value="${lifecycle.requiredStartedBundleCount}" /> </bean> + <service id="bundleWatcherService" ref="bundleWatcher"> + <interfaces> + <value>org.apache.unomi.lifecycle.BundleWatcher</value> + </interfaces> + </service> + </blueprint>
