This is an automated email from the ASF dual-hosted git repository. shuber pushed a commit to branch opensearch-persistence in repository https://gitbox.apache.org/repos/asf/unomi.git
commit b33711b860488b7e9f5dd132ff07c55a9e2ba2e0 Author: Serge Huber <shu...@jahia.com> AuthorDate: Thu Dec 5 09:56:49 2024 +0100 Additional remove commands for actions, conditions, sessions, rules to be able to fix problems with deployments --- .../apache/unomi/api/services/EventService.java | 6 ++ .../apache/unomi/api/services/ProfileService.java | 6 ++ .../unomi/rest/endpoints/EventServiceEndpoint.java | 16 ++-- .../rest/endpoints/ProfileServiceEndPoint.java | 21 +++-- .../unomi/rest/endpoints/RulesServiceEndPoint.java | 4 +- .../rest/endpoints/SegmentServiceEndPoint.java | 4 +- .../services/impl/events/EventServiceImpl.java | 29 ++++--- .../services/impl/profiles/ProfileServiceImpl.java | 96 +++++++++++----------- .../services/impl/rules/RulesServiceImpl.java | 34 ++++---- .../services/impl/segments/SegmentServiceImpl.java | 77 +++++++++-------- .../{ProfileRemove.java => ActionRemove.java} | 25 +++--- .../{ProfileRemove.java => ConditionRemove.java} | 25 +++--- .../{ProfileRemove.java => EventRemove.java} | 25 +++--- .../apache/unomi/shell/commands/ProfileRemove.java | 11 ++- .../unomi/shell/commands/RemoveCommandSupport.java | 56 +++++++++++++ .../apache/unomi/shell/commands/RuleRemove.java | 14 +++- .../apache/unomi/shell/commands/SegmentRemove.java | 13 ++- .../{ProfileRemove.java => SessionRemove.java} | 21 +++-- 18 files changed, 305 insertions(+), 178 deletions(-) diff --git a/api/src/main/java/org/apache/unomi/api/services/EventService.java b/api/src/main/java/org/apache/unomi/api/services/EventService.java index 7c59b37fc..cd18de26e 100644 --- a/api/src/main/java/org/apache/unomi/api/services/EventService.java +++ b/api/src/main/java/org/apache/unomi/api/services/EventService.java @@ -161,4 +161,10 @@ public interface EventService { * @param profileId identifier of the profile that we want to remove it's events */ void removeProfileEvents(String profileId); + + /** + * Delete an event by specifying its event identifier + * @param eventIdentifier the unique identifier for the event + */ + void deleteEvent(String eventIdentifier); } diff --git a/api/src/main/java/org/apache/unomi/api/services/ProfileService.java b/api/src/main/java/org/apache/unomi/api/services/ProfileService.java index 03da6ce9b..7da4d35b6 100644 --- a/api/src/main/java/org/apache/unomi/api/services/ProfileService.java +++ b/api/src/main/java/org/apache/unomi/api/services/ProfileService.java @@ -443,4 +443,10 @@ public interface ProfileService { */ @Deprecated void purgeMonthlyItems(int existsNumberOfMonths); + + /** + * Delete a session using its identifier + * @param sessionIdentifier the unique identifier for the session + */ + void deleteSession(String sessionIdentifier); } diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/EventServiceEndpoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/EventServiceEndpoint.java index f1bac4d1f..e8d1d615f 100644 --- a/rest/src/main/java/org/apache/unomi/rest/endpoints/EventServiceEndpoint.java +++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/EventServiceEndpoint.java @@ -26,11 +26,7 @@ import org.osgi.service.component.annotations.Reference; import javax.jws.WebMethod; import javax.jws.WebService; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; +import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import java.util.Set; @@ -80,6 +76,16 @@ public class EventServiceEndpoint { return eventService.getEvent(id); } + /** + * Deletes an event by id. + * @param id the identifier for the event to delete + */ + @DELETE + @Path("/{id}") + public void deleteEvent(@PathParam("id") final String id) { + eventService.deleteEvent(id); + } + /** * Retrieves the list of event types identifiers that the server has processed. * @return a Set of strings that contain event type identifiers. diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/ProfileServiceEndPoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/ProfileServiceEndPoint.java index e07f36df1..8828c16d4 100644 --- a/rest/src/main/java/org/apache/unomi/rest/endpoints/ProfileServiceEndPoint.java +++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/ProfileServiceEndPoint.java @@ -58,7 +58,7 @@ import java.util.*; @Component(service=ProfileServiceEndPoint.class,property = "osgi.jaxrs.resource=true") public class ProfileServiceEndPoint { - private static final Logger logger = LoggerFactory.getLogger(ProfileServiceEndPoint.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(ProfileServiceEndPoint.class.getName()); @Reference private ProfileService profileService; @@ -73,7 +73,7 @@ public class ProfileServiceEndPoint { private LocalizationHelper localizationHelper; public ProfileServiceEndPoint() { - logger.info("Initializing profile service endpoint..."); + LOGGER.info("Initializing profile service endpoint..."); } @WebMethod(exclude = true) @@ -132,7 +132,7 @@ public class ProfileServiceEndPoint { try { return exportProfiles(CustomObjectMapper.getObjectMapper().readValue(query, Query.class)); } catch (IOException e) { - logger.error(e.getMessage(), e); + LOGGER.error("{}", e.getMessage(), e); return Response.serverError().build(); } } @@ -151,7 +151,7 @@ public class ProfileServiceEndPoint { try { return exportProfiles(CustomObjectMapper.getObjectMapper().readValue(query, Query.class)); } catch (IOException e) { - logger.error(e.getMessage(), e); + LOGGER.error("{}", e.getMessage(), e); return Response.serverError().build(); } } @@ -399,7 +399,7 @@ public class ProfileServiceEndPoint { public Session loadSession(@PathParam("sessionId") String sessionId) throws ParseException { return profileService.loadSession(sessionId); } - + /** * Saves the specified session. * @@ -412,6 +412,17 @@ public class ProfileServiceEndPoint { return profileService.saveSession(session); } + /** + * Delete the session by specifying its unique identifier + * @param sessionId the session identifier for the session to delete + * @throws ParseException + */ + @DELETE + @Path("/sessions/{sessionId}") + public void deleteSession(@PathParam("sessionId") String sessionId) throws ParseException { + profileService.deleteSession(sessionId); + } + /** * Retrieves {@link Event}s for the {@link Session} identified by the provided session identifier, matching any of the provided event types, * ordered according to the specified {@code sortBy} String and paged: only {@code size} of them are retrieved, starting with the {@code offset}-th one. diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/RulesServiceEndPoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/RulesServiceEndPoint.java index 91298ee9e..3230e900c 100644 --- a/rest/src/main/java/org/apache/unomi/rest/endpoints/RulesServiceEndPoint.java +++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/RulesServiceEndPoint.java @@ -50,13 +50,13 @@ import java.util.Set; @Component(service=RulesServiceEndPoint.class,property = "osgi.jaxrs.resource=true") public class RulesServiceEndPoint { - private static final Logger logger = LoggerFactory.getLogger(RulesServiceEndPoint.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(RulesServiceEndPoint.class.getName()); @Reference private RulesService rulesService; public RulesServiceEndPoint() { - logger.info("Initializing rule service endpoint..."); + LOGGER.info("Initializing rule service endpoint..."); } @WebMethod(exclude=true) diff --git a/rest/src/main/java/org/apache/unomi/rest/endpoints/SegmentServiceEndPoint.java b/rest/src/main/java/org/apache/unomi/rest/endpoints/SegmentServiceEndPoint.java index 3cd547598..d987f2b03 100644 --- a/rest/src/main/java/org/apache/unomi/rest/endpoints/SegmentServiceEndPoint.java +++ b/rest/src/main/java/org/apache/unomi/rest/endpoints/SegmentServiceEndPoint.java @@ -50,13 +50,13 @@ import java.util.List; @Component(service=SegmentServiceEndPoint.class,property = "osgi.jaxrs.resource=true") public class SegmentServiceEndPoint { - private static final Logger logger = LoggerFactory.getLogger(SegmentServiceEndPoint.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(SegmentServiceEndPoint.class.getName()); @Reference private SegmentService segmentService; public SegmentServiceEndPoint() { - logger.info("Initializing segment service endpoint..."); + LOGGER.info("Initializing segment service endpoint..."); } @WebMethod(exclude=true) diff --git a/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java index fe8faa70b..eff0f90bb 100644 --- a/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/impl/events/EventServiceImpl.java @@ -17,7 +17,6 @@ package org.apache.unomi.services.impl.events; -import com.fasterxml.jackson.databind.JsonNode; import inet.ipaddr.IPAddress; import inet.ipaddr.IPAddressString; import org.apache.commons.lang3.StringUtils; @@ -32,7 +31,6 @@ import org.apache.unomi.api.actions.ActionPostExecutor; import org.apache.unomi.api.conditions.Condition; import org.apache.unomi.api.query.Query; import org.apache.unomi.api.services.*; -import org.apache.unomi.persistence.spi.CustomObjectMapper; import org.apache.unomi.persistence.spi.PersistenceService; import org.apache.unomi.persistence.spi.aggregate.TermsAggregate; import org.apache.unomi.api.utils.ParserHelper; @@ -52,7 +50,7 @@ import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; public class EventServiceImpl implements EventService { - private static final Logger logger = LoggerFactory.getLogger(EventServiceImpl.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(EventServiceImpl.class.getName()); private static final int MAX_RECURSION_DEPTH = 10; private List<EventListenerService> eventListeners = new CopyOnWriteArrayList<EventListenerService>(); @@ -124,20 +122,26 @@ public class EventServiceImpl implements EventService { } public String authenticateThirdPartyServer(String key, String ip) { - logger.debug("Authenticating third party server with key: " + key + " and IP: " + ip); + LOGGER.debug("Authenticating third party server with key: {} and IP: {}", key, ip); if (key != null) { for (Map.Entry<String, ThirdPartyServer> entry : thirdPartyServers.entrySet()) { ThirdPartyServer server = entry.getValue(); if (server.getKey().equals(key)) { - IPAddress ipAddress = new IPAddressString(ip).getAddress(); - for (IPAddress serverIpAddress : server.getIpAddresses()) { - if (serverIpAddress.contains(ipAddress)) { - return server.getId(); + if (ip != null) { + if (ip.startsWith("[") && ip.endsWith("]")) { + // This can happen with IPv6 addresses, we must remove the markers since our IPAddress library doesn't support them. + ip = ip.substring(1, ip.length() - 1); + } + IPAddress ipAddress = new IPAddressString(ip).getAddress(); + for (IPAddress serverIpAddress : server.getIpAddresses()) { + if (serverIpAddress.contains(ipAddress)) { + return server.getId(); + } } } } } - logger.warn("Could not authenticate any third party servers for key: {}", key); + LOGGER.warn("Could not authenticate any third party servers for key: {}", key); } return null; } @@ -148,7 +152,7 @@ public class EventServiceImpl implements EventService { private int send(Event event, int depth) { if (depth > MAX_RECURSION_DEPTH) { - logger.warn("Max recursion depth reached"); + LOGGER.warn("Max recursion depth reached"); return NO_CHANGE; } @@ -407,4 +411,9 @@ public class EventServiceImpl implements EventService { persistenceService.removeByQuery(profileCondition,Event.class); } + + @Override + public void deleteEvent(String eventIdentifier) { + persistenceService.remove(eventIdentifier, Event.class); + } } diff --git a/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java index dd30ba863..2c34efa89 100644 --- a/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/impl/profiles/ProfileServiceImpl.java @@ -160,7 +160,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList } - private static final Logger logger = LoggerFactory.getLogger(ProfileServiceImpl.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(ProfileServiceImpl.class.getName()); private BundleContext bundleContext; @@ -192,7 +192,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList private boolean forceRefreshOnSave = false; public ProfileServiceImpl() { - logger.info("Initializing profile service..."); + LOGGER.info("Initializing profile service..."); } public void setBundleContext(BundleContext bundleContext) { @@ -224,7 +224,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList } public void postConstruct() { - logger.debug("postConstruct {" + bundleContext.getBundle() + "}"); + LOGGER.debug("postConstruct {{}}", bundleContext.getBundle()); loadPropertyTypesFromPersistence(); processBundleStartup(bundleContext); @@ -237,7 +237,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList initializeDefaultPurgeValuesIfNecessary(); initializePurge(); schedulePropertyTypeLoad(); - logger.info("Profile service initialized."); + LOGGER.info("Profile service initialized."); } public void preDestroy() { @@ -248,7 +248,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList propertyTypeLoadTask.cancel(); } bundleContext.removeBundleListener(this); - logger.info("Profile service shutdown."); + LOGGER.info("Profile service shutdown."); } private void processBundleStartup(BundleContext bundleContext) { @@ -311,7 +311,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList } }; schedulerService.getScheduleExecutorService().scheduleAtFixedRate(propertyTypeLoadTask, 10000, propertiesRefreshInterval, TimeUnit.MILLISECONDS); - logger.info("Scheduled task for property type loading each 10s"); + LOGGER.info("Scheduled task for property type loading each 10s"); } public void reloadPropertyTypes(boolean refresh) { @@ -321,7 +321,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList } loadPropertyTypesFromPersistence(); } catch (Throwable t) { - logger.error("Error loading property types from persistence back-end", t); + LOGGER.error("Error loading property types from persistence back-end", t); } } @@ -329,7 +329,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList try { this.propertyTypes = new PropertyTypes(persistenceService.getAllItems(PropertyType.class, 0, -1, "rank").getList()); } catch (Exception e) { - logger.error("Error loading property types from persistence service", e); + LOGGER.error("Error loading property types from persistence service", e); } } @@ -348,7 +348,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList List<Condition> subConditions = new ArrayList<>(); if (inactiveNumberOfDays > 0) { - logger.info("Purging: Profile with no visits since {} days", inactiveNumberOfDays); + LOGGER.info("Purging: Profile with no visits since {} days", inactiveNumberOfDays); Condition inactiveTimeCondition = new Condition(profilePropertyConditionType); inactiveTimeCondition.setParameter("propertyName", "properties.lastVisit"); inactiveTimeCondition.setParameter("comparisonOperator", "lessThanOrEqualTo"); @@ -358,7 +358,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList if (existsNumberOfDays > 0) { Condition existTimeCondition = new Condition(profilePropertyConditionType); - logger.info("Purging: Profile created since more than {} days", existsNumberOfDays); + LOGGER.info("Purging: Profile created since more than {} days", existsNumberOfDays); existTimeCondition.setParameter("propertyName", "properties.firstVisit"); existTimeCondition.setParameter("comparisonOperator", "lessThanOrEqualTo"); existTimeCondition.setParameter("propertyValueDateExpr", "now-" + existsNumberOfDays + "d"); @@ -373,7 +373,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList @Override public void purgeSessionItems(int existsNumberOfDays) { if (existsNumberOfDays > 0) { - logger.info("Purging: Sessions created since more than {} days", existsNumberOfDays); + LOGGER.info("Purging: Sessions created since more than {} days", existsNumberOfDays); persistenceService.purgeTimeBasedItems(existsNumberOfDays, Session.class); } } @@ -381,7 +381,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList @Override public void purgeEventItems(int existsNumberOfDays) { if (existsNumberOfDays > 0) { - logger.info("Purging: Events created since more than {} days", existsNumberOfDays); + LOGGER.info("Purging: Events created since more than {} days", existsNumberOfDays); persistenceService.purgeTimeBasedItems(existsNumberOfDays, Event.class); } } @@ -393,21 +393,21 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList } private void initializePurge() { - logger.info("Purge: Initializing"); + LOGGER.info("Purge: Initializing"); if (purgeProfileInactiveTime > 0 || purgeProfileExistTime > 0 || purgeSessionExistTime > 0 || purgeEventExistTime > 0) { if (purgeProfileInactiveTime > 0) { - logger.info("Purge: Profile with no visits since more than {} days, will be purged", purgeProfileInactiveTime); + LOGGER.info("Purge: Profile with no visits since more than {} days, will be purged", purgeProfileInactiveTime); } if (purgeProfileExistTime > 0) { - logger.info("Purge: Profile created since more than {} days, will be purged", purgeProfileExistTime); + LOGGER.info("Purge: Profile created since more than {} days, will be purged", purgeProfileExistTime); } if (purgeSessionExistTime > 0) { - logger.info("Purge: Session items created since more than {} days, will be purged", purgeSessionExistTime); + LOGGER.info("Purge: Session items created since more than {} days, will be purged", purgeSessionExistTime); } if (purgeEventExistTime > 0) { - logger.info("Purge: Event items created since more than {} days, will be purged", purgeEventExistTime); + LOGGER.info("Purge: Event items created since more than {} days, will be purged", purgeEventExistTime); } purgeTask = new TimerTask() { @@ -415,7 +415,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList public void run() { try { long purgeStartTime = System.currentTimeMillis(); - logger.info("Purge: triggered"); + LOGGER.info("Purge: triggered"); // Profile purge purgeProfiles(purgeProfileInactiveTime, purgeProfileExistTime); @@ -423,18 +423,18 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList // Monthly items purge purgeSessionItems(purgeSessionExistTime); purgeEventItems(purgeEventExistTime); - logger.info("Purge: executed in {} ms", System.currentTimeMillis() - purgeStartTime); + LOGGER.info("Purge: executed in {} ms", System.currentTimeMillis() - purgeStartTime); } catch (Throwable t) { - logger.error("Error while purging", t); + LOGGER.error("Error while purging", t); } } }; schedulerService.getScheduleExecutorService().scheduleAtFixedRate(purgeTask, 1, purgeProfileInterval, TimeUnit.DAYS); - logger.info("Purge: purge scheduled with an interval of {} days", purgeProfileInterval); + LOGGER.info("Purge: purge scheduled with an interval of {} days", purgeProfileInterval); } else { - logger.info("Purge: No purge scheduled"); + LOGGER.info("Purge: No purge scheduled"); } } @@ -552,8 +552,6 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList String propertyId = propertyIdAndType.getKey(); if (profile.getProperties().get(propertyId) != null) { handleExportProperty(sb, profile.getProperties().get(propertyId), propertyIdAndType.getValue()); - } else { - sb.append(""); } sb.append(";"); } @@ -769,7 +767,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList for (Profile profileToMerge : profilesToMerge) { profileIdsToMerge.add(profileToMerge.getItemId()); } - logger.info("Merging profiles " + profileIdsToMerge + " into profile " + masterProfile.getItemId()); + LOGGER.info("Merging profiles {} into profile {}", profileIdsToMerge, masterProfile.getItemId()); boolean masterProfileChanged = false; @@ -785,11 +783,12 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList 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); + 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"); + LOGGER.warn("Couldn't resolve strategy {} for property {}, using default strategy instead", propertyMergeStrategyId, + profileProperty); propertyMergeStrategyId = "defaultMergeStrategy"; propertyMergeStrategyType = definitionsService.getPropertyMergeStrategyType(propertyMergeStrategyId); } @@ -804,7 +803,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList masterProfileChanged |= propertyMergeStrategyExecutor.mergeProperty(profileProperty, propertyType, profilesToMerge, masterProfile); } } catch (InvalidSyntaxException e) { - logger.error("Error retrieving strategy implementation", e); + LOGGER.error("Error retrieving strategy implementation", e); } } @@ -816,7 +815,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList // we now have to merge the profile's segments for (Profile profile : profilesToMerge) { - if (profile.getSegments() != null && profile.getSegments().size() > 0) { + if (profile.getSegments() != null && !profile.getSegments().isEmpty()) { masterProfile.getSegments().addAll(profile.getSegments()); // TODO better segments diff calculation masterProfileChanged = true; @@ -825,7 +824,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList // we now have to merge the profile's consents for (Profile profile : profilesToMerge) { - if (profile.getConsents() != null && profile.getConsents().size() > 0) { + if (profile.getConsents() != null && !profile.getConsents().isEmpty()) { for (String consentId : profile.getConsents().keySet()) { if (masterProfile.getConsents().containsKey(consentId)) { if (masterProfile.getConsents().get(consentId).getRevokeDate().before(new Date())) { @@ -861,7 +860,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList public String getPropertyTypeMapping(String fromPropertyTypeId) { Collection<PropertyType> types = getPropertyTypeByMapping(fromPropertyTypeId); - if (types.size() > 0) { + if (!types.isEmpty()) { return types.iterator().next().getMetadata().getId(); } return null; @@ -892,17 +891,17 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList return persistenceService.save(session) ? session : null; } - private Map removePersonalIdentifiersFromSessionProfile(final Map<String, Object> profileProperties) { + private Map<String, Object> removePersonalIdentifiersFromSessionProfile(final Map<String, Object> profileProperties) { Set<PropertyType> personalIdsProps = getPropertyTypeBySystemTag(PERSONAL_IDENTIFIER_TAG_NAME); - final List personalIdsPropsNames = new ArrayList<String>(); + final List<String> personalIdsPropsNames = new ArrayList<>(); personalIdsProps.forEach(propType -> personalIdsPropsNames.add(propType.getMetadata().getId())); - Set propsToRemove = new HashSet<String>(); + Set<String> propsToRemove = new HashSet<>(); profileProperties.keySet().forEach(propKey -> { if (personalIdsPropsNames.contains(propKey)) { propsToRemove.add(propKey); } }); - propsToRemove.forEach(propId -> profileProperties.remove(propId)); + propsToRemove.forEach(profileProperties::remove); return profileProperties; } @@ -935,7 +934,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList return true; } } - return subConditions.size() > 0 && isAnd; + return !subConditions.isEmpty() && isAnd; } else { Condition profileCondition = definitionsService.extractConditionBySystemTag(condition, "profileCondition"); Condition sessionCondition = definitionsService.extractConditionBySystemTag(condition, "sessionCondition"); @@ -947,14 +946,14 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList } public void batchProfilesUpdate(BatchUpdate update) { - logger.info("Starting batch profiles update"); + LOGGER.info("Starting batch profiles update"); long startTime = System.currentTimeMillis(); long updatedCount = 0; ParserHelper.resolveConditionType(definitionsService, update.getCondition(), "batch update on property " + update.getPropertyName()); PartialList<Profile> profiles = persistenceService.query(update.getCondition(), null, Profile.class, 0,update.getScrollBatchSize(), update.getScrollTimeValidity()); - while (profiles != null && profiles.getList().size() > 0) { + while (profiles != null && !profiles.getList().isEmpty()) { for (Profile profile : profiles.getList()) { if (PropertyHelper.setProperty(profile, update.getPropertyName(), update.getPropertyValue(), update.getStrategy())) { save(profile); @@ -965,7 +964,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList } long totalTime = System.currentTimeMillis() - startTime; - logger.info("Batch profiles updated: {} profiles in {}ms", updatedCount, totalTime); + LOGGER.info("Batch profiles updated: {} profiles in {}ms", updatedCount, totalTime); } public Persona loadPersona(String personaId) { @@ -1103,7 +1102,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList while (predefinedPersonaEntries.hasMoreElements()) { URL predefinedPersonaURL = predefinedPersonaEntries.nextElement(); - logger.debug("Found predefined persona at " + predefinedPersonaURL + ", loading... "); + LOGGER.debug("Found predefined persona at {}, loading... ", predefinedPersonaURL); try { PersonaWithSessions persona = getObjectMapper().readValue(predefinedPersonaURL, PersonaWithSessions.class); @@ -1116,9 +1115,9 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList session.setProfile(persona.getPersona()); persistenceService.save(session); } - logger.info("Predefined persona with id {} registered", itemId); + LOGGER.info("Predefined persona with id {} registered", itemId); } catch (IOException e) { - logger.error("Error while loading persona " + predefinedPersonaURL, e); + LOGGER.error("Error while loading persona {}", predefinedPersonaURL, e); } } } @@ -1132,7 +1131,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList List<PropertyType> bundlePropertyTypes = new ArrayList<>(); while (predefinedPropertyTypeEntries.hasMoreElements()) { URL predefinedPropertyTypeURL = predefinedPropertyTypeEntries.nextElement(); - logger.debug("Found predefined property type at " + predefinedPropertyTypeURL + ", loading... "); + LOGGER.debug("Found predefined property type at {}, loading... ", predefinedPropertyTypeURL); try { PropertyType propertyType = CustomObjectMapper.getObjectMapper().readValue(predefinedPropertyTypeURL, PropertyType.class); @@ -1141,9 +1140,9 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList persistenceService.save(propertyType); bundlePropertyTypes.add(propertyType); - logger.info("Predefined property type with id {} registered", propertyType.getMetadata().getId()); + LOGGER.info("Predefined property type with id {} registered", propertyType.getMetadata().getId()); } catch (IOException e) { - logger.error("Error while loading properties " + predefinedPropertyTypeURL, e); + LOGGER.error("Error while loading properties {}", predefinedPropertyTypeURL, e); } } propertyTypes = propertyTypes.with(bundlePropertyTypes); @@ -1171,7 +1170,7 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList return true; } } catch (ReflectiveOperationException e) { - logger.error("Cannot merge properties", e); + LOGGER.error("Cannot merge properties", e); } } return false; @@ -1286,4 +1285,9 @@ public class ProfileServiceImpl implements ProfileService, SynchronousBundleList public void refresh() { reloadPropertyTypes(true); } + + @Override + public void deleteSession(String sessionIdentifier) { + persistenceService.remove(sessionIdentifier, Session.class); + } } diff --git a/services/src/main/java/org/apache/unomi/services/impl/rules/RulesServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/rules/RulesServiceImpl.java index 79a1aa638..0861c53e3 100644 --- a/services/src/main/java/org/apache/unomi/services/impl/rules/RulesServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/impl/rules/RulesServiceImpl.java @@ -24,7 +24,6 @@ import org.apache.unomi.api.Metadata; import org.apache.unomi.api.PartialList; import org.apache.unomi.api.actions.Action; import org.apache.unomi.api.conditions.Condition; -import org.apache.unomi.api.conditions.ConditionType; import org.apache.unomi.api.query.Query; import org.apache.unomi.api.rules.Rule; import org.apache.unomi.api.rules.RuleStatistics; @@ -43,12 +42,11 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; public class RulesServiceImpl implements RulesService, EventListenerService, SynchronousBundleListener { public static final String TRACKED_PARAMETER = "trackedConditionParameters"; - private static final Logger logger = LoggerFactory.getLogger(RulesServiceImpl.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(RulesServiceImpl.class.getName()); private BundleContext bundleContext; @@ -61,12 +59,12 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn private List<Rule> allRules; private final Set<String> invalidRulesId = new HashSet<>(); - private Map<String, RuleStatistics> allRuleStatistics = new ConcurrentHashMap<>(); + private final Map<String, RuleStatistics> allRuleStatistics = new ConcurrentHashMap<>(); private Integer rulesRefreshInterval = 1000; private Integer rulesStatisticsRefreshInterval = 10000; - private List<RuleListenerService> ruleListeners = new CopyOnWriteArrayList<RuleListenerService>(); + private final List<RuleListenerService> ruleListeners = new CopyOnWriteArrayList<RuleListenerService>(); private Map<String, Set<Rule>> rulesByEventType = new HashMap<>(); private Boolean optimizedRulesActivated = true; @@ -108,7 +106,7 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn } public void postConstruct() { - logger.debug("postConstruct {" + bundleContext.getBundle() + "}"); + LOGGER.debug("postConstruct {{}}", bundleContext.getBundle()); loadPredefinedRules(bundleContext); for (Bundle bundle : bundleContext.getBundles()) { @@ -120,12 +118,12 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn bundleContext.addBundleListener(this); initializeTimers(); - logger.info("Rule service initialized."); + LOGGER.info("Rule service initialized."); } public void preDestroy() { bundleContext.removeBundleListener(this); - logger.info("Rule service shutdown."); + LOGGER.info("Rule service shutdown."); } private void processBundleStartup(BundleContext bundleContext) { @@ -149,14 +147,14 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn while (predefinedRuleEntries.hasMoreElements()) { URL predefinedRuleURL = predefinedRuleEntries.nextElement(); - logger.debug("Found predefined rule at " + predefinedRuleURL + ", loading... "); + LOGGER.debug("Found predefined rule at {}, loading... ", predefinedRuleURL); try { Rule rule = CustomObjectMapper.getObjectMapper().readValue(predefinedRuleURL, Rule.class); setRule(rule); - logger.info("Predefined rule with id {} registered", rule.getMetadata().getId()); + LOGGER.info("Predefined rule with id {} registered", rule.getMetadata().getId()); } catch (IOException e) { - logger.error("Error while loading rule definition " + predefinedRuleURL, e); + LOGGER.error("Error while loading rule definition {}", predefinedRuleURL, e); } } } @@ -273,7 +271,7 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn this.rulesByEventType = getRulesByEventType(newAllRules); this.allRules = newAllRules; } catch (Throwable t) { - logger.error("Error loading rules from persistence back-end", t); + LOGGER.error("Error loading rules from persistence back-end", t); } } @@ -315,7 +313,7 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn int changes = EventService.NO_CHANGE; for (Rule rule : rules) { - logger.debug("Fired rule " + rule.getMetadata().getId() + " for " + event.getEventType() + " - " + event.getItemId()); + LOGGER.debug("Fired rule {} for {} - {}", rule.getMetadata().getId(), event.getEventType(), event.getItemId()); fireExecuteActions(rule, event); long actionsStartTime = System.currentTimeMillis(); @@ -428,8 +426,8 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn } } else if ( trackedCondition.getConditionType() != null && - trackedCondition.getConditionType().getParameters() != null && - trackedCondition.getConditionType().getParameters().size() > 0 + trackedCondition.getConditionType().getParameters() != null && !trackedCondition.getConditionType() + .getParameters().isEmpty() ) { // lookup for track parameters Map<String, Object> trackedParameters = new HashMap<>(); @@ -442,10 +440,10 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn }); } } catch (Exception e) { - logger.warn("Unable to parse tracked parameter from {} for condition type {}", parameter, trackedCondition.getConditionType().getItemId()); + LOGGER.warn("Unable to parse tracked parameter from {} for condition type {}", parameter, trackedCondition.getConditionType().getItemId()); } }); - if (trackedParameters.size() > 0) { + if (!trackedParameters.isEmpty()) { evalCondition = new Condition(definitionsService.getConditionType("booleanCondition")); evalCondition.setParameter("operator", "and"); ArrayList<Condition> conditions = new ArrayList<>(); @@ -488,7 +486,7 @@ public class RulesServiceImpl implements RulesService, EventListenerService, Syn try { syncRuleStatistics(); } catch (Throwable t) { - logger.error("Error synching rule statistics between memory and persistence back-end", t); + LOGGER.error("Error synching rule statistics between memory and persistence back-end", t); } } }; diff --git a/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java b/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java index fee5ef0fb..1bc8730f4 100644 --- a/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java +++ b/services/src/main/java/org/apache/unomi/services/impl/segments/SegmentServiceImpl.java @@ -58,7 +58,7 @@ import java.util.stream.Collectors; public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentService, SynchronousBundleListener { - private static final Logger logger = LoggerFactory.getLogger(SegmentServiceImpl.class.getName()); + private static final Logger LOGGER = LoggerFactory.getLogger(SegmentServiceImpl.class.getName()); private static final String VALIDATION_PROFILE_ID = "validation-profile-id"; private static final String RESET_SCORING_SCRIPT = "resetScoringPlan"; @@ -85,7 +85,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe private int dailyDateExprEvaluationHourUtc = 5; public SegmentServiceImpl() { - logger.info("Initializing segment service..."); + LOGGER.info("Initializing segment service..."); } public void setBundleContext(BundleContext bundleContext) { @@ -145,7 +145,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe } public void postConstruct() throws IOException { - logger.debug("postConstruct {" + bundleContext.getBundle() + "}"); + LOGGER.debug("postConstruct {{}}", bundleContext.getBundle()); loadPredefinedSegments(bundleContext); loadPredefinedScorings(bundleContext); for (Bundle bundle : bundleContext.getBundles()) { @@ -156,12 +156,12 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe } bundleContext.addBundleListener(this); initializeTimer(); - logger.info("Segment service initialized."); + LOGGER.info("Segment service initialized."); } public void preDestroy() { bundleContext.removeBundleListener(this); - logger.info("Segment service shutdown."); + LOGGER.info("Segment service shutdown."); } private void processBundleStartup(BundleContext bundleContext) { @@ -186,7 +186,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe while (predefinedSegmentEntries.hasMoreElements()) { URL predefinedSegmentURL = predefinedSegmentEntries.nextElement(); - logger.debug("Found predefined segment at " + predefinedSegmentURL + ", loading... "); + LOGGER.debug("Found predefined segment at {}, loading... ", predefinedSegmentURL); try { Segment segment = CustomObjectMapper.getObjectMapper().readValue(predefinedSegmentURL, Segment.class); @@ -194,9 +194,9 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe segment.getMetadata().setScope("systemscope"); } setSegmentDefinition(segment); - logger.info("Predefined segment with id {} registered", segment.getMetadata().getId()); + LOGGER.info("Predefined segment with id {} registered", segment.getMetadata().getId()); } catch (IOException e) { - logger.error("Error while loading segment definition " + predefinedSegmentURL, e); + LOGGER.error("Error while loading segment definition {}", predefinedSegmentURL, e); } } } @@ -209,7 +209,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe while (predefinedScoringEntries.hasMoreElements()) { URL predefinedScoringURL = predefinedScoringEntries.nextElement(); - logger.debug("Found predefined scoring at " + predefinedScoringURL + ", loading... "); + LOGGER.debug("Found predefined scoring at {}, loading... ", predefinedScoringURL); try { Scoring scoring = CustomObjectMapper.getObjectMapper().readValue(predefinedScoringURL, Scoring.class); @@ -217,9 +217,9 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe scoring.getMetadata().setScope("systemscope"); } setScoringDefinition(scoring); - logger.info("Predefined scoring with id {} registered", scoring.getMetadata().getId()); + LOGGER.info("Predefined scoring with id {} registered", scoring.getMetadata().getId()); } catch (IOException e) { - logger.error("Error while loading segment definition " + predefinedScoringURL, e); + LOGGER.error("Error while loading segment definition {}", predefinedScoringURL, e); } } } @@ -286,10 +286,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe } } else if ("profileSegmentCondition".equals(condition.getConditionTypeId())) { @SuppressWarnings("unchecked") final List<String> referencedSegmentIds = (List<String>) condition.getParameter("segments"); - - if (referencedSegmentIds.indexOf(segmentToDeleteId) >= 0) { - return true; - } + return referencedSegmentIds.contains(segmentToDeleteId); } } return false; @@ -326,7 +323,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe } } else if ("profileSegmentCondition".equals(condition.getConditionTypeId())) { @SuppressWarnings("unchecked") final List<String> referencedSegmentIds = (List<String>) condition.getParameter("segments"); - if (referencedSegmentIds.indexOf(segmentId) >= 0) { + if (referencedSegmentIds.contains(segmentId)) { referencedSegmentIds.remove(segmentId); if (referencedSegmentIds.isEmpty()) { return null; @@ -758,8 +755,8 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe action.setActionType(definitionsService.getActionType("setEventOccurenceCountAction")); action.setParameter("pastEventCondition", parentCondition); - rule.setActions(Arrays.asList(action)); - rule.setLinkedItems(Arrays.asList(metadata.getId())); + rule.setActions(List.of(action)); + rule.setLinkedItems(List.of(metadata.getId())); // it's a new generated rules to keep track of the event count, we should update all the profile that match this past event // it will update the count of event occurrence on the profile directly @@ -868,7 +865,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe persistenceService.refreshIndex(Profile.class); } - logger.info("{} profiles updated for past event condition in {}ms", updatedProfileCount, System.currentTimeMillis() - t); + LOGGER.info("{} profiles updated for past event condition in {}ms", updatedProfileCount, System.currentTimeMillis() - t); } /** @@ -918,7 +915,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe String key = CustomObjectMapper.getObjectMapper().writeValueAsString(m); return "eventTriggered" + getMD5(key); } catch (JsonProcessingException e) { - logger.error("Cannot generate key", e); + LOGGER.error("Cannot generate key", e); return null; } } @@ -928,13 +925,13 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe Set<String> segmentOrScoringIdsToReevaluate = new HashSet<>(); // reevaluate auto generated rules used to store the event occurrence count on the profile for (Rule rule : rulesService.getAllRules()) { - if (rule.getActions() != null && rule.getActions().size() > 0) { + if (rule.getActions() != null && !rule.getActions().isEmpty()) { for (Action action : rule.getActions()) { if (action.getActionTypeId().equals("setEventOccurenceCountAction")) { Condition pastEventCondition = (Condition) action.getParameterValues().get("pastEventCondition"); if (pastEventCondition.containsParameter("numberOfDays")) { recalculatePastEventOccurrencesOnProfiles(rule.getCondition(), pastEventCondition, true, true); - logger.info("Event occurrence count on profiles updated for rule: {}", rule.getItemId()); + LOGGER.info("Event occurrence count on profiles updated for rule: {}", rule.getItemId()); if (rule.getLinkedItems() != null && rule.getLinkedItems().size() > 0) { segmentOrScoringIdsToReevaluate.addAll(rule.getLinkedItems()); } @@ -944,7 +941,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe } } int pastEventSegmentsAndScoringsSize = segmentOrScoringIdsToReevaluate.size(); - logger.info("Found {} segments or scoring plans containing pastEventCondition conditions", pastEventSegmentsAndScoringsSize); + LOGGER.info("Found {} segments or scoring plans containing pastEventCondition conditions", pastEventSegmentsAndScoringsSize); // get Segments and Scoring that contains relative date expressions segmentOrScoringIdsToReevaluate.addAll(allSegments.stream() @@ -953,26 +950,26 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe .collect(Collectors.toList())); segmentOrScoringIdsToReevaluate.addAll(allScoring.stream() - .filter(scoring -> scoring.getElements() != null && scoring.getElements().size() > 0 && scoring.getElements().stream() + .filter(scoring -> scoring.getElements() != null && !scoring.getElements().isEmpty() && scoring.getElements().stream() .anyMatch(scoringElement -> scoringElement != null && scoringElement.getCondition() != null && scoringElement.getCondition().toString().contains("propertyValueDateExpr"))) .map(Item::getItemId) .collect(Collectors.toList())); - logger.info("Found {} segments or scoring plans containing date relative expressions", segmentOrScoringIdsToReevaluate.size() - pastEventSegmentsAndScoringsSize); + LOGGER.info("Found {} segments or scoring plans containing date relative expressions", segmentOrScoringIdsToReevaluate.size() - pastEventSegmentsAndScoringsSize); // reevaluate segments and scoring. - if (segmentOrScoringIdsToReevaluate.size() > 0) { + if (!segmentOrScoringIdsToReevaluate.isEmpty()) { persistenceService.refreshIndex(Profile.class, null); for (String linkedItem : segmentOrScoringIdsToReevaluate) { Segment linkedSegment = getSegmentDefinition(linkedItem); if (linkedSegment != null) { - logger.info("Start segment recalculation for segment: {} - {}", linkedSegment.getItemId(), linkedSegment.getMetadata().getName()); + LOGGER.info("Start segment recalculation for segment: {} - {}", linkedSegment.getItemId(), linkedSegment.getMetadata().getName()); updateExistingProfilesForSegment(linkedSegment); continue; } Scoring linkedScoring = getScoringDefinition(linkedItem); if (linkedScoring != null) { - logger.info("Start scoring plan recalculation for scoring plan: {} - {}", linkedScoring.getItemId(), linkedScoring.getMetadata().getName()); + LOGGER.info("Start scoring plan recalculation for scoring plan: {} - {}", linkedScoring.getItemId(), linkedScoring.getMetadata().getName()); updateExistingProfilesForScoring(linkedScoring.getItemId(), linkedScoring.getElements(), linkedScoring.getMetadata().isEnabled()); } } @@ -1009,7 +1006,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe Condition profileIdCondition = definitionsService.getConditionBuilder().condition("idsCondition").parameter("ids", batchProfilesToUpdate).parameter("match", true).build(); persistenceService.updateWithQueryAndStoredScript(Profile.class, new String[]{"updatePastEventOccurences"}, new Map[]{paramPerProfile}, new Condition[]{profileIdCondition}); } catch (Exception e) { - logger.error("Error updating {} profiles for past event system properties", paramPerProfile.size(), e); + LOGGER.error("Error updating {} profiles for past event system properties", paramPerProfile.size(), e); } finally { paramPerProfile.clear(); batchProfilesToUpdate.clear(); @@ -1072,14 +1069,14 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe } else { updatedProfileCount += updateProfilesSegment(segmentCondition, segmentId, false, sendProfileUpdateEventForSegmentUpdate); } - logger.info("{} profiles updated in {}ms", updatedProfileCount, System.currentTimeMillis() - updateProfilesForSegmentStartTime); + LOGGER.info("{} profiles updated in {}ms", updatedProfileCount, System.currentTimeMillis() - updateProfilesForSegmentStartTime); } private long updateProfilesSegment(Condition profilesToUpdateCondition, String segmentId, boolean isAdd, boolean sendProfileUpdateEvent) { long updatedProfileCount = 0; PartialList<Profile> profiles = persistenceService.query(profilesToUpdateCondition, null, Profile.class, 0, segmentUpdateBatchSize, "10m"); - while (profiles != null && profiles.getList().size() > 0) { + while (profiles != null && !profiles.getList().isEmpty()) { long startTime = System.currentTimeMillis(); if (batchSegmentProfileUpdate) { batchUpdateProfilesSegment(segmentId, profiles.getList(), isAdd); @@ -1093,7 +1090,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe sendProfileUpdatedEvent(profiles.getList()); updatedProfileCount += profiles.size(); - logger.info("{} profiles {} to segment {} in {}ms", profiles.size(), isAdd ? "added" : "removed", segmentId, System.currentTimeMillis() - startTime); + LOGGER.info("{} profiles {} to segment {} in {}ms", profiles.size(), isAdd ? "added" : "removed", segmentId, System.currentTimeMillis() - startTime); profiles = persistenceService.continueScrollQuery(Profile.class, profiles.getScrollIdentifier(), profiles.getScrollTimeValidity()); } @@ -1120,11 +1117,11 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe Failsafe.with(retryPolicy). run(executionContext -> { - logger.warn("retry updating profile segment {}, profile {}, time {}", segmentId, profileId, new Date()); + LOGGER.warn("retry updating profile segment {}, profile {}, time {}", segmentId, profileId, new Date()); Profile profileToAddUpdated = persistenceService.load(profileId, Profile.class); Map<String, Object> sourceMapToUpdate = buildPropertiesMapForUpdateSegment(profileToAddUpdated, segmentId, isAdd); boolean isUpdated = persistenceService.update(profileToAddUpdated, Profile.class, sourceMapToUpdate); - if (isUpdated == false) + if (!isUpdated) throw new Exception(String.format("failed retry update profile segment {}, profile {}, time {}", segmentId, profileId, new Date())); }); } @@ -1184,7 +1181,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe } } persistenceService.updateWithQueryAndStoredScript(Profile.class, scripts, scriptParams, conditions); - logger.info("Updated scoring for profiles in {}ms", System.currentTimeMillis() - startTime); + LOGGER.info("Updated scoring for profiles in {}ms", System.currentTimeMillis() - startTime); } public void bundleChanged(BundleEvent event) { @@ -1205,17 +1202,17 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe public void run() { try { long currentTimeMillis = System.currentTimeMillis(); - logger.info("running scheduled task to recalculate segments and scoring that contains date relative conditions"); + LOGGER.info("running scheduled task to recalculate segments and scoring that contains date relative conditions"); recalculatePastEventConditions(); - logger.info("finished recalculate segments and scoring that contains date relative conditions in {}ms. ", System.currentTimeMillis() - currentTimeMillis); + LOGGER.info("finished recalculate segments and scoring that contains date relative conditions in {}ms. ", System.currentTimeMillis() - currentTimeMillis); } catch (Throwable t) { - logger.error("Error while updating profiles for segments and scoring that contains date relative conditions", t); + LOGGER.error("Error while updating profiles for segments and scoring that contains date relative conditions", t); } } }; long initialDelay = SchedulerServiceImpl.getTimeDiffInSeconds(dailyDateExprEvaluationHourUtc, ZonedDateTime.now(ZoneOffset.UTC)); long period = TimeUnit.DAYS.toSeconds(taskExecutionPeriod); - logger.info("daily recalculation job for segments and scoring that contains date relative conditions will run at fixed rate, " + + LOGGER.info("daily recalculation job for segments and scoring that contains date relative conditions will run at fixed rate, " + "initialDelay={}, taskExecutionPeriod={} in seconds", initialDelay, period); schedulerService.getScheduleExecutorService().scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS); @@ -1226,7 +1223,7 @@ public class SegmentServiceImpl extends AbstractServiceImpl implements SegmentSe allSegments = getAllSegmentDefinitions(); allScoring = getAllScoringDefinitions(); } catch (Throwable t) { - logger.error("Error while loading segments and scoring definitions from persistence back-end", t); + LOGGER.error("Error while loading segments and scoring definitions from persistence back-end", t); } } }; diff --git a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ActionRemove.java similarity index 61% copy from tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java copy to tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ActionRemove.java index 6fba5d3c4..29755788d 100644 --- a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java +++ b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ActionRemove.java @@ -16,25 +16,30 @@ */ package org.apache.unomi.shell.commands; -import org.apache.karaf.shell.api.action.Action; import org.apache.karaf.shell.api.action.Argument; import org.apache.karaf.shell.api.action.Command; import org.apache.karaf.shell.api.action.lifecycle.Reference; import org.apache.karaf.shell.api.action.lifecycle.Service; -import org.apache.unomi.api.services.ProfileService; +import org.apache.unomi.api.services.DefinitionsService; -@Command(scope = "unomi", name = "profile-remove", description = "This command will remove a profile") +@Command(scope = "unomi", name = "action-remove", description = "This command will remove an action type.") @Service -public class ProfileRemove implements Action { +public class ActionRemove extends RemoveCommandSupport { @Reference - ProfileService profileService; + DefinitionsService definitionsService; - @Argument(index = 0, name = "profile", description = "The identifier for the profile", required = true, multiValued = false) - String profileIdentifier; + @Argument(index = 0, name = "actionId", description = "The identifier for the action", required = true, multiValued = false) + String actionTypeIdentifier; - public Object execute() throws Exception { - profileService.delete(profileIdentifier, false); - return null; + @Override + public Object doRemove() throws Exception { + definitionsService.removeActionType(actionTypeIdentifier); + return true; + } + + @Override + public String getResourceDescription() { + return "action type [" + actionTypeIdentifier + "]"; } } diff --git a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ConditionRemove.java similarity index 60% copy from tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java copy to tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ConditionRemove.java index 6fba5d3c4..ef14a1bf4 100644 --- a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java +++ b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ConditionRemove.java @@ -16,25 +16,30 @@ */ package org.apache.unomi.shell.commands; -import org.apache.karaf.shell.api.action.Action; import org.apache.karaf.shell.api.action.Argument; import org.apache.karaf.shell.api.action.Command; import org.apache.karaf.shell.api.action.lifecycle.Reference; import org.apache.karaf.shell.api.action.lifecycle.Service; -import org.apache.unomi.api.services.ProfileService; +import org.apache.unomi.api.services.DefinitionsService; -@Command(scope = "unomi", name = "profile-remove", description = "This command will remove a profile") +@Command(scope = "unomi", name = "condition-remove", description = "This command will remove an condition type.") @Service -public class ProfileRemove implements Action { +public class ConditionRemove extends RemoveCommandSupport { @Reference - ProfileService profileService; + DefinitionsService definitionsService; - @Argument(index = 0, name = "profile", description = "The identifier for the profile", required = true, multiValued = false) - String profileIdentifier; + @Argument(index = 0, name = "conditionId", description = "The identifier for the condition", required = true, multiValued = false) + String conditionTypeIdentifier; - public Object execute() throws Exception { - profileService.delete(profileIdentifier, false); - return null; + @Override + public Object doRemove() throws Exception { + definitionsService.removeConditionType(conditionTypeIdentifier); + return true; + } + + @Override + public String getResourceDescription() { + return "condition type [" + conditionTypeIdentifier + "]"; } } diff --git a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/EventRemove.java similarity index 63% copy from tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java copy to tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/EventRemove.java index 6fba5d3c4..8517384e4 100644 --- a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java +++ b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/EventRemove.java @@ -16,25 +16,30 @@ */ package org.apache.unomi.shell.commands; -import org.apache.karaf.shell.api.action.Action; import org.apache.karaf.shell.api.action.Argument; import org.apache.karaf.shell.api.action.Command; import org.apache.karaf.shell.api.action.lifecycle.Reference; import org.apache.karaf.shell.api.action.lifecycle.Service; -import org.apache.unomi.api.services.ProfileService; +import org.apache.unomi.api.services.EventService; -@Command(scope = "unomi", name = "profile-remove", description = "This command will remove a profile") +@Command(scope = "unomi", name = "event-remove", description = "This command will remove an event.") @Service -public class ProfileRemove implements Action { +public class EventRemove extends RemoveCommandSupport { @Reference - ProfileService profileService; + EventService eventService; - @Argument(index = 0, name = "profile", description = "The identifier for the profile", required = true, multiValued = false) - String profileIdentifier; + @Argument(index = 0, name = "event", description = "The identifier for the event", required = true, multiValued = false) + String eventIdentifier; - public Object execute() throws Exception { - profileService.delete(profileIdentifier, false); - return null; + @Override + public Object doRemove() throws Exception { + eventService.deleteEvent(eventIdentifier); + return true; + } + + @Override + public String getResourceDescription() { + return "event [" + eventIdentifier + "]"; } } diff --git a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java index 6fba5d3c4..649d11d96 100644 --- a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java +++ b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java @@ -16,7 +16,6 @@ */ package org.apache.unomi.shell.commands; -import org.apache.karaf.shell.api.action.Action; import org.apache.karaf.shell.api.action.Argument; import org.apache.karaf.shell.api.action.Command; import org.apache.karaf.shell.api.action.lifecycle.Reference; @@ -25,7 +24,7 @@ import org.apache.unomi.api.services.ProfileService; @Command(scope = "unomi", name = "profile-remove", description = "This command will remove a profile") @Service -public class ProfileRemove implements Action { +public class ProfileRemove extends RemoveCommandSupport { @Reference ProfileService profileService; @@ -33,8 +32,12 @@ public class ProfileRemove implements Action { @Argument(index = 0, name = "profile", description = "The identifier for the profile", required = true, multiValued = false) String profileIdentifier; - public Object execute() throws Exception { + public String getResourceDescription() { + return "profile [" + profileIdentifier + "]"; + } + + public Object doRemove() throws Exception { profileService.delete(profileIdentifier, false); - return null; + return true; } } diff --git a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/RemoveCommandSupport.java b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/RemoveCommandSupport.java new file mode 100644 index 000000000..3b7353f5f --- /dev/null +++ b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/RemoveCommandSupport.java @@ -0,0 +1,56 @@ +/* + * 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.shell.commands; + +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Option; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.console.Session; + +import java.io.IOException; + +public abstract class RemoveCommandSupport implements Action { + + @Reference + Session session; + + @Option(name = "--force", description = "Force deletion without confirmation", required = false, multiValued = false) + boolean force; + + public abstract Object doRemove() throws Exception; + + public abstract String getResourceDescription(); + + @Override + public Object execute() throws Exception { + Object result = null; + // Prompt for confirmation + if (force || askForConfirmation("Are you sure you want to delete "+getResourceDescription()+" ? (yes/no): ")) { + result = doRemove(); + System.out.println("Resource deleted successfully."); + } else { + System.out.println("Operation cancelled."); + } + return result; + } + + private boolean askForConfirmation(String prompt) throws IOException { + String input = session.readLine(prompt, null); + return "yes".equals(input); + } + +} diff --git a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/RuleRemove.java b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/RuleRemove.java index b5afea0be..f2d0b89ce 100644 --- a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/RuleRemove.java +++ b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/RuleRemove.java @@ -16,7 +16,6 @@ */ package org.apache.unomi.shell.commands; -import org.apache.karaf.shell.api.action.Action; import org.apache.karaf.shell.api.action.Argument; import org.apache.karaf.shell.api.action.Command; import org.apache.karaf.shell.api.action.lifecycle.Reference; @@ -25,7 +24,7 @@ import org.apache.unomi.api.services.RulesService; @Command(scope = "unomi", name = "rule-remove", description = "This will allows to remove a rule in the Apache Unomi Context Server") @Service -public class RuleRemove implements Action { +public class RuleRemove extends RemoveCommandSupport { @Reference RulesService rulesService; @@ -33,8 +32,15 @@ public class RuleRemove implements Action { @Argument(index = 0, name = "rule", description = "The identifier for the rule", required = true, multiValued = false) String ruleIdentifier; - public Object execute() throws Exception { + @Override + public Object doRemove() throws Exception { rulesService.removeRule(ruleIdentifier); - return null; + return true; } + + @Override + public String getResourceDescription() { + return "rule [" + ruleIdentifier + "]"; + } + } diff --git a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/SegmentRemove.java b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/SegmentRemove.java index 14b4efdf1..5d6ca215a 100644 --- a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/SegmentRemove.java +++ b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/SegmentRemove.java @@ -16,7 +16,6 @@ */ package org.apache.unomi.shell.commands; -import org.apache.karaf.shell.api.action.Action; import org.apache.karaf.shell.api.action.Argument; import org.apache.karaf.shell.api.action.Command; import org.apache.karaf.shell.api.action.lifecycle.Reference; @@ -26,7 +25,7 @@ import org.apache.unomi.api.services.SegmentService; @Command(scope = "unomi", name = "segment-remove", description = "Remove segments in the Apache Unomi Context Server") @Service -public class SegmentRemove implements Action { +public class SegmentRemove extends RemoveCommandSupport { @Reference SegmentService segmentService; @@ -37,8 +36,8 @@ public class SegmentRemove implements Action { @Argument(index = 1, name = "validate", description = "Check if the segment is used in goals or other segments", required = false, multiValued = false) Boolean validate = true; - - public Object execute() throws Exception { + @Override + public Object doRemove() throws Exception { DependentMetadata dependantMetadata = segmentService.removeSegmentDefinition(segmentIdentifier, validate); if (!validate || (dependantMetadata.getSegments().isEmpty() && dependantMetadata.getScorings().isEmpty())) { System.out.println("Segment " + segmentIdentifier + " successfully deleted"); @@ -53,4 +52,10 @@ public class SegmentRemove implements Action { } return null; } + + @Override + public String getResourceDescription() { + return "segment [" + segmentIdentifier + "]"; + } + } diff --git a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/SessionRemove.java similarity index 67% copy from tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java copy to tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/SessionRemove.java index 6fba5d3c4..f7114c2cc 100644 --- a/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/ProfileRemove.java +++ b/tools/shell-dev-commands/src/main/java/org/apache/unomi/shell/commands/SessionRemove.java @@ -16,25 +16,30 @@ */ package org.apache.unomi.shell.commands; -import org.apache.karaf.shell.api.action.Action; import org.apache.karaf.shell.api.action.Argument; import org.apache.karaf.shell.api.action.Command; import org.apache.karaf.shell.api.action.lifecycle.Reference; import org.apache.karaf.shell.api.action.lifecycle.Service; import org.apache.unomi.api.services.ProfileService; -@Command(scope = "unomi", name = "profile-remove", description = "This command will remove a profile") +@Command(scope = "unomi", name = "session-remove", description = "This command will remove a session.") @Service -public class ProfileRemove implements Action { +public class SessionRemove extends RemoveCommandSupport { @Reference ProfileService profileService; - @Argument(index = 0, name = "profile", description = "The identifier for the profile", required = true, multiValued = false) - String profileIdentifier; + @Argument(index = 0, name = "session", description = "The identifier for the session", required = true, multiValued = false) + String sessionIdentifier; - public Object execute() throws Exception { - profileService.delete(profileIdentifier, false); - return null; + @Override + public Object doRemove() throws Exception { + profileService.deleteSession(sessionIdentifier); + return true; + } + + @Override + public String getResourceDescription() { + return "session [" + sessionIdentifier + "]"; } }