Search in sources :

Example 96 with RestQuery

use of org.opencastproject.util.doc.rest.RestQuery in project opencast by opencast.

the class BaseEndpoint method getVersion.

@GET
@Path("version")
@Produces({ "application/json", "application/v1.0.0+json" })
@RestQuery(name = "getversion", description = "Returns a list of available version as well as the default version.", returnDescription = "", reponses = { @RestResponse(description = "The default version is returned.", responseCode = HttpServletResponse.SC_OK) })
public Response getVersion() throws Exception {
    List<JValue> versions = new ArrayList<>();
    versions.add(v(ApiVersion.VERSION_1_0_0.toString()));
    JValue json = obj(f("versions", arr(versions)), f("default", v(ApiVersion.CURRENT_VERSION.toString())));
    return RestUtil.R.ok(MediaType.APPLICATION_JSON_TYPE, serializer.toJson(json));
}
Also used : JValue(com.entwinemedia.fn.data.json.JValue) ArrayList(java.util.ArrayList) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Example 97 with RestQuery

use of org.opencastproject.util.doc.rest.RestQuery 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 98 with RestQuery

use of org.opencastproject.util.doc.rest.RestQuery in project opencast by opencast.

the class EventsEndpoint method getAllEventMetadata.

@GET
@Path("{eventId}/metadata")
@Produces({ "application/json", "application/v1.0.0+json" })
@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) }, reponses = { @RestResponse(description = "The metadata collection is returned.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The specified event does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) })
public Response getAllEventMetadata(@HeaderParam("Accept") String acceptHeader, @PathParam("eventId") String id, @QueryParam("type") String type) throws Exception {
    if (StringUtils.trimToNull(type) == null) {
        Opt<MetadataList> metadataList = getEventMetadataById(id);
        if (metadataList.isSome()) {
            MetadataList actualList = metadataList.get();
            // API v1 should return a two separate fields for start date and start time. Since those fields were merged in index service, we have to split them up.
            Opt<MetadataCollection> collection = actualList.getMetadataByFlavor("dublincore/episode");
            if (collection.isSome()) {
                convertStartDateTimeToApiV1(collection.get());
                ExternalMetadataUtils.changeTypeOrderedTextToText(collection.get());
            }
            return ApiResponses.Json.ok(ApiVersion.VERSION_1_0_0, actualList.toJSON());
        } else
            return ApiResponses.notFound("Cannot find an event with id '%s'.", id);
    } else {
        return getEventMetadataByType(id, type);
    }
}
Also used : MetadataList(org.opencastproject.index.service.catalog.adapter.MetadataList) MetadataCollection(org.opencastproject.metadata.dublincore.MetadataCollection) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Example 99 with RestQuery

use of org.opencastproject.util.doc.rest.RestQuery in project opencast by opencast.

the class SeriesEndpoint method getSeries.

@GET
@Path("{seriesId}")
@Produces({ "application/json", "application/v1.0.0+json" })
@RestQuery(name = "getseries", description = "Returns a single series.", returnDescription = "", pathParameters = { @RestParameter(name = "seriesId", description = "The series id", isRequired = true, type = STRING) }, reponses = { @RestResponse(description = "The series is returned.", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "The specified series does not exist.", responseCode = HttpServletResponse.SC_NOT_FOUND) })
public Response getSeries(@HeaderParam("Accept") String acceptHeader, @PathParam("seriesId") String id) throws Exception {
    for (final Series s : indexService.getSeries(id, externalIndex)) {
        JValue subjects;
        if (s.getSubject() == null) {
            subjects = arr();
        } else {
            subjects = arr(splitSubjectIntoArray(s.getSubject()));
        }
        Date createdDate = s.getCreatedDateTime();
        return ApiResponses.Json.ok(VERSION_1_0_0, obj(f("identifier", v(s.getIdentifier())), f("title", v(s.getTitle())), f("description", v(s.getDescription(), BLANK)), f("creator", v(s.getCreator(), BLANK)), f("subjects", subjects), f("organization", v(s.getOrganization())), f("created", v(createdDate != null ? toUTC(createdDate.getTime()) : null, BLANK)), f("contributors", arr($(s.getContributors()).map(Functions.stringToJValue))), f("organizers", arr($(s.getOrganizers()).map(Functions.stringToJValue))), f("publishers", arr($(s.getPublishers()).map(Functions.stringToJValue))), f("opt_out", v(s.isOptedOut()))));
    }
    return ApiResponses.notFound("Cannot find an series with id '%s'.", id);
}
Also used : Series(org.opencastproject.index.service.impl.index.series.Series) JValue(com.entwinemedia.fn.data.json.JValue) Date(java.util.Date) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Example 100 with RestQuery

use of org.opencastproject.util.doc.rest.RestQuery in project opencast by opencast.

the class SeriesEndpoint method createNewSeries.

@POST
@Path("")
@Produces({ "application/json", "application/v1.0.0+json" })
@RestQuery(name = "createseries", description = "Creates a series.", returnDescription = "", restParameters = { @RestParameter(name = "metadata", isRequired = true, description = "Series metadata", type = STRING), @RestParameter(name = "acl", description = "A collection of roles with their possible action", isRequired = false, type = STRING), @RestParameter(name = "theme", description = "The theme ID to be applied to the series", isRequired = false, type = STRING) }, reponses = { @RestResponse(description = "A new series is created and its identifier is returned in the Location header.", responseCode = HttpServletResponse.SC_CREATED), @RestResponse(description = "The request is invalid or inconsistent..", responseCode = HttpServletResponse.SC_BAD_REQUEST), @RestResponse(description = "The user doesn't have the rights to create the series.", responseCode = HttpServletResponse.SC_UNAUTHORIZED) })
public Response createNewSeries(@HeaderParam("Accept") String acceptHeader, @FormParam("metadata") String metadataParam, @FormParam("acl") String aclParam, @FormParam("theme") String themeIdParam) throws UnauthorizedException, NotFoundException {
    if (isBlank(metadataParam))
        return R.badRequest("Required parameter 'metadata' is missing or invalid");
    MetadataList metadataList;
    try {
        metadataList = deserializeMetadataList(metadataParam);
    } catch (ParseException e) {
        logger.debug("Unable to parse series metadata '{}' because: {}", metadataParam, ExceptionUtils.getStackTrace(e));
        return R.badRequest(String.format("Unable to parse metadata because '%s'", e.toString()));
    } catch (NotFoundException e) {
        // One of the metadata fields could not be found in the catalogs or one of the catalogs cannot be found.
        return R.badRequest(e.getMessage());
    } catch (IllegalArgumentException e) {
        logger.debug("Unable to create series with metadata '{}' because: {}", metadataParam, ExceptionUtils.getStackTrace(e));
        return R.badRequest(e.getMessage());
    }
    Map<String, String> options = new TreeMap<>();
    Opt<Long> optThemeId = Opt.none();
    if (StringUtils.trimToNull(themeIdParam) != null) {
        try {
            Long themeId = Long.parseLong(themeIdParam);
            optThemeId = Opt.some(themeId);
        } catch (NumberFormatException e) {
            return R.badRequest(String.format("Unable to parse the theme id '%s' into a number", themeIdParam));
        }
    }
    AccessControlList acl;
    try {
        acl = AclUtils.deserializeJsonToAcl(aclParam, false);
    } catch (ParseException e) {
        logger.debug("Unable to parse acl '{}' because: '{}'", aclParam, ExceptionUtils.getStackTrace(e));
        return R.badRequest(String.format("Unable to parse acl '%s' because '%s'", aclParam, e.getMessage()));
    } catch (IllegalArgumentException e) {
        logger.debug("Unable to create new series with acl '{}' because: '{}'", aclParam, ExceptionUtils.getStackTrace(e));
        return R.badRequest(e.getMessage());
    }
    try {
        String seriesId = indexService.createSeries(metadataList, options, Opt.some(acl), optThemeId);
        return ApiResponses.Json.created(VERSION_1_0_0, URI.create(getSeriesUrl(seriesId)), obj(f("identifier", v(seriesId, BLANK))));
    } catch (IndexServiceException e) {
        logger.error("Unable to create series with metadata '{}', acl '{}', theme '{}' because: ", metadataParam, aclParam, themeIdParam, ExceptionUtils.getStackTrace(e));
        throw new WebApplicationException(e, Status.INTERNAL_SERVER_ERROR);
    }
}
Also used : AccessControlList(org.opencastproject.security.api.AccessControlList) WebApplicationException(javax.ws.rs.WebApplicationException) NotFoundException(org.opencastproject.util.NotFoundException) TreeMap(java.util.TreeMap) MetadataList(org.opencastproject.index.service.catalog.adapter.MetadataList) ParseException(org.json.simple.parser.ParseException) IndexServiceException(org.opencastproject.index.service.exception.IndexServiceException) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Aggregations

RestQuery (org.opencastproject.util.doc.rest.RestQuery)228 Path (javax.ws.rs.Path)226 Produces (javax.ws.rs.Produces)172 GET (javax.ws.rs.GET)97 POST (javax.ws.rs.POST)89 WebApplicationException (javax.ws.rs.WebApplicationException)83 NotFoundException (org.opencastproject.util.NotFoundException)83 UnauthorizedException (org.opencastproject.security.api.UnauthorizedException)55 MediaPackage (org.opencastproject.mediapackage.MediaPackage)52 SchedulerException (org.opencastproject.scheduler.api.SchedulerException)46 Event (org.opencastproject.index.service.impl.index.event.Event)34 ParseException (java.text.ParseException)33 JSONObject (org.json.simple.JSONObject)33 IOException (java.io.IOException)32 SearchIndexException (org.opencastproject.matterhorn.search.SearchIndexException)32 AclServiceException (org.opencastproject.authorization.xacml.manager.api.AclServiceException)31 Job (org.opencastproject.job.api.Job)30 Date (java.util.Date)29 ArrayList (java.util.ArrayList)28 PUT (javax.ws.rs.PUT)28