use of org.opencastproject.util.doc.rest.RestResponse in project opencast by opencast.
the class EventsEndpoint method updateEventMetadataByType.
@PUT
@Path("{eventId}/metadata")
@Produces({ "application/json", "application/v1.0.0+json" })
@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) }, reponses = { @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 '{}' because: {}", id, type, metadataJSON, ExceptionUtils.getStackTrace(e));
return RestUtil.R.badRequest(String.format("Unable to parse metadata fields as json from '%s' because '%s'", metadataJSON, ExceptionUtils.getStackTrace(e)));
} catch (IllegalArgumentException e) {
logger.debug("Unable to update event '{}' with metadata type '{}' and content '{}' because: {}", id, type, metadataJSON, ExceptionUtils.getStackTrace(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));
}
MetadataCollection collection = null;
EventCatalogUIAdapter adapter = null;
for (final Event event : indexService.getEvent(id, externalIndex)) {
MetadataList metadataList = new MetadataList();
// Try the main catalog first as we load it from the index.
if (flavor.get().equals(eventCatalogUIAdapter.getFlavor())) {
collection = EventUtils.getEventMetadata(event, eventCatalogUIAdapter);
adapter = eventCatalogUIAdapter;
} else {
metadataList.add(eventCatalogUIAdapter, EventUtils.getEventMetadata(event, eventCatalogUIAdapter));
}
// Try the other catalogs
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(MetadataField.copyMetadataFieldWithValue(field, StringUtils.join(subjectArray.iterator(), ",")));
} else if ("startDate".equals(key)) {
// Special handling for start date since in API v1 we expect start date and start time to be separate fields.
MetadataField<String> field = (MetadataField<String>) collection.getOutputFields().get(key);
Opt<Response> error = validateField(field, key, id, type, updatedFields);
if (error.isSome()) {
return error.get();
}
String apiPattern = field.getPattern().get();
if (configuredMetadataFields.containsKey("startDate")) {
apiPattern = configuredMetadataFields.get("startDate").getPattern().getOr(apiPattern);
}
SimpleDateFormat apiSdf = MetadataField.getSimpleDateFormatter(apiPattern);
SimpleDateFormat sdf = MetadataField.getSimpleDateFormatter(field.getPattern().get());
DateTime oldStartDate = new DateTime(sdf.parse(field.getValue().get()), 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(MetadataField.copyMetadataFieldWithValue(field, sdf.format(updatedStartDate.toDate())));
} else if ("startTime".equals(key)) {
// Special handling for start time since in API v1 we expect start date and start time to be separate fields.
MetadataField<String> field = (MetadataField<String>) 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")) {
apiPattern = configuredMetadataFields.get("startTime").getPattern().getOr(apiPattern);
}
SimpleDateFormat apiSdf = MetadataField.getSimpleDateFormatter(apiPattern);
SimpleDateFormat sdf = MetadataField.getSimpleDateFormatter(field.getPattern().get());
DateTime oldStartDate = new DateTime(sdf.parse(field.getValue().get()), 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(MetadataField.copyMetadataFieldWithValue(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(MetadataField.copyMetadataFieldWithValue(field, updatedFields.get(key)));
}
}
metadataList.add(adapter, collection);
indexService.updateEventMetadata(id, metadataList, externalIndex);
return ApiResponses.Json.noContent(ApiVersion.VERSION_1_0_0);
}
return ApiResponses.notFound("Cannot find an event with id '%s'.", id);
}
use of org.opencastproject.util.doc.rest.RestResponse in project opencast by opencast.
the class RestDocsAnnotationTest method testRestQueryDocs2.
/**
* This tests the functionality of @RestQuery, @RestParameter, @RestResponse, @Path, @Produces, @Consumes annotation
* type using a different technique.
*/
@Test
public void testRestQueryDocs2() {
Method testMethod;
try {
testMethod = TestServletSample.class.getMethod("methodA");
if (testMethod != null) {
RestDocData restDocData = new RestDocData("NAME", "TITLE", "URL", null, new TestServletSample(), new HashMap<String, String>());
RestQuery restQueryAnnotation = (RestQuery) testMethod.getAnnotation(RestQuery.class);
Path pathAnnotation = (Path) testMethod.getAnnotation(Path.class);
Produces producesAnnotation = (Produces) testMethod.getAnnotation(Produces.class);
String httpMethodString = null;
// we cannot hard code the GET.class or POST.class because we don't know which one is used.
for (Annotation a : testMethod.getAnnotations()) {
HttpMethod method = (HttpMethod) a.annotationType().getAnnotation(HttpMethod.class);
if (method != null) {
httpMethodString = method.value();
}
}
RestEndpointData endpoint = new RestEndpointData(testMethod.getReturnType(), restDocData.processMacro(restQueryAnnotation.name()), httpMethodString, "/" + pathAnnotation.value(), restDocData.processMacro(restQueryAnnotation.description()));
if (!restQueryAnnotation.returnDescription().isEmpty()) {
endpoint.addNote("Return value description: " + restDocData.processMacro(restQueryAnnotation.returnDescription()));
}
// name, description and return description
assertEquals("addTrackInputStream", endpoint.getName());
assertEquals("Add a media track to a given media package using an input stream", endpoint.getDescription());
assertEquals(1, endpoint.getNotes().size());
assertEquals("Return value description: augmented media package", endpoint.getNotes().get(0));
// HTTP method
assertEquals("POST", endpoint.getMethod());
assertEquals("/addTrack", endpoint.getPath());
// @Produces
if (producesAnnotation != null) {
for (String format : producesAnnotation.value()) {
endpoint.addFormat(new RestFormatData(format));
}
}
assertEquals(1, endpoint.getFormats().size());
assertEquals(MediaType.TEXT_XML, endpoint.getFormats().get(0).getName());
// responses
for (RestResponse restResp : restQueryAnnotation.reponses()) {
endpoint.addStatus(restResp, restDocData);
}
assertEquals(3, endpoint.getStatuses().size());
assertEquals(HttpServletResponse.SC_OK, endpoint.getStatuses().get(0).getCode());
assertEquals("Returns augmented media package", endpoint.getStatuses().get(0).getDescription());
assertEquals(HttpServletResponse.SC_BAD_REQUEST, endpoint.getStatuses().get(1).getCode());
assertEquals(null, endpoint.getStatuses().get(1).getDescription());
assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, endpoint.getStatuses().get(2).getCode());
assertEquals(null, endpoint.getStatuses().get(2).getDescription());
// body parameter
if (restQueryAnnotation.bodyParameter().type() != RestParameter.Type.NO_PARAMETER) {
endpoint.addBodyParam(restQueryAnnotation.bodyParameter(), restDocData);
}
assertEquals("BODY", endpoint.getBodyParam().getName());
assertEquals("The media track file", endpoint.getBodyParam().getDescription());
assertTrue(endpoint.getBodyParam().isRequired());
assertEquals(null, endpoint.getBodyParam().getDefaultValue());
assertTrue("FILE".equalsIgnoreCase(endpoint.getBodyParam().getType()));
// path parameter
for (RestParameter restParam : restQueryAnnotation.pathParameters()) {
endpoint.addPathParam(new RestParamData(restParam, restDocData));
}
assertEquals(1, endpoint.getPathParams().size());
assertEquals("wdID", endpoint.getPathParams().get(0).getName());
assertEquals("Workflow definition id", endpoint.getPathParams().get(0).getDescription());
assertTrue(endpoint.getPathParams().get(0).isRequired());
assertTrue(endpoint.getPathParams().get(0).isPath());
assertEquals(null, endpoint.getPathParams().get(0).getDefaultValue());
assertTrue("STRING".equalsIgnoreCase(endpoint.getPathParams().get(0).getType()));
// query parameters
for (RestParameter restParam : restQueryAnnotation.restParameters()) {
if (restParam.isRequired()) {
endpoint.addRequiredParam(new RestParamData(restParam, restDocData));
} else {
endpoint.addOptionalParam(new RestParamData(restParam, restDocData));
}
}
// #1
assertEquals(1, endpoint.getRequiredParams().size());
assertEquals("flavor", endpoint.getRequiredParams().get(0).getName());
assertEquals("The kind of media track", endpoint.getRequiredParams().get(0).getDescription());
assertTrue(endpoint.getRequiredParams().get(0).isRequired());
assertEquals("Default", endpoint.getRequiredParams().get(0).getDefaultValue());
assertTrue("STRING".equalsIgnoreCase(endpoint.getRequiredParams().get(0).getType()));
// #2
assertEquals(1, endpoint.getOptionalParams().size());
assertEquals("mediaPackage", endpoint.getOptionalParams().get(0).getName());
assertEquals("The media package as XML", endpoint.getOptionalParams().get(0).getDescription());
assertFalse(endpoint.getOptionalParams().get(0).isRequired());
assertEquals(null, endpoint.getOptionalParams().get(0).getDefaultValue());
assertTrue("TEXT".equalsIgnoreCase(endpoint.getOptionalParams().get(0).getType()));
}
} catch (SecurityException e) {
fail();
} catch (NoSuchMethodException e) {
fail();
}
}
use of org.opencastproject.util.doc.rest.RestResponse in project opencast by opencast.
the class RestDocData method addEndpoint.
/**
* Add an endpoint to the Rest documentation.
*
* @param restQuery
* the RestQuery annotation type storing information of an endpoint
* @param returnType
* the return type for this endpoint. If this is {@link javax.xml.bind.annotation.XmlRootElement} or
* {@link javax.xml.bind.annotation.XmlRootElement}, the XML schema for the class will be made available to
* clients
* @param produces
* the return type(s) of this endpoint, values should be constants from <a
* href="http://jackson.codehaus.org/javadoc/jax-rs/1.0/javax/ws/rs/core/MediaType.html"
* >javax.ws.rs.core.MediaType</a> or ExtendedMediaType
* (org.opencastproject.util.doc.rest.ExtendedMediaType).
* @param httpMethodString
* the HTTP method of this endpoint (e.g. GET, POST)
* @param path
* the path of this endpoint
*/
public void addEndpoint(RestQuery restQuery, Class<?> returnType, Produces produces, String httpMethodString, Path path) {
String pathValue = path.value().startsWith("/") ? path.value() : "/" + path.value();
RestEndpointData endpoint = new RestEndpointData(returnType, this.processMacro(restQuery.name()), httpMethodString, pathValue, processMacro(restQuery.description()));
// Add return description if needed
if (!restQuery.returnDescription().isEmpty()) {
endpoint.addNote("Return value description: " + processMacro(restQuery.returnDescription()));
}
// Add formats
if (produces != null) {
for (String format : produces.value()) {
endpoint.addFormat(new RestFormatData(format));
}
}
// Add responses
for (RestResponse restResp : restQuery.reponses()) {
endpoint.addStatus(restResp, this);
}
// Add body parameter
if (restQuery.bodyParameter().type() != RestParameter.Type.NO_PARAMETER) {
endpoint.addBodyParam(restQuery.bodyParameter(), this);
}
// Add path parameter
for (RestParameter pathParam : restQuery.pathParameters()) {
endpoint.addPathParam(new RestParamData(pathParam, this));
}
// Add query parameter (required and optional)
for (RestParameter restParam : restQuery.restParameters()) {
if (restParam.isRequired()) {
endpoint.addRequiredParam(new RestParamData(restParam, this));
} else {
endpoint.addOptionalParam(new RestParamData(restParam, this));
}
}
// Set the test form after all parameters are added.
endpoint.setTestForm(new RestFormData(endpoint));
// Add the endpoint to the corresponding group based on its HTTP method
if ("GET".equalsIgnoreCase(httpMethodString) || "HEAD".equalsIgnoreCase(httpMethodString)) {
addEndpoint(READ_ENDPOINT_HOLDER_NAME, endpoint);
} else if ("DELETE".equalsIgnoreCase(httpMethodString) || "POST".equalsIgnoreCase(httpMethodString) || "PUT".equalsIgnoreCase(httpMethodString)) {
addEndpoint(WRITE_ENDPOINT_HOLDER_NAME, endpoint);
}
}
Aggregations