From c3fbc87974a11feb4719ce90bfaf73e6cd852264 Mon Sep 17 00:00:00 2001
From: fkiefer <none@none>
Date: Wed, 1 Feb 2017 13:38:04 +0100
Subject: [PATCH] OO-2454 Upgrader 11_3_0 fixes

---
 .../org/olat/modules/video/VideoManager.java  | 55 ++++++++++++
 .../video/manager/VideoManagerImpl.java       | 57 +++++++++++-
 .../video/manager/VideoTranscodingDAO.java    | 87 ++++++++++++++++++-
 .../org/olat/upgrade/OLATUpgrade_11_3_0.java  | 69 +++++++++------
 4 files changed, 237 insertions(+), 31 deletions(-)

diff --git a/src/main/java/org/olat/modules/video/VideoManager.java b/src/main/java/org/olat/modules/video/VideoManager.java
index 2a0470e58cd..2118d8ddc1b 100644
--- a/src/main/java/org/olat/modules/video/VideoManager.java
+++ b/src/main/java/org/olat/modules/video/VideoManager.java
@@ -45,6 +45,14 @@ import org.olat.resource.OLATResource;
  */
 public interface VideoManager {
 	
+	/**
+	 * Checks for video file.
+	 *
+	 * @param videoResource the video resource
+	 * @return true, if successful
+	 */
+	public abstract boolean hasVideoFile(OLATResource videoResource);
+	
 	/**
 	 * get Videofile as File representation
 	 * @param videoResource
@@ -158,6 +166,22 @@ public interface VideoManager {
 	 * @return the all video transcodings
 	 */
 	public abstract List<TranscodingCount> getAllVideoTranscodingsCount();
+	
+	/**
+	 * Gets the all video transcodings count success.
+	 *
+	 * @param errorcode the errorcode
+	 * @return the all video transcodings count success
+	 */
+	public List<TranscodingCount> getAllVideoTranscodingsCountSuccess(int errorcode);
+
+	/**
+	 * Gets the all video transcodings count fails.
+	 *
+	 * @param errorcode the errorcode
+	 * @return the all video transcodings count fails
+	 */
+	public List<TranscodingCount> getAllVideoTranscodingsCountFails(int errorcode);
 
 	/**
 	 * Get a human readable aspect ratio from the given video size. Recognizes
@@ -274,6 +298,13 @@ public interface VideoManager {
 	 */
 	public abstract List<VideoTranscoding> getVideoTranscodingsPendingAndInProgress();
 	
+	/**
+	 * Gets the failed video transcodings.
+	 *
+	 * @return list of failed VideoTranscoding
+	 */
+	public abstract List<VideoTranscoding> getFailedVideoTranscodings();
+	
 	/**
 	 * Returns a list with 
 	 * @param videoResource
@@ -399,5 +430,29 @@ public interface VideoManager {
 	 * @param video the video
 	 */
 	public void startTranscodingProcessIfEnabled(OLATResource video);
+	
+	/**
+	 * Retranscode failed video transcoding.
+	 *
+	 * @param videoTranscoding
+	 * @return 
+	 */
+	public VideoTranscoding retranscodeFailedVideoTranscoding(VideoTranscoding videoTranscoding);
+
+	/**
+	 * Checks if is metadata file valid.
+	 *
+	 * @param videoResource
+	 * @return true, if is metadata file valid
+	 */
+	public boolean isMetadataFileValid(OLATResource videoResource);
+
+	/**
+	 * Checks for master container.
+	 *
+	 * @param videoResource
+	 * @return true, if master container can be resolved
+	 */
+	boolean hasMasterContainer(OLATResource videoResource);
 
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java b/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java
index a8504c6bc0f..4af421c20d3 100644
--- a/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java
+++ b/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java
@@ -324,10 +324,23 @@ public class VideoManagerImpl implements VideoManager {
 //		XStreamHelper.writeObject(XStreamHelper.createXStreamInstance(), metaDataFile, metaData);
 //	}
 
+	@Override
+	public boolean isMetadataFileValid(OLATResource videoResource) {
+		VFSContainer baseContainer = FileResourceManager.getInstance().getFileResourceRootImpl(videoResource);
+		VFSLeaf metaDataFile = (VFSLeaf) baseContainer.resolve(FILENAME_VIDEO_METADATA_XML);
+		try {
+			VideoMetadata meta = (VideoMetadata) XStreamHelper.readObject(XStreamHelper.createXStreamInstance(), metaDataFile);
+			return meta != null;
+		} catch (Exception e) {
+			log.error("Error while parsing XStream file for videoResource::" + videoResource, e);
+			return false;
+		}
+	}
+
 	@Override
 	public VideoMetadata readVideoMetadataFile(OLATResource videoResource){
 		VFSContainer baseContainer= FileResourceManager.getInstance().getFileResourceRootImpl(videoResource);
-		VFSLeaf metaDataFile = VFSManager.resolveOrCreateLeafFromPath(baseContainer, FILENAME_VIDEO_METADATA_XML);
+		VFSLeaf metaDataFile = (VFSLeaf) baseContainer.resolve(FILENAME_VIDEO_METADATA_XML);
 		try {
 			return (VideoMetadata) XStreamHelper.readObject(XStreamHelper.createXStreamInstance(), metaDataFile);
 		} catch (Exception e) {
@@ -347,6 +360,11 @@ public class VideoManagerImpl implements VideoManager {
 		}
 	}
 	
+	@Override
+	public VideoTranscoding retranscodeFailedVideoTranscoding(VideoTranscoding videoTranscoding) {
+		return videoTranscodingDao.updateTranscodingStatus(videoTranscoding);
+	}
+	
 	@Override
 	public void startTranscodingProcess(OLATResource video) {
 		List<VideoTranscoding> existingTranscodings = getVideoTranscodings(video);
@@ -412,6 +430,18 @@ public class VideoManagerImpl implements VideoManager {
 		return allVideoTranscodings;
 	}
 	
+	@Override 
+	public List<TranscodingCount> getAllVideoTranscodingsCountSuccess(int errorcode) {
+		List<TranscodingCount> allVideoTranscodings = videoTranscodingDao.getAllVideoTranscodingsCountSuccess(errorcode);
+		return allVideoTranscodings;
+	}
+	
+	@Override 
+	public List<TranscodingCount> getAllVideoTranscodingsCountFails(int errorcode) {
+		List<TranscodingCount> allVideoTranscodings = videoTranscodingDao.getAllVideoTranscodingsCountFails(errorcode);
+		return allVideoTranscodings;
+	}
+	
 	@Override
 	public List<VideoTranscoding> getOneVideoResolution(int resolution) {
 		List<VideoTranscoding> oneResolution = videoTranscodingDao.getOneVideoResolution(resolution);
@@ -489,6 +519,12 @@ public class VideoManagerImpl implements VideoManager {
 		return title;
 	}
 	
+	@Override
+	public boolean hasMasterContainer (OLATResource videoResource) {
+		VFSContainer baseContainer =  FileResourceManager.getInstance().getFileResourceRootImpl(videoResource);
+		VFSContainer masterContainer = (VFSContainer) baseContainer.resolve(DIRNAME_MASTER);
+		return masterContainer != null;		
+	}
 	
 	@Override
 	public VFSContainer getMasterContainer(OLATResource videoResource) {
@@ -691,6 +727,11 @@ public class VideoManagerImpl implements VideoManager {
 		return videoTranscodingDao.getVideoTranscodingsPendingAndInProgress();
 	}
 	
+	@Override
+	public List<VideoTranscoding> getFailedVideoTranscodings() {
+		return videoTranscodingDao.getFailedVideoTranscodings();
+	}
+	
 	@Override
 	public void deleteVideoTranscoding(VideoTranscoding videoTranscoding) {
 		videoTranscodingDao.deleteVideoTranscoding(videoTranscoding);
@@ -832,4 +873,18 @@ public class VideoManagerImpl implements VideoManager {
 		return videoMetadataDao.getAllVideoRepoEntries(typename);
 	}
 
+	@Override
+	public boolean hasVideoFile(OLATResource videoResource) {
+		try {
+			if (getVideoFile(videoResource) == null) {
+				return false;
+			} else {
+				return true;
+			}
+		} catch (Exception e) {
+			log.error("",e);
+			return false;
+		}		
+	}
+
 }
diff --git a/src/main/java/org/olat/modules/video/manager/VideoTranscodingDAO.java b/src/main/java/org/olat/modules/video/manager/VideoTranscodingDAO.java
index a4a8091b1bf..8c846310176 100644
--- a/src/main/java/org/olat/modules/video/manager/VideoTranscodingDAO.java
+++ b/src/main/java/org/olat/modules/video/manager/VideoTranscodingDAO.java
@@ -174,7 +174,59 @@ public class VideoTranscodingDAO {
 			.createQuery(sb.toString(), Object[].class)
 			.getResultList();
 		
-		List<TranscodingCount>  allTranscodings = new ArrayList<>();
+		List<TranscodingCount> allTranscodings = new ArrayList<>();
+		for (Object[] data : rawData) {
+			Long count = (Long) data[0];
+			Integer resolution = (Integer) data[1];
+			allTranscodings.add(new TranscodingCount(count, resolution));
+		}
+		return allTranscodings;
+	}
+	
+	/**
+	 * Gets the all video transcodings count FAILS.
+	 *
+	 * @return FAILS count
+	 */
+	List<TranscodingCount> getAllVideoTranscodingsCountFails(int errorcode) {
+		StringBuilder sb = new StringBuilder();
+		//[0] count of a distinct [1] resolution
+		sb.append("select count(trans.key), trans.resolution from videotranscoding as trans")
+			.append(" where trans.status <= :errorcode")
+			.append(" group by trans.resolution");
+		
+		List<Object[]> rawData = dbInstance.getCurrentEntityManager()
+			.createQuery(sb.toString(), Object[].class)
+			.setParameter("errorcode", errorcode)
+			.getResultList();
+		
+		List<TranscodingCount> allTranscodings = new ArrayList<>();
+		for (Object[] data : rawData) {
+			Long count = (Long) data[0];
+			Integer resolution = (Integer) data[1];
+			allTranscodings.add(new TranscodingCount(count, resolution));
+		}
+		return allTranscodings;
+	}
+	
+	/**
+	 * Gets the all video successful transcodings count.
+	 *
+	 * @return Success count
+	 */
+	List<TranscodingCount> getAllVideoTranscodingsCountSuccess(int errorcode) {
+		StringBuilder sb = new StringBuilder();
+		//[0] count of a distinct [1] resolution
+		sb.append("select count(trans.key), trans.resolution from videotranscoding as trans")
+			.append(" where trans.status > :errorcode")
+			.append(" group by trans.resolution");
+		
+		List<Object[]> rawData = dbInstance.getCurrentEntityManager()
+			.createQuery(sb.toString(), Object[].class)
+			.setParameter("errorcode", errorcode)
+			.getResultList();
+		
+		List<TranscodingCount> allTranscodings = new ArrayList<>();
 		for (Object[] data : rawData) {
 			Long count = (Long) data[0];
 			Integer resolution = (Integer) data[1];
@@ -193,9 +245,40 @@ public class VideoTranscodingDAO {
 		StringBuilder sb = new StringBuilder();
 			sb.append("select trans from videotranscoding as trans")
 			.append(" inner join fetch trans.videoResource as res")
-			.append(" where trans.status != 100")
+			.append(" where trans.status != 100 and trans.status > -2")//without error codes
 			.append(" order by trans.creationDate asc, trans.id asc");
 		return dbInstance.getCurrentEntityManager().createQuery(sb.toString(), VideoTranscoding.class).getResultList();
 	}
+	
+	/**
+	 * Gets the failed video transcodings.
+	 * currently error codes start at -2 until -4.
+	 *
+	 * @return the failed video transcodings
+	 */
+	List<VideoTranscoding> getFailedVideoTranscodings() {
+			StringBuilder sb = new StringBuilder();
+				sb.append("select trans from videotranscoding as trans")
+				.append(" inner join fetch trans.videoResource as res")
+				.append(" where trans.status <= -2")//error codes
+				.append(" order by trans.creationDate asc, trans.id asc");
+			return dbInstance.getCurrentEntityManager()
+					.createQuery(sb.toString(), VideoTranscoding.class)
+					.getResultList();
+	}
+	
+	/**
+	 * Update transcoding status so TranscodingJob can find the resource.
+	 *
+	 * @param videoTranscoding
+	 * @return updated videoTranscoding
+	 */
+	VideoTranscoding updateTranscodingStatus (VideoTranscoding videoTranscoding) {
+		((VideoTranscodingImpl) videoTranscoding).setLastModified(new Date());
+		videoTranscoding.setStatus(-1);
+		VideoTranscoding trans = dbInstance.getCurrentEntityManager().merge(videoTranscoding);
+		return trans;
+	}
+
 
 }
diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_11_3_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_11_3_0.java
index 01fb9951136..f3b5ad18909 100644
--- a/src/main/java/org/olat/upgrade/OLATUpgrade_11_3_0.java
+++ b/src/main/java/org/olat/upgrade/OLATUpgrade_11_3_0.java
@@ -114,38 +114,51 @@ public class OLATUpgrade_11_3_0 extends OLATUpgrade {
 	private boolean processVideoResource(RepositoryEntry entry) {
 		try {
 			OLATResource videoResource = entry.getOlatResource();
-			// update trackfiles on filesystem
+			if (!videoManager.hasMasterContainer(videoResource)) {
+				log.error("RepoEntry: " + entry.getKey() + " has no valid master container.");
+				//log error but return true to proceed
+				return true;
+			}
+			// update track files on file system
 			VFSContainer masterContainer = videoManager.getMasterContainer(videoResource);
-			VideoMetadata metafromXML = videoManager.readVideoMetadataFile(videoResource);
-			for (Entry<String, String> track : metafromXML.getAllTracks().entrySet()) {
-				VFSItem item = masterContainer.resolve(track.getValue());
-				if (item != null && item instanceof VFSLeaf) {
-					String path = VideoManagerImpl.TRACK + track.getKey() + VideoManagerImpl.DOT
-							+ FilenameUtils.getExtension(track.getValue());
-					//check if modified track file already exists
-					if (masterContainer.resolve(path) == null) {
-						VFSLeaf target = masterContainer.createChildLeaf(path);
-						VFSManager.copyContent((VFSLeaf) item, target);
+			if (videoManager.isMetadataFileValid(videoResource)) {
+				VideoMetadata metafromXML = videoManager.readVideoMetadataFile(videoResource);
+				for (Entry<String, String> track : metafromXML.getAllTracks().entrySet()) {
+					VFSItem item = masterContainer.resolve(track.getValue());
+					if (item != null && item instanceof VFSLeaf) {
+						String path = VideoManagerImpl.TRACK + track.getKey() + VideoManagerImpl.DOT
+								+ FilenameUtils.getExtension(track.getValue());
+						//check if modified track file already exists
+						if (masterContainer.resolve(path) == null) {
+							VFSLeaf target = masterContainer.createChildLeaf(path);
+							VFSManager.copyContent((VFSLeaf) item, target);
+						}
 					}
 				}
+			} else {
+				log.error("RepoEntry: " + entry.getKey() + " has no valid Video Metadata XML file.");
 			}
-			// create entries on database
-			File videoFile = videoManager.getVideoFile(videoResource);
-			String fileName = videoFile.getName();
-			long size = videoFile.length();
-			String format = FilenameUtils.getExtension(fileName);
-			if (videoManager.getVideoMetadata(videoResource) == null) {
-				VideoMetaImpl entity = new VideoMetaImpl();
-				entity.setVideoResource(videoResource);
-				entity.setFormat(format);
-				entity.setCreationDate(new Date());
-				entity.setLastModified(new Date());
-				Size resolution = videoManager.getVideoResolutionFromOLATResource(videoResource);
-				entity.setHeight(resolution.getHeight());
-				entity.setWidth(resolution.getWidth());
-				entity.setSize(size);
-				entity.setLength(entry.getExpenditureOfWork());
-				dbInstance.getCurrentEntityManager().persist(entity);
+			// create meta data entries on database
+			if (videoManager.hasVideoFile(videoResource)) {
+				File videoFile = videoManager.getVideoFile(videoResource);
+				String fileName = videoFile.getName();
+				long size = videoFile.length();
+				String format = FilenameUtils.getExtension(fileName);
+				if (videoManager.getVideoMetadata(videoResource) == null) {
+					VideoMetaImpl entity = new VideoMetaImpl();
+					entity.setVideoResource(videoResource);
+					entity.setFormat(format);
+					entity.setCreationDate(new Date());
+					entity.setLastModified(new Date());
+					Size resolution = videoManager.getVideoResolutionFromOLATResource(videoResource);
+					entity.setHeight(resolution.getHeight());
+					entity.setWidth(resolution.getWidth());
+					entity.setSize(size);
+					entity.setLength(entry.getExpenditureOfWork());
+					dbInstance.getCurrentEntityManager().persist(entity);
+				}
+			} else {
+				log.error("RepoEntry: " + entry.getKey() + " has no valid resource.");
 			}
 			return true;
 		} catch (Exception e) {
-- 
GitLab