1 /*
2 * Licensed to The Apereo Foundation under one or more contributor license
3 * agreements. See the NOTICE file distributed with this work for additional
4 * information regarding copyright ownership.
5 *
6 *
7 * The Apereo Foundation licenses this file to you under the Educational
8 * Community License, Version 2.0 (the "License"); you may not use this file
9 * except in compliance with the License. You may obtain a copy of the License
10 * at:
11 *
12 * http://opensource.org/licenses/ecl2.txt
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17 * License for the specific language governing permissions and limitations under
18 * the License.
19 *
20 */
21
22 package org.opencastproject.scheduler.api;
23
24 import org.opencastproject.mediapackage.MediaPackage;
25 import org.opencastproject.metadata.dublincore.DublinCoreCatalog;
26 import org.opencastproject.security.api.UnauthorizedException;
27 import org.opencastproject.util.NotFoundException;
28
29 import com.entwinemedia.fn.data.Opt;
30
31 import net.fortuna.ical4j.model.Period;
32 import net.fortuna.ical4j.model.property.RRule;
33
34 import java.util.Date;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.TimeZone;
39
40 /**
41 * Scheduler service manages events (creates new, updates already existing and removes events). It enables searches over
42 * existing events, retrieving event data like dublincore, acl or workflow configuration for specific event, search for
43 * conflicting events and generating calendar for capture agent.
44 */
45 public interface SchedulerService {
46
47 /**
48 * Identifier for service registration and location
49 */
50 String JOB_TYPE = "org.opencastproject.scheduler";
51
52 /** The workflow configuration prefix */
53 String WORKFLOW_CONFIG_PREFIX = "org.opencastproject.workflow.config.";
54
55 /**
56 * Creates new event using specified mediapackage, workflow configuration and capture agent configuration. The
57 * mediapackage id is used as the event's identifier.
58 *
59 * Default capture agent properties are created from agentId and DublinCore. Following values are generated:
60 * <ul>
61 * <li>event.title (mapped from dc:title)</li>
62 * <li>event.series (mapped from mediaPackage#getSeries())</li>
63 * <li>event.location (mapped from captureAgentId)</li>
64 * </ul>
65 *
66 * @param startDateTime
67 * the event start time (the start date must be before the end date)
68 * @param endDateTime
69 * the event end time (the end date must be after the start date)
70 * @param captureAgentId
71 * the capture agent id
72 * @param userIds
73 * the list of user identifiers of speakers/lecturers
74 * @param mediaPackage
75 * the mediapackage
76 * @param wfProperties
77 * the workflow configuration
78 * @param caMetadata
79 * the capture agent configuration
80 * @param schedulingSource
81 * the optional scheduling source from which the event comes from
82 * @throws UnauthorizedException
83 * if the caller is not authorized to take this action
84 * @throws SchedulerConflictException
85 * if there are conflicting events
86 * @throws SchedulerException
87 * if creating new events failed
88 */
89 void addEvent(Date startDateTime, Date endDateTime, String captureAgentId, Set<String> userIds,
90 MediaPackage mediaPackage, Map<String, String> wfProperties, Map<String, String> caMetadata,
91 Opt<String> schedulingSource) throws UnauthorizedException,
92 SchedulerConflictException, SchedulerException;
93
94 /**
95 * Creates a group of new event using specified mediapackage, workflow configuration and capture agent configuration.
96 * The mediapackage id is used as the event's identifier.
97 *
98 * Default capture agent properties are created from agentId and DublinCore. Following values are generated:
99 * <ul>
100 * <li>event.title (mapped from dc:title)</li>
101 * <li>event.series (mapped from mediaPackage#getSeries())</li>
102 * <li>event.location (mapped from captureAgentId)</li>
103 * </ul>
104 *
105 * @param rRule
106 * the {@link RRule} for the events to schedule
107 * @param start
108 * the start date for the recurrence
109 * @param end
110 * the end date for the recurrence
111 * @param duration
112 * the duration of the events
113 * @param tz
114 * the {@link TimeZone} for the events
115 * @param captureAgentId
116 * the capture agent id
117 * @param userIds
118 * the list of user identifiers of speakers/lecturers
119 * @param templateMp
120 * the mediapackage to base the events on
121 * @param wfProperties
122 * the workflow configuration
123 * @param caMetadata
124 * the capture agent configuration
125 * @param schedulingSource
126 * the optional scheduling source from which the event comes from
127 * @return A {@link Map} of mediapackage ID and {@link Period} where the event occurs
128 * @throws UnauthorizedException
129 * if the caller is not authorized to take this action
130 * @throws SchedulerConflictException
131 * if there are conflicting events
132 * @throws SchedulerException
133 * if creating new events failed
134 */
135 Map<String, Period> addMultipleEvents(RRule rRule, Date start, Date end, Long duration, TimeZone tz,
136 String captureAgentId, Set<String> userIds, MediaPackage templateMp, Map<String,
137 String> wfProperties, Map<String, String> caMetadata, Opt<String> schedulingSource)
138 throws UnauthorizedException, SchedulerConflictException, SchedulerException;
139
140 /**
141 * Updates event with specified ID and check for conflicts.
142 *
143 * Default capture agent properties are created from DublinCore. Following values are generated:
144 * <ul>
145 * <li>event.title (mapped from dc:title)</li>
146 * <li>event.series (mapped from mediaPackage#getSeries())</li>
147 * <li>event.location (mapped from captureAgentId)</li>
148 * </ul>
149 *
150 * @param mediaPackageId
151 * the optional event identifier
152 * @param startDateTime
153 * the optional event start time
154 * @param endDateTime
155 * the optional event end time
156 * @param captureAgentId
157 * the optional capture agent id
158 * @param userIds
159 * the optional list of user identifiers of speakers/lecturers
160 * @param mediaPackage
161 * the optional mediapackage to update
162 * @param wfProperties
163 * the optional workflow configuration to update
164 * @param caMetadata
165 * the optional capture configuration to update
166 * @throws NotFoundException
167 * if event with specified ID cannot be found
168 * @throws UnauthorizedException
169 * if the current user is not authorized to perform this action
170 * @throws SchedulerConflictException
171 * if there are conflicting events
172 * @throws SchedulerException
173 * if exception occurred
174 */
175 void updateEvent(String mediaPackageId, Opt<Date> startDateTime, Opt<Date> endDateTime, Opt<String> captureAgentId,
176 Opt<Set<String>> userIds, Opt<MediaPackage> mediaPackage, Opt<Map<String, String>> wfProperties,
177 Opt<Map<String, String>> caMetadata)
178 throws NotFoundException, UnauthorizedException, SchedulerConflictException, SchedulerException;
179
180 /**
181 * Updates event with specified ID and possibly checking for conflicts.
182 *
183 * Default capture agent properties are created from DublinCore. Following values are generated:
184 * <ul>
185 * <li>event.title (mapped from dc:title)</li>
186 * <li>event.series (mapped from mediaPackage#getSeries())</li>
187 * <li>event.location (mapped from captureAgentId)</li>
188 * </ul>
189 *
190 * @param mediaPackageId
191 * the event identifier
192 * @param startDateTime
193 * the optional event start time
194 * @param endDateTime
195 * the optional event end time
196 * @param captureAgentId
197 * the optional capture agent id
198 * @param userIds
199 * the optional list of user identifiers of speakers/lecturers
200 * @param mediaPackage
201 * the optional mediapackage to update
202 * @param wfProperties
203 * the optional workflow configuration to update
204 * @param caMetadata
205 * the optional capture configuration to update
206 * @param allowConflict
207 * the flag to ignore conflict checks
208 * @throws NotFoundException
209 * if event with specified ID cannot be found
210 * @throws UnauthorizedException
211 * if the current user is not authorized to perform this action
212 * @throws SchedulerConflictException
213 * if there are conflicting events
214 * @throws SchedulerException
215 * if exception occurred
216 */
217 void updateEvent(String mediaPackageId, Opt<Date> startDateTime, Opt<Date> endDateTime, Opt<String> captureAgentId,
218 Opt<Set<String>> userIds, Opt<MediaPackage> mediaPackage, Opt<Map<String, String>> wfProperties,
219 Opt<Map<String, String>> caMetadata, boolean allowConflict)
220 throws NotFoundException, UnauthorizedException, SchedulerConflictException, SchedulerException;
221
222 /**
223 * Removes event with specified ID.
224 *
225 * @param mediaPackageId
226 * the event identifier
227 * @throws NotFoundException
228 * if event with specified ID cannot be found
229 * @throws UnauthorizedException
230 * if the current user is not authorized to perform this action
231 * @throws SchedulerException
232 * if exception occurred
233 */
234 void removeEvent(String mediaPackageId)
235 throws NotFoundException, UnauthorizedException, SchedulerException;
236
237 /**
238 * Retrieves mediapackage associated with specified event ID.
239 *
240 * @param mediaPackageId
241 * ID of event for which mediapackage will be retrieved
242 * @return {@link MediaPackage} for specified event
243 * @throws NotFoundException
244 * if event with specified ID cannot be found
245 * @throws SchedulerException
246 * if exception occurred
247 */
248 MediaPackage getMediaPackage(String mediaPackageId)
249 throws NotFoundException, UnauthorizedException, SchedulerException;
250
251 /**
252 * Retrieves dublin core catalog associated with specified event ID.
253 *
254 * @param mediaPackageId
255 * ID of event for which DublinCore will be retrieved
256 * @return {@link DublinCoreCatalog} for specified event
257 * @throws NotFoundException
258 * if event with specified ID cannot be found
259 * @throws SchedulerException
260 * if exception occurred
261 */
262 DublinCoreCatalog getDublinCore(String mediaPackageId)
263 throws NotFoundException, UnauthorizedException, SchedulerException;
264
265 /**
266 * Retrieves the technical metadata associated with specified event ID.
267 *
268 * @param mediaPackageId
269 * ID of event for which technical metadata will be retrieved
270 * @return {@link TechnicalMetadata} for specified event
271 * @throws NotFoundException
272 * if event with specified ID cannot be found
273 * @throws SchedulerException
274 * if exception occurred
275 */
276 TechnicalMetadata getTechnicalMetadata(String mediaPackageId)
277 throws NotFoundException, UnauthorizedException, SchedulerException;
278
279 /**
280 * Retrieves workflow configuration associated with specified event ID.
281 *
282 * @param mediaPackageId
283 * ID of event for which workflow configuration will be retrieved
284 * @return configuration of the workflow
285 * @throws NotFoundException
286 * if event with specified ID cannot be found
287 * @throws SchedulerException
288 * if exception occurred
289 */
290 Map<String, String> getWorkflowConfig(String mediaPackageId)
291 throws NotFoundException, UnauthorizedException, SchedulerException;
292
293 /**
294 * Retrieves capture agent configuration for specified event.
295 *
296 * @param mediaPackageId
297 * ID of event for which capture agent configuration will be retrieved
298 * @return configurations of capture agent
299 * @throws NotFoundException
300 * if event with specified ID cannot be found
301 * @throws SchedulerException
302 * if exception occurred
303 */
304 Map<String, String> getCaptureAgentConfiguration(String mediaPackageId)
305 throws NotFoundException, UnauthorizedException, SchedulerException;
306
307 /**
308 * Query
309 */
310
311 /**
312 * Returns the number of scheduled events.
313 *
314 * @return the number of scheduled events
315 * @throws SchedulerException
316 * if exception occurred
317 */
318 int getEventCount() throws SchedulerException, UnauthorizedException;
319
320 /**
321 * Retrieves all events matching given filter.
322 *
323 * @param captureAgentId
324 * the capture agent id filter
325 * @param startsFrom
326 * the start from date filter
327 * @param startsTo
328 * the start to date filter
329 * @param endFrom
330 * the end from date filter
331 * @param endTo
332 * the end to date filter
333 * @return a {@link MediaPackage} list of matching events
334 * @throws SchedulerException
335 * if exception occurred
336 */
337 List<MediaPackage> search(Opt<String> captureAgentId, Opt<Date> startsFrom, Opt<Date> startsTo, Opt<Date> endFrom,
338 Opt<Date> endTo) throws SchedulerException, UnauthorizedException;
339
340 /**
341 * Retrieves the currently active recording for the given capture agent (if any).
342 *
343 * @param captureAgentId
344 * The id of the agent to get the current recording of.
345 * @return The currently active recording or none, if agent is currently idle
346 * @throws SchedulerException
347 * In case the current recording cannot be retrieved.
348 */
349 Opt<MediaPackage> getCurrentRecording(String captureAgentId) throws SchedulerException, UnauthorizedException;
350
351 /**
352 * Retrieves the upcoming recording for the given capture agent (if any).
353 *
354 * @param captureAgentId
355 * The id of the agent to get the upcoming recording of.
356 * @return The cupcoming recording or none, if there is none.
357 * @throws SchedulerException
358 * In case the upcoming recording cannot be retrieved.
359 */
360 Opt<MediaPackage> getUpcomingRecording(String captureAgentId) throws SchedulerException, UnauthorizedException;
361
362 /**
363 * Returns list of all conflicting events, i.e. all events that ends after start date and begins before end date.
364 *
365 * @param captureDeviceID
366 * capture device ID for which conflicting events are searched for
367 * @param startDate
368 * start date of conflicting period
369 * @param endDate
370 * end date of conflicting period
371 * @return a {@link MediaPackage} list of all conflicting events
372 * @throws SchedulerException
373 * if exception occurred
374 */
375 List<MediaPackage> findConflictingEvents(String captureDeviceID, Date startDate, Date endDate)
376 throws UnauthorizedException, SchedulerException;
377
378 /**
379 * Returns list of all conflicting events. Conflicting periods are calculated based on recurrence rule, start date,
380 * end date and duration of each conflicting period.
381 *
382 * @param captureAgentId
383 * capture agent ID for which conflicting events are searched for
384 * @param rrule
385 * recurrence rule
386 * @param startDate
387 * beginning of period
388 * @param endDate
389 * ending of period
390 * @param duration
391 * duration of each period
392 * @param timezone
393 * the time zone of the capture agent
394 * @return a {@link MediaPackage} list of all conflicting events
395 * @throws SchedulerException
396 * if exception occurred
397 */
398 List<MediaPackage> findConflictingEvents(String captureAgentId, RRule rrule, Date startDate, Date endDate,
399 long duration, TimeZone timezone) throws UnauthorizedException, SchedulerException;
400
401
402 /**
403 * CA
404 */
405
406 /**
407 * Generates calendar for specified capture agent.
408 *
409 * @param captureAgentId
410 * capture agent id filter
411 * @param seriesId
412 * series id filter
413 * @param cutoff
414 * cutoff date filter
415 * @return generated calendar
416 * @throws SchedulerException
417 * if exception occurred
418 */
419 String getCalendar(Opt<String> captureAgentId, Opt<String> seriesId, Opt<Date> cutoff) throws SchedulerException;
420
421 /**
422 * Returns hash of last modification of event belonging to specified capture agent.
423 *
424 * @param captureAgentId
425 * the capture agent identifier
426 * @return the last modification hash
427 * @throws SchedulerException
428 * if exception occurred
429 */
430 String getScheduleLastModified(String captureAgentId) throws SchedulerException;
431
432 /**
433 * Updates the state of a recording with the given state, if it exists.
434 *
435 * @param mediaPackageId
436 * The id of the recording in the system.
437 * @param state
438 * The state to set for that recording. This should be defined from {@link Recording}.
439 * @throws NotFoundException
440 * if the recording with the given id has not been found
441 */
442 boolean updateRecordingState(String mediaPackageId, String state) throws NotFoundException, SchedulerException;
443
444 /**
445 * Gets the state of a recording, if it exists.
446 *
447 * @param mediaPackageId
448 * The id of the recording.
449 * @return The state of the recording, or null if it does not exist. This should be defined from {@link Recording}.
450 * @throws NotFoundException
451 * if the recording with the given id has not been found
452 */
453 Recording getRecordingState(String mediaPackageId) throws NotFoundException, SchedulerException;
454
455 /**
456 * Removes a recording from the system, if the recording exists.
457 *
458 * @param mediaPackageId
459 * The id of the recording to remove.
460 * @throws NotFoundException
461 * if the recording with the given id has not been found
462 */
463 void removeRecording(String mediaPackageId) throws NotFoundException, SchedulerException;
464
465 /**
466 * Gets the state of all recordings in the system.
467 *
468 * @return A map of recording-state pairs.
469 */
470 Map<String, Recording> getKnownRecordings() throws SchedulerException;
471
472 /**
473 * Cleanup
474 */
475
476 /**
477 * Remove all of the scheduled events before a buffer.
478 *
479 * @param buffer
480 * The number of seconds before now that defines a cutoff for events, if they have their end time before this
481 * cutoff they will be removed
482 * @throws SchedulerException
483 */
484 void removeScheduledRecordingsBeforeBuffer(long buffer) throws UnauthorizedException, SchedulerException;
485
486 }