1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.opencastproject.assetmanager.impl.persistence;
22
23 import static org.opencastproject.util.data.functions.Misc.chuck;
24
25 import org.opencastproject.assetmanager.api.Availability;
26 import org.opencastproject.assetmanager.api.Snapshot;
27 import org.opencastproject.assetmanager.impl.SnapshotImpl;
28 import org.opencastproject.assetmanager.impl.VersionImpl;
29 import org.opencastproject.mediapackage.MediaPackage;
30 import org.opencastproject.mediapackage.MediaPackageElement;
31 import org.opencastproject.mediapackage.MediaPackageParser;
32
33 import org.eclipse.persistence.annotations.CascadeOnDelete;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 import java.util.Arrays;
38 import java.util.Date;
39 import java.util.Set;
40 import java.util.function.Function;
41
42 import javax.persistence.CascadeType;
43 import javax.persistence.Column;
44 import javax.persistence.Entity;
45 import javax.persistence.EntityManager;
46 import javax.persistence.FetchType;
47 import javax.persistence.GeneratedValue;
48 import javax.persistence.GenerationType;
49 import javax.persistence.Id;
50 import javax.persistence.Index;
51 import javax.persistence.Lob;
52 import javax.persistence.NamedQueries;
53 import javax.persistence.NamedQuery;
54 import javax.persistence.OneToMany;
55 import javax.persistence.Table;
56 import javax.persistence.TableGenerator;
57 import javax.persistence.Temporal;
58 import javax.persistence.TemporalType;
59 import javax.persistence.TypedQuery;
60 import javax.persistence.UniqueConstraint;
61
62
63 @Entity(name = "Snapshot")
64 @Table(name = "oc_assets_snapshot", indexes = {
65 @Index(name = "IX_oc_assets_snapshot_archival_date", columnList = ("archival_date")),
66 @Index(name = "IX_oc_assets_snapshot_mediapackage_id", columnList = ("mediapackage_id")),
67 @Index(name = "IX_oc_assets_snapshot_organization_id", columnList = ("organization_id")),
68 @Index(name = "IX_oc_assets_snapshot_owner", columnList = ("owner")),
69 @Index(name = "IX_oc_assets_snapshot_series", columnList = ("series_id, version"))
70 }, uniqueConstraints = {
71 @UniqueConstraint(columnNames = {"mediapackage_id", "version"}) })
72 @NamedQueries({
73 @NamedQuery(name = "Snapshot.countOrgEvents", query = "select count(distinct s.mediaPackageId) from Snapshot s "
74 + "where s.organizationId = :organizationId"),
75 @NamedQuery(name = "Snapshot.countEvents", query = "select count(distinct s.mediaPackageId) from Snapshot s"),
76 @NamedQuery(name = "Snapshot.countByMediaPackage", query = "select count(s) from Snapshot s "
77 + "where s.mediaPackageId = :mediaPackageId"),
78 @NamedQuery(name = "Snapshot.countByMediaPackageAndOrg", query = "select count(s) from Snapshot s "
79 + "where s.mediaPackageId = :mediaPackageId and s.organizationId = :organizationId"),
80 @NamedQuery(
81 name = "Snapshot.findByMpIdAndVersionOrderByVersionDesc",
82 query = "SELECT s FROM Snapshot s "
83 + "WHERE s.mediaPackageId = :mpId "
84 + "AND s.version = :version "
85 + "ORDER BY s.version DESC"
86 ),
87 @NamedQuery(
88 name = "Snapshot.findLatest",
89 query = "SELECT s FROM Snapshot s "
90 + "WHERE s.mediaPackageId = :mediaPackageId "
91 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
92 + "AND s.version = ( "
93 + " SELECT MAX(s2.version) FROM Snapshot s2 WHERE s2.mediaPackageId = s.mediaPackageId "
94 + ")"
95 ),
96 @NamedQuery(
97 name = "Snapshot.findLatestVersionFirst",
98 query = "SELECT s FROM Snapshot s "
99 + "WHERE s.mediaPackageId = :mediaPackageId "
100 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
101 + "ORDER BY s.version DESC"
102 ),
103 @NamedQuery(
104 name = "Snapshot.findOldestVersionFirst",
105 query = "SELECT s FROM Snapshot s "
106 + "WHERE s.mediaPackageId = :mediaPackageId "
107 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
108 + "ORDER BY s.version ASC"
109 ),
110 @NamedQuery(
111 name = "Snapshot.findByMpIdAndVersion",
112 query = "SELECT s FROM Snapshot s "
113 + "WHERE s.mediaPackageId = :mediaPackageId "
114 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
115 + "AND s.version = :version"
116 ),
117 @NamedQuery(
118 name = "Snapshot.findByDateOrderByMpId",
119 query = "SELECT s FROM Snapshot s "
120 + "WHERE s.archivalDate BETWEEN :startDate AND :endDate "
121 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
122 + "ORDER BY s.mediaPackageId ASC"
123 ),
124 @NamedQuery(
125 name = "Snapshot.findByMpIdAndDate",
126 query = "SELECT s FROM Snapshot s "
127 + "WHERE s.mediaPackageId = :mediaPackageId "
128 + "AND s.archivalDate BETWEEN :startDate AND :endDate "
129 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
130 ),
131 @NamedQuery(
132 name = "Snapshot.findByMpIdAndDateLatestVersionFirst",
133 query = "SELECT s FROM Snapshot s "
134 + "WHERE s.mediaPackageId = :mediaPackageId "
135 + "AND s.archivalDate BETWEEN :startDate AND :endDate "
136 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
137 + "ORDER BY s.version DESC"
138 ),
139 @NamedQuery(
140 name = "Snapshot.findByMpIdAndDateOldestVersionFirst",
141 query = "SELECT s FROM Snapshot s "
142 + "WHERE s.mediaPackageId = :mediaPackageId "
143 + "AND s.archivalDate BETWEEN :startDate AND :endDate "
144 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
145 + "ORDER BY s.version ASC"
146 ),
147 @NamedQuery(
148 name = "Snapshot.findByNotStorageAndDate",
149 query = "SELECT s FROM Snapshot s "
150 + "WHERE s.storageId != :storageId "
151 + "AND s.archivalDate BETWEEN :startDate AND :endDate "
152 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId)"
153 ),
154 @NamedQuery(
155 name = "Snapshot.findForIndexRebuild",
156 query = "SELECT s FROM Snapshot s "
157 + "WHERE s.version = ( "
158 + " SELECT MAX(s2.version) FROM Snapshot s2 "
159 + " WHERE s2.mediaPackageId = s.mediaPackageId "
160 + ") "
161 + "ORDER BY s.mediaPackageId DESC "
162 ),
163 @NamedQuery(
164 name = "Snapshot.delete",
165 query = "DELETE FROM Snapshot s "
166 + "WHERE s.mediaPackageId = :mediaPackageId "
167 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
168 ),
169 @NamedQuery(
170 name = "Snapshot.deleteAllButLatest",
171 query = "DELETE FROM Snapshot s "
172 + "WHERE s.mediaPackageId = :mediaPackageId "
173 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
174 + "AND s.version < ( "
175 + " SELECT MAX(s2.version) FROM Snapshot s2 WHERE s2.mediaPackageId = :mediaPackageId "
176 + ") "
177 ),
178 @NamedQuery(
179 name = "Snapshot.findLatestBySeriesId",
180 query = "SELECT s FROM Snapshot s "
181 + "WHERE s.seriesId = :seriesId "
182 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
183 + "AND s.version = ( "
184 + " SELECT MAX(s2.version) FROM Snapshot s2 WHERE s2.mediaPackageId = s.mediaPackageId "
185 + ")"
186 ),
187 @NamedQuery(
188 name = "Snapshot.findLatestByMpIds",
189 query = "SELECT s FROM Snapshot s "
190 + "WHERE s.mediaPackageId IN :mediaPackageIds "
191 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
192 + "AND s.version = ( "
193 + " SELECT MAX(s2.version) FROM Snapshot s2 WHERE s2.mediaPackageId = s.mediaPackageId "
194 + ") "
195 ),
196 @NamedQuery(
197 name = "Snapshot.findByMpIdOrgIdAndVersion",
198 query = "SELECT s FROM Snapshot s "
199 + "WHERE s.mediaPackageId = :mediaPackageId "
200 + "AND s.organizationId = :organizationId "
201 + "AND s.version = :version "
202 ),
203 @NamedQuery(
204 name = "Snapshot.countSnapshots",
205 query = "SELECT COUNT(s) FROM Snapshot s "
206 + "WHERE (:organizationId IS NULL OR s.organizationId = :organizationId)"
207 ),
208 @NamedQuery(
209 name = "Snapshot.updateStorageIdByVersionAndMpId",
210 query = "UPDATE Snapshot s SET s.storageId = :storageId "
211 + "WHERE s.version = :version "
212 + "AND s.mediaPackageId = :mediaPackageId"
213 ),
214 @NamedQuery(
215 name = "Snapshot.updateAvailabilityByVersionAndMpId",
216 query = "UPDATE Snapshot s SET s.availability = :availability "
217 + "WHERE s.version = :version "
218 + "AND s.mediaPackageId = :mediaPackageId"
219 ),
220 @NamedQuery(
221 name = "Snapshot.getSnapshotVersions",
222 query = "SELECT s.version FROM Snapshot s "
223 + "WHERE s.mediaPackageId = :mediaPackageId "
224 + "AND (:organizationId IS NULL OR s.organizationId = :organizationId) "
225 + "ORDER BY s.version ASC"
226 ),
227 })
228
229
230
231 @TableGenerator(name = "seq_oc_assets_snapshot", initialValue = 0, allocationSize = 50)
232 public class SnapshotDto {
233 private static final Logger logger = LoggerFactory.getLogger(SnapshotDto.class);
234
235 @Id
236 @Column(name = "id")
237 @GeneratedValue(strategy = GenerationType.TABLE, generator = "seq_oc_assets_snapshot")
238 private Long id;
239
240 @Column(name = "mediapackage_id", length = 128, nullable = false)
241 private String mediaPackageId;
242
243 @Column(name = "version", nullable = false)
244 private Long version;
245
246 @Column(name = "series_id", length = 128)
247 private String seriesId;
248
249 @Column(name = "organization_id", length = 128, nullable = false)
250 private String organizationId;
251
252 @Column(name = "archival_date", nullable = false)
253 @Temporal(TemporalType.TIMESTAMP)
254 private Date archivalDate;
255
256 @Column(name = "availability", nullable = false, length = 32)
257 private String availability;
258
259 @Column(name = "storage_id", nullable = false, length = 256)
260 private String storageId;
261
262 @Column(name = "owner", nullable = false, length = 256)
263 private String owner;
264
265 @Lob
266 @Column(name = "mediapackage_xml", length = 65535, nullable = false)
267 private String mediaPackageXml;
268
269 @CascadeOnDelete
270 @OneToMany(targetEntity = AssetDto.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "snapshot")
271 private Set<AssetDto> assets;
272
273 public static SnapshotDto mk(
274 MediaPackage mediaPackage,
275 VersionImpl version,
276 String organization,
277 Date archivalDate,
278 Availability availability,
279 String storageId,
280 String owner) {
281 try {
282 final SnapshotDto dto = new SnapshotDto();
283 dto.mediaPackageId = mediaPackage.getIdentifier().toString();
284 dto.version = version.value();
285 dto.seriesId = mediaPackage.getSeries();
286 dto.organizationId = organization;
287 dto.archivalDate = archivalDate;
288 dto.mediaPackageXml = MediaPackageParser.getAsXml(mediaPackage);
289 dto.availability = availability.name();
290 dto.storageId = storageId;
291 dto.owner = owner;
292 return dto;
293 } catch (Exception e) {
294 return chuck(e);
295 }
296 }
297
298 public static SnapshotDto mk(Snapshot snapshot) {
299 try {
300 return mk(snapshot.getMediaPackage(),
301 VersionImpl.mk(Long.parseLong(snapshot.getVersion().toString())),
302 snapshot.getOrganizationId(),
303 snapshot.getArchivalDate(),
304 snapshot.getAvailability(),
305 snapshot.getStorageId(),
306 snapshot.getOwner());
307 } catch (Exception e) {
308 return chuck(e);
309 }
310 }
311
312 public Long getId() {
313 return Database.insidePersistenceContextCheck(id);
314 }
315
316 public VersionImpl getVersion() {
317 return Conversions.toVersion(version);
318 }
319
320 public String getMediaPackageId() {
321 return mediaPackageId;
322 }
323
324 public String getStorageId() {
325 return storageId;
326 }
327
328 public String getOrganizationId() {
329 return organizationId;
330 }
331
332 public String getAvailability() {
333 return availability;
334 }
335
336 public String getOwner() {
337 return owner;
338 }
339
340 void setAvailability(Availability a) {
341 this.availability = a.name();
342 }
343
344 void setStorageId(String id) {
345 this.storageId = id;
346 }
347
348 public boolean addAsset(AssetDto asset) {
349 return this.assets.add(asset);
350 }
351
352 public boolean removeAsset(AssetDto asset) {
353 return this.assets.remove(asset);
354 }
355
356 public Snapshot toSnapshot() {
357 MediaPackage mediaPackage = Conversions.toMediaPackage(mediaPackageXml);
358
359 for (MediaPackageElement element: mediaPackage.getElements()) {
360 if (!Arrays.asList(element.getTags()).contains("archive")) {
361 logger.debug("Adding additional tag `archive` to element {} retrieved from asset manager", element);
362 element.addTag("archive");
363 }
364 }
365 return new SnapshotImpl(
366 id,
367 Conversions.toVersion(version),
368 organizationId,
369 archivalDate,
370 Availability.valueOf(availability),
371 storageId,
372 owner,
373 mediaPackage);
374 }
375
376
377
378
379
380
381
382
383 public static Function<EntityManager, Boolean> existsQuery(final String mediaPackageId) {
384 return existsQuery(mediaPackageId, null);
385 }
386
387
388
389
390
391
392
393
394
395
396 public static Function<EntityManager, Boolean> existsQuery(final String mediaPackageId, final String organization) {
397 return em -> {
398 TypedQuery<Long> query;
399 if (organization == null) {
400 query = em.createNamedQuery("Snapshot.countByMediaPackage", Long.class)
401 .setParameter("mediaPackageId", mediaPackageId);
402 } else {
403 query = em.createNamedQuery("Snapshot.countByMediaPackageAndOrg", Long.class)
404 .setParameter("mediaPackageId", mediaPackageId)
405 .setParameter("organizationId", organization);
406 }
407 logger.debug("Executing query {}", query);
408 return query.getSingleResult() > 0;
409 };
410 }
411
412
413
414
415
416
417
418
419 public static Function<EntityManager, Long> countEventsQuery(final String organization) {
420 return em -> {
421 TypedQuery<Long> query;
422 if (null != organization) {
423 query = em.createNamedQuery("Snapshot.countOrgEvents", Long.class)
424 .setParameter("organizationId", organization);
425 } else {
426 query = em.createNamedQuery("Snapshot.countEvents", Long.class);
427 }
428 logger.debug("Executing query {}", query);
429 return query.getSingleResult();
430 };
431 }
432
433
434
435
436
437
438
439
440 public static Function<EntityManager, Long> countSnapshotsQuery(final String organization) {
441 return em -> {
442 TypedQuery<Long> query;
443 query = em.createNamedQuery("Snapshot.countSnapshots", Long.class)
444 .setParameter("organizationId", organization);
445 logger.debug("Executing query {}", query);
446 return query.getSingleResult();
447 };
448 }
449 }