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.Functions.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
81
82
83 @TableGenerator(name = "seq_oc_assets_snapshot", initialValue = 0, allocationSize = 50)
84 public class SnapshotDto {
85 private static final Logger logger = LoggerFactory.getLogger(SnapshotDto.class);
86
87 @Id
88 @Column(name = "id")
89 @GeneratedValue(strategy = GenerationType.TABLE, generator = "seq_oc_assets_snapshot")
90 private Long id;
91
92 @Column(name = "mediapackage_id", length = 128, nullable = false)
93 private String mediaPackageId;
94
95 @Column(name = "version", nullable = false)
96 private Long version;
97
98 @Column(name = "series_id", length = 128)
99 private String seriesId;
100
101 @Column(name = "organization_id", length = 128, nullable = false)
102 private String organizationId;
103
104 @Column(name = "archival_date", nullable = false)
105 @Temporal(TemporalType.TIMESTAMP)
106 private Date archivalDate;
107
108 @Column(name = "availability", nullable = false, length = 32)
109 private String availability;
110
111 @Column(name = "storage_id", nullable = false, length = 256)
112 private String storageId;
113
114 @Column(name = "owner", nullable = false, length = 256)
115 private String owner;
116
117 @Lob
118 @Column(name = "mediapackage_xml", length = 65535, nullable = false)
119 private String mediaPackageXml;
120
121 @CascadeOnDelete
122 @OneToMany(targetEntity = AssetDto.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "snapshot")
123 private Set<AssetDto> assets;
124
125 public static SnapshotDto mk(
126 MediaPackage mediaPackage,
127 VersionImpl version,
128 String organization,
129 Date archivalDate,
130 Availability availability,
131 String storageId,
132 String owner) {
133 try {
134 final SnapshotDto dto = new SnapshotDto();
135 dto.mediaPackageId = mediaPackage.getIdentifier().toString();
136 dto.version = version.value();
137 dto.seriesId = mediaPackage.getSeries();
138 dto.organizationId = organization;
139 dto.archivalDate = archivalDate;
140 dto.mediaPackageXml = MediaPackageParser.getAsXml(mediaPackage);
141 dto.availability = availability.name();
142 dto.storageId = storageId;
143 dto.owner = owner;
144 return dto;
145 } catch (Exception e) {
146 return chuck(e);
147 }
148 }
149
150 public static SnapshotDto mk(Snapshot snapshot) {
151 try {
152 return mk(snapshot.getMediaPackage(),
153 VersionImpl.mk(Long.parseLong(snapshot.getVersion().toString())),
154 snapshot.getOrganizationId(),
155 snapshot.getArchivalDate(),
156 snapshot.getAvailability(),
157 snapshot.getStorageId(),
158 snapshot.getOwner());
159 } catch (Exception e) {
160 return chuck(e);
161 }
162 }
163
164 public Long getId() {
165 return Database.insidePersistenceContextCheck(id);
166 }
167
168 public VersionImpl getVersion() {
169 return Conversions.toVersion(version);
170 }
171
172 public String getMediaPackageId() {
173 return mediaPackageId;
174 }
175
176 public String getStorageId() {
177 return storageId;
178 }
179
180 void setAvailability(Availability a) {
181 this.availability = a.name();
182 }
183
184 void setStorageId(String id) {
185 this.storageId = id;
186 }
187
188 public boolean addAsset(AssetDto asset) {
189 return this.assets.add(asset);
190 }
191
192 public boolean removeAsset(AssetDto asset) {
193 return this.assets.remove(asset);
194 }
195
196 public Snapshot toSnapshot() {
197 MediaPackage mediaPackage = Conversions.toMediaPackage(mediaPackageXml);
198
199 for (MediaPackageElement element: mediaPackage.getElements()) {
200 if (!Arrays.asList(element.getTags()).contains("archive")) {
201 logger.debug("Adding additional tag `archive` to element {} retrieved from asset manager", element);
202 element.addTag("archive");
203 }
204 }
205 return new SnapshotImpl(
206 id,
207 Conversions.toVersion(version),
208 organizationId,
209 archivalDate,
210 Availability.valueOf(availability),
211 storageId,
212 owner,
213 mediaPackage);
214 }
215
216
217
218
219
220
221
222
223 public static Function<EntityManager, Boolean> existsQuery(final String mediaPackageId) {
224 return existsQuery(mediaPackageId, null);
225 }
226
227
228
229
230
231
232
233
234
235
236 public static Function<EntityManager, Boolean> existsQuery(final String mediaPackageId, final String organization) {
237 return em -> {
238 TypedQuery<Long> query;
239 if (organization == null) {
240 query = em.createNamedQuery("Snapshot.countByMediaPackage", Long.class)
241 .setParameter("mediaPackageId", mediaPackageId);
242 } else {
243 query = em.createNamedQuery("Snapshot.countByMediaPackageAndOrg", Long.class)
244 .setParameter("mediaPackageId", mediaPackageId)
245 .setParameter("organizationId", organization);
246 }
247 logger.debug("Executing query {}", query);
248 return query.getSingleResult() > 0;
249 };
250 }
251
252
253
254
255
256
257
258
259 public static Function<EntityManager, Long> countEventsQuery(final String organization) {
260 return em -> {
261 TypedQuery<Long> query;
262 if (null != organization) {
263 query = em.createNamedQuery("Snapshot.countOrgEvents", Long.class)
264 .setParameter("organizationId", organization);
265 } else {
266 query = em.createNamedQuery("Snapshot.countEvents", Long.class);
267 }
268 logger.debug("Executing query {}", query);
269 return query.getSingleResult();
270 };
271 }
272 }