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