You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2016/11/22 18:02:19 UTC

svn commit: r1770865 - in /openmeetings/application: branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/ branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/ branches/3.1.x/openmeetings-...

Author: solomax
Date: Tue Nov 22 18:02:19 2016
New Revision: 1770865

URL: http://svn.apache.org/viewvc?rev=1770865&view=rev
Log:
[OPENMEETINGS-1488] recording reminder/clean-up is improved

Added:
    openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java
Modified:
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java
    openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
    openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
    openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
    openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java
    openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java Tue Nov 22 18:02:19 2016
@@ -176,11 +176,12 @@ public class RecordingDao {
 		return null;
 	}
 
-	public List<Recording> getExpiring(Long groupId, int reminderDays) {
+	public List<Recording> getExpiring(Long groupId, int reminderDays, boolean notified) {
 		Instant date = Instant.now().minus(Duration.ofDays(reminderDays));
 		return em.createNamedQuery("getExpiringRecordings", Recording.class)
 				.setParameter("groupId", groupId)
 				.setParameter("date", Date.from(date))
+				.setParameter("notified", notified)
 				.getResultList();
 	}
 

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java Tue Nov 22 18:02:19 2016
@@ -97,7 +97,7 @@ import org.simpleframework.xml.Root;
 			+ "WHERE rec.deleted = false AND rec.roomId = r.id AND rec.insertedBy = u.id "
 			+ "AND (r.externalType = :externalType OR u.externalType = :externalType)")
 	, @NamedQuery(name = "getExpiringRecordings", query = "SELECT DISTINCT rec FROM Recording rec "
-			+ "WHERE rec.deleted = false AND rec.notified = false AND rec.inserted < :date "
+			+ "WHERE rec.deleted = false AND rec.notified = :notified AND rec.inserted < :date "
 			+ "  AND (rec.groupId = :groupId "
 			+ "    OR rec.ownerId IN (SELECT gu.user.id FROM GroupUser gu WHERE gu.group.id = :groupId)"
 			+ "    OR rec.roomId IN (SELECT rg.room.id FROM RoomGroup rg WHERE rg.group.id = :groupId)"

Added: openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java?rev=1770865&view=auto
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java (added)
+++ openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java Tue Nov 22 18:02:19 2016
@@ -0,0 +1,58 @@
+/*
+ * 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.openmeetings.service.quartz.scheduler;
+
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.function.BiConsumer;
+
+import org.apache.openmeetings.db.dao.record.RecordingDao;
+import org.apache.openmeetings.db.dao.user.GroupDao;
+import org.apache.openmeetings.db.entity.record.Recording;
+import org.apache.openmeetings.db.entity.user.Group;
+import org.apache.openmeetings.util.InitializationContainer;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractJob {
+	private static Logger log = Red5LoggerFactory.getLogger(AbstractJob.class, webAppRootKey);
+	@Autowired
+	private GroupDao groupDao;
+	@Autowired
+	RecordingDao recordingDao;
+
+	void processExpiringRecordings(boolean notified, BiConsumer<Recording, Long> consumer) {
+		if (!InitializationContainer.initComplete) {
+			return;
+		}
+		for (Group g : groupDao.getLimited()) {
+			for (Recording rec : recordingDao.getExpiring(g.getId(), g.getReminderDays(), notified)) {
+				try {
+					long days = g.getRecordingTtl() - ChronoUnit.DAYS.between(rec.getInserted().toInstant(), Instant.now());
+					consumer.accept(rec, days);
+				} catch (Exception e) {
+					log.error("Uexpected exception while processing expiring recordings emails", e);
+				}
+			}
+		}
+	}
+}

Modified: openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java Tue Nov 22 18:02:19 2016
@@ -18,7 +18,12 @@
  */
 package org.apache.openmeetings.service.quartz.scheduler;
 
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_AVI;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_FLV;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_OGG;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+
 import java.io.File;
 import java.io.FileFilter;
 
@@ -29,7 +34,7 @@ import org.red5.logging.Red5LoggerFactor
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
-public class CleanupJob {
+public class CleanupJob extends AbstractJob {
 	private static Logger log = Red5LoggerFactory.getLogger(CleanupJob.class, webAppRootKey);
 	private long sessionTimeout = 30 * 60 * 1000L;
 	private long testSetupTimeout = 60 * 60 * 1000L; // 1 hour
@@ -37,6 +42,22 @@ public class CleanupJob {
 	@Autowired
 	private SessiondataDao sessiondataDao;
 
+	public long getSessionTimeout() {
+		return sessionTimeout;
+	}
+
+	public void setSessionTimeout(long sessionTimeout) {
+		this.sessionTimeout = sessionTimeout;
+	}
+
+	public long getTestSetupTimeout() {
+		return testSetupTimeout;
+	}
+
+	public void setTestSetupTimeout(long testSetupTimeout) {
+		this.testSetupTimeout = testSetupTimeout;
+	}
+
 	public void cleanTestSetup() {
 		log.debug("CleanupJob.execute");
 		if (!InitializationContainer.initComplete) {
@@ -72,7 +93,7 @@ public class CleanupJob {
 	}
 
 	public void cleanSessions() {
-		log.trace("SessionClearJob.execute");
+		log.trace("CleanupJob.cleanSessions");
 		if (!InitializationContainer.initComplete) {
 			return;
 		}
@@ -84,19 +105,17 @@ public class CleanupJob {
 		}
 	}
 
-	public long getSessionTimeout() {
-		return sessionTimeout;
-	}
-
-	public void setSessionTimeout(long sessionTimeout) {
-		this.sessionTimeout = sessionTimeout;
-	}
-
-	public long getTestSetupTimeout() {
-		return testSetupTimeout;
-	}
-
-	public void setTestSetupTimeout(long testSetupTimeout) {
-		this.testSetupTimeout = testSetupTimeout;
+	public void cleanExpiredRecordings() {
+		log.debug("CleanupJob.cleanExpiredRecordings");
+		processExpiringRecordings(true, (rec, days) -> {
+			if (days < 0) {
+				log.debug("cleanExpiredRecordings:: following recording will be deleted {}", rec);
+				rec.getFile(EXTENSION_MP4).delete();
+				rec.getFile(EXTENSION_FLV).delete();
+				rec.getFile(EXTENSION_AVI).delete();
+				rec.getFile(EXTENSION_OGG).delete();
+				recordingDao.delete(rec);
+			}
+		});
 	}
 }

Modified: openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java Tue Nov 22 18:02:19 2016
@@ -20,15 +20,8 @@ package org.apache.openmeetings.service.
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 
-import java.time.Instant;
-import java.time.temporal.ChronoUnit;
-
 import org.apache.openmeetings.core.mail.MailHandler;
-import org.apache.openmeetings.db.dao.record.RecordingDao;
-import org.apache.openmeetings.db.dao.user.GroupDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
-import org.apache.openmeetings.db.entity.record.Recording;
-import org.apache.openmeetings.db.entity.user.Group;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.service.calendar.AppointmentLogic;
 import org.apache.openmeetings.service.mail.template.subject.AbstractSubjectEmailTemplate;
@@ -38,15 +31,11 @@ import org.red5.logging.Red5LoggerFactor
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
-public class ReminderJob {
+public class ReminderJob extends AbstractJob {
 	private static Logger log = Red5LoggerFactory.getLogger(ReminderJob.class, webAppRootKey);
 	@Autowired
 	private AppointmentLogic appointmentLogic;
 	@Autowired
-	private RecordingDao recordingDao;
-	@Autowired
-	private GroupDao groupDao;
-	@Autowired
 	private UserDao userDao;
 	@Autowired
 	private MailHandler mailHandler;
@@ -65,31 +54,20 @@ public class ReminderJob {
 
 	public void remindExpiringRecordings() {
 		log.debug("ReminderJob.remindExpiringRecordings");
-		if (!InitializationContainer.initComplete) {
-			return;
-		}
-		for (Group g : groupDao.getLimited()) {
-			for (Recording rec : recordingDao.getExpiring(g.getId(), g.getReminderDays())) {
-				try {
-					long days = g.getRecordingTtl() - ChronoUnit.DAYS.between(rec.getInserted().toInstant(), Instant.now());
-					if (days > 0) {
-						User u = userDao.get(rec.getOwnerId());
-						if (u == null) {
-							log.debug("Unable to send expiration email due to recording owner is NULL, {}", rec);
-							continue;
-						} else {
-							AbstractSubjectEmailTemplate templ = RecordingExpiringTemplate.get(u, rec, days);
-							mailHandler.send(u.getAddress().getEmail(), templ.getSubject(), templ.getEmail());
-						}
-					} else {
-						log.debug("Recording is too old to send notification, {} days", days);
-					}
-					rec.setNotified(true);
-					recordingDao.update(rec);
-				} catch (Exception e) {
-					log.error("Uexpected exception while sending expiring recordings emails", e);
+		processExpiringRecordings(false, (rec, days) -> {
+			if (days > 0) {
+				User u = userDao.get(rec.getOwnerId());
+				if (u == null) {
+					log.debug("Unable to send expiration email due to recording owner is NULL, {}", rec);
+				} else {
+					AbstractSubjectEmailTemplate templ = RecordingExpiringTemplate.get(u, rec, days);
+					mailHandler.send(u.getAddress().getEmail(), templ.getSubject(), templ.getEmail());
 				}
+			} else {
+				log.debug("Recording is too old to send notification, {} days", days);
 			}
-		}
+			rec.setNotified(true);
+			recordingDao.update(rec);
+		});
 	}
 }

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml Tue Nov 22 18:02:19 2016
@@ -119,6 +119,16 @@
 		<property name="startDelay" value="1800000"/><!-- 30 minutes --> 
 		<property name="repeatInterval" value="1800000"/> <!-- 30 minutes -->
 	</bean>
+	<bean id="cleanExpiredRecJobDetails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
+		<property name="targetObject" ref="cleanupJob" />
+		<property name="targetMethod" value="cleanExpiredRecordings" />
+		<property name="concurrent" value="false" />
+	</bean>
+	<bean id="triggerCleanExpiredRec" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
+		<property name="jobDetail" ref="cleanExpiredRecJobDetails" />
+		<property name="startDelay" value="5000"/><!-- 5 seconds -->
+		<property name="repeatInterval" value="3600000" /><!-- 1 hour -->
+	</bean>
 
 	<bean id="reminderJob" class="org.apache.openmeetings.service.quartz.scheduler.ReminderJob"/>
 	<bean id="meetingReminderJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
@@ -170,6 +180,7 @@
 			<list>
 				<ref bean="triggerCleanSessions" />
 				<ref bean="triggerCleanTestSetup" />
+				<ref bean="triggerCleanExpiredRec" />
 				<ref bean="triggerMeetingReminder" />
 				<ref bean="triggerExpiringRecording" />
 				<ref bean="triggerResetSendingMailStatus" />

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java Tue Nov 22 18:02:19 2016
@@ -176,11 +176,12 @@ public class RecordingDao {
 		return null;
 	}
 
-	public List<Recording> getExpiring(Long groupId, int reminderDays) {
+	public List<Recording> getExpiring(Long groupId, int reminderDays, boolean notified) {
 		Instant date = Instant.now().minus(Duration.ofDays(reminderDays));
 		return em.createNamedQuery("getExpiringRecordings", Recording.class)
 				.setParameter("groupId", groupId)
 				.setParameter("date", Date.from(date))
+				.setParameter("notified", notified)
 				.getResultList();
 	}
 

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java Tue Nov 22 18:02:19 2016
@@ -91,7 +91,7 @@ import org.simpleframework.xml.Root;
 			+ "WHERE rec.deleted = false AND rec.roomId = r.id AND rec.insertedBy = u.id "
 			+ "AND (r.externalType = :externalType OR u.externalType = :externalType)")
 	, @NamedQuery(name = "getExpiringRecordings", query = "SELECT DISTINCT rec FROM Recording rec "
-			+ "WHERE rec.deleted = false AND rec.notified = false AND rec.inserted < :date "
+			+ "WHERE rec.deleted = false AND rec.notified = :notified AND rec.inserted < :date "
 			+ "  AND (rec.groupId = :groupId "
 			+ "    OR rec.ownerId IN (SELECT gu.user.id FROM GroupUser gu WHERE gu.group.id = :groupId)"
 			+ "    OR rec.roomId IN (SELECT rg.room.id FROM RoomGroup rg WHERE rg.group.id = :groupId)"

Added: openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java?rev=1770865&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java Tue Nov 22 18:02:19 2016
@@ -0,0 +1,58 @@
+/*
+ * 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.openmeetings.service.quartz.scheduler;
+
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.function.BiConsumer;
+
+import org.apache.openmeetings.db.dao.record.RecordingDao;
+import org.apache.openmeetings.db.dao.user.GroupDao;
+import org.apache.openmeetings.db.entity.record.Recording;
+import org.apache.openmeetings.db.entity.user.Group;
+import org.apache.openmeetings.util.InitializationContainer;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractJob {
+	private static Logger log = Red5LoggerFactory.getLogger(AbstractJob.class, webAppRootKey);
+	@Autowired
+	private GroupDao groupDao;
+	@Autowired
+	RecordingDao recordingDao;
+
+	void processExpiringRecordings(boolean notified, BiConsumer<Recording, Long> consumer) {
+		if (!InitializationContainer.initComplete) {
+			return;
+		}
+		for (Group g : groupDao.getLimited()) {
+			for (Recording rec : recordingDao.getExpiring(g.getId(), g.getReminderDays(), notified)) {
+				try {
+					long days = g.getRecordingTtl() - ChronoUnit.DAYS.between(rec.getInserted().toInstant(), Instant.now());
+					consumer.accept(rec, days);
+				} catch (Exception e) {
+					log.error("Uexpected exception while processing expiring recordings emails", e);
+				}
+			}
+		}
+	}
+}

Modified: openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java Tue Nov 22 18:02:19 2016
@@ -18,7 +18,12 @@
  */
 package org.apache.openmeetings.service.quartz.scheduler;
 
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_AVI;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_FLV;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_OGG;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+
 import java.io.File;
 import java.io.FileFilter;
 
@@ -29,7 +34,7 @@ import org.red5.logging.Red5LoggerFactor
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
-public class CleanupJob {
+public class CleanupJob extends AbstractJob {
 	private static Logger log = Red5LoggerFactory.getLogger(CleanupJob.class, webAppRootKey);
 	private long sessionTimeout = 30 * 60 * 1000L;
 	private long testSetupTimeout = 60 * 60 * 1000L; // 1 hour
@@ -37,6 +42,22 @@ public class CleanupJob {
 	@Autowired
 	private SessiondataDao sessiondataDao;
 
+	public long getSessionTimeout() {
+		return sessionTimeout;
+	}
+
+	public void setSessionTimeout(long sessionTimeout) {
+		this.sessionTimeout = sessionTimeout;
+	}
+
+	public long getTestSetupTimeout() {
+		return testSetupTimeout;
+	}
+
+	public void setTestSetupTimeout(long testSetupTimeout) {
+		this.testSetupTimeout = testSetupTimeout;
+	}
+
 	public void cleanTestSetup() {
 		log.debug("CleanupJob.execute");
 		if (!InitializationContainer.initComplete) {
@@ -72,7 +93,7 @@ public class CleanupJob {
 	}
 
 	public void cleanSessions() {
-		log.trace("SessionClearJob.execute");
+		log.trace("CleanupJob.cleanSessions");
 		if (!InitializationContainer.initComplete) {
 			return;
 		}
@@ -84,19 +105,17 @@ public class CleanupJob {
 		}
 	}
 
-	public long getSessionTimeout() {
-		return sessionTimeout;
-	}
-
-	public void setSessionTimeout(long sessionTimeout) {
-		this.sessionTimeout = sessionTimeout;
-	}
-
-	public long getTestSetupTimeout() {
-		return testSetupTimeout;
-	}
-
-	public void setTestSetupTimeout(long testSetupTimeout) {
-		this.testSetupTimeout = testSetupTimeout;
+	public void cleanExpiredRecordings() {
+		log.debug("CleanupJob.cleanExpiredRecordings");
+		processExpiringRecordings(true, (rec, days) -> {
+			if (days < 0) {
+				log.debug("cleanExpiredRecordings:: following recording will be deleted {}", rec);
+				rec.getFile(EXTENSION_MP4).delete();
+				rec.getFile(EXTENSION_FLV).delete();
+				rec.getFile(EXTENSION_AVI).delete();
+				rec.getFile(EXTENSION_OGG).delete();
+				recordingDao.delete(rec);
+			}
+		});
 	}
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java Tue Nov 22 18:02:19 2016
@@ -20,24 +20,25 @@ package org.apache.openmeetings.service.
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 
-import org.apache.openmeetings.db.dao.record.RecordingDao;
-import org.apache.openmeetings.db.dao.user.GroupDao;
-import org.apache.openmeetings.db.entity.record.Recording;
-import org.apache.openmeetings.db.entity.user.Group;
+import org.apache.openmeetings.core.mail.MailHandler;
+import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.service.calendar.AppointmentLogic;
+import org.apache.openmeetings.service.mail.template.subject.AbstractSubjectEmailTemplate;
+import org.apache.openmeetings.service.mail.template.subject.RecordingExpiringTemplate;
 import org.apache.openmeetings.util.InitializationContainer;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
-public class ReminderJob {
+public class ReminderJob extends AbstractJob {
 	private static Logger log = Red5LoggerFactory.getLogger(ReminderJob.class, webAppRootKey);
 	@Autowired
 	private AppointmentLogic appointmentLogic;
 	@Autowired
-	private RecordingDao recordingDao;
+	private UserDao userDao;
 	@Autowired
-	private GroupDao groupDao;
+	private MailHandler mailHandler;
 
 	public void remindMeetings() {
 		log.debug("ReminderJob.remindMeetings");
@@ -53,13 +54,20 @@ public class ReminderJob {
 
 	public void remindExpiringRecordings() {
 		log.debug("ReminderJob.remindExpiringRecordings");
-		if (!InitializationContainer.initComplete) {
-			return;
-		}
-		for (Group g : groupDao.getLimited()) {
-			for (Recording rec : recordingDao.getExpiring(g.getId(), g.getReminderDays())) {
-				int i = 1;
+		processExpiringRecordings(false, (rec, days) -> {
+			if (days > 0) {
+				User u = userDao.get(rec.getOwnerId());
+				if (u == null) {
+					log.debug("Unable to send expiration email due to recording owner is NULL, {}", rec);
+				} else {
+					AbstractSubjectEmailTemplate templ = RecordingExpiringTemplate.get(u, rec, days);
+					mailHandler.send(u.getAddress().getEmail(), templ.getSubject(), templ.getEmail());
+				}
+			} else {
+				log.debug("Recording is too old to send notification, {} days", days);
 			}
-		}
+			rec.setNotified(true);
+			recordingDao.update(rec);
+		});
 	}
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml Tue Nov 22 18:02:19 2016
@@ -115,6 +115,16 @@
 		<property name="startDelay" value="1800000"/><!-- 30 minutes --> 
 		<property name="repeatInterval" value="1800000"/> <!-- 30 minutes -->
 	</bean>
+	<bean id="cleanExpiredRecJobDetails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
+		<property name="targetObject" ref="cleanupJob" />
+		<property name="targetMethod" value="cleanExpiredRecordings" />
+		<property name="concurrent" value="false" />
+	</bean>
+	<bean id="triggerCleanExpiredRec" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
+		<property name="jobDetail" ref="cleanExpiredRecJobDetails" />
+		<property name="startDelay" value="5000"/><!-- 5 seconds -->
+		<property name="repeatInterval" value="3600000" /><!-- 1 hour -->
+	</bean>
 
 	<bean id="reminderJob" class="org.apache.openmeetings.service.quartz.scheduler.ReminderJob"/>
 	<bean id="meetingReminderJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
@@ -166,6 +176,7 @@
 			<list>
 				<ref bean="triggerCleanSessions" />
 				<ref bean="triggerCleanTestSetup" />
+				<ref bean="triggerCleanExpiredRec" />
 				<ref bean="triggerMeetingReminder" />
 				<ref bean="triggerExpiringRecording" />
 				<ref bean="triggerResetSendingMailStatus" />

Modified: openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java (original)
+++ openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/record/RecordingDao.java Tue Nov 22 18:02:19 2016
@@ -176,11 +176,12 @@ public class RecordingDao {
 		return null;
 	}
 
-	public List<Recording> getExpiring(Long groupId, int reminderDays) {
+	public List<Recording> getExpiring(Long groupId, int reminderDays, boolean notified) {
 		Instant date = Instant.now().minus(Duration.ofDays(reminderDays));
 		return em.createNamedQuery("getExpiringRecordings", Recording.class)
 				.setParameter("groupId", groupId)
 				.setParameter("date", Date.from(date))
+				.setParameter("notified", notified)
 				.getResultList();
 	}
 

Modified: openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java (original)
+++ openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/record/Recording.java Tue Nov 22 18:02:19 2016
@@ -91,7 +91,7 @@ import org.simpleframework.xml.Root;
 			+ "WHERE rec.deleted = false AND rec.roomId = r.id AND rec.insertedBy = u.id "
 			+ "AND (r.externalType = :externalType OR u.externalType = :externalType)")
 	, @NamedQuery(name = "getExpiringRecordings", query = "SELECT DISTINCT rec FROM Recording rec "
-			+ "WHERE rec.deleted = false AND rec.notified = false AND rec.inserted < :date "
+			+ "WHERE rec.deleted = false AND rec.notified = :notified AND rec.inserted < :date "
 			+ "  AND (rec.groupId = :groupId "
 			+ "    OR rec.ownerId IN (SELECT gu.user.id FROM GroupUser gu WHERE gu.group.id = :groupId)"
 			+ "    OR rec.roomId IN (SELECT rg.room.id FROM RoomGroup rg WHERE rg.group.id = :groupId)"

Added: openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java?rev=1770865&view=auto
==============================================================================
--- openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java (added)
+++ openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/AbstractJob.java Tue Nov 22 18:02:19 2016
@@ -0,0 +1,58 @@
+/*
+ * 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.openmeetings.service.quartz.scheduler;
+
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.function.BiConsumer;
+
+import org.apache.openmeetings.db.dao.record.RecordingDao;
+import org.apache.openmeetings.db.dao.user.GroupDao;
+import org.apache.openmeetings.db.entity.record.Recording;
+import org.apache.openmeetings.db.entity.user.Group;
+import org.apache.openmeetings.util.InitializationContainer;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractJob {
+	private static Logger log = Red5LoggerFactory.getLogger(AbstractJob.class, webAppRootKey);
+	@Autowired
+	private GroupDao groupDao;
+	@Autowired
+	RecordingDao recordingDao;
+
+	void processExpiringRecordings(boolean notified, BiConsumer<Recording, Long> consumer) {
+		if (!InitializationContainer.initComplete) {
+			return;
+		}
+		for (Group g : groupDao.getLimited()) {
+			for (Recording rec : recordingDao.getExpiring(g.getId(), g.getReminderDays(), notified)) {
+				try {
+					long days = g.getRecordingTtl() - ChronoUnit.DAYS.between(rec.getInserted().toInstant(), Instant.now());
+					consumer.accept(rec, days);
+				} catch (Exception e) {
+					log.error("Uexpected exception while processing expiring recordings emails", e);
+				}
+			}
+		}
+	}
+}

Modified: openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java (original)
+++ openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/CleanupJob.java Tue Nov 22 18:02:19 2016
@@ -18,7 +18,12 @@
  */
 package org.apache.openmeetings.service.quartz.scheduler;
 
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_AVI;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_FLV;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_MP4;
+import static org.apache.openmeetings.util.OmFileHelper.EXTENSION_OGG;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+
 import java.io.File;
 import java.io.FileFilter;
 
@@ -29,7 +34,7 @@ import org.red5.logging.Red5LoggerFactor
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
-public class CleanupJob {
+public class CleanupJob extends AbstractJob {
 	private static Logger log = Red5LoggerFactory.getLogger(CleanupJob.class, webAppRootKey);
 	private long sessionTimeout = 30 * 60 * 1000L;
 	private long testSetupTimeout = 60 * 60 * 1000L; // 1 hour
@@ -37,6 +42,22 @@ public class CleanupJob {
 	@Autowired
 	private SessiondataDao sessiondataDao;
 
+	public long getSessionTimeout() {
+		return sessionTimeout;
+	}
+
+	public void setSessionTimeout(long sessionTimeout) {
+		this.sessionTimeout = sessionTimeout;
+	}
+
+	public long getTestSetupTimeout() {
+		return testSetupTimeout;
+	}
+
+	public void setTestSetupTimeout(long testSetupTimeout) {
+		this.testSetupTimeout = testSetupTimeout;
+	}
+
 	public void cleanTestSetup() {
 		log.debug("CleanupJob.execute");
 		if (!InitializationContainer.initComplete) {
@@ -72,7 +93,7 @@ public class CleanupJob {
 	}
 
 	public void cleanSessions() {
-		log.trace("SessionClearJob.execute");
+		log.trace("CleanupJob.cleanSessions");
 		if (!InitializationContainer.initComplete) {
 			return;
 		}
@@ -84,19 +105,17 @@ public class CleanupJob {
 		}
 	}
 
-	public long getSessionTimeout() {
-		return sessionTimeout;
-	}
-
-	public void setSessionTimeout(long sessionTimeout) {
-		this.sessionTimeout = sessionTimeout;
-	}
-
-	public long getTestSetupTimeout() {
-		return testSetupTimeout;
-	}
-
-	public void setTestSetupTimeout(long testSetupTimeout) {
-		this.testSetupTimeout = testSetupTimeout;
+	public void cleanExpiredRecordings() {
+		log.debug("CleanupJob.cleanExpiredRecordings");
+		processExpiringRecordings(true, (rec, days) -> {
+			if (days < 0) {
+				log.debug("cleanExpiredRecordings:: following recording will be deleted {}", rec);
+				rec.getFile(EXTENSION_MP4).delete();
+				rec.getFile(EXTENSION_FLV).delete();
+				rec.getFile(EXTENSION_AVI).delete();
+				rec.getFile(EXTENSION_OGG).delete();
+				recordingDao.delete(rec);
+			}
+		});
 	}
 }

Modified: openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java (original)
+++ openmeetings/application/trunk/openmeetings-service/src/main/java/org/apache/openmeetings/service/quartz/scheduler/ReminderJob.java Tue Nov 22 18:02:19 2016
@@ -20,24 +20,25 @@ package org.apache.openmeetings.service.
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 
-import org.apache.openmeetings.db.dao.record.RecordingDao;
-import org.apache.openmeetings.db.dao.user.GroupDao;
-import org.apache.openmeetings.db.entity.record.Recording;
-import org.apache.openmeetings.db.entity.user.Group;
+import org.apache.openmeetings.core.mail.MailHandler;
+import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.service.calendar.AppointmentLogic;
+import org.apache.openmeetings.service.mail.template.subject.AbstractSubjectEmailTemplate;
+import org.apache.openmeetings.service.mail.template.subject.RecordingExpiringTemplate;
 import org.apache.openmeetings.util.InitializationContainer;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
-public class ReminderJob {
+public class ReminderJob extends AbstractJob {
 	private static Logger log = Red5LoggerFactory.getLogger(ReminderJob.class, webAppRootKey);
 	@Autowired
 	private AppointmentLogic appointmentLogic;
 	@Autowired
-	private RecordingDao recordingDao;
+	private UserDao userDao;
 	@Autowired
-	private GroupDao groupDao;
+	private MailHandler mailHandler;
 
 	public void remindMeetings() {
 		log.debug("ReminderJob.remindMeetings");
@@ -53,13 +54,20 @@ public class ReminderJob {
 
 	public void remindExpiringRecordings() {
 		log.debug("ReminderJob.remindExpiringRecordings");
-		if (!InitializationContainer.initComplete) {
-			return;
-		}
-		for (Group g : groupDao.getLimited()) {
-			for (Recording rec : recordingDao.getExpiring(g.getId(), g.getReminderDays())) {
-				int i = 1;
+		processExpiringRecordings(false, (rec, days) -> {
+			if (days > 0) {
+				User u = userDao.get(rec.getOwnerId());
+				if (u == null) {
+					log.debug("Unable to send expiration email due to recording owner is NULL, {}", rec);
+				} else {
+					AbstractSubjectEmailTemplate templ = RecordingExpiringTemplate.get(u, rec, days);
+					mailHandler.send(u.getAddress().getEmail(), templ.getSubject(), templ.getEmail());
+				}
+			} else {
+				log.debug("Recording is too old to send notification, {} days", days);
 			}
-		}
+			rec.setNotified(true);
+			recordingDao.update(rec);
+		});
 	}
 }

Modified: openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml?rev=1770865&r1=1770864&r2=1770865&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/webapp/WEB-INF/classes/openmeetings-applicationContext.xml Tue Nov 22 18:02:19 2016
@@ -113,6 +113,16 @@
 		<property name="startDelay" value="1800000"/><!-- 30 minutes --> 
 		<property name="repeatInterval" value="1800000"/> <!-- 30 minutes -->
 	</bean>
+	<bean id="cleanExpiredRecJobDetails" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
+		<property name="targetObject" ref="cleanupJob" />
+		<property name="targetMethod" value="cleanExpiredRecordings" />
+		<property name="concurrent" value="false" />
+	</bean>
+	<bean id="triggerCleanExpiredRec" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
+		<property name="jobDetail" ref="cleanExpiredRecJobDetails" />
+		<property name="startDelay" value="5000"/><!-- 5 seconds -->
+		<property name="repeatInterval" value="3600000" /><!-- 1 hour -->
+	</bean>
 
 	<bean id="reminderJob" class="org.apache.openmeetings.service.quartz.scheduler.ReminderJob"/>
 	<bean id="meetingReminderJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
@@ -164,6 +174,7 @@
 			<list>
 				<ref bean="triggerCleanSessions" />
 				<ref bean="triggerCleanTestSetup" />
+				<ref bean="triggerCleanExpiredRec" />
 				<ref bean="triggerMeetingReminder" />
 				<ref bean="triggerExpiringRecording" />
 				<ref bean="triggerResetSendingMailStatus" />