Added Swagger documentation the files endpoints

Signed-off-by: Matthias Koller <m.koller@peak-solution.de>
diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ClassificationResource.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ClassificationResource.java
index 47fead1..ed3bc01 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ClassificationResource.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ClassificationResource.java
@@ -10,7 +10,7 @@
  *

  * SPDX-License-Identifier: EPL-2.0

  *

- ********************************************************************************/
+ ********************************************************************************/

 

 package org.eclipse.mdm.businessobjects.boundary;

 

@@ -29,7 +29,6 @@
 import javax.ws.rs.core.Response;

 import javax.ws.rs.core.Response.Status;

 

-import org.eclipse.mdm.api.base.model.Environment;

 import org.eclipse.mdm.api.base.model.TestStep;

 import org.eclipse.mdm.api.dflt.model.Classification;

 import org.eclipse.mdm.api.dflt.model.Domain;

@@ -43,6 +42,7 @@
 import io.swagger.v3.oas.annotations.media.Content;

 import io.swagger.v3.oas.annotations.media.Schema;

 import io.swagger.v3.oas.annotations.responses.ApiResponse;

+import io.swagger.v3.oas.annotations.tags.Tag;

 import io.vavr.Value;

 import io.vavr.collection.List;

 import io.vavr.collection.Seq;

@@ -51,6 +51,9 @@
  * @author Alexander Knoblauch

  *

  */

+@Tag(name = "Status")

+@Produces(MediaType.APPLICATION_JSON)

+@Consumes(MediaType.APPLICATION_JSON)

 @Path("/environments/{" + REQUESTPARAM_SOURCENAME + "}/classifications")

 public class ClassificationResource {

 

@@ -60,18 +63,23 @@
 	@EJB

 	private ClassificationService classificationService;

 

+	@Parameter(description = "Name of the MDM datasource", required = true)

+	@PathParam(REQUESTPARAM_SOURCENAME)

+	private String sourceName;

+

 	/**

 	 * delegates the request to the {@link EntityService}

 	 * 

-	 * @param sourceName name of the source (MDM {@link Environment} name)

-	 * @param id         id of the {@link Classification}

+	 * @param id id of the {@link Classification}

 	 * @return the result of the delegated request as {@link Response}

 	 */

 	@GET

-	@Produces(MediaType.APPLICATION_JSON)

+	@Operation(summary = "Find a Classification by ID", responses = {

+			@ApiResponse(description = "The Classification", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),

+			@ApiResponse(responseCode = "500", description = "Error") })

 	@Path("/{" + REQUESTPARAM_ID + "}")

-	public Response findClassification(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,

-			@PathParam(REQUESTPARAM_ID) String id) {

+	public Response findClassification(

+			@Parameter(description = "ID of the Classification", required = true) @PathParam(REQUESTPARAM_ID) String id) {

 		return entityService.find(V(sourceName), Classification.class, V(id))

 				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)

 				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);

@@ -80,19 +88,14 @@
 	/**

 	 * Returns the created/existing {@link Classification}.

 	 * 

-	 * @param sourceName name of the source (MDM {@link Environment} name)

-	 * @param body       The {@link Classification} to create.

+	 * @param body The {@link Classification} to create.

 	 * @return the created {@link TestStep} as {@link Response}.

 	 */

 	@POST

-	@Operation(summary = "Create a new Classification or return if already exists", responses = {

+	@Operation(summary = "Create a new Classification or return a existing Classification which references the same Status, ProjectDomain and Domain.", responses = {

 			@ApiResponse(description = "The created Classification", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),

 			@ApiResponse(responseCode = "500", description = "Error") })

-	@Produces(MediaType.APPLICATION_JSON)

-	@Consumes(MediaType.APPLICATION_JSON)

-	public Response create(

-			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,

-			String body) {

+	public Response createOrFind(String body) {

 

 		Seq<Value<?>> extractRequestBody = entityService.extractRequestBody(body, sourceName, io.vavr.collection.List

 				.of(org.eclipse.mdm.api.dflt.model.Status.class, ProjectDomain.class, Domain.class));

diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ContextFilesSubresource.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ContextFilesSubresource.java
index 1cd74ae..c38dd3a 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ContextFilesSubresource.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ContextFilesSubresource.java
@@ -41,7 +41,9 @@
 import org.eclipse.mdm.api.base.model.MimeType;

 import org.eclipse.mdm.api.base.model.TestStep;

 import org.eclipse.mdm.businessobjects.control.FileLinkActivity;

+import org.eclipse.mdm.businessobjects.entity.FileSize;

 import org.eclipse.mdm.businessobjects.entity.MDMEntityResponse;

+import org.eclipse.mdm.businessobjects.entity.MDMFileLink;

 import org.eclipse.mdm.businessobjects.service.EntityService;

 import org.eclipse.mdm.businessobjects.utils.Serializer;

 import org.eclipse.mdm.businessobjects.utils.ServiceUtils;

@@ -53,7 +55,6 @@
 import io.swagger.v3.oas.annotations.media.Content;

 import io.swagger.v3.oas.annotations.media.Schema;

 import io.swagger.v3.oas.annotations.responses.ApiResponse;

-import io.swagger.v3.oas.annotations.tags.Tag;

 import io.vavr.Tuple;

 

 /**

@@ -62,7 +63,6 @@
  * @author Johannes Stamm, peak-Solution GmbH

  *

  */

-@Tag(name = "ContextFiles")

 public class ContextFilesSubresource {

 

 	@EJB

@@ -95,6 +95,9 @@
 	 * @return

 	 */

 	@POST

+	@Operation(summary = "Creates a new file on a context attribute.", responses = {

+			@ApiResponse(description = "The stored file link.", content = @Content(schema = @Schema(implementation = MDMFileLink.class))),

+			@ApiResponse(responseCode = "400", description = "Error") })

 	@Produces(MediaType.APPLICATION_JSON)

 	@Consumes(MediaType.MULTIPART_FORM_DATA)

 	public Response createFile(

@@ -139,6 +142,9 @@
 	}

 

 	@GET

+	@Operation(summary = "Returns the size of a file in bytes.", responses = {

+			@ApiResponse(description = "The file size of the requested remote path.", content = @Content(schema = @Schema(implementation = FileSize.class))),

+			@ApiResponse(responseCode = "400", description = "Error") })

 	@Produces(MediaType.APPLICATION_JSON)

 	@Path("/size/{" + REQUESTPARAM_REMOTEPATH + "}")

 	public Response loadFileSize(

@@ -163,6 +169,9 @@
 	 * @return

 	 */

 	@DELETE

+	@Operation(summary = "Deletes an attached file from a context attribute.", responses = {

+			@ApiResponse(description = "The deleted file link", content = @Content(schema = @Schema(implementation = MDMFileLink.class))),

+			@ApiResponse(responseCode = "400", description = "Error") })

 	@Produces(MediaType.APPLICATION_JSON)

 	@Path("/{" + REQUESTPARAM_REMOTEPATH + "}")

 	public Response deleteFile(

@@ -179,18 +188,4 @@
 				.map(fileLink -> ServiceUtils.toResponse(Serializer.serializeFileLink(fileLink), Status.OK))

 				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);

 	}

-

-	@GET

-	@Produces(MediaType.APPLICATION_JSON)

-	@Path("sizes/{" + REQUESTPARAM_REMOTEPATH + "}")

-	public Response loadFileSizes(

-			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,

-			@Parameter(description = "The remote path of the file link whose content is to be retrieved", required = true) @PathParam(REQUESTPARAM_REMOTEPATH) String remotePath) {

-

-		return Response.status(Status.NOT_IMPLEMENTED).build();

-//		return entityService.find(V(sourceName), TestStep.class, V(id))

-//				.map(filesAttachable -> fileLinkActivity.loadFileSizes(sourceName, filesAttachable))

-//				.map(fileSizes -> ServiceUtils.toResponse(fileSizes, Status.OK))

-//				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);

-	}

 }

diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/FilesAttachableSubresource.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/FilesAttachableSubresource.java
index 61ff9ac..5049624 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/FilesAttachableSubresource.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/FilesAttachableSubresource.java
@@ -36,7 +36,9 @@
 import org.eclipse.mdm.api.base.model.FilesAttachable;

 import org.eclipse.mdm.api.base.model.MimeType;

 import org.eclipse.mdm.businessobjects.control.FileLinkActivity;

+import org.eclipse.mdm.businessobjects.entity.FileSize;

 import org.eclipse.mdm.businessobjects.entity.MDMEntityResponse;

+import org.eclipse.mdm.businessobjects.entity.MDMFileLink;

 import org.eclipse.mdm.businessobjects.service.EntityService;

 import org.eclipse.mdm.businessobjects.utils.Serializer;

 import org.eclipse.mdm.businessobjects.utils.ServiceUtils;

@@ -45,10 +47,10 @@
 

 import io.swagger.v3.oas.annotations.Operation;

 import io.swagger.v3.oas.annotations.Parameter;

+import io.swagger.v3.oas.annotations.media.ArraySchema;

 import io.swagger.v3.oas.annotations.media.Content;

 import io.swagger.v3.oas.annotations.media.Schema;

 import io.swagger.v3.oas.annotations.responses.ApiResponse;

-import io.swagger.v3.oas.annotations.tags.Tag;

 import io.vavr.Tuple;

 

 /**

@@ -57,7 +59,6 @@
  * @author Johannes Stamm, peak-Solution GmbH

  *

  */

-@Tag(name = "FilesAttachable")

 public class FilesAttachableSubresource {

 

 	@EJB

@@ -123,6 +124,9 @@
 	 * @return

 	 */

 	@DELETE

+	@Operation(summary = "Deletes an attached file.", responses = {

+			@ApiResponse(description = "The deleted file link", content = @Content(schema = @Schema(implementation = MDMFileLink.class))),

+			@ApiResponse(responseCode = "400", description = "Error") })

 	@Produces(MediaType.APPLICATION_JSON)

 	@Path("/{" + REQUESTPARAM_REMOTEPATH + "}")

 	public Response deleteFile(

@@ -144,6 +148,9 @@
 	 * @return

 	 */

 	@POST

+	@Operation(summary = "Attaches a new file.", responses = {

+			@ApiResponse(description = "The stored file link.", content = @Content(schema = @Schema(implementation = MDMFileLink.class))),

+			@ApiResponse(responseCode = "400", description = "Error") })

 	@Produces(MediaType.APPLICATION_JSON)

 	@Consumes(MediaType.MULTIPART_FORM_DATA)

 	public Response createFile(

@@ -172,12 +179,15 @@
 	 * @return The serialized {@link FileLink} with the size.

 	 */

 	@GET

+	@Operation(summary = "Returns the file size of file link.", responses = {

+			@ApiResponse(description = "The file size of the requested file link.", content = @Content(schema = @Schema(implementation = FileSize.class))),

+			@ApiResponse(responseCode = "400", description = "Error") })

 	@Produces(MediaType.APPLICATION_JSON)

 	@Path("/size/{" + REQUESTPARAM_REMOTEPATH + "}")

 	public Response loadFileSize(

 			@Parameter(description = "Name of the MDM datasource", required = true) @PathParam(REQUESTPARAM_SOURCENAME) String sourceName,

-			@Parameter(description = "The remote path of the file link whose content is to be retrieved", required = true) @PathParam(REQUESTPARAM_ID) String id,

-			@Parameter(description = "The remote path of the file link whose content is to be retrieved", required = true) @PathParam(REQUESTPARAM_REMOTEPATH) String remotePath) {

+			@Parameter(description = "The identifier of the FilesAttachable containing the file links", required = true) @PathParam(REQUESTPARAM_ID) String id,

+			@Parameter(description = "The remote path of the file link whose size is to be retrieved", required = true) @PathParam(REQUESTPARAM_REMOTEPATH) String remotePath) {

 

 		return entityService.find(V(sourceName), fileAttachableClass, V(id))

 				.map(filesAttachable -> Tuple.of(filesAttachable,

@@ -198,6 +208,9 @@
 	 * @return The serialized {@link FileLink} with the size.

 	 */

 	@GET

+	@Operation(summary = "Returns the sizes of all file links attached to a FilesAttachable.", responses = {

+			@ApiResponse(description = "The file size of the requested file link.", content = @Content(array = @ArraySchema(schema = @Schema(implementation = FileSize.class)))),

+			@ApiResponse(responseCode = "400", description = "Error") })

 	@Produces(MediaType.APPLICATION_JSON)

 	@Path("/sizes")

 	public Response loadFileSizes(

diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ProjectDomainResource.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ProjectDomainResource.java
index ba5e51b..415fdaf 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ProjectDomainResource.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/ProjectDomainResource.java
@@ -29,41 +29,55 @@
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import org.eclipse.mdm.api.base.model.Environment;
 import org.eclipse.mdm.api.dflt.model.ProjectDomain;
-import org.eclipse.mdm.businessobjects.entity.SearchAttribute;
+import org.eclipse.mdm.businessobjects.entity.MDMEntityResponse;
 import org.eclipse.mdm.businessobjects.service.EntityService;
 import org.eclipse.mdm.businessobjects.utils.RequestBody;
 import org.eclipse.mdm.businessobjects.utils.ServiceUtils;
 
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
 /**
  * {@link ProjectDomain} resource handling REST requests
  * 
  * @author Alexander Knoblauch, Peak Solution GmbH
  *
  */
+@Tag(name = "Status")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
 @Path("/environments/{" + REQUESTPARAM_SOURCENAME + "}/projectdomains")
 public class ProjectDomainResource {
 
 	@EJB
 	private EntityService entityService;
 
+	@Parameter(description = "Name of the MDM datasource", required = true)
+	@PathParam(REQUESTPARAM_SOURCENAME)
+	private String sourceName;
+
 	/**
 	 * Returns the found {@link ProjectDomain}.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param id         id of the {@link ProjectDomain}
+	 * @param id id of the {@link ProjectDomain}
 	 * @return the found {@link ProjectDomain} as {@link Response}
 	 */
 	@GET
-	@Produces(MediaType.APPLICATION_JSON)
+	@Operation(summary = "Find a ProjectDomain by ID", description = "Returns ProjectDomain based on ID", responses = {
+			@ApiResponse(description = "The ProjectDomain", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
 	@Path("/{" + REQUESTPARAM_ID + "}")
-	public Response find(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName, @PathParam(REQUESTPARAM_ID) String id) {
+	public Response find(
+			@Parameter(description = "ID of the ProjectDomain", required = true) @PathParam(REQUESTPARAM_ID) String id) {
 		return entityService.find(V(sourceName), ProjectDomain.class, V(id))
 				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
 				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
@@ -72,14 +86,14 @@
 	/**
 	 * Returns the (filtered) {@link ProjectDomain}s.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param filter     filter string to filter the {@link ProjectDomain} result
+	 * @param filter filter string to filter the {@link ProjectDomain} result
 	 * @return the (filtered) {@link ValueList}s as {@link Response}
 	 */
 	@GET
-	@Produces(MediaType.APPLICATION_JSON)
-	public Response findAll(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
-			@QueryParam("filter") String filter) {
+	@Operation(summary = "Find ProjectDomain by filter", description = "Get list of ProjectDomains", responses = {
+			@ApiResponse(description = "The ProjectDomains", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "400", description = "Error") })
+	public Response findAll(@Parameter(description = "Filter expression", required = false) String filter) {
 		return entityService.findAll(V(sourceName), ProjectDomain.class, filter)
 				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
 				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
@@ -88,14 +102,14 @@
 	/**
 	 * Returns the created {@link ProjectDomain}.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param body       The {@link ProjectDomain} to create.
+	 * @param body The {@link ProjectDomain} to create.
 	 * @return the created {@link ProjectDomain} as {@link Response}.
 	 */
 	@POST
-	@Produces(MediaType.APPLICATION_JSON)
-	@Consumes(MediaType.APPLICATION_JSON)
-	public Response create(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName, String body) {
+	@Operation(summary = "Create a new ProjectDomain", responses = {
+			@ApiResponse(description = "The created ProjectDomain", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "500", description = "Error") })
+	public Response create(String body) {
 		RequestBody requestBody = RequestBody.create(body);
 
 		return entityService
@@ -105,19 +119,20 @@
 	}
 
 	/**
-	 * Updates the {@link ProjectDomain} with all parameters set in the given JSON body
-	 * of the request.
+	 * Updates the {@link ProjectDomain} with all parameters set in the given JSON
+	 * body of the request.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param id         the identifier of the {@link ProjectDomain} to update.
-	 * @param body       the body of the request containing the attributes to update
+	 * @param id   the identifier of the {@link ProjectDomain} to update.
+	 * @param body the body of the request containing the attributes to update
 	 * @return the updated {@link ProjectDomain}
 	 */
 	@PUT
-	@Produces(MediaType.APPLICATION_JSON)
-	@Consumes(MediaType.APPLICATION_JSON)
+	@Operation(summary = "Update an existing ProjectDomain", description = "Updates the ProjectDomain with all parameters set in the body of the request.", responses = {
+			@ApiResponse(description = "The updated ProjectDomain", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
 	@Path("/{" + REQUESTPARAM_ID + "}")
-	public Response update(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName, @PathParam(REQUESTPARAM_ID) String id,
+	public Response update(
+			@Parameter(description = "ID of the ProjectDomain", required = true) @PathParam(REQUESTPARAM_ID) String id,
 			String body) {
 		RequestBody requestBody = RequestBody.create(body);
 
@@ -131,43 +146,18 @@
 	/**
 	 * Deletes and returns the deleted {@link ProjectDomain}.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param id         The identifier of the {@link ProjectDomain} to delete.
+	 * @param id The identifier of the {@link ProjectDomain} to delete.
 	 * @return the deleted {@link ProjectDomain }s as {@link Response}
 	 */
 	@DELETE
-	@Produces(MediaType.APPLICATION_JSON)
+	@Operation(summary = "Delete an existing ProjectDomain", responses = {
+			@ApiResponse(description = "The deleted ProjectDomain", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
 	@Path("/{" + REQUESTPARAM_ID + "}")
-	public Response delete(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
-			@PathParam(REQUESTPARAM_ID) String id) {
+	public Response delete(
+			@Parameter(description = "ID of the ProjectDomain", required = true) @PathParam(REQUESTPARAM_ID) String id) {
 		return entityService.delete(V(sourceName), entityService.find(V(sourceName), ProjectDomain.class, V(id)))
 				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
 				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
 	}
-
-	/**
-	 * Returns the search attributes for the {@link ProjectDomain} type.
-	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @return the {@link SearchAttribute}s as {@link Response}
-	 */
-	@GET
-	@Produces(MediaType.APPLICATION_JSON)
-	@Path("/searchattributes")
-	public Response getSearchAttributes(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName) {
-		return ServiceUtils.buildSearchAttributesResponse(V(sourceName), ProjectDomain.class, entityService);
-	}
-
-	/**
-	 * Returns a map of localization for the entity type and the attributes.
-	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @return the I18N as {@link Response}
-	 */
-	@GET
-	@Produces(MediaType.APPLICATION_JSON)
-	@Path("/localizations")
-	public Response localize(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName) {
-		return ServiceUtils.buildLocalizationResponse(V(sourceName), ProjectDomain.class, entityService);
-	}
 }
\ No newline at end of file
diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/StatusResource.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/StatusResource.java
index 5a2cffc..3d940b4 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/StatusResource.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/StatusResource.java
@@ -34,35 +34,51 @@
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import org.eclipse.mdm.api.base.model.Environment;
-import org.eclipse.mdm.businessobjects.entity.SearchAttribute;
+import org.eclipse.mdm.businessobjects.entity.MDMEntityResponse;
 import org.eclipse.mdm.businessobjects.service.EntityService;
 import org.eclipse.mdm.businessobjects.utils.RequestBody;
 import org.eclipse.mdm.businessobjects.utils.ServiceUtils;
 
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
 /**
  * {@link org.eclipse.mdm.api.dflt.model.Status} resource handling REST requests
  * 
  * @author Alexander Knoblauch, Peak Solution GmbH
  *
  */
+@Tag(name = "Status")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
 @Path("/environments/{" + REQUESTPARAM_SOURCENAME + "}/status")
 public class StatusResource {
 
 	@EJB
 	private EntityService entityService;
 
+	@Parameter(description = "Name of the MDM datasource", required = true)
+	@PathParam(REQUESTPARAM_SOURCENAME)
+	private String sourceName;
+
 	/**
 	 * Returns the found {@link org.eclipse.mdm.api.dflt.model.Status}.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param id         id of the {@link org.eclipse.mdm.api.dflt.model.Status}
-	 * @return the found {@link org.eclipse.mdm.api.dflt.model.Status} as {@link Response}
+	 * @param id id of the {@link org.eclipse.mdm.api.dflt.model.Status}
+	 * @return the found {@link org.eclipse.mdm.api.dflt.model.Status} as
+	 *         {@link Response}
 	 */
 	@GET
-	@Produces(MediaType.APPLICATION_JSON)
+	@Operation(summary = "Find a Status by ID", description = "Returns Status based on ID", responses = {
+			@ApiResponse(description = "The Status", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
 	@Path("/{" + REQUESTPARAM_ID + "}")
-	public Response find(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName, @PathParam(REQUESTPARAM_ID) String id) {
+	public Response find(
+			@Parameter(description = "ID of the ProjectDomain", required = true) @PathParam(REQUESTPARAM_ID) String id) {
 		return entityService.find(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class, V(id))
 				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
 				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
@@ -71,14 +87,16 @@
 	/**
 	 * Returns the (filtered) {@link org.eclipse.mdm.api.dflt.model.Status}s.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param filter     filter string to filter the {@link org.eclipse.mdm.api.dflt.model.Status} result
+	 * @param filter filter string to filter the
+	 *               {@link org.eclipse.mdm.api.dflt.model.Status} result
 	 * @return the (filtered) {@link ValueList}s as {@link Response}
 	 */
 	@GET
-	@Produces(MediaType.APPLICATION_JSON)
-	public Response findAll(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
-			@QueryParam("filter") String filter) {
+	@Operation(summary = "Find Status by filter", description = "Get list of Status", responses = {
+			@ApiResponse(description = "The Status", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "400", description = "Error") })
+	public Response findAll(
+			@Parameter(description = "Filter expression", required = false) @QueryParam("filter") String filter) {
 		return entityService.findAll(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class, filter)
 				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
 				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
@@ -87,86 +105,71 @@
 	/**
 	 * Returns the created {@link org.eclipse.mdm.api.dflt.model.Status}.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param body       The {@link org.eclipse.mdm.api.dflt.model.Status} to create.
-	 * @return the created {@link org.eclipse.mdm.api.dflt.model.Status} as {@link Response}.
+	 * @param body The {@link org.eclipse.mdm.api.dflt.model.Status} to create.
+	 * @return the created {@link org.eclipse.mdm.api.dflt.model.Status} as
+	 *         {@link Response}.
 	 */
 	@POST
-	@Produces(MediaType.APPLICATION_JSON)
-	@Consumes(MediaType.APPLICATION_JSON)
-	public Response create(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName, String body) {
+	@Operation(summary = "Create a new Status", responses = {
+			@ApiResponse(description = "The created Status", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "500", description = "Error") })
+	public Response create(String body) {
 		RequestBody requestBody = RequestBody.create(body);
 
 		return entityService
-				.create(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class, L(requestBody.getStringValueSupplier(ENTITYATTRIBUTE_NAME)))
+				.create(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class,
+						L(requestBody.getStringValueSupplier(ENTITYATTRIBUTE_NAME)))
 				.map(e -> ServiceUtils.buildEntityResponse(e, Status.CREATED))
 				.recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER).getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
 	}
 
 	/**
-	 * Updates the {@link org.eclipse.mdm.api.dflt.model.Status} with all parameters set in the given JSON body
-	 * of the request.
+	 * Updates the {@link org.eclipse.mdm.api.dflt.model.Status} with all parameters
+	 * set in the given JSON body of the request.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param id         the identifier of the {@link org.eclipse.mdm.api.dflt.model.Status} to update.
-	 * @param body       the body of the request containing the attributes to update
+	 * @param id   the identifier of the
+	 *             {@link org.eclipse.mdm.api.dflt.model.Status} to update.
+	 * @param body the body of the request containing the attributes to update
 	 * @return the updated {@link org.eclipse.mdm.api.dflt.model.Status}
 	 */
 	@PUT
-	@Produces(MediaType.APPLICATION_JSON)
-	@Consumes(MediaType.APPLICATION_JSON)
+	@Operation(summary = "Update an existing Status", description = "Updates the Status with all parameters set in the body of the request.", responses = {
+			@ApiResponse(description = "The updated Status", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
 	@Path("/{" + REQUESTPARAM_ID + "}")
-	public Response update(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName, @PathParam(REQUESTPARAM_ID) String id,
+	public Response update(
+			@Parameter(description = "ID of the Status", required = true) @PathParam(REQUESTPARAM_ID) String id,
 			String body) {
 		RequestBody requestBody = RequestBody.create(body);
 
 		return entityService
-				.update(V(sourceName), entityService.find(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class, V(id)),
+				.update(V(sourceName),
+						entityService.find(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class, V(id)),
 						requestBody.getValueMapSupplier())
 				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
 				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
 	}
 
 	/**
-	 * Deletes and returns the deleted {@link org.eclipse.mdm.api.dflt.model.Status}.
+	 * Deletes and returns the deleted
+	 * {@link org.eclipse.mdm.api.dflt.model.Status}.
 	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @param id         The identifier of the {@link org.eclipse.mdm.api.dflt.model.Status} to delete.
-	 * @return the deleted {@link org.eclipse.mdm.api.dflt.model.Status }s as {@link Response}
+	 * @param id The identifier of the {@link org.eclipse.mdm.api.dflt.model.Status}
+	 *           to delete.
+	 * @return the deleted {@link org.eclipse.mdm.api.dflt.model.Status }s as
+	 *         {@link Response}
 	 */
 	@DELETE
-	@Produces(MediaType.APPLICATION_JSON)
+	@Operation(summary = "Delete an existing Status", responses = {
+			@ApiResponse(description = "The deleted Status", content = @Content(schema = @Schema(implementation = MDMEntityResponse.class))),
+			@ApiResponse(responseCode = "400", description = "Invalid ID supplied") })
 	@Path("/{" + REQUESTPARAM_ID + "}")
-	public Response delete(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName,
-			@PathParam(REQUESTPARAM_ID) String id) {
-		return entityService.delete(V(sourceName), entityService.find(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class, V(id)))
+	public Response delete(
+			@Parameter(description = "ID of the Status", required = true) @PathParam(REQUESTPARAM_ID) String id) {
+		return entityService
+				.delete(V(sourceName),
+						entityService.find(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class, V(id)))
 				.map(e -> ServiceUtils.buildEntityResponse(e, Status.OK)).recover(ServiceUtils.ERROR_RESPONSE_SUPPLIER)
 				.getOrElse(ServiceUtils.SERVER_ERROR_RESPONSE);
 	}
-
-	/**
-	 * Returns the search attributes for the {@link org.eclipse.mdm.api.dflt.model.Status} type.
-	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @return the {@link SearchAttribute}s as {@link Response}
-	 */
-	@GET
-	@Produces(MediaType.APPLICATION_JSON)
-	@Path("/searchattributes")
-	public Response getSearchAttributes(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName) {
-		return ServiceUtils.buildSearchAttributesResponse(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class, entityService);
-	}
-
-	/**
-	 * Returns a map of localization for the entity type and the attributes.
-	 * 
-	 * @param sourceName name of the source (MDM {@link Environment} name)
-	 * @return the I18N as {@link Response}
-	 */
-	@GET
-	@Produces(MediaType.APPLICATION_JSON)
-	@Path("/localizations")
-	public Response localize(@PathParam(REQUESTPARAM_SOURCENAME) String sourceName) {
-		return ServiceUtils.buildLocalizationResponse(V(sourceName), org.eclipse.mdm.api.dflt.model.Status.class, entityService);
-	}
 }
\ No newline at end of file
diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/UserResource.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/UserResource.java
index 56f88ed..c5d74d8 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/UserResource.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/boundary/UserResource.java
@@ -36,7 +36,9 @@
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
 
+@Tag(name = "User")
 @Path("/user")
 @PermitAll
 public class UserResource {
diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/entity/MDMFileLink.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/entity/MDMFileLink.java
new file mode 100644
index 0000000..97e57e8
--- /dev/null
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/entity/MDMFileLink.java
@@ -0,0 +1,70 @@
+/********************************************************************************

+ * Copyright (c) 2015-2020 Contributors to the Eclipse Foundation

+ *

+ * See the NOTICE file(s) distributed with this work for additional

+ * information regarding copyright ownership.

+ *

+ * This program and the accompanying materials are made available under the

+ * terms of the Eclipse Public License v. 2.0 which is available at

+ * http://www.eclipse.org/legal/epl-2.0.

+ *

+ * SPDX-License-Identifier: EPL-2.0

+ *

+ ********************************************************************************/

+

+package org.eclipse.mdm.businessobjects.entity;

+

+import org.eclipse.mdm.api.base.model.FileLink;

+

+import io.swagger.v3.oas.annotations.media.Schema;

+

+/**

+ * MDMFileLink (Entity for a {@link FileLink})

+ * 

+ */

+@Schema(description = "Representation of a MDM FileLink")

+public class MDMFileLink {

+

+	private final String remotePath;

+

+	private final String mimeType;

+

+	private final String description;

+

+	/**

+	 * Constructor.

+	 * 

+	 * @param remotePath

+	 * @param mimeType

+	 * @param description

+	 */

+	public MDMFileLink(String remotePath, String mimeType, String description) {

+		this.remotePath = remotePath;

+		this.mimeType = mimeType;

+		this.description = description;

+	}

+

+	/**

+	 * @return the remotePath

+	 */

+	@Schema(description = "The remote path of the FileLink")

+	public String getRemotePath() {

+		return remotePath;

+	}

+

+	/**

+	 * @return the mimeType

+	 */

+	@Schema(description = "The mimetype of the FileLink")

+	public String getMimeType() {

+		return mimeType;

+	}

+

+	/**

+	 * @return the description

+	 */

+	@Schema(description = "The description of the FileLink")

+	public String getDescription() {

+		return description;

+	}

+}

diff --git a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/utils/Serializer.java b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/utils/Serializer.java
index 1193bdd..998b0aa 100644
--- a/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/utils/Serializer.java
+++ b/org.eclipse.mdm.businessobjects/src/main/java/org/eclipse/mdm/businessobjects/utils/Serializer.java
@@ -28,9 +28,9 @@
 import org.eclipse.mdm.api.base.model.Value;
 import org.eclipse.mdm.api.base.model.ValueType;
 import org.eclipse.mdm.businessobjects.control.MDMEntityAccessException;
+import org.eclipse.mdm.businessobjects.entity.MDMFileLink;
 
 import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
 
 /**
  * Serializer for values.
@@ -55,9 +55,8 @@
 		}
 	}
 
-	public static Map<String, String> serializeFileLink(FileLink fileLink) {
-		return ImmutableMap.of("remotePath", fileLink.getRemotePath(), "mimeType", fileLink.getMimeType().toString(),
-				"description", fileLink.getDescription());
+	public static MDMFileLink serializeFileLink(FileLink fileLink) {
+		return new MDMFileLink(fileLink.getRemotePath(), fileLink.getMimeType().toString(), fileLink.getDescription());
 	}
 
 	public static LocalDateTime parseDate(String value) {