http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/services/src/main/java/org/oasis_open/contextserver/impl/services/SegmentServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/services/src/main/java/org/oasis_open/contextserver/impl/services/SegmentServiceImpl.java
 
b/services/src/main/java/org/oasis_open/contextserver/impl/services/SegmentServiceImpl.java
deleted file mode 100644
index e853959..0000000
--- 
a/services/src/main/java/org/oasis_open/contextserver/impl/services/SegmentServiceImpl.java
+++ /dev/null
@@ -1,818 +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.oasis_open.contextserver.impl.services;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import org.oasis_open.contextserver.api.*;
-import org.oasis_open.contextserver.api.actions.Action;
-import org.oasis_open.contextserver.api.conditions.Condition;
-import org.oasis_open.contextserver.api.conditions.ConditionType;
-import org.oasis_open.contextserver.api.query.Query;
-import org.oasis_open.contextserver.api.rules.Rule;
-import org.oasis_open.contextserver.api.segments.Scoring;
-import org.oasis_open.contextserver.api.segments.ScoringElement;
-import org.oasis_open.contextserver.api.segments.Segment;
-import org.oasis_open.contextserver.api.segments.SegmentsAndScores;
-import org.oasis_open.contextserver.api.services.DefinitionsService;
-import org.oasis_open.contextserver.api.services.RulesService;
-import org.oasis_open.contextserver.api.services.SegmentService;
-import org.oasis_open.contextserver.persistence.spi.CustomObjectMapper;
-import org.oasis_open.contextserver.persistence.spi.PersistenceService;
-import org.oasis_open.contextserver.persistence.spi.aggregate.TermsAggregate;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.SynchronousBundleListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.json.*;
-import java.io.IOException;
-import java.net.URL;
-import java.security.MessageDigest;
-import java.util.*;
-
-public class SegmentServiceImpl implements SegmentService, 
SynchronousBundleListener {
-
-    private static final Logger logger = 
LoggerFactory.getLogger(SegmentServiceImpl.class.getName());
-
-    private BundleContext bundleContext;
-
-    private PersistenceService persistenceService;
-
-    private DefinitionsService definitionsService;
-
-    private RulesService rulesService;
-
-    private long taskExecutionPeriod = 24L * 60L * 60L * 1000L;
-
-    public SegmentServiceImpl() {
-        logger.info("Initializing segment service...");
-    }
-
-    private List<Segment> allSegments;
-    private List<Scoring> allScoring;
-
-    private Timer segmentTimer;
-
-    public static void dumpJSON(JsonValue tree, String key, String 
depthPrefix) {
-        if (key != null)
-            logger.info(depthPrefix + "Key " + key + ": ");
-        switch (tree.getValueType()) {
-            case OBJECT:
-                logger.info(depthPrefix + "OBJECT");
-                JsonObject object = (JsonObject) tree;
-                for (String name : object.keySet())
-                    dumpJSON(object.get(name), name, depthPrefix + "  ");
-                break;
-            case ARRAY:
-                logger.info(depthPrefix + "ARRAY");
-                JsonArray array = (JsonArray) tree;
-                for (JsonValue val : array)
-                    dumpJSON(val, null, depthPrefix + "  ");
-                break;
-            case STRING:
-                JsonString st = (JsonString) tree;
-                logger.info(depthPrefix + "STRING " + st.getString());
-                break;
-            case NUMBER:
-                JsonNumber num = (JsonNumber) tree;
-                logger.info(depthPrefix + "NUMBER " + num.toString());
-                break;
-            case TRUE:
-            case FALSE:
-            case NULL:
-                logger.info(depthPrefix + tree.getValueType().toString());
-                break;
-        }
-    }
-
-    public void setBundleContext(BundleContext bundleContext) {
-        this.bundleContext = bundleContext;
-    }
-
-    public void setPersistenceService(PersistenceService persistenceService) {
-        this.persistenceService = persistenceService;
-    }
-
-    public void setDefinitionsService(DefinitionsService definitionsService) {
-        this.definitionsService = definitionsService;
-    }
-
-    public void setRulesService(RulesService rulesService) {
-        this.rulesService = rulesService;
-    }
-
-    public void postConstruct() {
-        logger.debug("postConstruct {" + bundleContext.getBundle() + "}");
-        loadPredefinedSegments(bundleContext);
-        loadPredefinedScorings(bundleContext);
-        for (Bundle bundle : bundleContext.getBundles()) {
-            if (bundle.getBundleContext() != null) {
-                loadPredefinedSegments(bundle.getBundleContext());
-                loadPredefinedScorings(bundle.getBundleContext());
-            }
-        }
-        bundleContext.addBundleListener(this);
-        initializeTimer();
-    }
-
-    public void preDestroy() {
-        bundleContext.removeBundleListener(this);
-        cancelTimers();
-    }
-
-    private void cancelTimers() {
-        if(segmentTimer != null) {
-            segmentTimer.cancel();
-        }
-        logger.info("Segment purge: Purge unscheduled");
-    }
-
-    private void processBundleStartup(BundleContext bundleContext) {
-        if (bundleContext == null) {
-            return;
-        }
-        loadPredefinedSegments(bundleContext);
-        loadPredefinedScorings(bundleContext);
-
-        List<PluginType> types = 
definitionsService.getTypesByPlugin().get(bundleContext.getBundle().getBundleId());
-        List<String> addedConditions = new ArrayList<String>();
-        if (types != null) {
-            for (PluginType type : types) {
-                if (type instanceof ConditionType) {
-                    addedConditions.add(((ConditionType) type).getId());
-                }
-            }
-        }
-        if (!addedConditions.isEmpty()) {
-            for (Segment segment : persistenceService.query("missingPlugins", 
"true", null, Segment.class)) {
-                boolean succeed = 
ParserHelper.resolveConditionType(definitionsService, segment.getCondition());
-                if (succeed) {
-                    logger.info("Enable segment " + segment.getItemId());
-                    segment.getMetadata().setMissingPlugins(false);
-                    setSegmentDefinition(segment);
-                }
-            }
-        }
-    }
-
-    private void processBundleStop(BundleContext bundleContext) {
-        if (bundleContext == null) {
-            return;
-        }
-        List<PluginType> types = 
definitionsService.getTypesByPlugin().get(bundleContext.getBundle().getBundleId());
-        List<String> removedConditions = new ArrayList<String>();
-        if (types != null) {
-            for (PluginType type : types) {
-                if (type instanceof ConditionType) {
-                    removedConditions.add(((ConditionType) type).getId());
-                }
-            }
-        }
-        if (!removedConditions.isEmpty()) {
-            for (Segment segment : 
persistenceService.getAllItems(Segment.class)) {
-                List<String> conditions = 
ParserHelper.getConditionTypeIds(segment.getCondition());
-                if (!Collections.disjoint(conditions, removedConditions)) {
-                    logger.info("Disable segment " + segment.getItemId());
-                    segment.getMetadata().setMissingPlugins(true);
-                    setSegmentDefinition(segment);
-                }
-            }
-        }
-    }
-
-    private void loadPredefinedSegments(BundleContext bundleContext) {
-        Enumeration<URL> predefinedSegmentEntries = 
bundleContext.getBundle().findEntries("META-INF/cxs/segments", "*.json", true);
-        if (predefinedSegmentEntries == null) {
-            return;
-        }
-        while (predefinedSegmentEntries.hasMoreElements()) {
-            URL predefinedSegmentURL = predefinedSegmentEntries.nextElement();
-            logger.debug("Found predefined segment at " + predefinedSegmentURL 
+ ", loading... ");
-
-            try {
-                Segment segment = 
CustomObjectMapper.getObjectMapper().readValue(predefinedSegmentURL, 
Segment.class);
-                if (segment.getMetadata().getScope() == null) {
-                    segment.getMetadata().setScope("systemscope");
-                }
-                if (getSegmentDefinition(segment.getMetadata().getId()) == 
null) {
-                    setSegmentDefinition(segment);
-                }
-            } catch (IOException e) {
-                logger.error("Error while loading segment definition " + 
predefinedSegmentURL, e);
-            }
-        }
-    }
-
-    private void loadPredefinedScorings(BundleContext bundleContext) {
-        Enumeration<URL> predefinedScoringEntries = 
bundleContext.getBundle().findEntries("META-INF/cxs/scoring", "*.json", true);
-        if (predefinedScoringEntries == null) {
-            return;
-        }
-        while (predefinedScoringEntries.hasMoreElements()) {
-            URL predefinedScoringURL = predefinedScoringEntries.nextElement();
-            logger.debug("Found predefined scoring at " + predefinedScoringURL 
+ ", loading... ");
-
-            try {
-                Scoring scoring = 
CustomObjectMapper.getObjectMapper().readValue(predefinedScoringURL, 
Scoring.class);
-                if (scoring.getMetadata().getScope() == null) {
-                    scoring.getMetadata().setScope("systemscope");
-                }
-                if (getScoringDefinition(scoring.getMetadata().getId()) == 
null) {
-                    setScoringDefinition(scoring);
-                }
-            } catch (IOException e) {
-                logger.error("Error while loading segment definition " + 
predefinedScoringURL, e);
-            }
-        }
-    }
-
-    public PartialList<Metadata> getSegmentMetadatas(int offset, int size, 
String sortBy) {
-        return getMetadatas(offset, size, sortBy, Segment.class);
-    }
-
-    public PartialList<Metadata> getSegmentMetadatas(String scope, int offset, 
int size, String sortBy) {
-        PartialList<Segment> segments = 
persistenceService.query("metadata.scope", scope, sortBy, Segment.class, 
offset, size);
-        List<Metadata> details = new LinkedList<>();
-        for (Segment definition : segments.getList()) {
-            details.add(definition.getMetadata());
-        }
-        return new PartialList<>(details, segments.getOffset(), 
segments.getPageSize(), segments.getTotalSize());
-    }
-
-    public PartialList<Metadata> getSegmentMetadatas(Query query) {
-        return getMetadatas(query, Segment.class);
-    }
-
-    private List<Segment> getAllSegmentDefinitions() {
-        List<Segment> allItems = persistenceService.getAllItems(Segment.class);
-        for (Segment segment : allItems) {
-            ParserHelper.resolveConditionType(definitionsService, 
segment.getCondition());
-        }
-        return allItems;
-    }
-
-    public Segment getSegmentDefinition(String segmentId) {
-        Segment definition = persistenceService.load(segmentId, Segment.class);
-        if (definition != null) {
-            ParserHelper.resolveConditionType(definitionsService, 
definition.getCondition());
-        }
-        return definition;
-    }
-
-    public void setSegmentDefinition(Segment segment) {
-        ParserHelper.resolveConditionType(definitionsService, 
segment.getCondition());
-        if (segment.getMetadata().isEnabled() && 
!segment.getMetadata().isMissingPlugins()) {
-            updateAutoGeneratedRules(segment.getMetadata(), 
segment.getCondition());
-        }
-        // make sure we update the name and description metadata that might 
not match, so first we remove the entry from the map
-        persistenceService.save(segment);
-
-        updateExistingProfilesForSegment(segment);
-    }
-
-    private void checkIfSegmentIsImpacted(Segment segment, Condition 
condition, String segmentToDeleteId, Set<Segment> impactedSegments) {
-        if(condition != null) {
-            @SuppressWarnings("unchecked")
-            final List<Condition> subConditions = (List<Condition>) 
condition.getParameter("subConditions");
-            if (subConditions != null) {
-                for (Condition subCondition : subConditions) {
-                    checkIfSegmentIsImpacted(segment, subCondition, 
segmentToDeleteId, impactedSegments);
-                }
-            } else if 
("profileSegmentCondition".equals(condition.getConditionTypeId())) {
-                @SuppressWarnings("unchecked")
-                final List<String> referencedSegmentIds = (List<String>) 
condition.getParameter("segments");
-
-                if (referencedSegmentIds.indexOf(segmentToDeleteId) >= 0) {
-                    impactedSegments.add(segment);
-                }
-            }
-        }
-    }
-
-    /**
-     * Return an updated condition that do not contain a condition on the 
segmentId anymore
-     * it's remove the unnecessary boolean condition (if a condition is the 
only one of a boolean the boolean will be remove and the subcondition returned)
-     * it's return null when there is no more condition after (if the 
condition passed was only a segment condition on the segmentId)
-     * @param condition the condition to update
-     * @param segmentId the segment id to remove in the condition
-     * @return updated condition
-     */
-    private Condition updateImpactedCondition(Condition condition, String 
segmentId) {
-        if ("booleanCondition".equals(condition.getConditionTypeId())) {
-            @SuppressWarnings("unchecked")
-            final List<Condition> subConditions = (List<Condition>) 
condition.getParameter("subConditions");
-            List<Condition> updatedSubConditions = new LinkedList<>();
-            for (Condition subCondition : subConditions) {
-                Condition updatedCondition = 
updateImpactedCondition(subCondition, segmentId);
-                if(updatedCondition != null) {
-                    updatedSubConditions.add(updatedCondition);
-                }
-            }
-            if(!updatedSubConditions.isEmpty()){
-                if(updatedSubConditions.size() == 1) {
-                    return updatedSubConditions.get(0);
-                } else {
-                    condition.setParameter("subConditions", 
updatedSubConditions);
-                    return condition;
-                }
-            } else {
-                return null;
-            }
-        } else 
if("profileSegmentCondition".equals(condition.getConditionTypeId())) {
-            @SuppressWarnings("unchecked")
-            final List<String> referencedSegmentIds = (List<String>) 
condition.getParameter("segments");
-            if (referencedSegmentIds.indexOf(segmentId) >= 0) {
-                referencedSegmentIds.remove(segmentId);
-                if(referencedSegmentIds.isEmpty()) {
-                    return null;
-                } else {
-                    condition.setParameter("segments", referencedSegmentIds);
-                }
-            }
-        }
-        return condition;
-    }
-
-    private Set<Segment> getImpactedSegments(String segmentId) {
-        Set<Segment> impactedSegments = new HashSet<>(this.allSegments.size());
-        for (Segment segment : this.allSegments) {
-            checkIfSegmentIsImpacted(segment, segment.getCondition(), 
segmentId, impactedSegments);
-        }
-        return impactedSegments;
-    }
-
-    public List<Metadata> getImpactedSegmentMetadata(String segmentId) {
-        List<Metadata> details = new LinkedList<>();
-        for (Segment definition : getImpactedSegments(segmentId)) {
-            details.add(definition.getMetadata());
-        }
-
-        return details;
-    }
-
-    public List<Metadata> removeSegmentDefinition(String segmentId, boolean 
validate) {
-        Set<Segment> impactedSegments = getImpactedSegments(segmentId);
-        if (!validate || impactedSegments.isEmpty()) {
-            // update profiles
-            Condition segmentCondition = new Condition();
-            
segmentCondition.setConditionType(definitionsService.getConditionType("profilePropertyCondition"));
-            segmentCondition.setParameter("propertyName", "segments");
-            segmentCondition.setParameter("comparisonOperator", "equals");
-            segmentCondition.setParameter("propertyValue", segmentId);
-
-            List<Profile> previousProfiles = 
persistenceService.query(segmentCondition, null, Profile.class);
-            for (Profile profileToRemove : previousProfiles) {
-                profileToRemove.getSegments().remove(segmentId);
-                persistenceService.update(profileToRemove.getItemId(), null, 
Profile.class, "segments", profileToRemove.getSegments());
-            }
-
-            // update impacted segments
-            for (Segment segment : impactedSegments) {
-                Condition updatedCondition = 
updateImpactedCondition(segment.getCondition(), segmentId);
-                segment.setCondition(updatedCondition);
-                if(updatedCondition == null) {
-                    
clearAutoGeneratedRules(persistenceService.query("linkedItems", 
segment.getMetadata().getId(), null, Rule.class), 
segment.getMetadata().getId());
-                    segment.getMetadata().setEnabled(false);
-                }
-                setSegmentDefinition(segment);
-            }
-
-            persistenceService.remove(segmentId, Segment.class);
-            List<Rule> previousRules = persistenceService.query("linkedItems", 
segmentId, null, Rule.class);
-            clearAutoGeneratedRules(previousRules, segmentId);
-        }
-
-        List<Metadata> metadata = new LinkedList<>();
-        for (Segment definition : impactedSegments) {
-            metadata.add(definition.getMetadata());
-        }
-        return metadata;
-    }
-
-
-    public PartialList<Profile> getMatchingIndividuals(String segmentID, int 
offset, int size, String sortBy) {
-        Segment segment = getSegmentDefinition(segmentID);
-        if (segment == null) {
-            return new PartialList<Profile>();
-        }
-        return persistenceService.query(segment.getCondition(), sortBy, 
Profile.class, offset, size);
-    }
-
-    public long getMatchingIndividualsCount(String segmentID) {
-        if (getSegmentDefinition(segmentID) == null) {
-            return 0;
-        }
-
-        Condition excludeMergedProfilesCondition = new 
Condition(definitionsService.getConditionType("profilePropertyCondition"));
-        excludeMergedProfilesCondition.setParameter("propertyName", 
"mergedWith");
-        excludeMergedProfilesCondition.setParameter("comparisonOperator", 
"missing");
-        Condition condition = new 
Condition(definitionsService.getConditionType("booleanCondition"));
-        condition.setParameter("operator", "and");
-        condition.setParameter("subConditions", 
Arrays.asList(getSegmentDefinition(segmentID).getCondition(), 
excludeMergedProfilesCondition));
-
-        return persistenceService.queryCount(condition, Profile.ITEM_TYPE);
-    }
-
-    public Boolean isProfileInSegment(Profile profile, String segmentId) {
-        Set<String> matchingSegments = 
getSegmentsAndScoresForProfile(profile).getSegments();
-
-        return matchingSegments.contains(segmentId);
-    }
-
-    public SegmentsAndScores getSegmentsAndScoresForProfile(Profile profile) {
-        Set<String> segments = new HashSet<String>();
-        Map<String,Integer> scores = new HashMap<String, Integer>();
-
-        List<Segment> allSegments = this.allSegments;
-        for (Segment segment : allSegments) {
-            if (persistenceService.testMatch(segment.getCondition(), profile)) 
{
-                segments.add(segment.getMetadata().getId());
-            }
-        }
-
-        List<Scoring> allScoring = this.allScoring;
-        for (Scoring scoring : allScoring) {
-            if (scoring.getMetadata().isEnabled()) {
-                int score = 0;
-                for (ScoringElement scoringElement : scoring.getElements()) {
-                    if 
(persistenceService.testMatch(scoringElement.getCondition(), profile)) {
-                        score += scoringElement.getValue();
-                    }
-                }
-                if (score > 0) {
-                    scores.put(scoring.getMetadata().getId(), score);
-                }
-            }
-        }
-
-        return new SegmentsAndScores(segments, scores);
-    }
-
-    public List<Metadata> getSegmentMetadatasForProfile(Profile profile) {
-        List<Metadata> metadatas = new ArrayList<>();
-
-        List<Segment> allSegments = this.allSegments;
-        for (Segment segment : allSegments) {
-            if (persistenceService.testMatch(segment.getCondition(), profile)) 
{
-                metadatas.add(segment.getMetadata());
-            }
-        }
-
-        return metadatas;
-    }
-
-    public PartialList<Metadata> getScoringMetadatas(int offset, int size, 
String sortBy) {
-       return getMetadatas(offset, size, sortBy, Scoring.class);
-    }
-
-    public PartialList<Metadata> getScoringMetadatas(Query query) {
-        return getMetadatas(query, Scoring.class);
-    }
-
-    private List<Scoring> getAllScoringDefinitions() {
-        List<Scoring> allItems = persistenceService.getAllItems(Scoring.class);
-        for (Scoring scoring : allItems) {
-            for (ScoringElement element : scoring.getElements()) {
-                ParserHelper.resolveConditionType(definitionsService, 
element.getCondition());
-            }
-        }
-        return allItems;
-    }
-
-    public Scoring getScoringDefinition(String scoringId) {
-        Scoring definition = persistenceService.load(scoringId, Scoring.class);
-        if (definition != null) {
-            for (ScoringElement element : definition.getElements()) {
-                ParserHelper.resolveConditionType(definitionsService, 
element.getCondition());
-            }
-        }
-        return definition;
-    }
-
-    public void setScoringDefinition(Scoring scoring) {
-        for (ScoringElement element : scoring.getElements()) {
-            ParserHelper.resolveConditionType(definitionsService, 
element.getCondition());
-        }
-        for (ScoringElement element : scoring.getElements()) {
-            if (scoring.getMetadata().isEnabled() && 
!scoring.getMetadata().isMissingPlugins()) {
-                updateAutoGeneratedRules(scoring.getMetadata(), 
element.getCondition());
-            }
-        }
-        // make sure we update the name and description metadata that might 
not match, so first we remove the entry from the map
-        persistenceService.save(scoring);
-
-        updateExistingProfilesForScoring(scoring);
-    }
-
-    public void createScoringDefinition(String scope, String scoringId, String 
name, String description) {
-        Metadata metadata = new Metadata(scope, scoringId, name, description);
-        Scoring scoring = new Scoring(metadata);
-        Condition rootCondition = new Condition();
-        
rootCondition.setConditionType(definitionsService.getConditionType("booleanCondition"));
-        rootCondition.setParameter("operator", "and");
-        rootCondition.setParameter("subConditions", new 
ArrayList<Condition>());
-        scoring.setElements(new ArrayList<ScoringElement>());
-
-        setScoringDefinition(scoring);
-    }
-
-    public void removeScoringDefinition(String scoringId) {
-        persistenceService.remove(scoringId, Scoring.class);
-
-        updateExistingProfilesForRemovedScoring(scoringId);
-    }
-
-    public void updateAutoGeneratedRules(Metadata metadata, Condition 
condition) {
-        List<Rule> previousRules = persistenceService.query("linkedItems", 
metadata.getId(), null, Rule.class);
-        List<Rule> rules = new ArrayList<Rule>();
-        if (condition != null) {
-            getAutoGeneratedRules(metadata, condition, null, rules);
-        }
-        for (Rule rule : rules) {
-            rulesService.setRule(rule);
-        }
-        previousRules.removeAll(rules);
-        clearAutoGeneratedRules(previousRules, metadata.getId());
-    }
-
-    private void clearAutoGeneratedRules(List<Rule> rules, String idWithScope) 
{
-        for (Rule previousRule : rules) {
-            previousRule.getLinkedItems().remove(idWithScope);
-            if (previousRule.getLinkedItems().isEmpty()) {
-                // todo remove profile properties ?
-                persistenceService.remove(previousRule.getItemId(), 
Rule.class);
-            } else {
-                persistenceService.update(previousRule.getItemId(), null, 
Rule.class, "linkedItems", previousRule.getLinkedItems());
-            }
-        }
-    }
-
-    private void getAutoGeneratedRules(Metadata metadata, Condition condition, 
Condition parentCondition, List<Rule> rules) {
-        if 
(condition.getConditionType().getTagIDs().contains("eventCondition") && 
!condition.getConditionType().getTagIDs().contains("profileCondition")) {
-            try {
-                Map<String,Object> m = new HashMap<>(3);
-                m.put("scope",metadata.getScope());
-                m.put("condition", condition);
-                m.put("numberOfDays", 
parentCondition.getParameter("numberOfDays"));
-                String key = 
CustomObjectMapper.getObjectMapper().writeValueAsString(m);
-                key = "eventTriggered" + getMD5(key);
-                parentCondition.setParameter("generatedPropertyKey", key);
-                Rule rule = rulesService.getRule(key);
-                if (rule == null) {
-                    rule = new Rule(new Metadata(metadata.getScope(), key, 
"Auto generated rule for "+metadata.getName(), ""));
-                    rule.setCondition(condition);
-                    rule.getMetadata().setHidden(true);
-                    final Action action = new Action();
-                    
action.setActionType(definitionsService.getActionType("setEventOccurenceCountAction"));
-                    action.setParameter("pastEventCondition", parentCondition);
-
-                    rule.setActions(Arrays.asList(action));
-                    rule.setLinkedItems(Arrays.asList(metadata.getId()));
-                    rules.add(rule);
-
-                    updateExistingProfilesForPastEventCondition(condition, 
parentCondition);
-                } else {
-                    rule.getLinkedItems().add(metadata.getId());
-                    rules.add(rule);
-                }
-            } catch (JsonProcessingException e) {
-                logger.error(e.getMessage(), e);
-            }
-        } else {
-            Collection<Object> values = new 
ArrayList<>(condition.getParameterValues().values());
-            for (Object parameterValue : values) {
-                if (parameterValue instanceof Condition) {
-                    getAutoGeneratedRules(metadata, (Condition) 
parameterValue, condition, rules);
-                } else if (parameterValue instanceof Collection) {
-                    for (Object subCondition : (Collection<?>) parameterValue) 
{
-                        if (subCondition instanceof Condition) {
-                            getAutoGeneratedRules(metadata, (Condition) 
subCondition, condition, rules);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    private void updateExistingProfilesForPastEventCondition(Condition 
eventCondition, Condition parentCondition) {
-        long t = System.currentTimeMillis();
-        List<Condition> l = new ArrayList<Condition>();
-        Condition andCondition = new Condition();
-        
andCondition.setConditionType(definitionsService.getConditionType("booleanCondition"));
-        andCondition.setParameter("operator", "and");
-        andCondition.setParameter("subConditions", l);
-
-        l.add(eventCondition);
-
-        Integer numberOfDays = (Integer) 
parentCondition.getParameter("numberOfDays");
-        if (numberOfDays != null) {
-            Condition numberOfDaysCondition = new Condition();
-            
numberOfDaysCondition.setConditionType(definitionsService.getConditionType("sessionPropertyCondition"));
-            numberOfDaysCondition.setParameter("propertyName", "timeStamp");
-            numberOfDaysCondition.setParameter("comparisonOperator", 
"greaterThan");
-            numberOfDaysCondition.setParameter("propertyValue", "now-" + 
numberOfDays + "d");
-            l.add(numberOfDaysCondition);
-        }
-        String propertyKey = (String) 
parentCondition.getParameter("generatedPropertyKey");
-        Map<String, Long> res = 
persistenceService.aggregateQuery(andCondition, new 
TermsAggregate("profileId"), Event.ITEM_TYPE);
-        for (Map.Entry<String, Long> entry : res.entrySet()) {
-            if (!entry.getKey().startsWith("_")) {
-                Map<String,Object> p = new HashMap<>();
-                p.put(propertyKey, entry.getValue());
-                Map<String,Object> p2 = new HashMap<>();
-                p2.put("pastEvents",p);
-                try {
-                    persistenceService.update(entry.getKey(), null, 
Profile.class, "systemProperties", p2);
-                } catch (Exception e) {
-                    logger.error(e.getMessage(), e);
-                }
-            }
-        }
-
-        logger.info("Profiles past condition updated in {}", 
System.currentTimeMillis()-t);
-    }
-
-    private void updateExistingProfilesForSegment(Segment segment) {
-        long t = System.currentTimeMillis();
-        Condition segmentCondition = new Condition();
-
-        
segmentCondition.setConditionType(definitionsService.getConditionType("profilePropertyCondition"));
-        segmentCondition.setParameter("propertyName", "segments");
-        segmentCondition.setParameter("comparisonOperator", "equals");
-        segmentCondition.setParameter("propertyValue", segment.getItemId());
-
-        if(segment.getMetadata().isEnabled()) {
-            List<Profile> previousProfiles = 
persistenceService.query(segmentCondition, null, Profile.class);
-            List<Profile> newProfiles = 
persistenceService.query(segment.getCondition(), null, Profile.class);
-
-            List<Profile> add = new ArrayList<>(newProfiles);
-            add.removeAll(previousProfiles);
-            previousProfiles.removeAll(newProfiles);
-
-            for (Profile profileToAdd : add) {
-                profileToAdd.getSegments().add(segment.getItemId());
-                persistenceService.update(profileToAdd.getItemId(), null, 
Profile.class, "segments", profileToAdd.getSegments());
-            }
-            for (Profile profileToRemove : previousProfiles) {
-                profileToRemove.getSegments().remove(segment.getItemId());
-                persistenceService.update(profileToRemove.getItemId(), null, 
Profile.class, "segments", profileToRemove.getSegments());
-            }
-        } else {
-            List<Profile> previousProfiles = 
persistenceService.query(segmentCondition, null, Profile.class);
-            for (Profile profileToRemove : previousProfiles) {
-                profileToRemove.getSegments().remove(segment.getItemId());
-                persistenceService.update(profileToRemove.getItemId(), null, 
Profile.class, "segments", profileToRemove.getSegments());
-            }
-        }
-        logger.info("Profiles updated in {}", System.currentTimeMillis()-t);
-    }
-
-    private void updateExistingProfilesForScoring(Scoring scoring) {
-        long t = System.currentTimeMillis();
-        Condition scoringCondition = new Condition();
-        
scoringCondition.setConditionType(definitionsService.getConditionType("profilePropertyCondition"));
-        scoringCondition.setParameter("propertyName", "scores." + 
scoring.getItemId());
-        scoringCondition.setParameter("comparisonOperator", "exists");
-        List<Profile> previousProfiles = 
persistenceService.query(scoringCondition, null, Profile.class);
-
-        HashMap<String, Object> scriptParams = new HashMap<>();
-        scriptParams.put("scoringId", scoring.getItemId());
-
-        for (Profile profileToRemove : previousProfiles) {
-            persistenceService.update(profileToRemove.getItemId(), null, 
Profile.class, "ctx._source.scores.remove(scoringId)", scriptParams);
-        }
-        if(scoring.getMetadata().isEnabled()) {
-            String script = "if (ctx._source.scores.containsKey(scoringId)) { 
ctx._source.scores[scoringId] += scoringValue } else { 
ctx._source.scores[scoringId] = scoringValue }";
-            for (ScoringElement element : scoring.getElements()) {
-                scriptParams.put("scoringValue", element.getValue());
-                for (Profile p : 
persistenceService.query(element.getCondition(), null, Profile.class)) {
-                    persistenceService.update(p.getItemId(), null, 
Profile.class, script, scriptParams);
-                }
-            }
-        }
-        logger.info("Profiles updated in {}", System.currentTimeMillis()-t);
-    }
-
-    private void updateExistingProfilesForRemovedScoring(String scoringId) {
-        long t = System.currentTimeMillis();
-        Condition scoringCondition = new Condition();
-        
scoringCondition.setConditionType(definitionsService.getConditionType("profilePropertyCondition"));
-        scoringCondition.setParameter("propertyName", "scores." + scoringId);
-        scoringCondition.setParameter("comparisonOperator", "exists");
-        List<Profile> previousProfiles = 
persistenceService.query(scoringCondition, null, Profile.class);
-
-        HashMap<String, Object> scriptParams = new HashMap<>();
-        scriptParams.put("scoringId", scoringId);
-
-        for (Profile profileToRemove : previousProfiles) {
-            persistenceService.update(profileToRemove.getItemId(), null, 
Profile.class, "ctx._source.scores.remove(scoringId)", scriptParams);
-        }
-        logger.info("Profiles updated in {}", System.currentTimeMillis()-t);
-    }
-
-    private String getMD5(String md5) {
-        try {
-            MessageDigest md = MessageDigest.getInstance("MD5");
-            byte[] array = md.digest(md5.getBytes());
-            StringBuffer sb = new StringBuffer();
-            for (int i = 0; i < array.length; ++i) {
-                sb.append(Integer.toHexString((array[i] & 0xFF) | 
0x100).substring(1, 3));
-            }
-            return sb.toString();
-        } catch (java.security.NoSuchAlgorithmException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public void bundleChanged(BundleEvent event) {
-        switch (event.getType()) {
-            case BundleEvent.STARTED:
-                processBundleStartup(event.getBundle().getBundleContext());
-               break;
-            case BundleEvent.STOPPING:
-                processBundleStop(event.getBundle().getBundleContext());
-                break;
-        }
-    }
-
-    private void initializeTimer() {
-        segmentTimer = new Timer();
-        TimerTask task = new TimerTask() {
-            @Override
-            public void run() {
-                for (Metadata metadata : rulesService.getRuleMetadatas()) {
-                    Rule rule = rulesService.getRule(metadata.getId());
-                    for (Action action : rule.getActions()) {
-                        if 
(action.getActionTypeId().equals("setEventOccurenceCountAction")) {
-                            Condition pastEventCondition = (Condition) 
action.getParameterValues().get("pastEventCondition");
-                            if 
(pastEventCondition.containsParameter("numberOfDays")) {
-                                
updateExistingProfilesForPastEventCondition(rule.getCondition(), 
pastEventCondition);
-                            }
-                        }
-                    }
-                }
-            }
-        };
-        segmentTimer.scheduleAtFixedRate(task, getDay(1).getTime(), 
taskExecutionPeriod);
-
-        task = new TimerTask() {
-            @Override
-            public void run() {
-                allSegments = getAllSegmentDefinitions();
-                allScoring = getAllScoringDefinitions();
-            }
-        };
-        segmentTimer.scheduleAtFixedRate(task, 0, 1000);
-    }
-
-    private GregorianCalendar getDay(int offset) {
-        GregorianCalendar gc = new GregorianCalendar();
-        gc = new GregorianCalendar(gc.get(Calendar.YEAR), 
gc.get(Calendar.MONTH), gc.get(Calendar.DAY_OF_MONTH));
-        gc.add(Calendar.DAY_OF_MONTH, offset);
-        return gc;
-    }
-
-    public void setTaskExecutionPeriod(long taskExecutionPeriod) {
-        this.taskExecutionPeriod = taskExecutionPeriod;
-    }
-
-    private <T extends MetadataItem> PartialList<Metadata> getMetadatas(int 
offset, int size, String sortBy, Class<T> clazz) {
-        PartialList<T> items = persistenceService.getAllItems(clazz, offset, 
size, sortBy);
-        List<Metadata> details = new LinkedList<>();
-        for (T definition : items.getList()) {
-            details.add(definition.getMetadata());
-        }
-        return new PartialList<>(details, items.getOffset(), 
items.getPageSize(), items.getTotalSize());
-    }
-
-    private <T extends MetadataItem> PartialList<Metadata> getMetadatas(Query 
query, Class<T> clazz) {
-        if(query.isForceRefresh()){
-            persistenceService.refresh();
-        }
-        definitionsService.resolveConditionType(query.getCondition());
-        PartialList<T> items = persistenceService.query(query.getCondition(), 
query.getSortby(), clazz, query.getOffset(), query.getLimit());
-        List<Metadata> details = new LinkedList<>();
-        for (T definition : items.getList()) {
-            details.add(definition.getMetadata());
-        }
-        return new PartialList<>(details, items.getOffset(), 
items.getPageSize(), items.getTotalSize());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml 
b/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
index 05d01ff..7d3bc87 100644
--- a/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/services/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -16,8 +16,9 @@
   ~ limitations under the License.
   -->
 
-<blueprint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
+<blueprint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
            
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0";
+           xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0";
            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
            http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 
http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd";>
 
@@ -32,18 +33,18 @@
     </cm:property-placeholder>
 
     <reference id="persistenceService"
-               
interface="org.oasis_open.contextserver.persistence.spi.PersistenceService"/>
+               
interface="org.apache.unomi.persistence.spi.PersistenceService"/>
     <reference id="httpService" interface="org.osgi.service.http.HttpService"/>
 
     <!-- Service definitions -->
 
-    <bean id="definitionsServiceImpl" 
class="org.oasis_open.contextserver.impl.services.DefinitionsServiceImpl"
+    <bean id="definitionsServiceImpl" 
class="org.apache.unomi.services.services.DefinitionsServiceImpl"
           init-method="postConstruct" destroy-method="preDestroy">
         <property name="bundleContext" ref="blueprintBundleContext"/>
     </bean>
     <service id="definitionsService" ref="definitionsServiceImpl" 
auto-export="interfaces"/>
 
-    <bean id="eventServiceImpl" 
class="org.oasis_open.contextserver.impl.services.EventServiceImpl">
+    <bean id="eventServiceImpl" 
class="org.apache.unomi.services.services.EventServiceImpl">
         <property name="persistenceService" ref="persistenceService"/>
         <property name="profileService" ref="profileServiceImpl"/>
         <property name="definitionsService" ref="definitionsServiceImpl"/>
@@ -60,7 +61,7 @@
     </bean>
     <service id="eventService" ref="eventServiceImpl" 
auto-export="interfaces"/>
 
-    <bean id="goalsServiceImpl" 
class="org.oasis_open.contextserver.impl.services.GoalsServiceImpl"
+    <bean id="goalsServiceImpl" 
class="org.apache.unomi.services.services.GoalsServiceImpl"
           init-method="postConstruct" destroy-method="preDestroy">
         <property name="persistenceService" ref="persistenceService"/>
         <property name="definitionsService" ref="definitionsServiceImpl"/>
@@ -70,11 +71,11 @@
     <service id="goalsService" ref="goalsServiceImpl" 
auto-export="interfaces"/>
 
     <bean id="actionExecutorDispatcherImpl"
-          
class="org.oasis_open.contextserver.impl.actions.ActionExecutorDispatcher">
+          class="org.apache.unomi.services.actions.ActionExecutorDispatcher">
         <property name="bundleContext" ref="blueprintBundleContext"/>
     </bean>
 
-    <bean id="rulesServiceImpl" 
class="org.oasis_open.contextserver.impl.services.RulesServiceImpl"
+    <bean id="rulesServiceImpl" 
class="org.apache.unomi.services.services.RulesServiceImpl"
           init-method="postConstruct" destroy-method="preDestroy">
         <property name="persistenceService" ref="persistenceService"/>
         <property name="definitionsService" ref="definitionsServiceImpl"/>
@@ -84,7 +85,7 @@
     </bean>
     <service id="rulesService" ref="rulesServiceImpl" 
auto-export="interfaces"/>
 
-    <bean id="segmentServiceImpl" 
class="org.oasis_open.contextserver.impl.services.SegmentServiceImpl"
+    <bean id="segmentServiceImpl" 
class="org.apache.unomi.services.services.SegmentServiceImpl"
           init-method="postConstruct" destroy-method="preDestroy">
         <property name="persistenceService" ref="persistenceService"/>
         <property name="definitionsService" ref="definitionsServiceImpl"/>
@@ -94,7 +95,7 @@
     </bean>
     <service id="segmentService" ref="segmentServiceImpl" 
auto-export="interfaces"/>
 
-    <bean id="profileServiceImpl" 
class="org.oasis_open.contextserver.impl.services.ProfileServiceImpl"
+    <bean id="profileServiceImpl" 
class="org.apache.unomi.services.services.ProfileServiceImpl"
           init-method="postConstruct" destroy-method="preDestroy">
         <property name="persistenceService" ref="persistenceService"/>
         <property name="definitionsService" ref="definitionsServiceImpl"/>
@@ -107,7 +108,7 @@
     </bean>
     <service id="profileService" ref="profileServiceImpl" 
auto-export="interfaces"/>
 
-    <bean id="queryServiceImpl" 
class="org.oasis_open.contextserver.impl.services.QueryServiceImpl"
+    <bean id="queryServiceImpl" 
class="org.apache.unomi.services.services.QueryServiceImpl"
           init-method="postConstruct" destroy-method="preDestroy">
         <property name="persistenceService" ref="persistenceService"/>
         <property name="definitionsService" ref="definitionsServiceImpl"/>
@@ -121,7 +122,7 @@
         <service-properties>
             <entry key="initializerId" value="comparisonOperator"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.conditions.initializers.ComparisonOperatorChoiceListInitializer">
+        <bean 
class="org.apache.unomi.services.conditions.initializers.ComparisonOperatorChoiceListInitializer">
             <property name="bundleContext" ref="blueprintBundleContext"/>
         </bean>
     </service>
@@ -130,7 +131,7 @@
         <service-properties>
             <entry key="initializerId" value="eventProperty"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.conditions.initializers.EventPropertyChoiceListInitializer">
+        <bean 
class="org.apache.unomi.services.conditions.initializers.EventPropertyChoiceListInitializer">
             <property name="eventService" ref="eventServiceImpl"/>
         </bean>
     </service>
@@ -139,7 +140,7 @@
         <service-properties>
             <entry key="initializerId" value="segments"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.conditions.initializers.SegmentsChoiceListInitializer">
+        <bean 
class="org.apache.unomi.services.conditions.initializers.SegmentsChoiceListInitializer">
             <property name="segmentService" ref="segmentServiceImpl"/>
         </bean>
     </service>
@@ -148,7 +149,7 @@
         <service-properties>
             <entry key="initializerId" value="eventTypeId"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.conditions.initializers.EventTypeIdChoiceListInitializer">
+        <bean 
class="org.apache.unomi.services.conditions.initializers.EventTypeIdChoiceListInitializer">
             <property name="eventService" ref="eventServiceImpl"/>
         </bean>
     </service>
@@ -157,14 +158,14 @@
         <service-properties>
             <entry key="initializerId" value="country"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.conditions.initializers.CountryChoiceListInitializer"/>
+        <bean 
class="org.apache.unomi.services.conditions.initializers.CountryChoiceListInitializer"/>
     </service>
 
     <service auto-export="interfaces">
         <service-properties>
             <entry key="initializerId" value="goals"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.conditions.initializers.GoalsChoiceListInitializer">
+        <bean 
class="org.apache.unomi.services.conditions.initializers.GoalsChoiceListInitializer">
             <property name="goalsService" ref="goalsServiceImpl"/>
         </bean>
     </service>
@@ -172,7 +173,7 @@
 
     <!-- We use a listener here because using the list directly for listening 
to proxies coming from the same bundle didn't seem to work -->
     <reference-list id="eventListenerServices"
-                    
interface="org.oasis_open.contextserver.api.services.EventListenerService"
+                    
interface="org.apache.unomi.api.services.EventListenerService"
                     availability="optional">
         <reference-listener
                 bind-method="bind" unbind-method="unbind" 
ref="eventServiceImpl"/>
@@ -184,7 +185,7 @@
         <service-properties>
             <entry key="propertyMergeStrategyExecutorId" 
value="defaultPropertyMergeStrategyExecutor"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.mergers.DefaultPropertyMergeStrategyExecutor">
+        <bean 
class="org.apache.unomi.services.mergers.DefaultPropertyMergeStrategyExecutor">
         </bean>
     </service>
 
@@ -192,7 +193,7 @@
         <service-properties>
             <entry key="propertyMergeStrategyExecutorId" 
value="addPropertyMergeStrategyExecutor"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.mergers.AddPropertyMergeStrategyExecutor">
+        <bean 
class="org.apache.unomi.services.mergers.AddPropertyMergeStrategyExecutor">
         </bean>
     </service>
 
@@ -200,7 +201,7 @@
         <service-properties>
             <entry key="propertyMergeStrategyExecutorId" 
value="mostRecentPropertyMergeStrategyExecutor"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.mergers.MostRecentPropertyMergeStrategyExecutor">
+        <bean 
class="org.apache.unomi.services.mergers.MostRecentPropertyMergeStrategyExecutor">
         </bean>
     </service>
 
@@ -208,7 +209,7 @@
         <service-properties>
             <entry key="propertyMergeStrategyExecutorId" 
value="oldestPropertyMergeStrategyExecutor"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.mergers.OldestPropertyMergeStrategyExecutor">
+        <bean 
class="org.apache.unomi.services.mergers.OldestPropertyMergeStrategyExecutor">
         </bean>
     </service>
 
@@ -216,7 +217,7 @@
         <service-properties>
             <entry key="propertyMergeStrategyExecutorId" 
value="nonEmptyPropertyMergeStrategyExecutor"/>
         </service-properties>
-        <bean 
class="org.oasis_open.contextserver.impl.mergers.NonEmptyPropertyMergeStrategyExecutor">
+        <bean 
class="org.apache.unomi.services.mergers.NonEmptyPropertyMergeStrategyExecutor">
         </bean>
     </service>
 

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/src/site/markdown/clustering.md
----------------------------------------------------------------------
diff --git a/src/site/markdown/clustering.md b/src/site/markdown/clustering.md
index 5917cb5..7c51889 100644
--- a/src/site/markdown/clustering.md
+++ b/src/site/markdown/clustering.md
@@ -19,7 +19,7 @@ Cluster setup
 =============
 
 Context server relies on Elasticsearch to discover and configure its cluster. 
You just need to install multiple context
-servers on the same network, and enable the discovery protocol in 
$MY_KARAF_HOME/etc/org.oasis_open.contextserver.persistence.elasticsearch.cfg 
file :
+servers on the same network, and enable the discovery protocol in 
$MY_KARAF_HOME/etc/org.apache.unomi.persistence.elasticsearch.cfg file :
 
     discovery.zen.ping.multicast.enabled=true
 
@@ -68,7 +68,7 @@ Node C :
 
 ### Specific configuration
 If multicast is not allowed on your network, you'll need to switch to unicast 
protocol and manually configure the server IPs. This can be
-done by disabling the elasticsearch automatic discovery in 
$MY_KARAF_HOME/etc/org.oasis_open.contextserver.persistence.elasticsearch.cfg :
+done by disabling the elasticsearch automatic discovery in 
$MY_KARAF_HOME/etc/org.apache.unomi.persistence.elasticsearch.cfg :
 
     discovery.zen.ping.multicast.enabled=false
 

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/src/site/markdown/configuration.md
----------------------------------------------------------------------
diff --git a/src/site/markdown/configuration.md 
b/src/site/markdown/configuration.md
index 5059e75..5340d30 100644
--- a/src/site/markdown/configuration.md
+++ b/src/site/markdown/configuration.md
@@ -23,20 +23,21 @@ Changing the default configuration
 
 If you want to change the default configuration, you can perform any 
modification you want in the $MY_KARAF_HOME/etc directory.
 
-The context server configuration is kept in the 
$MY_KARAF_HOME/etc/org.oasis_open.contextserver.web.cfg . It defines the
+The context server configuration is kept in the 
$MY_KARAF_HOME/etc/org.apache.unomi.web.cfg . It defines the
 addresses and port where it can be found :
 
     contextserver.address=localhost
     contextserver.port=8181
     contextserver.secureAddress=localhost
     contextserver.securePort=9443
+    contextserver.domain=apache.org
 
 If you need to specify an Elasticsearch cluster name that is different than 
the default, it is recommended to do this
 BEFORE you start the server for the first time, or you will loose all the data 
you have stored previously.
 
 To change the cluster name, first create a file called 
 
-    
$MY_KARAF_HOME/etc/org.oasis_open.contextserver.persistence.elasticsearch.cfg
+    $MY_KARAF_HOME/etc/org.apache.unomi.persistence.elasticsearch.cfg
 
 with the following contents:
 
@@ -71,7 +72,7 @@ In order to use it, you need to install the Geonames database 
into . Get the "al
 http://download.geonames.org/export/dump/
 
 Download it and put it in the "etc" directory, without unzipping it.
-Edit $MY_KARAF_HOME/etc/org.oasis_open.contextserver.geonames.cfg and set 
request.geonamesDatabase.forceImport to true, import should start right away.
+Edit $MY_KARAF_HOME/etc/org.apache.unomi.geonames.cfg and set 
request.geonamesDatabase.forceImport to true, import should start right away.
 Otherwise, import should start at the next startup. Import runs in background, 
but can take about 15 minutes.
 At the end, you should have about 4 million entries in the geonames index.
  
@@ -186,3 +187,87 @@ Step 4 : Setup a proxy in front of the context server
 
 As an alternative to an application-level firewall, you could also route all 
traffic to the context server through
 a proxy, and use it to filter any communication.
+
+Integrating with an Apache HTTP web server
+------------------------------------------
+
+If you want to setup an Apache HTTP web server in from of Apache Unomi, here 
is an example configuration using 
+mod_proxy.
+
+In your Unomi package directory, in /etc/org.apache.unomi.web.cfg for 
unomi.apache.org
+   
+   contextserver.address=unomi.apache.org
+   contextserver.port=80
+   contextserver.secureAddress=unomi.apache.org
+   contextserver.securePort=443
+   contextserver.domain=apache.org
+
+Main virtual host config:
+
+    <VirtualHost *:80>
+            Include /var/www/vhosts/unomi.apache.org/conf/common.conf
+    </VirtualHost>
+    
+    <IfModule mod_ssl.c>
+        <VirtualHost *:443>
+            Include /var/www/vhosts/unomi.apache.org/conf/common.conf
+    
+            SSLEngine on
+    
+            SSLCertificateFile    
/var/www/vhosts/unomi.apache.org/conf/ssl/24d5b9691e96eafa.crt
+            SSLCertificateKeyFile 
/var/www/vhosts/unomi.apache.org/conf/ssl/apache.org.key
+            SSLCertificateChainFile 
/var/www/vhosts/unomi.apache.org/conf/ssl/gd_bundle-g2-g1.crt
+    
+    
+            <FilesMatch "\.(cgi|shtml|phtml|php)$">
+                    SSLOptions +StdEnvVars
+            </FilesMatch>
+            <Directory /usr/lib/cgi-bin>
+                    SSLOptions +StdEnvVars
+            </Directory>
+            BrowserMatch "MSIE [2-6]" \
+                    nokeepalive ssl-unclean-shutdown \
+                    downgrade-1.0 force-response-1.0
+            BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
+    
+        </VirtualHost>
+    </IfModule>
+    
+common.conf:
+
+    ServerName unomi.apache.org
+    ServerAdmin [email protected]
+    
+    DocumentRoot /var/www/vhosts/unomi.apache.org/html
+    CustomLog /var/log/apache2/access-unomi.apache.org.log combined
+    <Directory />
+            Options FollowSymLinks
+            AllowOverride None
+    </Directory>
+    <Directory /var/www/vhosts/unomi.apache.org/html>
+            Options FollowSymLinks MultiViews
+            AllowOverride None
+            Order allow,deny
+            allow from all
+    </Directory>
+    <Location /cxs>
+        Order deny,allow
+        deny from all
+        allow from 88.198.26.2
+        allow from www.apache.org
+    </Location>
+    
+    RewriteEngine On
+    RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
+    RewriteRule .* - [F]
+    ProxyPreserveHost On
+    ProxyPass /server-status !
+    ProxyPass /robots.txt !
+    
+    RewriteCond %{HTTP_USER_AGENT} Googlebot [OR]
+    RewriteCond %{HTTP_USER_AGENT} msnbot [OR]
+    RewriteCond %{HTTP_USER_AGENT} Slurp
+    RewriteRule ^.* - [F,L]
+    
+    ProxyPass / http://localhost:8181/ connectiontimeout=20 timeout=300 ttl=120
+    ProxyPassReverse / http://localhost:8181/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/wab/pom.xml
----------------------------------------------------------------------
diff --git a/wab/pom.xml b/wab/pom.xml
index dabfb0f..d054b78 100644
--- a/wab/pom.xml
+++ b/wab/pom.xml
@@ -15,7 +15,8 @@
   ~ limitations under the License.
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://maven.apache.org/POM/4.0.0";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
@@ -121,11 +122,11 @@
                         
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
                         <Embed-Directory>WEB-INF/lib</Embed-Directory>
                         <Import-Package>
-                            org.oasis_open.contextserver.api,
-                            org.oasis_open.contextserver.api.conditions,
-                            org.oasis_open.contextserver.api.segments,
-                            org.oasis_open.contextserver.api.rules,
-                            org.oasis_open.contextserver.api.query,
+                            org.apache.unomi.api,
+                            org.apache.unomi.api.conditions,
+                            org.apache.unomi.api.segments,
+                            org.apache.unomi.api.rules,
+                            org.apache.unomi.api.query,
                             *
                         </Import-Package>
                         <Web-ContextPath>/</Web-ContextPath>

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
----------------------------------------------------------------------
diff --git a/wab/src/main/java/org/apache/unomi/web/ContextServlet.java 
b/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
new file mode 100644
index 0000000..2e43302
--- /dev/null
+++ b/wab/src/main/java/org/apache/unomi/web/ContextServlet.java
@@ -0,0 +1,368 @@
+/*
+ * 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.web;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.io.IOUtils;
+import org.apache.unomi.api.*;
+import org.apache.unomi.api.conditions.Condition;
+import org.apache.unomi.api.services.EventService;
+import org.apache.unomi.api.services.ProfileService;
+import org.apache.unomi.api.services.RulesService;
+import org.apache.unomi.persistence.spi.CustomObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.*;
+
+/**
+ * A servlet filter to serve a context-specific Javascript containing the 
current request context object.
+ */
+public class ContextServlet extends HttpServlet {
+    public static final String BASE_SCRIPT_LOCATION = "/javascript/base.js";
+    public static final String IMPERSONATE_BASE_SCRIPT_LOCATION = 
"/javascript/impersonateBase.js";
+    public static final String PROFILE_OVERRIDE_MARKER = "---IGNORE---";
+    private static final Logger logger = 
LoggerFactory.getLogger(ContextServlet.class.getName());
+    private static final long serialVersionUID = 2928875830103325238L;
+    private ProfileService profileService;
+    private EventService eventService;
+    private RulesService rulesService;
+
+    private String profileIdCookieName = "context-profile-id";
+    private String profileIdCookieDomain;
+//    private String personaIdCookieName = "context-persona-id";
+
+
+    @Override
+    public void service(ServletRequest request, ServletResponse response) 
throws ServletException, IOException {
+        final Date timestamp = new Date();
+        if (request.getParameter("timestamp") != null) {
+            
timestamp.setTime(Long.parseLong(request.getParameter("timestamp")));
+        }
+        // first we must retrieve the context for the current visitor, and 
build a Javascript object to attach to the
+        // script output.
+        String profileId;
+
+        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+        String httpMethod = httpServletRequest.getMethod();
+//        logger.debug(HttpUtils.dumpRequestInfo(httpServletRequest));
+
+        // set up CORS headers as soon as possible so that errors are not 
misconstrued on the client for CORS errors
+        HttpUtils.setupCORSHeaders(httpServletRequest, response);
+
+        if ("options".equals(httpMethod.toLowerCase())) {
+            response.flushBuffer();
+            return;
+        }
+
+        Profile profile = null;
+
+        String cookieProfileId = null;
+        String cookiePersonaId = null;
+        Cookie[] cookies = httpServletRequest.getCookies();
+        for (Cookie cookie : cookies) {
+            if (profileIdCookieName.equals(cookie.getName())) {
+                cookieProfileId = cookie.getValue();
+            }
+        }
+
+        Session session = null;
+
+        String personaId = request.getParameter("personaId");
+        if (personaId != null) {
+            PersonaWithSessions personaWithSessions = 
profileService.loadPersonaWithSessions(personaId);
+            if (personaWithSessions == null) {
+                logger.error("Couldn't find persona with id=" + personaId);
+                profile = null;
+            } else {
+                profile = personaWithSessions.getPersona();
+                session = personaWithSessions.getLastSession();
+            }
+        }
+
+        String sessionId = request.getParameter("sessionId");
+
+        if (cookieProfileId == null && sessionId == null && personaId == null) 
{
+            
((HttpServletResponse)response).sendError(HttpServletResponse.SC_BAD_REQUEST);
+            return;
+        }
+
+        boolean profileCreated = false;
+
+        ContextRequest contextRequest = null;
+        String scope = null;
+        String stringPayload = HttpUtils.getPayload(httpServletRequest);
+        if (stringPayload != null) {
+            ObjectMapper mapper = CustomObjectMapper.getObjectMapper();
+            JsonFactory factory = mapper.getFactory();
+            try {
+                contextRequest = 
mapper.readValue(factory.createParser(stringPayload), ContextRequest.class);
+            } catch (Exception e) {
+                logger.error("Cannot read payload " + stringPayload, e);
+                return;
+            }
+            scope = contextRequest.getSource().getScope();
+        }
+
+        int changes = EventService.NO_CHANGE;
+
+        if (profile == null) {
+            if (sessionId != null) {
+                session = profileService.loadSession(sessionId, timestamp);
+                if (session != null) {
+                    profileId = session.getProfileId();
+                    profile = profileService.load(profileId);
+                    profile = checkMergedProfile(response, profile, session);
+                }
+            }
+            if (profile == null) {
+                // profile not stored in session
+                if (cookieProfileId == null) {
+                    // no profileId cookie was found, we generate a new one 
and create the profile in the profile service
+                    profile = createNewProfile(null, response, timestamp);
+                    profileCreated = true;
+                } else {
+                    profile = profileService.load(cookieProfileId);
+                    if (profile == null) {
+                        // this can happen if we have an old cookie but have 
reset the server,
+                        // or if we merged the profiles and somehow this 
cookie didn't get updated.
+                        profile = createNewProfile(null, response, timestamp);
+                        profileCreated = true;
+                        HttpUtils.sendProfileCookie(profile, response, 
profileIdCookieName, profileIdCookieDomain);
+                    } else {
+                        profile = checkMergedProfile(response, profile, 
session);
+                    }
+                }
+
+            } else if (cookieProfileId == null || 
!cookieProfileId.equals(profile.getItemId())) {
+                // profile if stored in session but not in cookie
+                HttpUtils.sendProfileCookie(profile, response, 
profileIdCookieName, profileIdCookieDomain);
+            }
+            // associate profile with session
+            if (sessionId != null && session == null) {
+                session = new Session(sessionId, profile, timestamp, scope);
+                changes |= EventService.SESSION_UPDATED;
+                Event event = new Event("sessionCreated", session, profile, 
scope, null, session, timestamp);
+
+                event.getAttributes().put(Event.HTTP_REQUEST_ATTRIBUTE, 
request);
+                event.getAttributes().put(Event.HTTP_RESPONSE_ATTRIBUTE, 
response);
+                logger.debug("Received event " + event.getEventType() + " for 
profile=" + profile.getItemId() + " session=" + session.getItemId() + " 
target=" + event.getTarget() + " timestamp=" + timestamp);
+                changes |= eventService.send(event);
+            }
+        }
+
+        if (profileCreated) {
+            changes |= EventService.PROFILE_UPDATED;
+
+            Event profileUpdated = new Event("profileUpdated", session, 
profile, scope, null, profile, timestamp);
+            profileUpdated.setPersistent(false);
+            profileUpdated.getAttributes().put(Event.HTTP_REQUEST_ATTRIBUTE, 
request);
+            profileUpdated.getAttributes().put(Event.HTTP_RESPONSE_ATTRIBUTE, 
response);
+
+            logger.debug("Received event {} for profile={} {} target={} 
timestamp={}", profileUpdated.getEventType(), profile.getItemId(),
+                    session != null ? " session=" + session.getItemId() : "", 
profileUpdated.getTarget(), timestamp);
+            changes |= eventService.send(profileUpdated);
+        }
+
+        ContextResponse data = new ContextResponse();
+
+        if(contextRequest != null){
+            changes |= handleRequest(contextRequest, profile, session, data, 
request, response, timestamp);
+        }
+
+        if ((changes & EventService.PROFILE_UPDATED) == 
EventService.PROFILE_UPDATED && profile != null) {
+            profileService.save(profile);
+        }
+        if ((changes & EventService.SESSION_UPDATED) == 
EventService.SESSION_UPDATED && session != null) {
+            profileService.saveSession(session);
+        }
+
+
+        String extension = 
httpServletRequest.getRequestURI().substring(httpServletRequest.getRequestURI().lastIndexOf(".")
 + 1);
+        boolean noScript = "json".equals(extension);
+        String contextAsJSONString = 
CustomObjectMapper.getObjectMapper().writeValueAsString(data);
+        Writer responseWriter;
+        if(noScript){
+            response.setCharacterEncoding("UTF-8");
+            responseWriter = response.getWriter();
+            response.setContentType("application/json");
+            IOUtils.write(contextAsJSONString, responseWriter);
+        }else {
+            responseWriter = response.getWriter();
+            responseWriter.append("window.digitalData = window.digitalData || 
{};\n")
+                    .append("var cxs = ")
+                    .append(contextAsJSONString)
+                    .append(";\n");
+
+            // now we copy the base script source code
+            InputStream baseScriptStream = 
getServletContext().getResourceAsStream(profile instanceof Persona ? 
IMPERSONATE_BASE_SCRIPT_LOCATION : BASE_SCRIPT_LOCATION);
+            IOUtils.copy(baseScriptStream, responseWriter);
+        }
+
+        responseWriter.flush();
+    }
+
+    private Profile checkMergedProfile(ServletResponse response, Profile 
profile, Session session) {
+        String profileId;
+        if (profile != null && profile.getMergedWith() != null) {
+            profileId = profile.getMergedWith();
+            Profile profileToDelete = profile;
+            profile = profileService.load(profileId);
+            if (profile != null) {
+                logger.debug("Session profile was merged with profile " + 
profileId + ", replacing profile in session");
+                if (session != null) {
+                    session.setProfile(profile);
+                    profileService.saveSession(session);
+                }
+                HttpUtils.sendProfileCookie(profile, response, 
profileIdCookieName, profileIdCookieDomain);
+            } else {
+                logger.warn("Couldn't find merged profile" + profileId + ", 
falling back to profile " + profileToDelete.getItemId());
+                profile = profileToDelete;
+                profile.setMergedWith(null);
+                profileService.save(profile);
+            }
+        }
+        return profile;
+    }
+
+    private int handleRequest(ContextRequest contextRequest, Profile profile, 
Session session, ContextResponse data, ServletRequest request, ServletResponse 
response, Date timestamp)
+            throws IOException {
+        int changes = EventService.NO_CHANGE;
+        // execute provided events if any
+        if(contextRequest.getEvents() != null && !(profile instanceof 
Persona)) {
+            for (Event event : contextRequest.getEvents()){
+                if(event.getEventType() != null) {
+                    Event eventToSend;
+                    if(event.getProperties() != null){
+                        eventToSend = new Event(event.getEventType(), session, 
profile, contextRequest.getSource().getScope(), event.getSource(), 
event.getTarget(), event.getProperties(), timestamp);
+                    } else {
+                        eventToSend = new Event(event.getEventType(), session, 
profile, contextRequest.getSource().getScope(), event.getSource(), 
event.getTarget(), timestamp);
+                    }
+                    event.getAttributes().put(Event.HTTP_REQUEST_ATTRIBUTE, 
request);
+                    event.getAttributes().put(Event.HTTP_RESPONSE_ATTRIBUTE, 
response);
+                    logger.debug("Received event " + event.getEventType() + " 
for profile=" + profile.getItemId() + " session=" + session.getItemId() + " 
target=" + event.getTarget() + " timestamp=" + timestamp);
+                    changes |= eventService.send(eventToSend);
+                }
+            }
+        }
+
+        data.setProfileId(profile.getItemId());
+
+        if (contextRequest.isRequireSegments()) {
+            data.setProfileSegments(profile.getSegments());
+        }
+
+        if (contextRequest.getRequiredProfileProperties() != null) {
+            Map<String, Object> profileProperties = new HashMap<String, 
Object>(profile.getProperties());
+            if (!contextRequest.getRequiredProfileProperties().contains("*")) {
+                
profileProperties.keySet().retainAll(contextRequest.getRequiredProfileProperties());
+            }
+            data.setProfileProperties(profileProperties);
+        }
+        if (session != null) {
+            data.setSessionId(session.getItemId());
+            if (contextRequest.getRequiredSessionProperties() != null) {
+                Map<String, Object> sessionProperties = new HashMap<String, 
Object>(session.getProperties());
+                if 
(!contextRequest.getRequiredSessionProperties().contains("*")) {
+                    
sessionProperties.keySet().retainAll(contextRequest.getRequiredSessionProperties());
+                }
+                data.setSessionProperties(sessionProperties);
+            }
+        }
+
+        processOverrides(contextRequest, profile, session);
+
+        List<ContextRequest.FilteredContent> filterNodes = 
contextRequest.getFilters();
+        if (filterNodes != null) {
+            data.setFilteringResults(new HashMap<String, Boolean>());
+            for (ContextRequest.FilteredContent filteredContent : filterNodes) 
{
+                boolean result = true;
+                for (ContextRequest.Filter filter : 
filteredContent.getFilters()) {
+                    Condition condition = filter.getCondition();
+                    result &= profileService.matchCondition(condition, 
profile, session);
+                }
+                data.getFilteringResults().put(filteredContent.getFilterid(), 
result);
+            }
+        }
+
+        if(!(profile instanceof Persona)) {
+            
data.setTrackedConditions(rulesService.getTrackedConditions(contextRequest.getSource()));
+        } else {
+            data.setTrackedConditions(Collections.<Condition>emptySet());
+        }
+
+        return changes;
+    }
+
+    private void processOverrides(ContextRequest contextRequest, Profile 
profile, Session session) {
+        if (contextRequest.getSegmentOverrides() != null) {
+            profile.setSegments(contextRequest.getSegmentOverrides());
+        }
+
+        if (contextRequest.getProfilePropertiesOverrides() != null) {
+            
profile.setProperties(contextRequest.getProfilePropertiesOverrides());
+        }
+
+        if (contextRequest.getSessionPropertiesOverrides() != null) {
+            
session.setProperties(contextRequest.getSessionPropertiesOverrides()); // we do 
this just in case a cache is behind this
+        }
+    }
+
+    private Profile createNewProfile(String existingProfileId, ServletResponse 
response, Date timestamp) {
+        Profile profile;
+        String profileId = existingProfileId;
+        if (profileId == null) {
+            profileId = UUID.randomUUID().toString();
+        }
+        profile = new Profile(profileId);
+        profile.setProperty("firstVisit", timestamp);
+        HttpUtils.sendProfileCookie(profile, response, profileIdCookieName, 
profileIdCookieDomain);
+        return profile;
+    }
+
+
+    public void destroy() {
+    }
+
+    public void setProfileService(ProfileService profileService) {
+        this.profileService = profileService;
+    }
+
+    public void setEventService(EventService eventService) {
+        this.eventService = eventService;
+    }
+
+    public void setRulesService(RulesService rulesService) {
+        this.rulesService = rulesService;
+    }
+
+    public void setProfileIdCookieDomain(String profileIdCookieDomain) {
+        this.profileIdCookieDomain = profileIdCookieDomain;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/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
new file mode 100644
index 0000000..c34ead2
--- /dev/null
+++ b/wab/src/main/java/org/apache/unomi/web/EventsCollectorServlet.java
@@ -0,0 +1,185 @@
+/*
+ * 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.web;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.unomi.api.*;
+import org.apache.unomi.api.services.EventService;
+import org.apache.unomi.api.services.PrivacyService;
+import org.apache.unomi.api.services.ProfileService;
+import org.apache.unomi.persistence.spi.CustomObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.List;
+
+public class EventsCollectorServlet extends HttpServlet {
+    private static final Logger logger = 
LoggerFactory.getLogger(EventsCollectorServlet.class.getName());
+
+    private static final long serialVersionUID = 2008054804885122957L;
+
+    private EventService eventService;
+    private ProfileService profileService;
+    private PrivacyService privacyService;
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
+
+        doEvent(req, resp);
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
+
+        doEvent(req, resp);
+    }
+
+    @Override
+    protected void doOptions(HttpServletRequest request, HttpServletResponse 
response) throws ServletException, IOException {
+//        logger.debug(HttpUtils.dumpRequestInfo(request));
+        HttpUtils.setupCORSHeaders(request, response);
+        response.flushBuffer();
+    }
+
+    private void doEvent(HttpServletRequest request, HttpServletResponse 
response) throws IOException {
+        Date timestamp = new Date();
+        if (request.getParameter("timestamp") != null) {
+            
timestamp.setTime(Long.parseLong(request.getParameter("timestamp")));
+        }
+
+//        logger.debug(HttpUtils.dumpRequestInfo(request));
+
+        HttpUtils.setupCORSHeaders(request, response);
+
+        Profile profile = null;
+
+        String sessionId = request.getParameter("sessionId");
+        if (sessionId == null) {
+            return;
+        }
+
+        Session session = profileService.loadSession(sessionId, timestamp);
+        if (session == null) {
+            return;
+        }
+
+        String profileId = session.getProfileId();
+        if (profileId == null) {
+            return;
+        }
+
+        profile = profileService.load(profileId);
+        if (profile == null || profile instanceof Persona) {
+            return;
+        }
+
+        String payload = HttpUtils.getPayload(request);
+        if(payload == null){
+            return;
+        }
+
+        Profile realProfile = profile;
+        Boolean profileIsAnonymous = 
privacyService.isAnonymous(profile.getItemId());
+        if (profileIsAnonymous != null && profileIsAnonymous.booleanValue()) {
+            // we are surfing anonymously, we must use the global anonymous 
profile if it exists, or create it if
+            // it doesn't.
+            Profile anonymousProfile = 
profileService.load(PrivacyService.GLOBAL_ANONYMOUS_PROFILE_ID);
+            if (anonymousProfile == null) {
+                anonymousProfile = new 
Profile(PrivacyService.GLOBAL_ANONYMOUS_PROFILE_ID);
+                profileService.save(profile);
+            }
+            realProfile = profile;
+            profile = anonymousProfile;
+        }
+
+        List<String> filteredEventTypes = 
privacyService.getFilteredEventTypes(profile.getItemId());
+
+        ObjectMapper mapper = CustomObjectMapper.getObjectMapper();
+        JsonFactory factory = mapper.getFactory();
+        EventsCollectorRequest events = null;
+        try {
+            events = mapper.readValue(factory.createParser(payload), 
EventsCollectorRequest.class);
+        } catch (Exception e) {
+            logger.error("Cannot read payload " + payload,e);
+            return;
+        }
+        if (events == null || events.getEvents() == null) {
+            return;
+        }
+
+        int changes = 0;
+        for (Event event : events.getEvents()){
+            if(event.getEventType() != null){
+                Event eventToSend;
+                if(event.getProperties() != null){
+                    eventToSend = new Event(event.getEventType(), session, 
profile, event.getScope(), event.getSource(), event.getTarget(), 
event.getProperties(), timestamp);
+                } else {
+                    eventToSend = new Event(event.getEventType(), session, 
profile, event.getScope(), event.getSource(), event.getTarget(), timestamp);
+                }
+
+                if (filteredEventTypes != null && 
filteredEventTypes.contains(event.getEventType())) {
+                    logger.debug("Profile is filtering event type {}", 
event.getEventType());
+                    continue;
+                }
+
+                eventToSend.getAttributes().put(Event.HTTP_REQUEST_ATTRIBUTE, 
request);
+                eventToSend.getAttributes().put(Event.HTTP_RESPONSE_ATTRIBUTE, 
response);
+                logger.debug("Received event " + event.getEventType() + " for 
profile=" + profile.getItemId() + " session=" + session.getItemId() + " 
target=" + event.getTarget() + " timestamp=" + timestamp);
+                int eventChanged = eventService.send(eventToSend);
+                //if the event execution changes the profile
+                if ((eventChanged & EventService.PROFILE_UPDATED) == 
EventService.PROFILE_UPDATED) {
+                    profile = eventToSend.getProfile();
+                    session.setProfile(profile);
+                }
+                changes |= eventChanged;
+            }
+        }
+
+        if ((changes & EventService.PROFILE_UPDATED) == 
EventService.PROFILE_UPDATED) {
+            profileService.save(profile);
+        }
+        if ((changes & EventService.SESSION_UPDATED) == 
EventService.SESSION_UPDATED) {
+            profileService.saveSession(session);
+        }
+
+
+        PrintWriter responseWriter = response.getWriter();
+        responseWriter.append("{\"updated\":" + changes + "}");
+        responseWriter.flush();
+    }
+
+    public void setEventService(EventService eventService) {
+        this.eventService = eventService;
+    }
+
+    public void setProfileService(ProfileService profileService) {
+        this.profileService = profileService;
+    }
+
+    public void setPrivacyService(PrivacyService privacyService) {
+        this.privacyService = privacyService;
+    }
+}

Reply via email to