Search in sources :

Example 1 with RestResponse

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);
}
Also used : JSONArray(org.json.simple.JSONArray) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) MetadataField(org.opencastproject.metadata.dublincore.MetadataField) DateTime(org.joda.time.DateTime) MetadataList(org.opencastproject.index.service.catalog.adapter.MetadataList) RestResponse(org.opencastproject.util.doc.rest.RestResponse) Response(javax.ws.rs.core.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) Opt(com.entwinemedia.fn.data.Opt) CommonEventCatalogUIAdapter(org.opencastproject.index.service.catalog.adapter.events.CommonEventCatalogUIAdapter) EventCatalogUIAdapter(org.opencastproject.metadata.dublincore.EventCatalogUIAdapter) MediaPackage(org.opencastproject.mediapackage.MediaPackage) Event(org.opencastproject.index.service.impl.index.event.Event) JSONParser(org.json.simple.parser.JSONParser) MetadataCollection(org.opencastproject.metadata.dublincore.MetadataCollection) ParseException(org.json.simple.parser.ParseException) SimpleDateFormat(java.text.SimpleDateFormat) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) RestQuery(org.opencastproject.util.doc.rest.RestQuery) PUT(javax.ws.rs.PUT)

Example 2 with RestResponse

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();
    }
}
Also used : Path(javax.ws.rs.Path) RestResponse(org.opencastproject.util.doc.rest.RestResponse) HttpMethod(javax.ws.rs.HttpMethod) Method(java.lang.reflect.Method) Annotation(java.lang.annotation.Annotation) Produces(javax.ws.rs.Produces) RestParameter(org.opencastproject.util.doc.rest.RestParameter) RestQuery(org.opencastproject.util.doc.rest.RestQuery) HttpMethod(javax.ws.rs.HttpMethod) Test(org.junit.Test)

Example 3 with RestResponse

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);
    }
}
Also used : RestResponse(org.opencastproject.util.doc.rest.RestResponse) RestParameter(org.opencastproject.util.doc.rest.RestParameter)

Aggregations

RestResponse (org.opencastproject.util.doc.rest.RestResponse)3 Path (javax.ws.rs.Path)2 Produces (javax.ws.rs.Produces)2 RestParameter (org.opencastproject.util.doc.rest.RestParameter)2 RestQuery (org.opencastproject.util.doc.rest.RestQuery)2 Opt (com.entwinemedia.fn.data.Opt)1 Annotation (java.lang.annotation.Annotation)1 Method (java.lang.reflect.Method)1 SimpleDateFormat (java.text.SimpleDateFormat)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 HttpMethod (javax.ws.rs.HttpMethod)1 PUT (javax.ws.rs.PUT)1 Response (javax.ws.rs.core.Response)1 DateTime (org.joda.time.DateTime)1 JSONArray (org.json.simple.JSONArray)1 JSONParser (org.json.simple.parser.JSONParser)1 ParseException (org.json.simple.parser.ParseException)1 Test (org.junit.Test)1 MetadataList (org.opencastproject.index.service.catalog.adapter.MetadataList)1 CommonEventCatalogUIAdapter (org.opencastproject.index.service.catalog.adapter.events.CommonEventCatalogUIAdapter)1