diff --git a/pom.xml b/pom.xml index 773164874bfacb7d6bdc93c197fa229546436c27..1a69f130bae2d1cabd9af40d2fa131239cfe69c2 100644 --- a/pom.xml +++ b/pom.xml @@ -424,6 +424,16 @@ <artifactId>cxf-rt-rs-http-sci</artifactId> <version>${apache.cxf}</version> </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-service-description-openapi-v3</artifactId> + <version>${apache.cxf}</version> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>swagger-ui</artifactId> + <version>3.22.2</version> + </dependency> <dependency> <groupId>jakarta.xml.ws</groupId> <artifactId>jakarta.xml.ws-api</artifactId> @@ -2483,6 +2493,11 @@ <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.dataformat</groupId> + <artifactId>jackson-dataformat-yaml</artifactId> + <version>${jackson.version}</version> </dependency> <!-- end Apache CXF dependency and Active MQ Broker --> diff --git a/src/main/java/org/olat/admin/restapi/RestapiAdminController.java b/src/main/java/org/olat/admin/restapi/RestapiAdminController.java index 071be9a4fe2d805c40742d5d6380767697b287e4..3825618bfb45d34b1cba7fb4c7b09afa87f733a8 100644 --- a/src/main/java/org/olat/admin/restapi/RestapiAdminController.java +++ b/src/main/java/org/olat/admin/restapi/RestapiAdminController.java @@ -94,6 +94,10 @@ public class RestapiAdminController extends FormBasicController { String link = Settings.getServerContextPathURI() + RestSecurityHelper.SUB_CONTEXT + "/api/doc"; docLinkFlc.contextPut("docLink", link); + String openApiLink = Settings.getServerContextPathURI() + RestSecurityHelper.SUB_CONTEXT + "/openapi.json"; + docLinkFlc.contextPut("openApiLink", openApiLink); + String swaggerUiLink = Settings.getServerContextPathURI() + RestSecurityHelper.SUB_CONTEXT + "/api-docs/?url=" + RestSecurityHelper.SUB_CONTEXT + "/openapi.json"; + docLinkFlc.contextPut("swaggerUiLink", swaggerUiLink); FormLayoutContainer accessDataFlc = FormLayoutContainer.createDefaultFormLayout("flc_access_data", getTranslator()); layoutContainer.add(accessDataFlc); diff --git a/src/main/java/org/olat/admin/restapi/_content/docLink.html b/src/main/java/org/olat/admin/restapi/_content/docLink.html index 396df069dd7f2ec5686cb9eccccd09c44a0df62f..1f4fa6035b2036d49aedcc898f5a2ddb424879a5 100644 --- a/src/main/java/org/olat/admin/restapi/_content/docLink.html +++ b/src/main/java/org/olat/admin/restapi/_content/docLink.html @@ -1 +1 @@ -<p>$r.translate("rest.doc"): <a href="$docLink" target="_blanck">$docLink</a></p> \ No newline at end of file +<p>$r.translate("rest.doc"): <a href="$docLink" target="_blanck">$docLink <i class="o_icon o_icon_content_popup"> </i></a><p><h5><i class="o_icon o_icon_warn"> </i> $r.translate("rest.doc.openapi.experimental")</h5><p>$r.translate("rest.doc.openapi"): <a href="$openApiLink" target="_blanck">$openApiLink <i class="o_icon o_icon_code"> </i></a><br>$r.translate("rest.doc.swagger.ui"): <a href="$swaggerUiLink" target="_blanck">$swaggerUiLink <i class="o_icon o_icon_content_popup"> </i></a></p> \ No newline at end of file diff --git a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties index e77dea9718c31e76d450a3facc0ea1741cb9f768..ddec53d12a6992fc90489e52f3d2d527f9f1e3d5 100644 --- a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties @@ -1,5 +1,8 @@ #Mon Mar 02 09:54:03 CET 2009 rest.doc=Dokumentation +rest.doc.openapi=Raw JSON +rest.doc.openapi.experimental=Experimental Dokumentation OpenAPI 3.0 +rest.doc.swagger.ui=SwaggerUI rest.title=REST API rest.intro=Die REST API macht viele OLAT-Funktionalit\u00E4ten f\u00FCr andere Systeme zug\u00E4nglich. Es ist u.a. m\u00F6glich, Benutzer und Lerngruppen zu verwalten, Kurse zu importieren und Kataloge zu f\u00FChren. rest.enabled=REST API Zugang diff --git a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties index 100ebc204d70602dfebe87ffe76507f038ebf0be..d6ebfb35846c31be0c7338d7b4fa319678ff2845 100644 --- a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties @@ -42,6 +42,9 @@ managed.relation.role=Managed user to user relations managed.repo=Managed learning resources managed.user.portrait=Managed user portrait rest.doc=Documentation +rest.doc.openapi=Raw JSON +rest.doc.openapi.experimental=Experimental documentation OpenAPI 3.0 +rest.doc.swagger.ui=SwaggerUI rest.enabled=Access REST API rest.intro=REST API makes various OLAT features accessible to other systems. It is e.g. possible to manage users and learning groups, import courses, or assemble catalogs. rest.on=on diff --git a/src/main/java/org/olat/restapi/_spring/restApiContext.xml b/src/main/java/org/olat/restapi/_spring/restApiContext.xml index 030165e4141b6264a8a8a1999c1ca59a378f1221..0d6d34220ad9441f67ef99f31040da1464371f74 100644 --- a/src/main/java/org/olat/restapi/_spring/restApiContext.xml +++ b/src/main/java/org/olat/restapi/_spring/restApiContext.xml @@ -8,12 +8,19 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> + <!-- CXF OpenApiFeature --> + <bean id="openApiFeature" class="org.apache.cxf.jaxrs.openapi.OpenApiFeature"> + <!-- customize some of the properties --> + </bean> <jaxrs:server address="/" basePackages="org.olat"> <jaxrs:providers> <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/> <bean class="org.olat.restapi.security.OpenOLATContainerResponseFilter" /> </jaxrs:providers> + <jaxrs:features> + <ref bean="openApiFeature" /> + </jaxrs:features> </jaxrs:server> <context:component-scan base-package="org.olat.restapi,org.olat.restapi.security,org.olat.restapi.system" /> diff --git a/src/main/java/org/olat/restapi/repository/RepositoryEntriesWebService.java b/src/main/java/org/olat/restapi/repository/RepositoryEntriesWebService.java index 1b157c255035aff526f1fd4b3e30ec4ddf96366f..645eb712f0ecd50f02be365b5456557dc33b8869 100644 --- a/src/main/java/org/olat/restapi/repository/RepositoryEntriesWebService.java +++ b/src/main/java/org/olat/restapi/repository/RepositoryEntriesWebService.java @@ -31,7 +31,6 @@ import static org.olat.restapi.security.RestSecurityHelper.getRoles; import static org.olat.restapi.security.RestSecurityHelper.getUserRequest; import java.io.File; -import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -52,8 +51,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; -import javax.ws.rs.core.UriBuilder; -import javax.ws.rs.core.UriInfo; import org.apache.logging.log4j.Logger; import org.olat.basesecurity.OrganisationRoles; @@ -82,6 +79,11 @@ import org.olat.restapi.support.vo.RepositoryEntryVOes; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.*; + /** * Description:<br> * This handles the repository entries @@ -117,46 +119,6 @@ public class RepositoryEntriesWebService { public Response getVersion() { return Response.ok(VERSION).build(); } - - /** - * List all entries in the OLAT repository - * @response.representation.200.qname {http://www.example.com}repositoryEntryVO - * @response.representation.200.mediaType text/plain, text/html, application/xml, application/json - * @response.representation.200.doc List all entries in the repository - * @response.representation.200.example {@link org.olat.restapi.support.vo.Examples#SAMPLE_REPOENTRYVOes} - * @param uriInfo The URI information - * @param httpRequest The HTTP request - * @return - */ - @GET - @Produces({MediaType.TEXT_HTML, MediaType.TEXT_PLAIN}) - public Response getEntriesText(@Context UriInfo uriInfo, @Context HttpServletRequest httpRequest) { - try { - // list of courses open for everybody - Roles roles = getRoles(httpRequest); - Identity identity = getIdentity(httpRequest); - - SearchRepositoryEntryParameters params = new SearchRepositoryEntryParameters(identity, roles); - List<RepositoryEntry> coursRepos = repositoryManager.genericANDQueryWithRolesRestriction(params, 0, -1, false); - - StringBuilder sb = new StringBuilder(); - sb.append("Course List\n"); - for (RepositoryEntry repoE : coursRepos) { - UriBuilder baseUriBuilder = uriInfo.getBaseUriBuilder(); - URI repoUri = baseUriBuilder.path(RepositoryEntriesWebService.class) - .path(repoE.getKey().toString()) - .build(); - - sb.append("<a href=\"").append(repoUri).append(">") - .append(repoE.getDisplayname()).append("(").append(repoE.getKey()).append(")") - .append("</a>").append("\n"); - } - - return Response.ok(sb.toString()).build(); - } catch(Exception e) { - throw new WebApplicationException(e); - } - } /** * List all entries in the OLAT repository @@ -176,6 +138,17 @@ public class RepositoryEntriesWebService { */ @GET @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", + description = "JVM system properties of a particular host.", + content = { + @Content(mediaType = "application/json", schema = @Schema(implementation = RepositoryEntryVO[].class)), + @Content(mediaType = "application/xml", schema = @Schema(implementation = RepositoryEntryVO[].class)) + } + )} + ) + @Operation(summary = "List all entries in the repository", + description = "List all entries in the OpenOLAT repository.") public Response getEntries(@QueryParam("start") @DefaultValue("0") Integer start, @QueryParam("limit") @DefaultValue("25") Integer limit, @QueryParam("managed") Boolean managed, @QueryParam("externalId") String externalId,