EventsEndpoint implements ManagedService { @PUT @Path("{eventId}/metadata") @RestQuery(name = "updateeventmetadata", description = "Update the metadata with the matching type of the specified event. For a metadata catalog there is the flavor such as 'dublincore/episode' and this is the unique type.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "type", isRequired = true, description = "The type of metadata to update", type = STRING), @RestParameter(name = "metadata", description = "Metadata catalog in JSON format", isRequired = true, type = STRING) }, responses = { @RestResponse(description = "The metadata of the given namespace has been updated.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The request is invalid or inconsistent.", responseCode = HttpServletResponse.SC_BAD_REQUEST), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) public Response updateEventMetadataByType(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id, @QueryParam("type") String type, @FormParam("metadata") String metadataJSON) throws Exception { Map<String, String> updatedFields; JSONParser parser = new JSONParser(); try { updatedFields = RequestUtils.getKeyValueMap(metadataJSON); } catch (ParseException e) { logger.debug("Unable to update event '{}' with metadata type '{}' and content '{}'", id, type, metadataJSON, e); return RestUtil.R.badRequest(String.format("Unable to parse metadata fields as json from '%s'", metadataJSON)); } catch (IllegalArgumentException e) { logger.debug("Unable to update event '{}' with metadata type '{}' and content '{}'", id, type, metadataJSON, e); return RestUtil.R.badRequest(e.getMessage()); } if (updatedFields == null || updatedFields.size() == 0) { return RestUtil.R.badRequest( String.format("Unable to parse metadata fields as json from '%s' because there were no fields to update.", metadataJSON)); } Opt<MediaPackageElementFlavor> flavor = getFlavor(type); if (flavor.isNone()) { return R.badRequest( String.format("Unable to parse type '%s' as a flavor so unable to find the matching catalog.", type)); } DublinCoreMetadataCollection collection = null; EventCatalogUIAdapter adapter = null; for (final Event event : indexService.getEvent(id, externalIndex)) { MetadataList metadataList = new MetadataList(); if (flavor.get().equals(eventCatalogUIAdapter.getFlavor())) { collection = EventUtils.getEventMetadata(event, eventCatalogUIAdapter); adapter = eventCatalogUIAdapter; } else { metadataList.add(eventCatalogUIAdapter, EventUtils.getEventMetadata(event, eventCatalogUIAdapter)); } List<EventCatalogUIAdapter> catalogUIAdapters = getEventCatalogUIAdapters(); catalogUIAdapters.remove(eventCatalogUIAdapter); MediaPackage mediaPackage = indexService.getEventMediapackage(event); if (catalogUIAdapters.size() > 0) { for (EventCatalogUIAdapter catalogUIAdapter : catalogUIAdapters) { if (flavor.get().equals(catalogUIAdapter.getFlavor())) { collection = catalogUIAdapter.getFields(mediaPackage); adapter = eventCatalogUIAdapter; } else { metadataList.add(catalogUIAdapter, catalogUIAdapter.getFields(mediaPackage)); } } } if (collection == null) { return ApiResponses.notFound("Cannot find a catalog with type '%s' for event with id '%s'.", type, id); } for (String key : updatedFields.keySet()) { if ("subjects".equals(key)) { MetadataField field = collection.getOutputFields().get(DublinCore.PROPERTY_SUBJECT.getLocalName()); Opt<Response> error = validateField(field, key, id, type, updatedFields); if (error.isSome()) { return error.get(); } collection.removeField(field); JSONArray subjectArray = (JSONArray) parser.parse(updatedFields.get(key)); collection.addField( MetadataJson.copyWithDifferentJsonValue(field, StringUtils.join(subjectArray.iterator(), ","))); } else if ("startDate".equals(key)) { MetadataField field = collection.getOutputFields().get(key); Opt<Response> error = validateField(field, key, id, type, updatedFields); if (error.isSome()) { return error.get(); } String apiPattern = field.getPattern(); if (configuredMetadataFields.containsKey("startDate")) { final String startDate = configuredMetadataFields.get("startDate").getPattern(); apiPattern = startDate == null ? apiPattern : startDate; } SimpleDateFormat apiSdf = MetadataField.getSimpleDateFormatter(apiPattern); SimpleDateFormat sdf = MetadataField.getSimpleDateFormatter(field.getPattern()); DateTime oldStartDate = new DateTime(sdf.parse((String) field.getValue()), DateTimeZone.UTC); DateTime newStartDate = new DateTime(apiSdf.parse(updatedFields.get(key)), DateTimeZone.UTC); DateTime updatedStartDate = oldStartDate.withDate(newStartDate.year().get(), newStartDate.monthOfYear().get(), newStartDate.dayOfMonth().get()); collection.removeField(field); collection.addField( MetadataJson.copyWithDifferentJsonValue(field, sdf.format(updatedStartDate.toDate()))); } else if ("startTime".equals(key)) { MetadataField field = collection.getOutputFields().get("startDate"); Opt<Response> error = validateField(field, "startDate", id, type, updatedFields); if (error.isSome()) { return error.get(); } String apiPattern = "HH:mm"; if (configuredMetadataFields.containsKey("startTime")) { final String startTime = configuredMetadataFields.get("startTime").getPattern(); apiPattern = startTime == null ? apiPattern : startTime; } SimpleDateFormat apiSdf = MetadataField.getSimpleDateFormatter(apiPattern); SimpleDateFormat sdf = MetadataField.getSimpleDateFormatter(field.getPattern()); DateTime oldStartDate = new DateTime(sdf.parse((String) field.getValue()), DateTimeZone.UTC); DateTime newStartDate = new DateTime(apiSdf.parse(updatedFields.get(key)), DateTimeZone.UTC); DateTime updatedStartDate = oldStartDate.withTime( newStartDate.hourOfDay().get(), newStartDate.minuteOfHour().get(), newStartDate.secondOfMinute().get(), newStartDate.millisOfSecond().get()); collection.removeField(field); collection.addField( MetadataJson.copyWithDifferentJsonValue(field, sdf.format(updatedStartDate.toDate()))); } else { MetadataField field = collection.getOutputFields().get(key); Opt<Response> error = validateField(field, key, id, type, updatedFields); if (error.isSome()) { return error.get(); } collection.removeField(field); collection.addField( MetadataJson.copyWithDifferentJsonValue(field, updatedFields.get(key))); } } metadataList.add(adapter, collection); indexService.updateEventMetadata(id, metadataList, externalIndex); return Response.noContent().build(); } return ApiResponses.notFound("Cannot find an event with id '%s'.", id); }  void setIndexService(IndexService indexService); void setIngestService(IngestService ingestService); void setUrlSigningService(UrlSigningService urlSigningService); SecurityService getSecurityService(); SchedulerService getSchedulerService(); void setSchedulerService(SchedulerService schedulerService); void setCommonEventCatalogUIAdapter(CommonEventCatalogUIAdapter eventCatalogUIAdapter); void addCatalogUIAdapter(EventCatalogUIAdapter catalogUIAdapter); void removeCatalogUIAdapter(EventCatalogUIAdapter catalogUIAdapter); CaptureAgentStateService getAgentStateService(); void setAgentStateService(CaptureAgentStateService agentStateService); List<EventCatalogUIAdapter> getEventCatalogUIAdapters(String organization); @Override void updated(Dictionary<String, ?> properties); static boolean isNullOrEmpty(List<String> list); @GET @Path("{eventId}") @RestQuery(name = "getevent", description = "Returns a single event. By setting the optional sign parameter to true, the method will pre-sign distribution urls if signing is turned on in Opencast. Remember to consider the maximum validity of signed URLs when caching this response.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "sign", isRequired = false, description = "Whether distribution urls should be signed.", type = Type.BOOLEAN), @RestParameter(name = "withacl", isRequired = false, description = "Whether the acl metadata should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "withmetadata", isRequired = false, description = "Whether the metadata catalogs should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "withscheduling", isRequired = false, description = "Whether the scheduling information should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "withpublications", isRequired = false, description = "Whether the publication ids and urls should be included in the response.", type = Type.BOOLEAN), }, responses = { @RestResponse(description = "The event is returned.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response getEvent(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id,
          @QueryParam("sign") boolean sign, @QueryParam("withacl") Boolean withAcl,
          @QueryParam("withmetadata") Boolean withMetadata, @QueryParam("withscheduling") Boolean withScheduling,
          @QueryParam("withpublications") Boolean withPublications); @GET @Path("{eventId}/media") Response getEventMedia(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id); @DELETE @Path("{eventId}") @RestQuery(name = "deleteevent", description = "Deletes an event.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, responses = { @RestResponse(description = "The event has been deleted.", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response deleteEvent(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id); @POST @Path("{eventId}") @RestQuery(name = "updateeventmetadata", description = "Updates an event.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "acl", isRequired = false, description = "A collection of roles with their possible action", type = Type.STRING), @RestParameter(name = "metadata", isRequired = false, description = "Event metadata as Form param", type = Type.STRING), @RestParameter(name = "scheduling", isRequired = false, description = "Scheduling information as Form param", type = Type.STRING), @RestParameter(name = "presenter", isRequired = false, description = "Presenter movie track", type = Type.FILE), @RestParameter(name = "presentation", isRequired = false, description = "Presentation movie track", type = Type.FILE), @RestParameter(name = "audio", isRequired = false, description = "Audio track", type = Type.FILE), @RestParameter(name = "processing", isRequired = false, description = "Processing instructions task configuration", type = Type.STRING), }, responses = { @RestResponse(description = "The event has been updated.", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "The event could not be updated due to a scheduling conflict.", responseCode = HttpServletResponse.SC_CONFLICT), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response updateEventMetadata(@HeaderParam("Accept") String acceptHeader, @Context HttpServletRequest request,
          @PathParam("eventId") String eventId); @POST @Path("/") @Consumes(MediaType.MULTIPART_FORM_DATA) @RestQuery(name = "createevent", description = "Creates an event by sending metadata, access control list, processing instructions and files in a multipart request.", returnDescription = "", restParameters = { @RestParameter(name = "acl", isRequired = false, description = "A collection of roles with their possible action", type = STRING), @RestParameter(name = "metadata", description = "Event metadata as Form param", isRequired = false, type = STRING), @RestParameter(name = "scheduling", description = "Scheduling information as Form param", isRequired = false, type = STRING), @RestParameter(name = "presenter", description = "Presenter movie track", isRequired = false, type = Type.FILE), @RestParameter(name = "presentation", description = "Presentation movie track", isRequired = false, type = Type.FILE), @RestParameter(name = "audio", description = "Audio track", isRequired = false, type = Type.FILE), @RestParameter(name = "processing", description = "Processing instructions task configuration", isRequired = false, type = STRING) }, responses = { @RestResponse(description = "A new event is created and its identifier is returned in the Location header.", responseCode = HttpServletResponse.SC_CREATED), @RestResponse(description = "The event could not be created due to a scheduling conflict.", responseCode = HttpServletResponse.SC_CONFLICT), @RestResponse(description = "The request is invalid or inconsistent..", responseCode = HttpServletResponse.SC_BAD_REQUEST) }) Response createNewEvent(@HeaderParam("Accept") String acceptHeader, @Context HttpServletRequest request); @GET @Path("/") @RestQuery(name = "getevents", description = "Returns a list of events. By setting the optional sign parameter to true, the method will pre-sign distribution urls if signing is turned on in Opencast. Remember to consider the maximum validity of signed URLs when caching this response.", returnDescription = "", restParameters = { @RestParameter(name = "sign", isRequired = false, description = "Whether distribution urls should be signed.", type = Type.BOOLEAN), @RestParameter(name = "withacl", isRequired = false, description = "Whether the acl metadata should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "withmetadata", isRequired = false, description = "Whether the metadata catalogs should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "withscheduling", isRequired = false, description = "Whether the scheduling information should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "withpublications", isRequired = false, description = "Whether the publication ids and urls should be included in the response.", type = Type.BOOLEAN), @RestParameter(name = "onlyWithWriteAccess", isRequired = false, description = "Whether only to get the events to which we have write access.", type = Type.BOOLEAN), @RestParameter(name = "filter", isRequired = false, description = "A comma seperated list of filters to limit the results with. A filter is the filter's name followed by a colon \":\" and then the value to filter with so it is the form <Filter Name>:<Value to Filter With>.", type = STRING), @RestParameter(name = "sort", description = "Sort the results based upon a list of comma seperated sorting criteria. In the comma seperated list each type of sorting is specified as a pair such as: <Sort Name>:ASC or <Sort Name>:DESC. Adding the suffix ASC or DESC sets the order as ascending or descending order and is mandatory.", isRequired = false, type = STRING), @RestParameter(name = "limit", description = "The maximum number of results to return for a single request.", isRequired = false, type = RestParameter.Type.INTEGER), @RestParameter(name = "offset", description = "The index of the first result to return.", isRequired = false, type = RestParameter.Type.INTEGER) }, responses = { @RestResponse(description = "A (potentially empty) list of events is returned.", responseCode = HttpServletResponse.SC_OK) }) Response getEvents(@HeaderParam("Accept") String acceptHeader, @QueryParam("id") String id,
          @QueryParam("commentReason") String reasonFilter, @QueryParam("commentResolution") String resolutionFilter,
          @QueryParam("filter") List<String> filter, @QueryParam("sort") String sort, @QueryParam("offset") Integer offset,
          @QueryParam("limit") Integer limit, @QueryParam("sign") boolean sign, @QueryParam("withacl") Boolean withAcl,
          @QueryParam("withmetadata") Boolean withMetadata, @QueryParam("withscheduling") Boolean withScheduling,
          @QueryParam("onlyWithWriteAccess") Boolean onlyWithWriteAccess, @QueryParam("withpublications") Boolean withPublications); @GET @Path("{eventId}/acl") @RestQuery(name = "geteventacl", description = "Returns an event's access policy.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, responses = { @RestResponse(description = "The access control list for the specified event is returned.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response getEventAcl(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id); @PUT @Path("{eventId}/acl") @RestQuery(name = "updateeventacl", description = "Update an event's access policy.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "acl", isRequired = true, description = "Access policy", type = STRING) }, responses = { @RestResponse(description = "The access control list for the specified event is updated.", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response updateEventAcl(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id,
          @FormParam("acl") String acl); @POST @Path("{eventId}/acl/{action}") @RestQuery(name = "addeventace", description = "Grants permission to execute action on the specified event to any user with role role. Note that this is a convenience method to avoid having to build and post a complete access control list.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING), @RestParameter(name = "action", description = "The action that is allowed to be executed", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "role", isRequired = true, description = "The role that is granted permission", type = STRING) }, responses = { @RestResponse(description = "The permission has been created in the access control list of the specified event.", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response addEventAce(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id,
          @PathParam("action") String action, @FormParam("role") String role); @DELETE @Path("{eventId}/acl/{action}/{role}") @RestQuery(name = "deleteeventace", description = "Revokes permission to execute action on the specified event from any user with role role.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING), @RestParameter(name = "action", description = "The action that is no longer allowed to be executed", isRequired = true, type = STRING), @RestParameter(name = "role", description = "The role that is no longer granted permission", isRequired = true, type = STRING) }, responses = { @RestResponse(description = "The permission has been revoked from the access control list of the specified event.", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response deleteEventAce(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id,
          @PathParam("action") String action, @PathParam("role") String role); @GET @Path("{eventId}/metadata") @RestQuery(name = "geteventmetadata", description = "Returns the event's metadata of the specified type. For a metadata catalog there is the flavor such as 'dublincore/episode' and this is the unique type.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "type", isRequired = false, description = "The type of metadata to get", type = STRING) }, responses = { @RestResponse(description = "The metadata collection is returned.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response getAllEventMetadata(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id,
          @QueryParam("type") String type); @PUT @Path("{eventId}/metadata") @RestQuery(name = "updateeventmetadata", description = "Update the metadata with the matching type of the specified event. For a metadata catalog there is the flavor such as 'dublincore/episode' and this is the unique type.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "type", isRequired = true, description = "The type of metadata to update", type = STRING), @RestParameter(name = "metadata", description = "Metadata catalog in JSON format", isRequired = true, type = STRING) }, responses = { @RestResponse(description = "The metadata of the given namespace has been updated.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The request is invalid or inconsistent.", responseCode = HttpServletResponse.SC_BAD_REQUEST), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response updateEventMetadataByType(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id,
          @QueryParam("type") String type, @FormParam("metadata") String metadataJSON); @DELETE @Path("{eventId}/metadata") @RestQuery(name = "deleteeventmetadata", description = "Delete the metadata namespace catalog of the specified event. This will remove all fields and values of the catalog.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "type", isRequired = true, description = "The type of metadata to delete", type = STRING) }, responses = { @RestResponse(description = "The metadata of the given namespace has been updated.", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "The main metadata catalog dublincore/episode cannot be deleted as it has mandatory fields.", responseCode = HttpServletResponse.SC_FORBIDDEN), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response deleteEventMetadataByType(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id,
          @QueryParam("type") String type); @GET @Path("{eventId}/publications") @RestQuery(name = "geteventpublications", description = "Returns an event's list of publications.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "sign", description = "Whether distribution urls should be signed.", isRequired = false, type = Type.BOOLEAN) }, responses = { @RestResponse(description = "The list of publications is returned.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response getEventPublications(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id,
          @QueryParam("sign") boolean sign); @GET @Path("{eventId}/publications/{publicationId}") @RestQuery(name = "geteventpublication", description = "Returns a single publication.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING), @RestParameter(name = "publicationId", description = "The publication id", isRequired = true, type = STRING) }, restParameters = { @RestParameter(name = "sign", description = "Whether distribution urls should be signed.", isRequired = false, type = Type.BOOLEAN) }, responses = { @RestResponse(description = "The track details are returned.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The specified event or publication does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response getEventPublication(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String eventId,
          @PathParam("publicationId") String publicationId, @QueryParam("sign") boolean sign); @GET @Path("{eventId}/scheduling") @Produces({ ApiMediaType.JSON, ApiMediaType.VERSION_1_1_0, ApiMediaType.VERSION_1_2_0, ApiMediaType.VERSION_1_3_0, ApiMediaType.VERSION_1_4_0, ApiMediaType.VERSION_1_5_0 }) @RestQuery(name = "geteventscheduling", description = "Returns an event's scheduling information.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = STRING) }, responses = { @RestResponse(description = "The scheduling information for the specified event is returned.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The specified event has no scheduling information.", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response getEventScheduling(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id); @PUT @Path("{eventId}/scheduling") @Produces({ ApiMediaType.JSON, ApiMediaType.VERSION_1_1_0, ApiMediaType.VERSION_1_2_0, ApiMediaType.VERSION_1_3_0, ApiMediaType.VERSION_1_4_0, ApiMediaType.VERSION_1_5_0 }) @RestQuery(name = "updateeventscheduling", description = "Update an event's scheduling information.", returnDescription = "", pathParameters = { @RestParameter(name = "eventId", description = "The event id", isRequired = true, type = Type.STRING) }, restParameters = { @RestParameter(name = "scheduling", isRequired = true, description = "Scheduling Information", type = Type.STRING), @RestParameter(name = "allowConflict", description = "Allow conflicts when updating scheduling", isRequired = false, type = Type.BOOLEAN) }, responses = { @RestResponse(description = "The scheduling information for the specified event is updated.", responseCode = HttpServletResponse.SC_NO_CONTENT), @RestResponse(description = "The specified event has no scheduling information to update.", responseCode = HttpServletResponse.SC_NOT_ACCEPTABLE), @RestResponse(description = "The scheduling information could not be updated due to a conflict.", responseCode = HttpServletResponse.SC_CONFLICT), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response updateEventScheduling(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id,
                                 @FormParam("scheduling") String scheduling,
                                 @FormParam("allowConflict") @DefaultValue("false") boolean allowConflict);  }
@Test public void testUpdateEventMetadataByType() throws IOException { String jsonString = IOUtils.toString(getClass().getResource("/event-metadata-update.json"), UTF_8); String expectedJson = IOUtils.toString(getClass().getResource("/event-metadata-update-expected.json"), UTF_8); String eventId = TestEventsEndpoint.METADATA_UPDATE_EVENT; given().formParam("metadata", jsonString).pathParam("event_id", eventId).queryParam("type", "dublincore/episode") .expect().statusCode(SC_NO_CONTENT).when().put(env.host("{event_id}/metadata")); MetadataList actualMetadataList = TestEventsEndpoint.getCapturedMetadataList2().getValue(); assertThat(MetadataJson.collectionToJson(actualMetadataList.getMetadataByFlavor("dublincore/episode"), true).toString(), SameJSONAs.sameJSONAs(expectedJson).allowingAnyArrayOrdering()); }