1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.opencastproject.message.broker.api.assetmanager;
22
23 import org.opencastproject.mediapackage.Catalog;
24 import org.opencastproject.mediapackage.MediaPackage;
25 import org.opencastproject.mediapackage.MediaPackageElements;
26 import org.opencastproject.mediapackage.MediaPackageException;
27 import org.opencastproject.mediapackage.MediaPackageParser;
28 import org.opencastproject.message.broker.api.MessageItem;
29 import org.opencastproject.metadata.dublincore.DublinCoreCatalog;
30 import org.opencastproject.metadata.dublincore.DublinCores;
31 import org.opencastproject.security.api.AccessControlList;
32 import org.opencastproject.security.api.AccessControlParser;
33 import org.opencastproject.util.RequireUtil;
34 import org.opencastproject.workspace.api.Workspace;
35
36 import org.apache.commons.io.IOUtils;
37
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.Serializable;
41 import java.nio.charset.StandardCharsets;
42 import java.util.Date;
43 import java.util.Optional;
44 import java.util.function.Function;
45
46 import javax.annotation.ParametersAreNonnullByDefault;
47
48
49
50
51 @ParametersAreNonnullByDefault
52 public abstract class AssetManagerItem implements MessageItem, Serializable {
53 private static final long serialVersionUID = 5440420510139202434L;
54
55 public enum Type {
56 Update, Delete
57 }
58
59
60
61 private final String mediaPackageId;
62 private final long date;
63
64 private AssetManagerItem(String mediaPackageId, Date date) {
65 this.mediaPackageId = RequireUtil.notNull(mediaPackageId, "mediaPackageId");
66 this.date = RequireUtil.notNull(date, "date").getTime();
67 }
68
69 public abstract Type getType();
70
71 public abstract <A> A decompose(Function<? super TakeSnapshot, ? extends A> takeSnapshot,
72 Function<? super DeleteEpisode, ? extends A> deleteEpisode);
73
74 public final Date getDate() {
75 return new Date(date);
76 }
77
78 @Override
79 public final String getId() {
80 return mediaPackageId;
81 }
82
83
84
85
86
87
88
89
90 public static final class TakeSnapshot extends AssetManagerItem {
91 private static final long serialVersionUID = 3530625835200867594L;
92
93 private final String mediapackage;
94 private final String acl;
95 private final long version;
96 private final String episodeDublincore;
97
98 private TakeSnapshot(String mediaPackageId, String mediapackage, String episodeDublincore, String acl, long version,
99 Date date) {
100 super(mediaPackageId, date);
101 this.mediapackage = mediapackage;
102 this.episodeDublincore = episodeDublincore;
103 this.acl = acl;
104 this.version = version;
105 }
106
107 @Override
108 public <A> A decompose(Function<? super TakeSnapshot, ? extends A> takeSnapshot,
109 Function<? super DeleteEpisode, ? extends A> deleteEpisode) {
110 return takeSnapshot.apply(this);
111 }
112
113 @Override
114 public Type getType() {
115 return Type.Update;
116 }
117
118 public MediaPackage getMediapackage() {
119 try {
120 return MediaPackageParser.getFromXml(mediapackage);
121 } catch (MediaPackageException e) {
122 throw new RuntimeException(e);
123 }
124 }
125
126 public AccessControlList getAcl() {
127 return AccessControlParser.parseAclSilent(acl);
128 }
129
130 public Optional<DublinCoreCatalog> getEpisodeDublincore() {
131 if (episodeDublincore == null) {
132 return Optional.empty();
133 }
134
135 try (InputStream is = IOUtils.toInputStream(episodeDublincore, "UTF-8")) {
136 return Optional.of(DublinCores.read(is));
137 } catch (IOException e) {
138 throw new RuntimeException(e);
139 }
140 }
141
142 public long getVersion() {
143 return version;
144 }
145
146
147
148 public static final Function<TakeSnapshot, MediaPackage> getMediaPackage =
149 new Function<TakeSnapshot, MediaPackage>() {
150 @Override
151 public MediaPackage apply(TakeSnapshot a) {
152 return a.getMediapackage();
153 }
154 };
155
156 public static final Function<TakeSnapshot, Optional<DublinCoreCatalog>> getEpisodeDublincore
157 = new Function<TakeSnapshot, Optional<DublinCoreCatalog>>() {
158 @Override
159 public Optional<DublinCoreCatalog> apply(TakeSnapshot a) {
160 return a.getEpisodeDublincore();
161 }
162 };
163
164 public static final Function<TakeSnapshot, AccessControlList> getAcl =
165 new Function<TakeSnapshot, AccessControlList>() {
166 @Override
167 public AccessControlList apply(TakeSnapshot a) {
168 return a.getAcl();
169 }
170 };
171
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185 public static final class DeleteEpisode extends AssetManagerItem {
186 private static final long serialVersionUID = -4906056424740181256L;
187
188 private DeleteEpisode(String mediaPackageId, Date date) {
189 super(mediaPackageId, date);
190 }
191
192 @Override
193 public <A> A decompose(Function<? super TakeSnapshot, ? extends A> takeSnapshot,
194 Function<? super DeleteEpisode, ? extends A> deleteEpisode) {
195 return deleteEpisode.apply(this);
196 }
197
198 @Override
199 public Type getType() {
200 return Type.Delete;
201 }
202
203 public String getMediaPackageId() {
204 return getId();
205 }
206
207 public static final Function<DeleteEpisode, String> getMediaPackageId = new Function<DeleteEpisode, String>() {
208 @Override
209 public String apply(DeleteEpisode a) {
210 return a.getMediaPackageId();
211 }
212 };
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236 public static TakeSnapshot add(Workspace workspace, MediaPackage mp, AccessControlList acl, long version, Date date) {
237 String dcXml = null;
238 for (Catalog catalog: mp.getCatalogs(MediaPackageElements.EPISODE)) {
239 try (InputStream in = workspace.read(catalog.getURI())) {
240 dcXml = IOUtils.toString(in, StandardCharsets.UTF_8);
241 } catch (Exception e) {
242 throw new IllegalStateException(String.format("Unable to load dublin core catalog for event '%s'",
243 mp.getIdentifier()), e);
244 }
245 }
246 return new TakeSnapshot(mp.getIdentifier().toString(), MediaPackageParser.getAsXml(mp), dcXml,
247 AccessControlParser.toJsonSilent(acl), version, date);
248 }
249
250
251
252
253
254
255
256
257 public static AssetManagerItem deleteEpisode(String mediaPackageId, Date date) {
258 return new DeleteEpisode(mediaPackageId, date);
259 }
260 }