This is an automated email from the ASF dual-hosted git repository.
shuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/unomi.git
The following commit(s) were added to refs/heads/master by this push:
new 8ebcf41 Add possibility to use a "requiresScores" parameter in the
ContextRequest. (#360)
8ebcf41 is described below
commit 8ebcf413cc0b6c4ed19c8c0e8f5ba9d1f4e5cbaf
Author: Serge Huber <[email protected]>
AuthorDate: Mon Nov 15 09:35:14 2021 +0100
Add possibility to use a "requiresScores" parameter in the ContextRequest.
(#360)
- Implement new ContextRequest parameter
- Add integration tests that tests with and without the parameter.
- Update documentation to surface the new parameter
---
.../java/org/apache/unomi/api/ContextRequest.java | 18 +++++++++
.../java/org/apache/unomi/api/ContextResponse.java | 18 +++++++++
.../test/java/org/apache/unomi/itests/BasicIT.java | 2 +-
.../org/apache/unomi/itests/ContextServletIT.java | 44 ++++++++++++++++++++++
itests/src/test/resources/score1.json | 17 +++++++++
itests/src/test/resources/withRequireScores.json | 5 +++
.../src/test/resources/withoutRequireScores.json | 4 ++
manual/src/main/asciidoc/recipes.adoc | 5 ++-
manual/src/main/asciidoc/request-examples.adoc | 6 ++-
.../unomi/rest/endpoints/ContextJsonEndpoint.java | 3 ++
10 files changed, 117 insertions(+), 5 deletions(-)
diff --git a/api/src/main/java/org/apache/unomi/api/ContextRequest.java
b/api/src/main/java/org/apache/unomi/api/ContextRequest.java
index 78c4720..319afd0 100644
--- a/api/src/main/java/org/apache/unomi/api/ContextRequest.java
+++ b/api/src/main/java/org/apache/unomi/api/ContextRequest.java
@@ -57,6 +57,7 @@ public class ContextRequest {
private boolean requireSegments;
private List<String> requiredProfileProperties;
private List<String> requiredSessionProperties;
+ private boolean requireScores;
private List<Event> events;
private List<PersonalizationService.PersonalizedContent> filters;
private List<PersonalizationService.PersonalizationRequest>
personalizations;
@@ -151,6 +152,23 @@ public class ContextRequest {
}
/**
+ * Specifies whether the profiles scores should be part of the
ContextResponse.
+ * @return a boolean indicating if the scores should be part of the
response.
+ */
+ public boolean isRequireScores() {
+ return requireScores;
+ }
+
+ /**
+ * Setting this value to true indicates that the profile scores should be
included in the response. By default this
+ * value is false.
+ * @param requireScores set to true if you want the scores to be part of
the context response
+ */
+ public void setRequireScores(boolean requireScores) {
+ this.requireScores = requireScores;
+ }
+
+ /**
* Retrieves the filters aimed at content personalization that should be
evaluated for the given session and/or profile so that the context server can
tell the client
* whether the content associated with the filter should be activated for
this profile/session. The filter identifier is used in the {@link
ContextResponse} with the
* associated evaluation result.
diff --git a/api/src/main/java/org/apache/unomi/api/ContextResponse.java
b/api/src/main/java/org/apache/unomi/api/ContextResponse.java
index 632d1b7..b7467e0 100644
--- a/api/src/main/java/org/apache/unomi/api/ContextResponse.java
+++ b/api/src/main/java/org/apache/unomi/api/ContextResponse.java
@@ -46,6 +46,8 @@ public class ContextResponse implements Serializable {
private Set<String> profileSegments;
+ private Map<String,Integer> profileScores;
+
private Map<String, Boolean> filteringResults;
private int processedEvents;
@@ -153,6 +155,22 @@ public class ContextResponse implements Serializable {
}
/**
+ * Retrieve the current scores for the profile if they were requested in
the request using the requireScores boolean.
+ * @return a map that contains the score identifier as the key and the
score value as the value
+ */
+ public Map<String, Integer> getProfileScores() {
+ return profileScores;
+ }
+
+ /**
+ * Stores the scores for the current profile if requested using the
requireScores boolean in the request.
+ * @param profileScores a map that contains the score identifier as the
key and the score value as the value
+ */
+ public void setProfileScores(Map<String, Integer> profileScores) {
+ this.profileScores = profileScores;
+ }
+
+ /**
* Retrieves the results of the evaluation content filtering definitions
and whether individual definitions match with the associated profile
(potentially modified by
* overridden values).
*
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 d7a2387..dd95038 100644
--- a/itests/src/test/java/org/apache/unomi/itests/BasicIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/BasicIT.java
@@ -59,7 +59,7 @@ import java.util.*;
public class BasicIT extends BaseIT {
private final static Logger LOGGER =
LoggerFactory.getLogger(BasicIT.class);
- private ObjectMapper objectMapper = new ObjectMapper();
+ private final 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";
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 4ebcfad..c3e2b3d 100644
--- a/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/ContextServletIT.java
@@ -23,11 +23,14 @@ import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.unomi.api.*;
import org.apache.unomi.api.conditions.Condition;
+import org.apache.unomi.api.segments.Scoring;
+import org.apache.unomi.api.segments.ScoringElement;
import org.apache.unomi.api.segments.Segment;
import org.apache.unomi.api.services.DefinitionsService;
import org.apache.unomi.api.services.EventService;
import org.apache.unomi.api.services.ProfileService;
import org.apache.unomi.api.services.SegmentService;
+import org.apache.unomi.persistence.spi.CustomObjectMapper;
import org.apache.unomi.persistence.spi.PersistenceService;
import org.junit.After;
import org.junit.Before;
@@ -555,4 +558,45 @@ public class ContextServletIT extends BaseIT {
Thread.sleep(2000); //Making sure event is updated in DB
}
+
+ @Test
+ public void testRequireScoring() throws IOException, InterruptedException {
+
+ Map<String,String> parameters = new HashMap<>();
+ String scoringSource = getValidatedBundleJSON("score1.json",
parameters);
+ Scoring scoring =
CustomObjectMapper.getObjectMapper().readValue(scoringSource, Scoring.class);
+ segmentService.setScoringDefinition(scoring);
+ refreshPersistence();
+
+ // first let's make sure everything works without the requireScoring
parameter
+ parameters = new HashMap<>();
+ HttpPost request = new HttpPost(URL + CONTEXT_URL);
+ request.setEntity(new
StringEntity(getValidatedBundleJSON("withoutRequireScores.json", parameters),
ContentType.create("application/json")));
+ TestUtils.RequestResponse response =
TestUtils.executeContextJSONRequest(request);
+ assertEquals("Invalid response code", 200, response.getStatusCode());
+ refreshPersistence();
+ Thread.sleep(2000); //Making sure event is updated in DB
+
+ assertNotNull("Context response should not be null",
response.getContextResponse());
+ Map<String,Integer> scores =
response.getContextResponse().getProfileScores();
+ assertNull("Context response should not contain scores", scores);
+
+ // now let's test adding it.
+ parameters = new HashMap<>();
+ request = new HttpPost(URL + CONTEXT_URL);
+ request.setEntity(new
StringEntity(getValidatedBundleJSON("withRequireScores.json", parameters),
ContentType.create("application/json")));
+ response = TestUtils.executeContextJSONRequest(request);
+ assertEquals("Invalid response code", 200, response.getStatusCode());
+ refreshPersistence();
+ Thread.sleep(2000); //Making sure event is updated in DB
+
+ assertNotNull("Context response should not be null",
response.getContextResponse());
+ scores = response.getContextResponse().getProfileScores();
+ assertNotNull("Context response should contain scores", scores);
+ assertNotNull("score1 not found in profile scores",
scores.get("score1"));
+ assertEquals("score1 does not have expected value", 1,
scores.get("score1").intValue());
+
+ segmentService.removeScoringDefinition(scoring.getItemId(), false);
+ }
+
}
diff --git a/itests/src/test/resources/score1.json
b/itests/src/test/resources/score1.json
new file mode 100644
index 0000000..a8fd0fc
--- /dev/null
+++ b/itests/src/test/resources/score1.json
@@ -0,0 +1,17 @@
+{
+ "itemId" : "score1",
+ "metadata" : {
+ "id" : "score1",
+ "name" : "Score 1",
+ "enabled" : true
+ },
+ "elements" : [
+ {
+ "condition" : {
+ "type" : "matchAllCondition",
+ "parameterValues" : {}
+ },
+ "value" : 1
+ }
+ ]
+}
\ No newline at end of file
diff --git a/itests/src/test/resources/withRequireScores.json
b/itests/src/test/resources/withRequireScores.json
new file mode 100644
index 0000000..22eac30
--- /dev/null
+++ b/itests/src/test/resources/withRequireScores.json
@@ -0,0 +1,5 @@
+{
+ "requireScores": true,
+ "profileId": "test-profile-id",
+ "sessionId": "test-session-id"
+}
\ No newline at end of file
diff --git a/itests/src/test/resources/withoutRequireScores.json
b/itests/src/test/resources/withoutRequireScores.json
new file mode 100644
index 0000000..67925a1
--- /dev/null
+++ b/itests/src/test/resources/withoutRequireScores.json
@@ -0,0 +1,4 @@
+{
+ "profileId": "test-profile-id",
+ "sessionId": "test-session-id"
+}
\ No newline at end of file
diff --git a/manual/src/main/asciidoc/recipes.adoc
b/manual/src/main/asciidoc/recipes.adoc
index f8bf2db..e878bfd 100644
--- a/manual/src/main/asciidoc/recipes.adoc
+++ b/manual/src/main/asciidoc/recipes.adoc
@@ -23,7 +23,7 @@ Apache Unomi.
The simplest way to retrieve profile data for the current profile is to simply
send a request to the /cxs/context.json
endpoint. However you will need to send a body along with that request. Here's
an example:
-Here is an example that will retrieve all the session and profile properties.
+Here is an example that will retrieve all the session and profile properties,
as well as the profile's segments and scores
[source]
----
@@ -38,7 +38,8 @@ curl -X POST
http://localhost:8181/cxs/context.json?sessionId=1234 \
},
"requiredProfileProperties":["*"],
"requiredSessionProperties":["*"],
- "requireSegments":true
+ "requireSegments":true,
+ "requireScores":true
}
EOF
----
diff --git a/manual/src/main/asciidoc/request-examples.adoc
b/manual/src/main/asciidoc/request-examples.adoc
index 33928cf..0480fdf 100644
--- a/manual/src/main/asciidoc/request-examples.adoc
+++ b/manual/src/main/asciidoc/request-examples.adoc
@@ -41,7 +41,8 @@ By default, in order to optimize the amount of data sent over
the network, Apach
the profile or session properties. If you need this data, you must send a JSON
object to configure the resulting output
of the context.js(on) servlet.
-Here is an example that will retrieve all the session and profile properties.
+Here is an example that will retrieve all the session and profile properties,
as well as the profile's segments and
+scores
[source]
----
@@ -56,7 +57,8 @@ curl -X POST
http://localhost:8181/cxs/context.json?sessionId=1234 \
},
"requiredProfileProperties":["*"],
"requiredSessionProperties":["*"],
- "requireSegments":true
+ "requireSegments":true,
+ "requireScores":true
}
EOF
----
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 aa5ac98..3184e60 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
@@ -383,6 +383,9 @@ public class ContextJsonEndpoint {
if (contextRequest.isRequireSegments()) {
data.setProfileSegments(profile.getSegments());
}
+ if (contextRequest.isRequireScores()) {
+ data.setProfileScores(profile.getScores());
+ }
if (contextRequest.getRequiredProfileProperties() != null) {
Map<String, Object> profileProperties = new
HashMap<>(profile.getProperties());