use of com.entwinemedia.fn.data.Opt in project opencast by opencast.
the class AbstractEventEndpoint method updateEventScheduling.
@PUT
@Path("{eventId}/scheduling")
@RestQuery(name = "updateEventScheduling", description = "Updates the scheduling information of an event", returnDescription = "The method doesn't return any content", pathParameters = { @RestParameter(name = "eventId", isRequired = true, description = "The event identifier", type = RestParameter.Type.STRING) }, restParameters = { @RestParameter(name = "scheduling", isRequired = true, description = "The updated scheduling (JSON object)", type = RestParameter.Type.TEXT) }, reponses = { @RestResponse(responseCode = SC_BAD_REQUEST, description = "The required params were missing in the request."), @RestResponse(responseCode = SC_NOT_FOUND, description = "If the event has not been found."), @RestResponse(responseCode = SC_NO_CONTENT, description = "The method doesn't return any content") })
public Response updateEventScheduling(@PathParam("eventId") String eventId, @FormParam("scheduling") String scheduling) throws NotFoundException, UnauthorizedException, SearchIndexException {
if (StringUtils.isBlank(scheduling))
return RestUtil.R.badRequest("Missing parameters");
try {
final Event event = getEventOrThrowNotFoundException(eventId);
TechnicalMetadata technicalMetadata = getSchedulerService().getTechnicalMetadata(eventId);
final org.codehaus.jettison.json.JSONObject schedulingJson = new org.codehaus.jettison.json.JSONObject(scheduling);
Opt<String> agentId = Opt.none();
if (schedulingJson.has(SCHEDULING_AGENT_ID_KEY)) {
agentId = Opt.some(schedulingJson.getString(SCHEDULING_AGENT_ID_KEY));
logger.trace("Updating agent id of event '{}' from '{}' to '{}'", eventId, technicalMetadata.getAgentId(), agentId);
}
Opt<Date> start = Opt.none();
if (schedulingJson.has(SCHEDULING_START_KEY)) {
start = Opt.some(new Date(DateTimeSupport.fromUTC(schedulingJson.getString(SCHEDULING_START_KEY))));
logger.trace("Updating start time of event '{}' id from '{}' to '{}'", eventId, DateTimeSupport.toUTC(technicalMetadata.getStartDate().getTime()), DateTimeSupport.toUTC(start.get().getTime()));
}
Opt<Date> end = Opt.none();
if (schedulingJson.has(SCHEDULING_END_KEY)) {
end = Opt.some(new Date(DateTimeSupport.fromUTC(schedulingJson.getString(SCHEDULING_END_KEY))));
logger.trace("Updating end time of event '{}' id from '{}' to '{}'", eventId, DateTimeSupport.toUTC(technicalMetadata.getEndDate().getTime()), DateTimeSupport.toUTC(end.get().getTime()));
}
Opt<Map<String, String>> agentConfiguration = Opt.none();
if (schedulingJson.has(SCHEDULING_AGENT_CONFIGURATION_KEY)) {
agentConfiguration = Opt.some(JSONUtils.toMap(schedulingJson.getJSONObject(SCHEDULING_AGENT_CONFIGURATION_KEY)));
logger.trace("Updating agent configuration of event '{}' id from '{}' to '{}'", eventId, technicalMetadata.getCaptureAgentConfiguration(), agentConfiguration);
}
Opt<Opt<Boolean>> optOut = Opt.none();
if (schedulingJson.has(SCHEDULING_OPT_OUT_KEY)) {
optOut = Opt.some(Opt.some(schedulingJson.getBoolean(SCHEDULING_OPT_OUT_KEY)));
logger.trace("Updating optout status of event '{}' id from '{}' to '{}'", eventId, event.getOptedOut(), optOut);
}
if (start.isNone() && end.isNone() && agentId.isNone() && agentConfiguration.isNone() && optOut.isNone())
return Response.noContent().build();
if ((start.isSome() || end.isSome()) && end.getOr(technicalMetadata.getEndDate()).before(start.getOr(technicalMetadata.getStartDate())))
return RestUtil.R.badRequest("The end date is before the start date");
getSchedulerService().updateEvent(eventId, start, end, agentId, Opt.<Set<String>>none(), Opt.<MediaPackage>none(), Opt.<Map<String, String>>none(), agentConfiguration, optOut, SchedulerService.ORIGIN);
return Response.noContent().build();
} catch (JSONException e) {
return RestUtil.R.badRequest("The scheduling object is not valid");
} catch (ParseException e) {
return RestUtil.R.badRequest("The UTC dates in the scheduling object is not valid");
} catch (SchedulerException e) {
logger.error("Unable to update scheduling technical metadata of event {}: {}", eventId, ExceptionUtils.getStackTrace(e));
throw new WebApplicationException(e, SC_INTERNAL_SERVER_ERROR);
}
}
use of com.entwinemedia.fn.data.Opt in project opencast by opencast.
the class MetadataField method createDateMetadata.
/**
* Create a metadata field based on a {@link Date}.
*
* @param inputID
* The identifier of the new metadata field
* @param label
* The label of the new metadata field
* @param readOnly
* Define if the new metadata is or not a readonly field
* @param required
* Define if the new metadata field is or not required
* @param pattern
* The date pattern for {@link SimpleDateFormat}.
* @param order
* The ui order for the new field, 0 at the top and progressively down from there.
* @return The new metadata field
*/
public static MetadataField<Date> createDateMetadata(String inputID, Opt<String> outputID, String label, boolean readOnly, boolean required, final String pattern, Opt<Integer> order, Opt<String> namespace) {
final SimpleDateFormat dateFormat = getSimpleDateFormatter(pattern);
Fn<Opt<Date>, JValue> dateToJSON = new Fn<Opt<Date>, JValue>() {
@Override
public JValue apply(Opt<Date> date) {
if (date.isNone())
return Jsons.BLANK;
else {
return v(dateFormat.format(date.get()), Jsons.BLANK);
}
}
};
Fn<Object, Date> jsonToDate = new Fn<Object, Date>() {
@Override
public Date apply(Object value) {
try {
String date = (String) value;
if (StringUtils.isBlank(date))
return null;
return dateFormat.parse(date);
} catch (java.text.ParseException e) {
logger.error("Not able to parse date {}: {}", value, e.getMessage());
return null;
}
}
};
MetadataField<Date> dateField = new MetadataField<>(inputID, outputID, label, readOnly, required, null, Opt.none(), Type.DATE, JsonType.DATE, Opt.<Map<String, String>>none(), Opt.<String>none(), dateToJSON, jsonToDate, order, namespace);
if (StringUtils.isNotBlank(pattern)) {
dateField.setPattern(Opt.some(pattern));
}
return dateField;
}
use of com.entwinemedia.fn.data.Opt in project opencast by opencast.
the class MetadataField method createTemporalMetadata.
private static MetadataField<String> createTemporalMetadata(String inputID, Opt<String> outputID, String label, boolean readOnly, boolean required, final String pattern, final Type type, final JsonType jsonType, Opt<Integer> order, Opt<String> namespace) {
if (StringUtils.isBlank(pattern)) {
throw new IllegalArgumentException("For temporal metadata field " + inputID + " of type " + type + " there needs to be a pattern.");
}
final SimpleDateFormat dateFormat = getSimpleDateFormatter(pattern);
Fn<Object, String> jsonToDateString = new Fn<Object, String>() {
@Override
public String apply(Object value) {
String date = (String) value;
if (StringUtils.isBlank(date))
return "";
try {
dateFormat.parse(date);
} catch (java.text.ParseException e) {
logger.error("Not able to parse date string {}: {}", value, getMessage(e));
return null;
}
return date;
}
};
Fn<Opt<String>, JValue> dateToJSON = new Fn<Opt<String>, JValue>() {
@Override
public JValue apply(Opt<String> periodEncodedString) {
if (periodEncodedString.isNone() || StringUtils.isBlank(periodEncodedString.get())) {
return Jsons.BLANK;
}
// Try to parse the metadata as DCIM metadata.
DCMIPeriod p = EncodingSchemeUtils.decodePeriod(periodEncodedString.get());
if (p != null) {
return v(dateFormat.format(p.getStart()), Jsons.BLANK);
}
// Not DCIM metadata so it might already be formatted (given from the front and is being returned there
try {
dateFormat.parse(periodEncodedString.get());
return v(periodEncodedString.get(), Jsons.BLANK);
} catch (Exception e) {
logger.error("Unable to parse temporal metadata '{}' as either DCIM data or a formatted date using pattern {} because: {}", periodEncodedString.get(), pattern, getStackTrace(e));
throw new IllegalArgumentException(e);
}
}
};
MetadataField<String> temporalStart = new MetadataField<>(inputID, outputID, label, readOnly, required, null, Opt.none(), type, jsonType, Opt.<Map<String, String>>none(), Opt.<String>none(), dateToJSON, jsonToDateString, order, namespace);
temporalStart.setPattern(Opt.some(pattern));
return temporalStart;
}
use of com.entwinemedia.fn.data.Opt in project opencast by opencast.
the class SchedulerRestService method updateEvent.
@PUT
@Path("{id}")
@RestQuery(name = "updaterecordings", description = "Updates specified event", returnDescription = "Status OK is returned if event was successfully updated, NOT FOUND if specified event does not exist or BAD REQUEST if data is missing or invalid", pathParameters = { @RestParameter(name = "id", description = "ID of event to be updated", isRequired = true, type = Type.STRING) }, restParameters = { @RestParameter(name = "start", isRequired = false, description = "Updated start date for event", type = Type.INTEGER), @RestParameter(name = "end", isRequired = false, description = "Updated end date for event", type = Type.INTEGER), @RestParameter(name = "agent", isRequired = false, description = "Updated agent for event", type = Type.STRING), @RestParameter(name = "users", isRequired = false, type = Type.STRING, description = "Updated comma separated list of user ids (speakers/lecturers) for the event"), @RestParameter(name = "mediaPackage", isRequired = false, description = "Updated media package for event", type = Type.TEXT), @RestParameter(name = "wfproperties", isRequired = false, description = "Workflow configuration properties", type = Type.TEXT), @RestParameter(name = "agentparameters", isRequired = false, description = "Updated Capture Agent properties", type = Type.TEXT), @RestParameter(name = "updateOptOut", isRequired = true, defaultValue = "false", description = "Whether to update the opt out status", type = Type.BOOLEAN), @RestParameter(name = "optOut", isRequired = false, description = "Update opt out status", type = Type.BOOLEAN), @RestParameter(name = "origin", isRequired = false, description = "The origin", type = Type.STRING) }, reponses = { @RestResponse(responseCode = HttpServletResponse.SC_OK, description = "Event was successfully updated"), @RestResponse(responseCode = HttpServletResponse.SC_NOT_FOUND, description = "Event with specified ID does not exist"), @RestResponse(responseCode = HttpServletResponse.SC_CONFLICT, description = "Unable to update event, conflicting events found (ConflicsFound)"), @RestResponse(responseCode = HttpServletResponse.SC_CONFLICT, description = "Unable to update event, event locked by a transaction (TransactionLock)"), @RestResponse(responseCode = HttpServletResponse.SC_FORBIDDEN, description = "Event with specified ID cannot be updated"), @RestResponse(responseCode = HttpServletResponse.SC_UNAUTHORIZED, description = "You do not have permission to update the event. Maybe you need to authenticate."), @RestResponse(responseCode = HttpServletResponse.SC_BAD_REQUEST, description = "Data is missing or invalid") })
public Response updateEvent(@PathParam("id") String eventID, @FormParam("start") Long startTime, @FormParam("end") Long endTime, @FormParam("agent") String agentId, @FormParam("users") String users, @FormParam("mediaPackage") String mediaPackageXml, @FormParam("wfproperties") String workflowProperties, @FormParam("agentparameters") String agentParameters, @FormParam("updateOptOut") boolean updateOptOut, @FormParam("optOut") Boolean optOutBoolean, @FormParam("origin") String origin) throws UnauthorizedException {
if (StringUtils.isBlank(origin))
origin = SchedulerService.ORIGIN;
if (startTime != null) {
if (startTime < 0) {
logger.debug("Cannot add event with negative start time ({} < 0)", startTime);
return RestUtil.R.badRequest("Cannot add event with negative start time");
}
if (endTime != null && endTime <= startTime) {
logger.debug("Cannot add event without proper end time ({} <= {})", startTime, endTime);
return RestUtil.R.badRequest("Cannot add event without proper end time");
}
}
MediaPackage mediaPackage = null;
if (StringUtils.isNotBlank(mediaPackageXml)) {
try {
mediaPackage = MediaPackageParser.getFromXml(mediaPackageXml);
} catch (Exception e) {
logger.debug("Could not parse media packagey", e);
return Response.status(Status.BAD_REQUEST).build();
}
}
Map<String, String> caProperties = null;
if (StringUtils.isNotBlank(agentParameters)) {
try {
Properties prop = parseProperties(agentParameters);
caProperties = new HashMap<>();
caProperties.putAll((Map) prop);
} catch (Exception e) {
logger.debug("Could not parse capture agent properties: {}", agentParameters, e);
return Response.status(Status.BAD_REQUEST).build();
}
}
Map<String, String> wfProperties = null;
if (StringUtils.isNotBlank(workflowProperties)) {
try {
Properties prop = parseProperties(workflowProperties);
wfProperties = new HashMap<>();
wfProperties.putAll((Map) prop);
} catch (IOException e) {
logger.debug("Could not parse workflow configuration properties: {}", workflowProperties, e);
return Response.status(Status.BAD_REQUEST).build();
}
}
Set<String> userIds = null;
String[] ids = StringUtils.split(StringUtils.trimToNull(users), ",");
if (ids != null) {
userIds = new HashSet<>(Arrays.asList(ids));
}
Date startDate = null;
if (startTime != null) {
startDate = new DateTime(startTime).toDateTime(DateTimeZone.UTC).toDate();
}
Date endDate = null;
if (endTime != null) {
endDate = new DateTime(endTime).toDateTime(DateTimeZone.UTC).toDate();
}
final Opt<Opt<Boolean>> optOut;
if (updateOptOut) {
optOut = Opt.some(Opt.nul(optOutBoolean));
} else {
optOut = Opt.none();
}
try {
service.updateEvent(eventID, Opt.nul(startDate), Opt.nul(endDate), Opt.nul(StringUtils.trimToNull(agentId)), Opt.nul(userIds), Opt.nul(mediaPackage), Opt.nul(wfProperties), Opt.nul(caProperties), optOut, origin);
return Response.ok().build();
} catch (SchedulerTransactionLockException | SchedulerConflictException e) {
return Response.status(Status.CONFLICT).entity(generateErrorResponse(e)).type(MediaType.APPLICATION_JSON).build();
} catch (SchedulerException e) {
logger.warn("Error updating event with id '{}'", eventID, e);
return Response.status(Status.FORBIDDEN).build();
} catch (NotFoundException e) {
logger.info("Event with id '{}' does not exist.", eventID);
return Response.status(Status.NOT_FOUND).build();
} catch (UnauthorizedException e) {
throw e;
} catch (Exception e) {
logger.error("Unable to update event with id '{}'", eventID, e);
return Response.serverError().build();
}
}
Aggregations