Repository: incubator-unomi Updated Branches: refs/heads/master 38b50c6da -> 485a0f1e4
UNOMI-133 Add (GDPR) consents to visitor profiles - Consents are no longer items, as they are only used inside Profiles - Added REVOKE ConsentGrant type - Added Javadocs on Profile and Consent classes - Moved consent tests methods from Profile to Consent - New integration test to test consent modifications using events - Modified the ModifyConsentAction to only work on a single consent - Renamed the modifyConsents event to modifyConsent to operate on a single consent - Fixed a small problem with the EventCollector that wasn't specifiying a consent type for it's output. Signed-off-by: Serge Huber <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-unomi/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-unomi/commit/485a0f1e Tree: http://git-wip-us.apache.org/repos/asf/incubator-unomi/tree/485a0f1e Diff: http://git-wip-us.apache.org/repos/asf/incubator-unomi/diff/485a0f1e Branch: refs/heads/master Commit: 485a0f1e4b301f5da7897e06b29e51182863f4ba Parents: 38b50c6 Author: Serge Huber <[email protected]> Authored: Mon Nov 13 11:35:07 2017 +0100 Committer: Serge Huber <[email protected]> Committed: Mon Nov 13 11:35:07 2017 +0100 ---------------------------------------------------------------------- .../main/java/org/apache/unomi/api/Consent.java | 160 +++++++++++++++++-- .../java/org/apache/unomi/api/ConsentGrant.java | 7 +- .../main/java/org/apache/unomi/api/Profile.java | 70 ++++---- .../java/org/apache/unomi/itests/AllITs.java | 3 +- .../apache/unomi/itests/ModifyConsentIT.java | 99 ++++++++++++ plugins/baseplugin/pom.xml | 5 + .../baseplugin/actions/ModifyConsentAction.java | 63 ++++++++ .../actions/ModifyConsentsAction.java | 67 -------- .../cxs/actions/modifyConsentAction.json | 16 ++ .../cxs/actions/modifyConsentsAction.json | 16 -- .../conditions/modifyConsentEventCondition.json | 23 +++ .../modifyConsentsEventCondition.json | 23 --- .../META-INF/cxs/rules/modifyConsents.json | 23 +++ .../resources/OSGI-INF/blueprint/blueprint.xml | 4 +- .../unomi/web/EventsCollectorServlet.java | 2 +- 15 files changed, 426 insertions(+), 155 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/api/src/main/java/org/apache/unomi/api/Consent.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/unomi/api/Consent.java b/api/src/main/java/org/apache/unomi/api/Consent.java index 6359a52..1f60252 100644 --- a/api/src/main/java/org/apache/unomi/api/Consent.java +++ b/api/src/main/java/org/apache/unomi/api/Consent.java @@ -16,57 +16,199 @@ */ package org.apache.unomi.api; +import javax.xml.bind.annotation.XmlTransient; +import java.text.DateFormat; +import java.text.ParseException; import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; /** * A consent is an object attached to a profile that indicates whether the profile has agreed or denied a special * consent type. For example a user might have agreed to receiving a newsletter but might have not agreed to being * tracked. */ -public class Consent extends Item { +public class Consent { - private String typeId; // types are defined and managed externally of Apache Unomi + private String typeIdentifier; // type identifiers are defined and managed externally of Apache Unomi private ConsentGrant grant; private Date grantDate; private Date revokeDate; - public Consent(String itemId, String typeId, ConsentGrant grant, Date grantDate, Date revokeDate) { - super(itemId); - this.typeId = typeId; + /** + * Empty constructor mostly used for JSON (de-) serialization + */ + public Consent() { + } + + /** + * A constructor to directly build a consent with all it's properties + * @param typeIdentifier the identifier of the type this consent applies to + * @param grant the type of grant that we are storing for this consent. May be one of @ConsentGrant.DENY, @ConsentGrant.GRANT, @ConsentGrant.REVOKE + * @param grantDate the starting date at which this consent was given + * @param revokeDate the date at which this consent will (automatically) revoke + */ + public Consent(String typeIdentifier, ConsentGrant grant, Date grantDate, Date revokeDate) { + this.typeIdentifier = typeIdentifier; this.grant = grant; this.grantDate = grantDate; this.revokeDate = revokeDate; } - public void setTypeId(String typeId) { - this.typeId = typeId; + /** + * A constructor from a map used for example when we use the deserialized data from event + * properties. + * @param consentMap a Map that contains the following key-value pairs : typeIdentifier:String, grant:String (must + * be one of GRANT, DENY or REVOKE), grantDate:String (ISO8601 date format !), revokeDate:String (ISO8601 date format !) + * @param dateFormat a DateFormat instance to convert the date string to date objects + */ + public Consent(Map<String,Object> consentMap, DateFormat dateFormat) throws ParseException { + if (consentMap.containsKey("typeIdentifier")) { + setTypeIdentifier((String) consentMap.get("typeIdentifier")); + } + if (consentMap.containsKey("grant")) { + String grantString = (String) consentMap.get("grant"); + setGrant(ConsentGrant.valueOf(grantString)); + } + if (consentMap.containsKey("grantDate")) { + String grantDateStr = (String) consentMap.get("grantDate"); + if (grantDateStr != null && grantDateStr.trim().length() > 0) { + setGrantDate(dateFormat.parse(grantDateStr)); + } + } + if (consentMap.containsKey("revokeDate")) { + String revokeDateStr = (String) consentMap.get("revokeDate"); + if (revokeDateStr != null && revokeDateStr.trim().length() > 0) { + setRevokeDate(dateFormat.parse(revokeDateStr)); + } + } + } + + /** + * Set the type identifier. This must be (no validation is done) a unique identifier for the consent type. These + * are usually externally defined, Apache Unomi has no knowledge of them except for this type identifier. + * @param typeIdentifier a unique String to identify the consent type + */ + public void setTypeIdentifier(String typeIdentifier) { + this.typeIdentifier = typeIdentifier; } - public String getTypeId() { - return typeId; + /** + * Retrieve the consent type identifier for this consent. + * @return a String containing the type identifier + */ + public String getTypeIdentifier() { + return typeIdentifier; } + /** + * Retrieves the grant for this consent. This is of type @ConsentGrant + * @return the current value for the grant. + */ public ConsentGrant getGrant() { return grant; } + /** + * Sets the grant for this consent. A Consent Grant of type REVOKE means that this consent is meant to be destroyed. + * @param grant the grant to set on this consent + */ public void setGrant(ConsentGrant grant) { this.grant = grant; } + /** + * Retrieve the date at which this consent was given. If this date is in the future the consent should not be + * considered valid yet. + * @return a valid date or null if this date was not set. + */ public Date getGrantDate() { return grantDate; } + /** + * Sets the date from which this consent applies. + * @param grantDate a valid Date or null if we set not starting date (immediately valid) + */ public void setGrantDate(Date grantDate) { this.grantDate = grantDate; } + /** + * Retrieves the end date for this consent. After this date the consent is no longer valid and should be disposed of. + * If this date is not set it means the consent will never expire + * @return a valid Date or null to indicate an unlimited consent + */ public Date getRevokeDate() { return revokeDate; } + /** + * Sets the end date for this consent. After this date the consent is no longer valid and should be disposed of. + * If this date is not set it means the consent will never expire + * @param revokeDate a valid Date or null to indicate an unlimited consent + */ public void setRevokeDate(Date revokeDate) { this.revokeDate = revokeDate; } + + /** + * Test if the consent is GRANTED right now. + * @return true if the consent is granted using the current date (internally a new Date() is created and the + * @Consent#isConsentGivenAtDate is called. + */ + @XmlTransient + public boolean isConsentGrantedNow() { + return isConsentGrantedAtDate(new Date()); + } + + /** + * Tests if the consent is GRANTED at the specified date + * @param testDate the date against which to test the consent to be granted. + * @return true if the consent is granted at the specified date, false otherwise. + */ + @XmlTransient + public boolean isConsentGrantedAtDate(Date testDate) { + if (getGrantDate().before(testDate) && (getRevokeDate() == null || (getRevokeDate().after(testDate)))) { + if (getGrant().equals(ConsentGrant.GRANT)) { + return true; + } + } + return false; + } + + /** + * This is a utility method to generate a Map based on the contents of the consents. The format of the map is the + * same as the one used in the Map Consent constructor. For dates you must specify a dateFormat that will be used + * to format the dates. This dateFormat should usually support ISO8601 to make integrate with Javascript clients + * easy to integrate. + * @param dateFormat a dateFormat instance such as ISO8601DateFormat to generate the String formats for the grantDate + * and revokeDate map entries. + * @return a Map that contains the following key-value pairs : typeIdentifier:String, grant:String (must + * be one of GRANT, DENY or REVOKE), grantDate:String (generated by the dateFormat), revokeDate:String (generated by the dateFormat) + */ + @XmlTransient + public Map<String,Object> toMap(DateFormat dateFormat) { + Map<String,Object> map = new LinkedHashMap<>(); + map.put("typeIdentifier", typeIdentifier); + map.put("grant", grant.toString()); + if (grantDate != null) { + map.put("grantDate", dateFormat.format(grantDate)); + } + if (revokeDate != null) { + map.put("revokeDate", dateFormat.format(revokeDate)); + } + return map; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Consent{"); + sb.append("typeIdentifier='").append(typeIdentifier).append('\''); + sb.append(", grant=").append(grant); + sb.append(", grantDate=").append(grantDate); + sb.append(", revokeDate=").append(revokeDate); + sb.append('}'); + return sb.toString(); + } } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/api/src/main/java/org/apache/unomi/api/ConsentGrant.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/unomi/api/ConsentGrant.java b/api/src/main/java/org/apache/unomi/api/ConsentGrant.java index a72125d..fea2642 100644 --- a/api/src/main/java/org/apache/unomi/api/ConsentGrant.java +++ b/api/src/main/java/org/apache/unomi/api/ConsentGrant.java @@ -16,7 +16,12 @@ */ package org.apache.unomi.api; +/** + * This enum class represents the type of grant a @Consent might have. The revoke grant type is a special one used to + * remove a consent for a profile. + */ public enum ConsentGrant { GRANT, - DENY + DENY, + REVOKE } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/api/src/main/java/org/apache/unomi/api/Profile.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/unomi/api/Profile.java b/api/src/main/java/org/apache/unomi/api/Profile.java index fa83e39..a6f7ec0 100644 --- a/api/src/main/java/org/apache/unomi/api/Profile.java +++ b/api/src/main/java/org/apache/unomi/api/Profile.java @@ -195,57 +195,57 @@ public class Profile extends Item { this.scores = scores; } + /** + * Returns all the consents, including the revokes ones. + * @return a map that contains the consent type ID as key, and the consent itself as a value + */ public Map<String, Consent> getConsents() { return consents; } + /** + * Returns true if this profile is an anonymous profile. + */ @XmlTransient public boolean isAnonymousProfile() { Boolean anonymous = (Boolean) getSystemProperties().get("isAnonymousProfile"); return anonymous != null && anonymous; } + /** + * Set a consent into the profile. + * @param consent if the consent is a REVOKE grant, it will try to remove a consent with the same type id if it + * exists for the profile. + * @return true if the operation was successful (inserted excpetion in the case of a revoke grant, in which case + * it is successful if there was a consent to revoke). + */ @XmlTransient - public boolean grantConsent(String consentTypeId, Date grantDate, Date revokeDate) { - Consent consent = new Consent(itemId, consentTypeId, ConsentGrant.GRANT, grantDate, revokeDate); - consents.put(consentTypeId, consent); - return true; - } - - @XmlTransient - public boolean denyConsent(String consentTypeId, Date grantDate, Date revokeDate) { - Consent consent = new Consent(itemId, consentTypeId, ConsentGrant.DENY, grantDate, revokeDate); - consents.put(consentTypeId, consent); - return true; - } - - @XmlTransient - public boolean revokeConsent(String consentTypeId) { - if (consents.containsKey(consentTypeId)) { - consents.remove(consentTypeId); - return true; - } - return false; - } - - @XmlTransient - public boolean isConsentGiven(String consentTypeId) { - if (consents.containsKey(consentTypeId)) { - Consent consent = consents.get(consentTypeId); - Date nowDate = new Date(); - if (consent.getGrantDate().before(nowDate) && (consent.getRevokeDate() == null || (consent.getRevokeDate().after(nowDate)))) { - if (consent.getGrant().equals(ConsentGrant.GRANT)) { - return true; - } + public boolean setConsent(Consent consent) { + if (ConsentGrant.REVOKE.equals(consent.getGrant())) { + if (consents.containsKey(consent.getTypeIdentifier())) { + consents.remove(consent.getTypeIdentifier()); + return true; } + return false; } - return false; + consents.put(consent.getTypeIdentifier(), consent); + return true; } @Override public String toString() { - return new StringBuilder(512).append("{id: \"").append(getItemId()).append("\", segments: ") - .append(getSegments()).append(", scores: ").append(getScores()).append(", properties: ") - .append(getProperties()).append("}").toString(); + final StringBuilder sb = new StringBuilder("Profile{"); + sb.append("properties=").append(properties); + sb.append(", systemProperties=").append(systemProperties); + sb.append(", segments=").append(segments); + sb.append(", scores=").append(scores); + sb.append(", mergedWith='").append(mergedWith).append('\''); + sb.append(", consents=").append(consents); + sb.append(", itemId='").append(itemId).append('\''); + sb.append(", itemType='").append(itemType).append('\''); + sb.append(", scope='").append(scope).append('\''); + sb.append(", version=").append(version); + sb.append('}'); + return sb.toString(); } } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/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 4eb8733..bcdedc1 100644 --- a/itests/src/test/java/org/apache/unomi/itests/AllITs.java +++ b/itests/src/test/java/org/apache/unomi/itests/AllITs.java @@ -38,7 +38,8 @@ import org.junit.runners.Suite.SuiteClasses; ProfileImportRankingIT.class, ProfileImportActorsIT.class, ProfileExportIT.class, - PropertiesUpdateActionIT.class + PropertiesUpdateActionIT.class, + ModifyConsentIT.class }) public class AllITs { } http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/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 new file mode 100644 index 0000000..52e60ef --- /dev/null +++ b/itests/src/test/java/org/apache/unomi/itests/ModifyConsentIT.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +package org.apache.unomi.itests; + +import com.fasterxml.jackson.databind.util.ISO8601DateFormat; +import org.apache.unomi.api.Consent; +import org.apache.unomi.api.ConsentGrant; +import org.apache.unomi.api.Event; +import org.apache.unomi.api.Profile; +import org.apache.unomi.api.services.EventService; +import org.apache.unomi.api.services.ProfileService; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import java.io.IOException; +import java.util.Date; + +/** + * An integration test for consent modifications using Apache Unomi @Event + */ +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerSuite.class) +public class ModifyConsentIT extends BaseIT { + + private final static Logger LOGGER = LoggerFactory.getLogger(ModifyConsentIT.class); + + private final static String PROFILE_TEST_ID = "profile-consent"; + + @Inject + protected ProfileService profileService; + + @Inject + protected EventService eventService; + + @Before + public void setUp() throws IOException { + Profile profile = new Profile(); + profile.setItemId(PROFILE_TEST_ID); + profileService.save(profile); + LOGGER.info("Profile saved with ID [{}].", profile.getItemId()); + } + + @Test + public void testConsentGrant() throws InterruptedException { + Profile profile = profileService.load(PROFILE_TEST_ID); + Assert.assertNotNull(profile); + Assert.assertTrue(profile.getConsents().size() == 0); + + Event modifyConsentEvent = new Event("modifyConsent", null, profile, null, null, profile, new Date()); + modifyConsentEvent.setPersistent(false); + + ISO8601DateFormat dateFormat = new ISO8601DateFormat(); + Consent consent1 = new Consent("consentType01", ConsentGrant.GRANT, new Date(), null); + modifyConsentEvent.setProperty("consent", consent1.toMap(dateFormat)); + int changes = eventService.send(modifyConsentEvent); + Consent consent2 = new Consent("consentType02", ConsentGrant.GRANT, new Date(), null); + modifyConsentEvent.setProperty("consent", consent2.toMap(dateFormat)); + changes |= eventService.send(modifyConsentEvent); + + if ((changes & EventService.PROFILE_UPDATED) == EventService.PROFILE_UPDATED) { + profileService.save(profile); + } + + LOGGER.info("Changes of the event : {}", changes); + + Assert.assertTrue(changes > 0); + + //Wait for data to be processed + Thread.sleep(10000); + + profile = profileService.load(PROFILE_TEST_ID); + + Assert.assertTrue(profile.getConsents().size() == 2); + + + } +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/plugins/baseplugin/pom.xml ---------------------------------------------------------------------- diff --git a/plugins/baseplugin/pom.xml b/plugins/baseplugin/pom.xml index fb1068c..ec0dfff 100644 --- a/plugins/baseplugin/pom.xml +++ b/plugins/baseplugin/pom.xml @@ -73,6 +73,11 @@ <groupId>javassist</groupId> <artifactId>javassist</artifactId> </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <scope>provided</scope> + </dependency> </dependencies> <build> http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/actions/ModifyConsentAction.java ---------------------------------------------------------------------- diff --git a/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/actions/ModifyConsentAction.java b/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/actions/ModifyConsentAction.java new file mode 100644 index 0000000..344d5eb --- /dev/null +++ b/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/actions/ModifyConsentAction.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.unomi.plugins.baseplugin.actions; + +import com.fasterxml.jackson.databind.util.ISO8601DateFormat; +import org.apache.unomi.api.Consent; +import org.apache.unomi.api.Event; +import org.apache.unomi.api.Profile; +import org.apache.unomi.api.actions.Action; +import org.apache.unomi.api.actions.ActionExecutor; +import org.apache.unomi.api.services.EventService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.ParseException; +import java.util.Map; + +/** + * This class will process consent modification actions and update the profile's consents accordingly. + */ +public class ModifyConsentAction implements ActionExecutor { + + private static final Logger logger = LoggerFactory.getLogger(ModifyConsentAction.class.getName()); + + public static final String CONSENT_PROPERTY_NAME = "consent"; + + @Override + public int execute(Action action, Event event) { + Profile profile = event.getProfile(); + boolean isProfileUpdated = false; + + ISO8601DateFormat dateFormat = new ISO8601DateFormat(); + Map consentMap = (Map) event.getProperties().get(CONSENT_PROPERTY_NAME); + if (consentMap != null) { + if (consentMap.containsKey("typeIdentifier") && consentMap.containsKey("grant")) { + Consent consent = null; + try { + consent = new Consent(consentMap, dateFormat); + isProfileUpdated = profile.setConsent(consent); + } catch (ParseException e) { + logger.error("Error parsing date format", e); + } + } else { + logger.warn("Event properties for modifyConsent is missing typeIdentifier and grant properties. We will ignore this event."); + } + } + return isProfileUpdated ? EventService.PROFILE_UPDATED : EventService.NO_CHANGE; + } +} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/actions/ModifyConsentsAction.java ---------------------------------------------------------------------- diff --git a/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/actions/ModifyConsentsAction.java b/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/actions/ModifyConsentsAction.java deleted file mode 100644 index 84a1d2c..0000000 --- a/plugins/baseplugin/src/main/java/org/apache/unomi/plugins/baseplugin/actions/ModifyConsentsAction.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.unomi.plugins.baseplugin.actions; - -import org.apache.unomi.api.Consent; -import org.apache.unomi.api.Event; -import org.apache.unomi.api.Profile; -import org.apache.unomi.api.actions.Action; -import org.apache.unomi.api.actions.ActionExecutor; -import org.apache.unomi.api.services.EventService; - -import java.util.List; - -/** - * This class will process consent modification actions and update the profile's consents accordingly. - */ -public class ModifyConsentsAction implements ActionExecutor { - - public static final String GRANTED_CONSENTS = "grantedConsents"; - public static final String DENIED_CONSENTS = "deniedConsents"; - public static final String REVOKED_CONSENTS = "revokedConsents"; - - @Override - public int execute(Action action, Event event) { - - Profile profile = event.getProfile(); - boolean isProfileUpdated = false; - - List<Consent> grantedConsents = (List<Consent>) event.getProperties().get(GRANTED_CONSENTS); - if (grantedConsents != null) { - for (Consent consent : grantedConsents) { - profile.grantConsent(consent.getTypeId(), consent.getGrantDate(), consent.getRevokeDate()); - } - isProfileUpdated = true; - } - List<Consent> deniedConsents = (List<Consent>) event.getProperties().get(DENIED_CONSENTS); - if (deniedConsents != null) { - for (Consent consent : deniedConsents) { - profile.denyConsent(consent.getTypeId(), consent.getGrantDate(), consent.getRevokeDate()); - } - isProfileUpdated = true; - } - List<Consent> revokedConsents = (List<Consent>) event.getProperties().get(REVOKED_CONSENTS); - if (revokedConsents != null) { - for (Consent consent : revokedConsents) { - profile.revokeConsent(consent.getTypeId()); - } - isProfileUpdated = true; - } - - return isProfileUpdated ? EventService.PROFILE_UPDATED : EventService.NO_CHANGE; - } -} http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/plugins/baseplugin/src/main/resources/META-INF/cxs/actions/modifyConsentAction.json ---------------------------------------------------------------------- diff --git a/plugins/baseplugin/src/main/resources/META-INF/cxs/actions/modifyConsentAction.json b/plugins/baseplugin/src/main/resources/META-INF/cxs/actions/modifyConsentAction.json new file mode 100644 index 0000000..b954afe --- /dev/null +++ b/plugins/baseplugin/src/main/resources/META-INF/cxs/actions/modifyConsentAction.json @@ -0,0 +1,16 @@ +{ + "metadata": { + "id": "modifyConsentAction", + "name": "modifyConsentAction", + "description": "Modify a profile consent", + "systemTags": [ + "profileTags", + "demographic" + ], + "readOnly": true + }, + "actionExecutor": "modifyConsent", + "parameters": [ + + ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/plugins/baseplugin/src/main/resources/META-INF/cxs/actions/modifyConsentsAction.json ---------------------------------------------------------------------- diff --git a/plugins/baseplugin/src/main/resources/META-INF/cxs/actions/modifyConsentsAction.json b/plugins/baseplugin/src/main/resources/META-INF/cxs/actions/modifyConsentsAction.json deleted file mode 100644 index 2910019..0000000 --- a/plugins/baseplugin/src/main/resources/META-INF/cxs/actions/modifyConsentsAction.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "metadata": { - "id": "modifyConsentsAction", - "name": "modifyConsentsAction", - "description": "Modify profile consents", - "systemTags": [ - "profileTags", - "demographic" - ], - "readOnly": true - }, - "actionExecutor": "modifyConsents", - "parameters": [ - - ] -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/plugins/baseplugin/src/main/resources/META-INF/cxs/conditions/modifyConsentEventCondition.json ---------------------------------------------------------------------- diff --git a/plugins/baseplugin/src/main/resources/META-INF/cxs/conditions/modifyConsentEventCondition.json b/plugins/baseplugin/src/main/resources/META-INF/cxs/conditions/modifyConsentEventCondition.json new file mode 100644 index 0000000..b24c479 --- /dev/null +++ b/plugins/baseplugin/src/main/resources/META-INF/cxs/conditions/modifyConsentEventCondition.json @@ -0,0 +1,23 @@ +{ + "metadata": { + "id": "modifyConsentEventCondition", + "name": "modifyConsentEventCondition", + "description": "", + "systemTags": [ + "profileTags", + "event", + "condition", + "eventCondition" + ], + "readOnly": true + }, + "parentCondition": { + "type": "eventTypeCondition", + "parameterValues": { + "eventTypeId": "modifyConsent" + } + }, + + "parameters": [ + ] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/plugins/baseplugin/src/main/resources/META-INF/cxs/conditions/modifyConsentsEventCondition.json ---------------------------------------------------------------------- diff --git a/plugins/baseplugin/src/main/resources/META-INF/cxs/conditions/modifyConsentsEventCondition.json b/plugins/baseplugin/src/main/resources/META-INF/cxs/conditions/modifyConsentsEventCondition.json deleted file mode 100644 index ec1333e..0000000 --- a/plugins/baseplugin/src/main/resources/META-INF/cxs/conditions/modifyConsentsEventCondition.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "metadata": { - "id": "modifyConsentsEventCondition", - "name": "modifyConsentsEventCondition", - "description": "", - "systemTags": [ - "profileTags", - "event", - "condition", - "eventCondition" - ], - "readOnly": true - }, - "parentCondition": { - "type": "eventTypeCondition", - "parameterValues": { - "eventTypeId": "modifyConsents" - } - }, - - "parameters": [ - ] -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/plugins/baseplugin/src/main/resources/META-INF/cxs/rules/modifyConsents.json ---------------------------------------------------------------------- diff --git a/plugins/baseplugin/src/main/resources/META-INF/cxs/rules/modifyConsents.json b/plugins/baseplugin/src/main/resources/META-INF/cxs/rules/modifyConsents.json new file mode 100644 index 0000000..34531a7 --- /dev/null +++ b/plugins/baseplugin/src/main/resources/META-INF/cxs/rules/modifyConsents.json @@ -0,0 +1,23 @@ +{ + "metadata" : { + "id": "modifyConsent", + "name": "Modify consent", + "description" : "Modify a consent", + "readOnly":true + }, + + "condition" : { + "type": "modifyConsentEventCondition", + "parameterValues": { + } + }, + + "actions" : [ + { + "type": "modifyConsentAction", + "parameterValues": { + } + } + ] + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/plugins/baseplugin/src/main/resources/OSGI-INF/blueprint/blueprint.xml ---------------------------------------------------------------------- diff --git a/plugins/baseplugin/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/plugins/baseplugin/src/main/resources/OSGI-INF/blueprint/blueprint.xml index c2a7012..6778b4f 100644 --- a/plugins/baseplugin/src/main/resources/OSGI-INF/blueprint/blueprint.xml +++ b/plugins/baseplugin/src/main/resources/OSGI-INF/blueprint/blueprint.xml @@ -182,9 +182,9 @@ <service auto-export="interfaces"> <service-properties> - <entry key="actionExecutorId" value="modifyConsents"/> + <entry key="actionExecutorId" value="modifyConsent"/> </service-properties> - <bean class="org.apache.unomi.plugins.baseplugin.actions.ModifyConsentsAction"> + <bean class="org.apache.unomi.plugins.baseplugin.actions.ModifyConsentAction"> </bean> </service> http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/485a0f1e/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java ---------------------------------------------------------------------- diff --git a/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java b/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java index 480be81..432a694 100644 --- a/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java +++ b/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java @@ -37,7 +37,6 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.UUID; @@ -214,6 +213,7 @@ public class EventsCollectorServlet extends HttpServlet { profileService.saveSession(session); } + response.setContentType("application/json"); PrintWriter responseWriter = response.getWriter(); responseWriter.append("{\"updated\":" + changes + "}"); responseWriter.flush();
