http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/services/src/main/java/org/oasis_open/contextserver/impl/services/ProfileServiceImpl.java ---------------------------------------------------------------------- diff --git a/services/src/main/java/org/oasis_open/contextserver/impl/services/ProfileServiceImpl.java b/services/src/main/java/org/oasis_open/contextserver/impl/services/ProfileServiceImpl.java deleted file mode 100644 index 556fe0e..0000000 --- a/services/src/main/java/org/oasis_open/contextserver/impl/services/ProfileServiceImpl.java +++ /dev/null @@ -1,704 +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 org.apache.commons.lang3.StringUtils; -import org.oasis_open.contextserver.api.*; -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.services.DefinitionsService; -import org.oasis_open.contextserver.api.services.ProfileService; -import org.oasis_open.contextserver.api.services.QueryService; -import org.oasis_open.contextserver.impl.actions.ActionExecutorDispatcher; -import org.oasis_open.contextserver.persistence.spi.CustomObjectMapper; -import org.oasis_open.contextserver.persistence.spi.PersistenceService; -import org.oasis_open.contextserver.persistence.spi.PropertyHelper; -import org.osgi.framework.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URL; -import java.util.*; - -public class ProfileServiceImpl implements ProfileService, SynchronousBundleListener { - - private static final Logger logger = LoggerFactory.getLogger(ProfileServiceImpl.class.getName()); - - private BundleContext bundleContext; - - private PersistenceService persistenceService; - - private DefinitionsService definitionsService; - - private QueryService queryService; - - private ActionExecutorDispatcher actionExecutorDispatcher; - - private Condition purgeProfileQuery; - private Integer purgeProfileExistTime = 0; - private Integer purgeProfileInactiveTime = 0; - private Integer purgeSessionsAndEventsTime = 0; - private Integer purgeProfileInterval = 0; - - private Timer allPropertyTypesTimer; - - private Timer purgeProfileTimer; - - private List<PropertyType> allPropertyTypes; - - public ProfileServiceImpl() { - logger.info("Initializing profile service..."); - } - - 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 postConstruct() { - logger.debug("postConstruct {" + bundleContext.getBundle() + "}"); - - processBundleStartup(bundleContext); - for (Bundle bundle : bundleContext.getBundles()) { - if (bundle.getBundleContext() != null) { - processBundleStartup(bundle.getBundleContext()); - } - } - bundleContext.addBundleListener(this); - initializePurge(); - schedulePropertyTypeLoad(); - } - - public void preDestroy() { - bundleContext.removeBundleListener(this); - cancelPurge(); - cancelPropertyTypeLoad(); - } - - private void processBundleStartup(BundleContext bundleContext) { - if (bundleContext == null) { - return; - } - loadPredefinedPersonas(bundleContext); - loadPredefinedPropertyTypes(bundleContext); - } - - private void processBundleStop(BundleContext bundleContext) { - } - - public void setQueryService(QueryService queryService) { - this.queryService = queryService; - } - - public void setPurgeProfileExistTime(Integer purgeProfileExistTime) { - this.purgeProfileExistTime = purgeProfileExistTime; - } - - public void setPurgeProfileInactiveTime(Integer purgeProfileInactiveTime) { - this.purgeProfileInactiveTime = purgeProfileInactiveTime; - } - - public void setPurgeSessionsAndEventsTime(Integer purgeSessionsAndEventsTime) { - this.purgeSessionsAndEventsTime = purgeSessionsAndEventsTime; - } - - public void setPurgeProfileInterval(Integer purgeProfileInterval) { - this.purgeProfileInterval = purgeProfileInterval; - } - - private void schedulePropertyTypeLoad() { - allPropertyTypesTimer = new Timer(); - TimerTask task = new TimerTask() { - @Override - public void run() { - try { - allPropertyTypes = persistenceService.getAllItems(PropertyType.class); - } catch (Exception e) { - logger.error(e.getMessage(), e); - } - } - }; - allPropertyTypesTimer.scheduleAtFixedRate(task, 0, 5000); - logger.info("Scheduled task for property type loading each 5s"); - } - - private void cancelPropertyTypeLoad() { - if (allPropertyTypesTimer != null) { - allPropertyTypesTimer.cancel(); - logger.info("Cancelled task for property type loading"); - } - } - - private void initializePurge() { - logger.info("Profile purge: Initializing"); - - if (purgeProfileInactiveTime > 0 || purgeProfileExistTime > 0 || purgeSessionsAndEventsTime > 0) { - if (purgeProfileInactiveTime > 0) { - logger.info("Profile purge: Profile with no visits since {} days, will be purged", purgeProfileInactiveTime); - } - if (purgeProfileExistTime > 0) { - logger.info("Profile purge: Profile created since {} days, will be purged", purgeProfileExistTime); - } - - purgeProfileTimer = new Timer(); - TimerTask task = new TimerTask() { - @Override - public void run() { - long t = System.currentTimeMillis(); - logger.debug("Profile purge: Purge triggered"); - - if (purgeProfileQuery == null) { - ConditionType profilePropertyConditionType = definitionsService.getConditionType("profilePropertyCondition"); - ConditionType booleanCondition = definitionsService.getConditionType("booleanCondition"); - if (profilePropertyConditionType == null || booleanCondition == null) { - // definition service not yet fully instantiate - return; - } - - purgeProfileQuery = new Condition(booleanCondition); - purgeProfileQuery.setParameter("operator", "or"); - List<Condition> subConditions = new ArrayList<>(); - - if (purgeProfileInactiveTime > 0) { - Condition inactiveTimeCondition = new Condition(profilePropertyConditionType); - inactiveTimeCondition.setParameter("propertyName", "lastVisit"); - inactiveTimeCondition.setParameter("comparisonOperator", "lessThanOrEqualTo"); - inactiveTimeCondition.setParameter("propertyValueDateExpr", "now-" + purgeProfileInactiveTime + "d"); - subConditions.add(inactiveTimeCondition); - } - - if (purgeProfileExistTime > 0) { - Condition existTimeCondition = new Condition(profilePropertyConditionType); - existTimeCondition.setParameter("propertyName", "firstVisit"); - existTimeCondition.setParameter("comparisonOperator", "lessThanOrEqualTo"); - existTimeCondition.setParameter("propertyValueDateExpr", "now-" + purgeProfileExistTime + "d"); - subConditions.add(existTimeCondition); - } - - purgeProfileQuery.setParameter("subConditions", subConditions); - } - - persistenceService.removeByQuery(purgeProfileQuery, Profile.class); - - if (purgeSessionsAndEventsTime > 0) { - persistenceService.purge(getMonth(-purgeSessionsAndEventsTime).getTime()); - } - - logger.info("Profile purge: purge executed in {} ms", System.currentTimeMillis() - t); - } - }; - purgeProfileTimer.scheduleAtFixedRate(task, getDay(1).getTime(), purgeProfileInterval * 24L * 60L * 60L * 1000L); - - logger.info("Profile purge: purge scheduled with an interval of {} days", purgeProfileInterval); - } else { - logger.info("Profile purge: No purge scheduled"); - } - } - - private void cancelPurge() { - if (purgeProfileTimer != null) { - purgeProfileTimer.cancel(); - } - logger.info("Profile purge: Purge unscheduled"); - } - - 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; - } - - private GregorianCalendar getMonth(int offset) { - GregorianCalendar gc = new GregorianCalendar(); - gc = new GregorianCalendar(gc.get(Calendar.YEAR), gc.get(Calendar.MONTH), 1); - gc.add(Calendar.MONTH, offset); - return gc; - } - - public long getAllProfilesCount() { - Condition condition = new Condition(definitionsService.getConditionType("profilePropertyCondition")); - condition.setParameter("propertyName", "mergedWith"); - condition.setParameter("comparisonOperator", "missing"); - return persistenceService.queryCount(condition, Profile.ITEM_TYPE); - } - - public <T extends Profile> PartialList<T> search(Query query, final Class<T> clazz) { - if (query.getCondition() != null && definitionsService.resolveConditionType(query.getCondition())) { - if (StringUtils.isNotBlank(query.getText())) { - return persistenceService.queryFullText(query.getText(), query.getCondition(), query.getSortby(), clazz, query.getOffset(), query.getLimit()); - } else { - return persistenceService.query(query.getCondition(), query.getSortby(), clazz, query.getOffset(), query.getLimit()); - } - } else { - if (StringUtils.isNotBlank(query.getText())) { - return persistenceService.queryFullText(query.getText(), query.getSortby(), clazz, query.getOffset(), query.getLimit()); - } else { - return persistenceService.getAllItems(clazz, query.getOffset(), query.getLimit(), query.getSortby()); - } - } - } - - @Override - public boolean createPropertyType(PropertyType property) { - if (persistenceService.load(property.getItemId(), PropertyType.class) != null) { - return false; - } - return persistenceService.save(property); - } - - @Override - public boolean deletePropertyType(String propertyId) { - return persistenceService.remove(propertyId, PropertyType.class); - } - - @Override - public Set<PropertyType> getExistingProperties(String tagId, String itemType) { - Set<PropertyType> filteredProperties = new LinkedHashSet<PropertyType>(); - // TODO: here we limit the result to the definition we have, but what if some properties haven't definition but exist in ES mapping ? - Set<PropertyType> profileProperties = getPropertyTypeByTag(tagId, true); - Map<String, Map<String, Object>> itemMapping = persistenceService.getMapping(itemType); - - if (itemMapping == null || itemMapping.isEmpty() || itemMapping.get("properties") == null || itemMapping.get("properties").get("properties") == null) { - return filteredProperties; - } - - Map<String, Map<String, String>> propMapping = (Map<String, Map<String, String>>) itemMapping.get("properties").get("properties"); - for (PropertyType propertyType : profileProperties) { - if (propMapping.containsKey(propertyType.getMetadata().getId())) { - filteredProperties.add(propertyType); - } - } - return filteredProperties; - } - - - // TODO: can be improve to use ES mappings directly to read the existing properties - @Override - public String exportProfilesPropertiesToCsv(Query query) { - StringBuilder sb = new StringBuilder(); - Set<PropertyType> profileProperties = getExistingProperties("profileProperties", Profile.ITEM_TYPE); - PropertyType[] propertyTypes = profileProperties.toArray(new PropertyType[profileProperties.size()]); - PartialList<Profile> profiles = search(query, Profile.class); - - sb.append("profileId;"); - // headers - for (int i = 0; i < propertyTypes.length; i++) { - PropertyType propertyType = propertyTypes[i]; - sb.append(propertyType.getMetadata().getId()); - if (i < propertyTypes.length - 1) { - sb.append(";"); - } else { - sb.append("\n"); - } - } - - // rows - for (Profile profile : profiles.getList()) { - sb.append(profile.getItemId()); - sb.append(";"); - for (int i = 0; i < propertyTypes.length; i++) { - PropertyType propertyType = propertyTypes[i]; - if (profile.getProperties().get(propertyType.getMetadata().getId()) != null) { - handleExportProperty(sb, profile.getProperties().get(propertyType.getMetadata().getId()), propertyType); - } else { - sb.append(""); - } - if (i < propertyTypes.length - 1) { - sb.append(";"); - } else { - sb.append("\n"); - } - } - } - - return sb.toString(); - } - - // TODO may be moved this in a specific Export Utils Class and improve it to handle date format, ... - private void handleExportProperty(StringBuilder sb, Object propertyValue, PropertyType propertyType) { - if (propertyValue instanceof Collection && propertyType.isMultivalued()) { - Collection propertyValues = (Collection) propertyValue; - if (propertyValues.size() > 0) { - Object[] propertyValuesArray = propertyValues.toArray(); - for (int i = 0; i < propertyValuesArray.length; i++) { - Object o = propertyValuesArray[i]; - if (o instanceof String && i == 0) { - sb.append("\""); - } - sb.append(propertyValue.toString()); - if (o instanceof String && i == propertyValuesArray.length - 1) { - sb.append("\""); - } else { - sb.append(","); - } - } - } - } else { - if (propertyValue instanceof String) { - sb.append("\""); - } - sb.append(propertyValue.toString()); - if (propertyValue instanceof String) { - sb.append("\""); - } - } - } - - public PartialList<Profile> findProfilesByPropertyValue(String propertyName, String propertyValue, int offset, int size, String sortBy) { - return persistenceService.query(propertyName, propertyValue, sortBy, Profile.class, offset, size); - } - - public Profile load(String profileId) { - return persistenceService.load(profileId, Profile.class); - } - - public Profile save(Profile profile) { - persistenceService.save(profile); - return persistenceService.load(profile.getItemId(), Profile.class); - } - - public Persona savePersona(Persona profile) { - if (persistenceService.load(profile.getItemId(), Persona.class) == null) { - Session session = new PersonaSession(UUID.randomUUID().toString(), profile, new Date()); - persistenceService.save(profile); - persistenceService.save(session); - } else { - persistenceService.save(profile); - } - - return persistenceService.load(profile.getItemId(), Persona.class); - } - - public void delete(String profileId, boolean persona) { - if (persona) { - persistenceService.remove(profileId, Persona.class); - } else { - Condition mergeCondition = new Condition(definitionsService.getConditionType("profilePropertyCondition")); - mergeCondition.setParameter("propertyName", "mergedWith"); - mergeCondition.setParameter("comparisonOperator", "equals"); - mergeCondition.setParameter("propertyValue", profileId); - persistenceService.removeByQuery(mergeCondition, Profile.class); - - persistenceService.remove(profileId, Profile.class); - } - } - - public Profile mergeProfiles(Profile masterProfile, List<Profile> profilesToMerge) { - - // now let's remove all the already merged profiles from the list. - List<Profile> filteredProfilesToMerge = new ArrayList<>(); - - for (Profile filteredProfile : profilesToMerge) { - if (!filteredProfile.getItemId().equals(masterProfile.getItemId())) { - filteredProfilesToMerge.add(filteredProfile); - } - } - - if (filteredProfilesToMerge.isEmpty()) { - return masterProfile; - } - - profilesToMerge = filteredProfilesToMerge; - - Set<String> allProfileProperties = new LinkedHashSet<>(); - for (Profile profile : profilesToMerge) { - allProfileProperties.addAll(profile.getProperties().keySet()); - } - - Collection<PropertyType> profilePropertyTypes = getAllPropertyTypes("profiles"); - Map<String, PropertyType> profilePropertyTypeById = new HashMap<>(); - for (PropertyType propertyType : profilePropertyTypes) { - profilePropertyTypeById.put(propertyType.getMetadata().getId(), propertyType); - } - Set<String> profileIdsToMerge = new TreeSet<>(); - for (Profile profileToMerge : profilesToMerge) { - profileIdsToMerge.add(profileToMerge.getItemId()); - } - logger.info("Merging profiles " + profileIdsToMerge + " into profile " + masterProfile.getItemId()); - - for (String profileProperty : allProfileProperties) { - PropertyType propertyType = profilePropertyTypeById.get(profileProperty); - String propertyMergeStrategyId = "defaultMergeStrategy"; - if (propertyType != null) { - if (propertyType.getMergeStrategy() != null && propertyMergeStrategyId.length() > 0) { - propertyMergeStrategyId = propertyType.getMergeStrategy(); - } - } - PropertyMergeStrategyType propertyMergeStrategyType = definitionsService.getPropertyMergeStrategyType(propertyMergeStrategyId); - if (propertyMergeStrategyType == null) { - // we couldn't find the strategy - if (propertyMergeStrategyId.equals("defaultMergeStrategy")) { - logger.warn("Couldn't resolve default strategy, ignoring property merge for property " + profileProperty); - continue; - } else { - // todo: improper algorithm⦠it is possible that the defaultMergeStrategy couldn't be resolved here - logger.warn("Couldn't resolve strategy " + propertyMergeStrategyId + " for property " + profileProperty + ", using default strategy instead"); - propertyMergeStrategyId = "defaultMergeStrategy"; - propertyMergeStrategyType = definitionsService.getPropertyMergeStrategyType(propertyMergeStrategyId); - } - } - - // todo: find a way to avoid resolving PropertyMergeStrategyExecutor every time? - Collection<ServiceReference<PropertyMergeStrategyExecutor>> matchingPropertyMergeStrategyExecutors; - try { - matchingPropertyMergeStrategyExecutors = bundleContext.getServiceReferences(PropertyMergeStrategyExecutor.class, propertyMergeStrategyType.getFilter()); - for (ServiceReference<PropertyMergeStrategyExecutor> propertyMergeStrategyExecutorReference : matchingPropertyMergeStrategyExecutors) { - PropertyMergeStrategyExecutor propertyMergeStrategyExecutor = bundleContext.getService(propertyMergeStrategyExecutorReference); - propertyMergeStrategyExecutor.mergeProperty(profileProperty, propertyType, profilesToMerge, masterProfile); - } - } catch (InvalidSyntaxException e) { - logger.error("Error retrieving strategy implementation", e); - } - - } - - // we now have to merge the profile's segments - for (Profile profile : profilesToMerge) { - masterProfile.getSegments().addAll(profile.getSegments()); - } - - return masterProfile; - } - - public PartialList<Session> getProfileSessions(String profileId, String query, int offset, int size, String sortBy) { - if (StringUtils.isNotBlank(query)) { - return persistenceService.queryFullText("profileId", profileId, query, sortBy, Session.class, offset, size); - } else { - return persistenceService.query("profileId", profileId, sortBy, Session.class, offset, size); - } - } - - public String getPropertyTypeMapping(String fromPropertyTypeId) { - Collection<PropertyType> types = getPropertyTypeByMapping(fromPropertyTypeId); - if (types.size() > 0) { - return types.iterator().next().getMetadata().getId(); - } - return null; - } - - public Session loadSession(String sessionId, Date dateHint) { - Session s = persistenceService.load(sessionId, dateHint, Session.class); - if (s == null && dateHint != null) { - GregorianCalendar gc = new GregorianCalendar(); - gc.setTime(dateHint); - if (gc.get(Calendar.DAY_OF_MONTH) == 1) { - gc.add(Calendar.DAY_OF_MONTH, -1); - s = persistenceService.load(sessionId, gc.getTime(), Session.class); - } - } - return s; - } - - public Session saveSession(Session session) { - return persistenceService.save(session) ? session : null; - } - - public PartialList<Session> findProfileSessions(String profileId) { - return persistenceService.query("profileId", profileId, "timeStamp:desc", Session.class, 0, 50); - } - - @Override - public boolean matchCondition(Condition condition, Profile profile, Session session) { - ParserHelper.resolveConditionType(definitionsService, condition); - Condition profileCondition = definitionsService.extractConditionByTag(condition, "profileCondition"); - Condition sessionCondition = definitionsService.extractConditionByTag(condition, "sessionCondition"); - if (profileCondition != null && !persistenceService.testMatch(profileCondition, profile)) { - return false; - } - if (sessionCondition != null && !persistenceService.testMatch(sessionCondition, session)) { - return false; - } - return true; - } - - public void batchProfilesUpdate(BatchUpdate update) { - ParserHelper.resolveConditionType(definitionsService, update.getCondition()); - List<Profile> profiles = persistenceService.query(update.getCondition(), null, Profile.class); - - for (Profile profile : profiles) { - if (PropertyHelper.setProperty(profile, update.getPropertyName(), update.getPropertyValue(), update.getStrategy())) { -// Event profileUpdated = new Event("profileUpdated", null, profile, null, null, profile, new Date()); -// profileUpdated.setPersistent(false); -// eventService.send(profileUpdated); - save(profile); - } - } - } - - public Persona loadPersona(String personaId) { - return persistenceService.load(personaId, Persona.class); - } - - public PersonaWithSessions loadPersonaWithSessions(String personaId) { - Persona persona = persistenceService.load(personaId, Persona.class); - if (persona == null) { - return null; - } - List<PersonaSession> sessions = persistenceService.query("profileId", persona.getItemId(), "timeStamp:desc", PersonaSession.class); - return new PersonaWithSessions(persona, sessions); - } - - public Persona createPersona(String personaId) { - Persona newPersona = new Persona(personaId); - - Session session = new PersonaSession(UUID.randomUUID().toString(), newPersona, new Date()); - - persistenceService.save(newPersona); - persistenceService.save(session); - return newPersona; - } - - - public Collection<PropertyType> getAllPropertyTypes(String target) { - return persistenceService.query("target", target, null, PropertyType.class); - } - - public HashMap<String, Collection<PropertyType>> getAllPropertyTypes() { - Collection<PropertyType> props = persistenceService.getAllItems(PropertyType.class, 0, -1, "rank").getList(); - - HashMap<String, Collection<PropertyType>> propertyTypes = new HashMap<>(); - for (PropertyType prop : props) { - if (!propertyTypes.containsKey(prop.getTarget())) { - propertyTypes.put(prop.getTarget(), new LinkedHashSet<PropertyType>()); - } - propertyTypes.get(prop.getTarget()).add(prop); - } - return propertyTypes; - } - - public Set<PropertyType> getPropertyTypeByTag(String tag, boolean includeFromSubtags) { - Set<PropertyType> propertyTypes = new LinkedHashSet<PropertyType>(); - Collection<PropertyType> directPropertyTypes = persistenceService.query("tags", tag, "rank", PropertyType.class); - - if (directPropertyTypes != null) { - propertyTypes.addAll(directPropertyTypes); - } - if (includeFromSubtags) { - for (Tag subTag : definitionsService.getTag(tag).getSubTags()) { - Set<PropertyType> childPropertyTypes = getPropertyTypeByTag(subTag.getId(), true); - propertyTypes.addAll(childPropertyTypes); - } - } - return propertyTypes; - } - - public Collection<PropertyType> getPropertyTypeByMapping(String propertyName) { - Collection<PropertyType> l = new TreeSet<PropertyType>(new Comparator<PropertyType>() { - @Override - public int compare(PropertyType o1, PropertyType o2) { - if (o1.getRank() == o2.getRank()) { - return o1.getMetadata().getName().compareTo(o1.getMetadata().getName()); - } else if (o1.getRank() < o2.getRank()) { - return -1; - } else { - return 1; - } - } - }); - - for (PropertyType propertyType : allPropertyTypes) { - if (propertyType.getAutomaticMappingsFrom() != null && propertyType.getAutomaticMappingsFrom().contains(propertyName)) { - l.add(propertyType); - } - } - return l; - } - - public PropertyType getPropertyType(String id) { - return persistenceService.load(id, PropertyType.class); - } - - public PartialList<Session> getPersonaSessions(String personaId, int offset, int size, String sortBy) { - return persistenceService.query("profileId", personaId, sortBy, Session.class, offset, size); - } - - private void loadPredefinedPersonas(BundleContext bundleContext) { - if (bundleContext == null) { - return; - } - Enumeration<URL> predefinedPersonaEntries = bundleContext.getBundle().findEntries("META-INF/cxs/personas", "*.json", true); - if (predefinedPersonaEntries == null) { - return; - } - - while (predefinedPersonaEntries.hasMoreElements()) { - URL predefinedPersonaURL = predefinedPersonaEntries.nextElement(); - logger.debug("Found predefined persona at " + predefinedPersonaURL + ", loading... "); - - try { - PersonaWithSessions persona = CustomObjectMapper.getObjectMapper().readValue(predefinedPersonaURL, PersonaWithSessions.class); - persistenceService.save(persona.getPersona()); - - List<PersonaSession> sessions = persona.getSessions(); - for (PersonaSession session : sessions) { - session.setProfile(persona.getPersona()); - persistenceService.save(session); - } - } catch (IOException e) { - logger.error("Error while loading persona " + predefinedPersonaURL, e); - } - - } - } - - private void loadPredefinedPropertyTypes(BundleContext bundleContext) { - Enumeration<URL> predefinedPropertyTypeEntries = bundleContext.getBundle().findEntries("META-INF/cxs/properties", "*.json", true); - if (predefinedPropertyTypeEntries == null) { - return; - } - - while (predefinedPropertyTypeEntries.hasMoreElements()) { - URL predefinedPropertyTypeURL = predefinedPropertyTypeEntries.nextElement(); - logger.debug("Found predefined property type at " + predefinedPropertyTypeURL + ", loading... "); - - try { - PropertyType propertyType = CustomObjectMapper.getObjectMapper().readValue(predefinedPropertyTypeURL, PropertyType.class); - String[] splitPath = predefinedPropertyTypeURL.getPath().split("/"); - String target = splitPath[4]; - propertyType.setTarget(target); - - persistenceService.save(propertyType); - } catch (IOException e) { - logger.error("Error while loading properties " + predefinedPropertyTypeURL, 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; - } - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/services/src/main/java/org/oasis_open/contextserver/impl/services/QueryServiceImpl.java ---------------------------------------------------------------------- diff --git a/services/src/main/java/org/oasis_open/contextserver/impl/services/QueryServiceImpl.java b/services/src/main/java/org/oasis_open/contextserver/impl/services/QueryServiceImpl.java deleted file mode 100644 index ff67dd3..0000000 --- a/services/src/main/java/org/oasis_open/contextserver/impl/services/QueryServiceImpl.java +++ /dev/null @@ -1,109 +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 org.oasis_open.contextserver.api.conditions.Condition; -import org.oasis_open.contextserver.api.query.AggregateQuery; -import org.oasis_open.contextserver.api.services.DefinitionsService; -import org.oasis_open.contextserver.api.services.QueryService; -import org.oasis_open.contextserver.persistence.spi.PersistenceService; -import org.oasis_open.contextserver.persistence.spi.aggregate.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; - -public class QueryServiceImpl implements QueryService { - private static final Logger logger = LoggerFactory.getLogger(QueryServiceImpl.class.getName()); - - private PersistenceService persistenceService; - - private DefinitionsService definitionsService; - - public void setPersistenceService(PersistenceService persistenceService) { - this.persistenceService = persistenceService; - } - - public void setDefinitionsService(DefinitionsService definitionsService) { - this.definitionsService = definitionsService; - } - - public void postConstruct() { - } - - public void preDestroy() { - } - - @Override - public Map<String, Long> getAggregate(String itemType, String property) { - return persistenceService.aggregateQuery(null, new TermsAggregate(property), itemType); - } - - @Override - public Map<String, Long> getAggregate(String itemType, String property, AggregateQuery query) { - if (query != null) { - // resolve condition - if (query.getCondition() != null) { - ParserHelper.resolveConditionType(definitionsService, query.getCondition()); - } - - // resolve aggregate - if (query.getAggregate() != null) { - String aggregateType = query.getAggregate().getType(); - if (aggregateType != null) { - // try to guess the aggregate type - if (aggregateType.equals("date")) { - String interval = (String) query.getAggregate().getParameters().get("interval"); - String format = (String) query.getAggregate().getParameters().get("format"); - return persistenceService.aggregateQuery(query.getCondition(), new DateAggregate(property, interval, format), itemType); - } else if (aggregateType.equals("dateRange") && query.getAggregate().getDateRanges() != null && query.getAggregate().getDateRanges().size() > 0) { - String format = (String) query.getAggregate().getParameters().get("format"); - return persistenceService.aggregateQuery(query.getCondition(), new DateRangeAggregate(query.getAggregate().getProperty(), format, query.getAggregate().getDateRanges()), itemType); - } else if (aggregateType.equals("numericRange") && query.getAggregate().getNumericRanges() != null && query.getAggregate().getNumericRanges().size() > 0) { - return persistenceService.aggregateQuery(query.getCondition(), new NumericRangeAggregate(query.getAggregate().getProperty(), query.getAggregate().getNumericRanges()), itemType); - } else if (aggregateType.equals("ipRange") && query.getAggregate().ipRanges() != null && query.getAggregate().ipRanges().size() > 0) { - return persistenceService.aggregateQuery(query.getCondition(), new IpRangeAggregate(query.getAggregate().getProperty(), query.getAggregate().ipRanges()), itemType); - } - } - } - - // fall back on terms aggregate - return persistenceService.aggregateQuery(query.getCondition(), new TermsAggregate(property), itemType); - } - - return getAggregate(itemType, property); - } - - @Override - public Map<String, Double> getMetric(String type, String property, String slashConcatenatedMetrics, Condition condition) { - if (condition.getConditionType() == null) { - ParserHelper.resolveConditionType(definitionsService, condition); - } - return persistenceService.getSingleValuesMetrics(condition, slashConcatenatedMetrics.split("/"), property, type); - } - - @Override - public long getQueryCount(String itemType, Condition condition) { - if (condition.getConditionType() == null) { - ParserHelper.resolveConditionType(definitionsService, condition); - } - return persistenceService.queryCount(condition, itemType); - } - - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-unomi/blob/dc1d1520/services/src/main/java/org/oasis_open/contextserver/impl/services/RulesServiceImpl.java ---------------------------------------------------------------------- diff --git a/services/src/main/java/org/oasis_open/contextserver/impl/services/RulesServiceImpl.java b/services/src/main/java/org/oasis_open/contextserver/impl/services/RulesServiceImpl.java deleted file mode 100644 index 5fadfea..0000000 --- a/services/src/main/java/org/oasis_open/contextserver/impl/services/RulesServiceImpl.java +++ /dev/null @@ -1,385 +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 org.oasis_open.contextserver.api.*; -import org.oasis_open.contextserver.api.actions.ActionExecutor; -import org.oasis_open.contextserver.api.query.Query; -import org.oasis_open.contextserver.api.services.*; -import org.oasis_open.contextserver.impl.actions.ActionExecutorDispatcher; -import org.oasis_open.contextserver.api.actions.Action; -import org.oasis_open.contextserver.api.actions.ActionType; -import org.oasis_open.contextserver.api.conditions.Condition; -import org.oasis_open.contextserver.api.conditions.ConditionType; -import org.oasis_open.contextserver.api.rules.Rule; -import org.oasis_open.contextserver.persistence.spi.CustomObjectMapper; -import org.oasis_open.contextserver.persistence.spi.PersistenceService; -import org.osgi.framework.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URL; -import java.util.*; - -public class RulesServiceImpl implements RulesService, EventListenerService, SynchronousBundleListener { - - private static final Logger logger = LoggerFactory.getLogger(RulesServiceImpl.class.getName()); - public static final String RULE_QUERY_PREFIX = "rule_"; - - private BundleContext bundleContext; - - private PersistenceService persistenceService; - - private DefinitionsService definitionsService; - - private EventService eventService; - - private ActionExecutorDispatcher actionExecutorDispatcher; - private List<Rule> allRules; - - private Timer rulesTimer; - - 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 setEventService(EventService eventService) { - this.eventService = eventService; - } - - public void setActionExecutorDispatcher(ActionExecutorDispatcher actionExecutorDispatcher) { - this.actionExecutorDispatcher = actionExecutorDispatcher; - } - - public void postConstruct() { - logger.debug("postConstruct {" + bundleContext.getBundle() + "}"); - - loadPredefinedRules(bundleContext); - for (Bundle bundle : bundleContext.getBundles()) { - if (bundle.getBundleContext() != null) { - loadPredefinedRules(bundle.getBundleContext()); - } - } - try { - for (ServiceReference<ActionExecutor> reference : bundleContext.getServiceReferences(ActionExecutor.class, null)) { - ActionExecutor service = bundleContext.getService(reference); - actionExecutorDispatcher.addExecutor(reference.getProperty("actionExecutorId").toString(), reference.getBundle().getBundleId(), service); - } - } catch (Exception e) { - logger.error("Cannot get services",e); - } - - bundleContext.addBundleListener(this); - - initializeTimer(); - } - - public void preDestroy() { - bundleContext.removeBundleListener(this); - cancelTimers(); - } - - private void cancelTimers() { - if(rulesTimer != null) { - rulesTimer.cancel(); - } - logger.info("Rule purge: Purge unscheduled"); - } - - private void processBundleStartup(BundleContext bundleContext) { - if (bundleContext == null) { - return; - } - loadPredefinedRules(bundleContext); - - List<PluginType> types = definitionsService.getTypesByPlugin().get(bundleContext.getBundle().getBundleId()); - List<String> addedConditions = new ArrayList<String>(); - List<String> addedActions = new ArrayList<String>(); - if (types != null) { - for (PluginType type : types) { - if (type instanceof ConditionType) { - addedConditions.add(((ConditionType) type).getId()); - } else if (type instanceof ActionType) { - addedActions.add(((ActionType) type).getId()); - } - } - } - if (!addedConditions.isEmpty() || !addedActions.isEmpty()) { - for (Rule rule : persistenceService.query("missingPlugins", "true", null, Rule.class)) { - boolean succeed = ParserHelper.resolveConditionType(definitionsService, rule.getCondition()) && - ParserHelper.resolveActionTypes(definitionsService, rule.getActions()); - if (succeed) { - logger.info("Enable rule " + rule.getItemId()); - rule.getMetadata().setMissingPlugins(false); - setRule(rule); - } - } - } - if (bundleContext.getBundle().getRegisteredServices() != null) { - for (ServiceReference<?> reference : bundleContext.getBundle().getRegisteredServices()) { - Object service = bundleContext.getService(reference); - if (service instanceof ActionExecutor) { - actionExecutorDispatcher.addExecutor(reference.getProperty("actionExecutorId").toString(), bundleContext.getBundle().getBundleId(), (ActionExecutor) service); - } - } - } - } - - private void processBundleStop(BundleContext bundleContext) { - if (bundleContext == null) { - return; - } - List<PluginType> types = definitionsService.getTypesByPlugin().get(bundleContext.getBundle().getBundleId()); - List<String> removedConditions = new ArrayList<String>(); - List<String> removedActions = new ArrayList<String>(); - if (types != null) { - for (PluginType type : types) { - if (type instanceof ConditionType) { - removedConditions.add(((ConditionType) type).getId()); - } else if (type instanceof ActionType) { - removedActions.add(((ActionType) type).getId()); - } - } - } - if (!removedConditions.isEmpty() || !removedActions.isEmpty()) { - for (Rule rule : persistenceService.getAllItems(Rule.class)) { - List<String> conditions = ParserHelper.getConditionTypeIds(rule.getCondition()); - List<String> actions = new ArrayList<String>(); - for (Action action : rule.getActions()) { - actions.add(action.getActionTypeId()); - } - if (!Collections.disjoint(conditions, removedConditions) || !Collections.disjoint(actions, removedActions)) { - logger.info("Disable rule " + rule.getItemId()); - rule.getMetadata().setMissingPlugins(true); - setRule(rule); - } - } - } - actionExecutorDispatcher.removeExecutors(bundleContext.getBundle().getBundleId()); - } - - private void loadPredefinedRules(BundleContext bundleContext) { - Enumeration<URL> predefinedRuleEntries = bundleContext.getBundle().findEntries("META-INF/cxs/rules", "*.json", true); - if (predefinedRuleEntries == null) { - return; - } - - while (predefinedRuleEntries.hasMoreElements()) { - URL predefinedSegmentURL = predefinedRuleEntries.nextElement(); - logger.debug("Found predefined segment at " + predefinedSegmentURL + ", loading... "); - - try { - Rule rule = CustomObjectMapper.getObjectMapper().readValue(predefinedSegmentURL, Rule.class); - if (rule.getMetadata().getScope() == null) { - rule.getMetadata().setScope("systemscope"); - } - if (getRule(rule.getMetadata().getId()) == null) { - setRule(rule); - } - } catch (IOException e) { - logger.error("Error while loading segment definition " + predefinedSegmentURL, e); - } - - } - } - - public Set<Rule> getMatchingRules(Event event) { - Set<Rule> matchedRules = new LinkedHashSet<Rule>(); - - Boolean hasEventAlreadyBeenRaisedForSession = null; - Boolean hasEventAlreadyBeenRaisedForProfile = null; - - List<Rule> allItems = allRules; - - for (Rule rule : allItems) { - String scope = rule.getMetadata().getScope(); - if (scope.equals(Metadata.SYSTEM_SCOPE) || scope.equals(event.getScope())) { - Condition eventCondition = definitionsService.extractConditionByTag(rule.getCondition(), "eventCondition"); - - if (eventCondition == null) { - continue; - } - - if (!persistenceService.testMatch(eventCondition, event)) { - continue; - } - - Condition sourceCondition = definitionsService.extractConditionByTag(rule.getCondition(), "sourceEventCondition"); - if (sourceCondition != null && !persistenceService.testMatch(sourceCondition, event.getSource())) { - continue; - } - - if (rule.isRaiseEventOnlyOnceForProfile()) { - hasEventAlreadyBeenRaisedForProfile = hasEventAlreadyBeenRaisedForProfile != null ? hasEventAlreadyBeenRaisedForProfile : eventService.hasEventAlreadyBeenRaised(event, false); - if (hasEventAlreadyBeenRaisedForProfile) { - continue; - } - } else if (rule.isRaiseEventOnlyOnceForSession()) { - hasEventAlreadyBeenRaisedForSession = hasEventAlreadyBeenRaisedForSession != null ? hasEventAlreadyBeenRaisedForSession : eventService.hasEventAlreadyBeenRaised(event, true); - if (hasEventAlreadyBeenRaisedForSession) { - continue; - } - } - - Condition profileCondition = definitionsService.extractConditionByTag(rule.getCondition(), "profileCondition"); - if (profileCondition != null && !persistenceService.testMatch(profileCondition, event.getProfile())) { - continue; - } - Condition sessionCondition = definitionsService.extractConditionByTag(rule.getCondition(), "sessionCondition"); - if (sessionCondition != null && !persistenceService.testMatch(sessionCondition, event.getSession())) { - continue; - } - matchedRules.add(rule); - } - } - - return matchedRules; - } - - private List<Rule> getAllRules() { - List<Rule> allItems = persistenceService.getAllItems(Rule.class, 0, -1, "priority").getList(); - for (Rule rule : allItems) { - ParserHelper.resolveConditionType(definitionsService, rule.getCondition()); - ParserHelper.resolveActionTypes(definitionsService, rule.getActions()); - } - return allItems; - } - - - public boolean canHandle(Event event) { - return true; - } - - public int onEvent(Event event) { - Set<Rule> rules = getMatchingRules(event); - - int changes = EventService.NO_CHANGE; - for (Rule rule : rules) { - logger.debug("Fired rule " + rule.getMetadata().getId() + " for " + event.getEventType() + " - " + event.getItemId()); - for (Action action : rule.getActions()) { - changes |= actionExecutorDispatcher.execute(action, event); - } - - Event ruleFired = new Event("ruleFired", event.getSession(), event.getProfile(), event.getScope(), event, rule, event.getTimeStamp()); - ruleFired.getAttributes().putAll(event.getAttributes()); - ruleFired.setPersistent(false); - changes |= eventService.send(ruleFired); - } - return changes; - } - - public Set<Metadata> getRuleMetadatas() { - Set<Metadata> metadatas = new HashSet<Metadata>(); - for (Rule rule : persistenceService.getAllItems(Rule.class, 0, 50, null).getList()) { - metadatas.add(rule.getMetadata()); - } - return metadatas; - } - - public PartialList<Metadata> getRuleMetadatas(Query query) { - if(query.isForceRefresh()){ - persistenceService.refresh(); - } - definitionsService.resolveConditionType(query.getCondition()); - List<Metadata> descriptions = new LinkedList<>(); - PartialList<Rule> rules = persistenceService.query(query.getCondition(), query.getSortby(), Rule.class, query.getOffset(), query.getLimit()); - for (Rule definition : rules.getList()) { - descriptions.add(definition.getMetadata()); - } - return new PartialList<>(descriptions, rules.getOffset(), rules.getPageSize(), rules.getTotalSize()); - } - - public Rule getRule(String ruleId) { - Rule rule = persistenceService.load(ruleId, Rule.class); - if (rule != null) { - if (rule.getCondition() != null) { - ParserHelper.resolveConditionType(definitionsService, rule.getCondition()); - } - if (rule.getActions() != null) { - ParserHelper.resolveActionTypes(definitionsService, rule.getActions()); - } - } - return rule; - } - - public void setRule(Rule rule) { - Condition condition = rule.getCondition(); - if (condition != null) { - if (rule.getMetadata().isEnabled() && !rule.getMetadata().isMissingPlugins()) { - ParserHelper.resolveConditionType(definitionsService, condition); - definitionsService.extractConditionByTag(condition, "eventCondition"); - } - } - persistenceService.save(rule); - } - - public Set<Condition> getTrackedConditions(Item source){ - Set<Condition> trackedConditions = new HashSet<>(); - for (Rule r : allRules) { - Condition trackedCondition = definitionsService.extractConditionByTag(r.getCondition(), "trackedCondition"); - if(trackedCondition != null){ - Condition sourceEventPropertyCondition = definitionsService.extractConditionByTag(r.getCondition(), "sourceEventCondition"); - if(source != null && sourceEventPropertyCondition != null) { - ParserHelper.resolveConditionType(definitionsService, sourceEventPropertyCondition); - if(persistenceService.testMatch(sourceEventPropertyCondition, source)){ - trackedConditions.add(trackedCondition); - } - } else { - trackedConditions.add(trackedCondition); - } - - } - } - return trackedConditions; - } - - public void removeRule(String ruleId) { - persistenceService.remove(ruleId, Rule.class); - } - - private void initializeTimer() { - rulesTimer = new Timer(); - TimerTask task = new TimerTask() { - @Override - public void run() { - allRules = getAllRules(); - } - }; - rulesTimer.schedule(task, 0, 1000); - } - - public void bundleChanged(BundleEvent event) { - switch (event.getType()) { - case BundleEvent.STARTED: - processBundleStartup(event.getBundle().getBundleContext()); - break; - case BundleEvent.STOPPING: - processBundleStop(event.getBundle().getBundleContext()); - break; - } - } -}
