use of org.apereo.portal.events.PortalEvent in project uPortal by Jasig.
the class JpaPortalEventStore method getPortalEvents.
@Override
public void getPortalEvents(DateTime startTime, DateTime endTime, int maxEvents, FunctionWithoutResult<PortalEvent> handler) {
final Session session = this.getEntityManager().unwrap(Session.class);
final org.hibernate.Query query = session.createQuery(this.selectQuery);
query.setParameter(this.startTimeParameter.getName(), startTime);
query.setParameter(this.endTimeParameter.getName(), endTime);
if (maxEvents > 0) {
query.setMaxResults(maxEvents);
}
for (final ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY); results.next(); ) {
final PersistentPortalEvent persistentPortalEvent = (PersistentPortalEvent) results.get(0);
final PortalEvent portalEvent = this.toPortalEvent(persistentPortalEvent.getEventData(), persistentPortalEvent.getEventType());
handler.apply(portalEvent);
persistentPortalEvent.setAggregated(true);
session.evict(persistentPortalEvent);
}
}
use of org.apereo.portal.events.PortalEvent in project uPortal by Jasig.
the class PortalRawEventsAggregatorImpl method doCloseAggregations.
@Override
@AggrEventsTransactional
public EventProcessingResult doCloseAggregations() {
if (!this.clusterLockService.isLockOwner(AGGREGATION_LOCK_NAME)) {
throw new IllegalStateException("The cluster lock " + AGGREGATION_LOCK_NAME + " must be owned by the current thread and server");
}
final IEventAggregatorStatus cleanUnclosedStatus = eventAggregationManagementDao.getEventAggregatorStatus(IEventAggregatorStatus.ProcessingType.CLEAN_UNCLOSED, true);
// Update status with current server name
final String serverName = this.portalInfoProvider.getUniqueServerName();
cleanUnclosedStatus.setServerName(serverName);
cleanUnclosedStatus.setLastStart(new DateTime());
// Determine date of most recently aggregated data
final IEventAggregatorStatus eventAggregatorStatus = eventAggregationManagementDao.getEventAggregatorStatus(IEventAggregatorStatus.ProcessingType.AGGREGATION, false);
if (eventAggregatorStatus == null || eventAggregatorStatus.getLastEventDate() == null) {
// Nothing has been aggregated, skip unclosed cleanup
cleanUnclosedStatus.setLastEnd(new DateTime());
eventAggregationManagementDao.updateEventAggregatorStatus(cleanUnclosedStatus);
return new EventProcessingResult(0, null, null, true);
}
final DateTime lastAggregatedDate = eventAggregatorStatus.getLastEventDate();
// If lastCleanUnclosedDate is null use the oldest date dimension as there can be
// no aggregations that exist before it
final DateTime lastCleanUnclosedDate;
if (cleanUnclosedStatus.getLastEventDate() == null) {
final DateDimension oldestDateDimension = this.dateDimensionDao.getOldestDateDimension();
lastCleanUnclosedDate = oldestDateDimension.getDate().toDateTime();
} else {
lastCleanUnclosedDate = cleanUnclosedStatus.getLastEventDate();
}
if (!(lastCleanUnclosedDate.isBefore(lastAggregatedDate))) {
logger.debug("No events aggregated since last unclosed aggregation cleaning, skipping clean: {}", lastAggregatedDate);
return new EventProcessingResult(0, lastCleanUnclosedDate, lastAggregatedDate, true);
}
// Switch to flush on commit to avoid flushes during queries
final EntityManager entityManager = this.getEntityManager();
entityManager.flush();
entityManager.setFlushMode(FlushModeType.COMMIT);
// Track the number of closed aggregations and the last date of a cleaned interval
int closedAggregations = 0;
int cleanedIntervals = 0;
DateTime cleanUnclosedEnd;
final Thread currentThread = Thread.currentThread();
final String currentName = currentThread.getName();
try {
currentThread.setName(currentName + "-" + lastCleanUnclosedDate + "-" + lastAggregatedDate);
// Local caches used to reduce db io
final IntervalsForAggregatorHelper intervalsForAggregatorHelper = new IntervalsForAggregatorHelper();
final Map<AggregationInterval, AggregationIntervalInfo> previousIntervals = new HashMap<AggregationInterval, AggregationIntervalInfo>();
// A DateTime within the next interval to close aggregations in
DateTime nextIntervalDate = lastCleanUnclosedDate;
do {
// Reset our goal of catching up to the last aggregated event on every iteration
cleanUnclosedEnd = lastAggregatedDate;
// For each interval the aggregator supports, cleanup the unclosed aggregations
for (final AggregationInterval interval : intervalsForAggregatorHelper.getHandledIntervals()) {
final AggregationIntervalInfo previousInterval = previousIntervals.get(interval);
if (previousInterval != null && nextIntervalDate.isBefore(previousInterval.getEnd())) {
logger.debug("{} interval before {} has already been cleaned during this execution, ignoring", interval, previousInterval.getEnd());
continue;
}
// The END date of the last clean session will find us the next interval to
// clean
final AggregationIntervalInfo nextIntervalToClean = intervalHelper.getIntervalInfo(interval, nextIntervalDate);
previousIntervals.put(interval, nextIntervalToClean);
if (nextIntervalToClean == null) {
continue;
}
final DateTime start = nextIntervalToClean.getStart();
final DateTime end = nextIntervalToClean.getEnd();
if (!end.isBefore(lastAggregatedDate)) {
logger.debug("{} interval between {} and {} is still active, ignoring", new Object[] { interval, start, end });
continue;
}
// Track the oldest interval end, this ensures that nothing is missed
if (end.isBefore(cleanUnclosedEnd)) {
cleanUnclosedEnd = end;
}
logger.debug("Cleaning unclosed {} aggregations between {} and {}", new Object[] { interval, start, end });
for (final IntervalAwarePortalEventAggregator<PortalEvent> portalEventAggregator : intervalAwarePortalEventAggregators) {
checkShutdown();
final Class<? extends IPortalEventAggregator<?>> aggregatorType = getClass(portalEventAggregator);
// Get aggregator specific interval info config
final AggregatedIntervalConfig aggregatorIntervalConfig = intervalsForAggregatorHelper.getAggregatorIntervalConfig(aggregatorType);
// cleanUnclosedAggregations
if (aggregatorIntervalConfig.isIncluded(interval)) {
closedAggregations += portalEventAggregator.cleanUnclosedAggregations(start, end, interval);
}
}
cleanedIntervals++;
}
// Set the next interval to the end date from the last aggregation run
nextIntervalDate = cleanUnclosedEnd;
logger.debug("Closed {} aggregations across {} interval before {} with goal of {}", new Object[] { closedAggregations, cleanedIntervals, cleanUnclosedEnd, lastAggregatedDate });
// Loop until either the batchSize of cleaned aggregations has been reached or no
// aggregation work is done
} while (closedAggregations <= cleanUnclosedAggregationsBatchSize && cleanedIntervals <= cleanUnclosedIntervalsBatchSize && cleanUnclosedEnd.isBefore(lastAggregatedDate));
} finally {
currentThread.setName(currentName);
}
// Update the status object and store it
cleanUnclosedStatus.setLastEventDate(cleanUnclosedEnd);
cleanUnclosedStatus.setLastEnd(new DateTime());
eventAggregationManagementDao.updateEventAggregatorStatus(cleanUnclosedStatus);
return new EventProcessingResult(closedAggregations, lastCleanUnclosedDate, lastAggregatedDate, !cleanUnclosedEnd.isBefore(lastAggregatedDate));
}
use of org.apereo.portal.events.PortalEvent in project uPortal by Jasig.
the class JpaPortalEventStore method aggregatePortalEvents.
@Override
@RawEventsTransactional
public boolean aggregatePortalEvents(DateTime startTime, DateTime endTime, int maxEvents, Function<PortalEvent, Boolean> handler) {
final Session session = this.getEntityManager().unwrap(Session.class);
session.setFlushMode(FlushMode.COMMIT);
final org.hibernate.Query query = session.createQuery(this.selectUnaggregatedQuery);
query.setParameter(this.startTimeParameter.getName(), startTime);
query.setParameter(this.endTimeParameter.getName(), endTime);
if (maxEvents > 0) {
query.setMaxResults(maxEvents);
}
int resultCount = 0;
for (final ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY); results.next(); ) {
final PersistentPortalEvent persistentPortalEvent = (PersistentPortalEvent) results.get(0);
final PortalEvent portalEvent;
try {
portalEvent = this.toPortalEvent(persistentPortalEvent.getEventData(), persistentPortalEvent.getEventType());
} catch (RuntimeException e) {
this.logger.warn("Failed to convert PersistentPortalEvent to PortalEvent: " + persistentPortalEvent, e);
// Mark the event as error and store the mark to prevent trying to reprocess the
// broken event data
persistentPortalEvent.setErrorAggregating(true);
session.persist(persistentPortalEvent);
continue;
}
try {
final Boolean eventHandled = handler.apply(portalEvent);
if (!eventHandled) {
this.logger.debug("Aggregation stop requested before processing event {}", portalEvent);
return false;
}
// Mark the event as aggregated and store the mark
persistentPortalEvent.setAggregated(true);
session.persist(persistentPortalEvent);
// periodic flush and clear of session to manage memory demands
if (++resultCount % this.flushPeriod == 0) {
this.logger.debug("Aggregated {} events, flush and clear {} EntityManager.", resultCount, BaseRawEventsJpaDao.PERSISTENCE_UNIT_NAME);
session.flush();
session.clear();
}
} catch (Exception e) {
this.logger.warn("Failed to aggregate portal event: " + persistentPortalEvent, e);
// mark the event as erred and move on. This will not be picked up by processing
// again
persistentPortalEvent.setErrorAggregating(true);
session.persist(persistentPortalEvent);
}
}
return true;
}
Aggregations