/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.course.statistic;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.hibernate.FlushMode;
import org.junit.Assert;
import org.olat.core.commons.persistence.DB;
import org.olat.core.logging.activity.LoggingObject;
import org.olat.core.util.CodeHelper;
import org.olat.course.nodes.CourseNode;
import org.olat.course.statistic.daily.DailyStat;
import org.olat.course.statistic.dayofweek.DayOfWeekStat;
import org.olat.course.statistic.hourofday.HourOfDayStat;
import org.olat.course.statistic.weekly.WeeklyStat;
import org.olat.properties.Property;
import org.olat.properties.PropertyManager;
import org.olat.repository.RepositoryEntry;
import org.olat.test.OlatTestCase;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 5 mai 2017<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
abstract class AbstractStatisticUpdateManagerTest extends OlatTestCase {
private Map<String,Map<String,AtomicInteger>> inMemoryStatistics = new HashMap<>();
@Autowired
protected DB dbInstance;
@Autowired
protected StatisticUpdateManager statisticUpdateManager;
protected void cleanUpLog() {
String deleteLogQuery = "delete from " + LoggingObject.class.getName() + " log";
dbInstance.createQuery(deleteLogQuery)
.executeUpdate(FlushMode.AUTO);
String deleteDailyQuery = "delete from " + DailyStat.class.getName() + " log";
dbInstance.createQuery(deleteDailyQuery)
.executeUpdate(FlushMode.AUTO);
String deleteWeeklyQuery = "delete from " + WeeklyStat.class.getName() + " log";
dbInstance.createQuery(deleteWeeklyQuery)
.executeUpdate(FlushMode.AUTO);
String deleteDayOfWeekQuery = "delete from " + DayOfWeekStat.class.getName() + " log";
dbInstance.createQuery(deleteDayOfWeekQuery)
.executeUpdate(FlushMode.AUTO);
String deleteHourOfDayQuery = "delete from " + HourOfDayStat.class.getName() + " log";
dbInstance.createQuery(deleteHourOfDayQuery)
.executeUpdate(FlushMode.AUTO);
dbInstance.commitAndCloseSession();
}
protected void incrementInMemoryStatistics(Long repositoryEntryKey, String nodeIdent, String date) {
String key = repositoryEntryKey + "- "+ nodeIdent;
Map<String,AtomicInteger> node = inMemoryStatistics.get(key);
if(node == null) {
node = new HashMap<>();
inMemoryStatistics.put(key, node);
}
AtomicInteger counter = node.get(date);
if(counter == null) {
counter = new AtomicInteger(0);
node.put(date, counter);
}
counter.incrementAndGet();
}
protected Integer getInMemoryStatistics(RepositoryEntry repositoryEntry, CourseNode courseNode, String date) {
String key = repositoryEntry.getKey() + "- "+ courseNode.getIdent();
Map<String,AtomicInteger> node = inMemoryStatistics.get(key);
if(node == null) {
return null;
}
AtomicInteger counter = node.get(date);
return counter == null ? null : new Integer(counter.get());
}
protected void updateStatistics() {
StatisticsWait countDown = new StatisticsWait();
statisticUpdateManager.updateStatistics(false, countDown);
countDown.waitStatistics();
}
protected void updateAllStatistics() {
StatisticsWait countDown = new StatisticsWait();
statisticUpdateManager.updateStatistics(true, countDown);
countDown.waitStatistics();
}
protected Calendar addLog(Long repositoryEntryKey, String courseNodeIdent, Calendar start, int dayInPast, int hour, int minute, int second) {
String sessionId = "session-" + CodeHelper.getGlobalForeverUniqueID();
LoggingObject logObj = new LoggingObject(sessionId, 123l, "logger", "u", "launch", "node");
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, start.get(Calendar.YEAR));
cal.set(Calendar.MONTH, start.get(Calendar.MONTH));
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
cal.set(Calendar.SECOND, second);
if(dayInPast > 0) {
cal.add(Calendar.DATE, -dayInPast);
}
logObj.setCreationDate(cal.getTime());
logObj.setResourceAdminAction(Boolean.FALSE);
logObj.setUserProperty2("OpenOLAT");
logObj.setUserProperty3("openolat@openolat.org");
logObj.setBusinessPath("[RepositoryEntry:" + repositoryEntryKey + "][CourseNode:" + courseNodeIdent + "]");
dbInstance.saveObject(logObj);
return cal;
}
protected void setLastUpdate(Calendar ref, int dayInThePast) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, ref.get(Calendar.YEAR));
cal.set(Calendar.MONTH, ref.get(Calendar.MONTH));
cal.set(Calendar.DATE, 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.add(Calendar.DATE, -dayInThePast);
long lastUpdated = cal.getTimeInMillis();
PropertyManager pm = PropertyManager.getInstance();
Property p = pm.findProperty(null, null, null, "STATISTICS_PROPERTIES", "LAST_UPDATED");
if(p == null) {
p = pm.createPropertyInstance(null, null, null, "STATISTICS_PROPERTIES", "LAST_UPDATED", null, lastUpdated, null, null);
} else {
p.setLongValue(lastUpdated);
}
pm.saveProperty(p);
}
public static class StatisticsWait implements Runnable {
private CountDownLatch countDown = new CountDownLatch(1);
@Override
public void run() {
countDown.countDown();
}
public void waitStatistics() {
try {
countDown.await(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Assert.fail("Test takes too long (more than 10s)");
}
}
}
}