1 package de.dlr.shepard.context.references.file.endpoints; 2 3 import de.dlr.shepard.common.filters.Subscribable; 4 import de.dlr.shepard.common.mongoDB.NamedInputStream; 5 import de.dlr.shepard.common.util.Constants; 6 import de.dlr.shepard.context.references.file.entities.FileReference; 7 import de.dlr.shepard.context.references.file.io.FileReferenceIO; 8 import de.dlr.shepard.context.references.file.services.FileReferenceService; 9 import de.dlr.shepard.data.file.entities.ShepardFile; 10 import jakarta.enterprise.context.RequestScoped; 11 import jakarta.inject.Inject; 12 import jakarta.validation.Valid; 13 import jakarta.validation.constraints.NotNull; 14 import jakarta.validation.constraints.PositiveOrZero; 15 import jakarta.ws.rs.Consumes; 16 import jakarta.ws.rs.DELETE; 17 import jakarta.ws.rs.GET; 18 import jakarta.ws.rs.POST; 19 import jakarta.ws.rs.Path; 20 import jakarta.ws.rs.PathParam; 21 import jakarta.ws.rs.Produces; 22 import jakarta.ws.rs.QueryParam; 23 import jakarta.ws.rs.core.Context; 24 import jakarta.ws.rs.core.MediaType; 25 import jakarta.ws.rs.core.Response; 26 import jakarta.ws.rs.core.Response.Status; 27 import jakarta.ws.rs.core.SecurityContext; 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.UUID; 31 import org.eclipse.microprofile.openapi.annotations.Operation; 32 import org.eclipse.microprofile.openapi.annotations.enums.SchemaType; 33 import org.eclipse.microprofile.openapi.annotations.media.Content; 34 import org.eclipse.microprofile.openapi.annotations.media.Schema; 35 import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; 36 import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; 37 import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; 38 import org.eclipse.microprofile.openapi.annotations.tags.Tag; 39 40 @Consumes(MediaType.APPLICATION_JSON) 41 @Produces(MediaType.APPLICATION_JSON) 42 @Path( 43 Constants.COLLECTIONS + 44 "/{" + 45 Constants.COLLECTION_ID + 46 "}/" + 47 Constants.DATA_OBJECTS + 48 "/{" + 49 Constants.DATA_OBJECT_ID + 50 "}/" + 51 Constants.FILE_REFERENCES 52 ) 53 @RequestScoped 54 public class FileReferenceRest { 55 56 @Inject 57 FileReferenceService fileReferenceService; 58 59 @Context 60 private SecurityContext securityContext; 61 62 @GET 63 @Tag(name = Constants.FILE_REFERENCE) 64 @Operation(description = "Get all file references") 65 @APIResponse( 66 description = "ok", 67 responseCode = "200", 68 content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = FileReferenceIO.class)) 69 ) 70 @APIResponse(responseCode = "400", description = "bad request") 71 @APIResponse(responseCode = "401", description = "not authorized") 72 @APIResponse(responseCode = "403", description = "forbidden") 73 @APIResponse(responseCode = "404", description = "not found") 74 @Parameter(name = Constants.COLLECTION_ID) 75 @Parameter(name = Constants.DATA_OBJECT_ID) 76 @Parameter(name = Constants.VERSION_UID) 77 public Response getAllFileReferences( 78 @PathParam(Constants.COLLECTION_ID) @NotNull @PositiveOrZero Long collectionId, 79 @PathParam(Constants.DATA_OBJECT_ID) @NotNull @PositiveOrZero Long dataObjectId, 80 @QueryParam(Constants.VERSION_UID) @org.hibernate.validator.constraints.UUID String versionUID 81 ) { 82 UUID versionUUID = null; 83 if (versionUID != null) { 84 versionUUID = UUID.fromString(versionUID); 85 } 86 List<FileReference> references = fileReferenceService.getAllReferencesByDataObjectId( 87 collectionId, 88 dataObjectId, 89 versionUUID 90 ); 91 var result = new ArrayList<FileReferenceIO>(references.size()); 92 for (var ref : references) { 93 result.add(new FileReferenceIO(ref)); 94 } 95 return Response.ok(result).build(); 96 } 97 98 @GET 99 @Path("/{" + Constants.FILE_REFERENCE_ID + "}") 100 @Tag(name = Constants.FILE_REFERENCE) 101 @Operation(description = "Get file reference") 102 @APIResponse( 103 description = "ok", 104 responseCode = "200", 105 content = @Content(schema = @Schema(implementation = FileReferenceIO.class)) 106 ) 107 @APIResponse(responseCode = "400", description = "bad request") 108 @APIResponse(responseCode = "401", description = "not authorized") 109 @APIResponse(responseCode = "403", description = "forbidden") 110 @APIResponse(responseCode = "404", description = "not found") 111 @Parameter(name = Constants.COLLECTION_ID) 112 @Parameter(name = Constants.DATA_OBJECT_ID) 113 @Parameter(name = Constants.FILE_REFERENCE_ID) 114 @Parameter(name = Constants.VERSION_UID) 115 public Response getFileReference( 116 @PathParam(Constants.COLLECTION_ID) @NotNull @PositiveOrZero Long collectionId, 117 @PathParam(Constants.DATA_OBJECT_ID) @NotNull @PositiveOrZero Long dataObjectId, 118 @PathParam(Constants.FILE_REFERENCE_ID) @NotNull @PositiveOrZero Long referenceId, 119 @QueryParam(Constants.VERSION_UID) @org.hibernate.validator.constraints.UUID String versionUID 120 ) { 121 UUID versionUUID = null; 122 if (versionUID != null) { 123 versionUUID = UUID.fromString(versionUID); 124 } 125 FileReference ref = fileReferenceService.getReference(collectionId, dataObjectId, referenceId, versionUUID); 126 return Response.ok(new FileReferenceIO(ref)).build(); 127 } 128 129 @POST 130 @Subscribable 131 @Tag(name = Constants.FILE_REFERENCE) 132 @Operation(description = "Create a new file reference") 133 @APIResponse( 134 description = "created", 135 responseCode = "201", 136 content = @Content(schema = @Schema(implementation = FileReferenceIO.class)) 137 ) 138 @APIResponse(responseCode = "400", description = "bad request") 139 @APIResponse(responseCode = "401", description = "not authorized") 140 @APIResponse(responseCode = "403", description = "forbidden") 141 @APIResponse(responseCode = "404", description = "not found") 142 @Parameter(name = Constants.COLLECTION_ID) 143 @Parameter(name = Constants.DATA_OBJECT_ID) 144 public Response createFileReference( 145 @PathParam(Constants.COLLECTION_ID) @NotNull @PositiveOrZero Long collectionId, 146 @PathParam(Constants.DATA_OBJECT_ID) @NotNull @PositiveOrZero Long dataObjectId, 147 @RequestBody( 148 required = true, 149 content = @Content(schema = @Schema(implementation = FileReferenceIO.class)) 150 ) @Valid FileReferenceIO fileReference 151 ) { 152 FileReference ref = fileReferenceService.createReference(collectionId, dataObjectId, fileReference); 153 return Response.ok(new FileReferenceIO(ref)).status(Status.CREATED).build(); 154 } 155 156 @DELETE 157 @Path("/{" + Constants.FILE_REFERENCE_ID + "}") 158 @Subscribable 159 @Tag(name = Constants.FILE_REFERENCE) 160 @Operation(description = "Delete file reference") 161 @APIResponse(description = "deleted", responseCode = "204") 162 @APIResponse(responseCode = "400", description = "bad request") 163 @APIResponse(responseCode = "401", description = "not authorized") 164 @APIResponse(responseCode = "403", description = "forbidden") 165 @APIResponse(responseCode = "404", description = "not found") 166 @Parameter(name = Constants.COLLECTION_ID) 167 @Parameter(name = Constants.DATA_OBJECT_ID) 168 @Parameter(name = Constants.FILE_REFERENCE_ID) 169 public Response deleteFileReference( 170 @PathParam(Constants.COLLECTION_ID) @NotNull @PositiveOrZero Long collectionId, 171 @PathParam(Constants.DATA_OBJECT_ID) @NotNull @PositiveOrZero Long dataObjectId, 172 @PathParam(Constants.FILE_REFERENCE_ID) @NotNull @PositiveOrZero Long fileReferenceId 173 ) { 174 fileReferenceService.deleteReference(collectionId, dataObjectId, fileReferenceId); 175 return Response.status(Status.NO_CONTENT).build(); 176 } 177 178 @GET 179 @Path("/{" + Constants.FILE_REFERENCE_ID + "}/payload/{" + Constants.OID + "}") 180 @Produces({ MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON }) 181 @Tag(name = Constants.FILE_REFERENCE) 182 @Operation(description = "Get file payload") 183 @APIResponse( 184 description = "ok", 185 responseCode = "200", 186 content = @Content( 187 mediaType = MediaType.APPLICATION_OCTET_STREAM, 188 schema = @Schema(type = SchemaType.STRING, format = "binary") 189 ) 190 ) 191 @APIResponse(responseCode = "400", description = "bad request") 192 @APIResponse(responseCode = "401", description = "not authorized") 193 @APIResponse(responseCode = "403", description = "forbidden") 194 @APIResponse(responseCode = "404", description = "not found") 195 @Parameter(name = Constants.COLLECTION_ID) 196 @Parameter(name = Constants.DATA_OBJECT_ID) 197 @Parameter(name = Constants.FILE_REFERENCE_ID) 198 @Parameter(name = Constants.OID) 199 @Parameter(name = Constants.VERSION_UID) 200 public Response getFilePayload( 201 @PathParam(Constants.COLLECTION_ID) @NotNull @PositiveOrZero Long collectionId, 202 @PathParam(Constants.DATA_OBJECT_ID) @NotNull @PositiveOrZero Long dataObjectId, 203 @PathParam(Constants.FILE_REFERENCE_ID) @NotNull @PositiveOrZero Long fileReferenceId, 204 @PathParam(Constants.OID) @NotNull String oid, 205 @QueryParam(Constants.VERSION_UID) @org.hibernate.validator.constraints.UUID String versionUID 206 ) { 207 UUID versionUUID = null; 208 if (versionUID != null) { 209 versionUUID = UUID.fromString(versionUID); 210 } 211 NamedInputStream payload = fileReferenceService.getPayload( 212 collectionId, 213 dataObjectId, 214 fileReferenceId, 215 oid, 216 versionUUID 217 ); 218 return Response.ok(payload.getInputStream(), MediaType.APPLICATION_OCTET_STREAM) 219 .header("Content-Disposition", "attachment; filename=\"" + payload.getName() + "\"") 220 .header("Content-Length", payload.getSize()) 221 .build(); 222 } 223 224 @GET 225 @Path("/{" + Constants.FILE_REFERENCE_ID + "}/payload") 226 @Tag(name = Constants.FILE_REFERENCE) 227 @Operation(description = "Get associated files") 228 @APIResponse( 229 description = "ok", 230 responseCode = "200", 231 content = @Content(schema = @Schema(type = SchemaType.ARRAY, implementation = ShepardFile.class)) 232 ) 233 @APIResponse(responseCode = "400", description = "bad request") 234 @APIResponse(responseCode = "401", description = "not authorized") 235 @APIResponse(responseCode = "403", description = "forbidden") 236 @APIResponse(responseCode = "404", description = "not found") 237 @Parameter(name = Constants.COLLECTION_ID) 238 @Parameter(name = Constants.DATA_OBJECT_ID) 239 @Parameter(name = Constants.FILE_REFERENCE_ID) 240 @Parameter(name = Constants.VERSION_UID) 241 public Response getFiles( 242 @PathParam(Constants.COLLECTION_ID) @NotNull @PositiveOrZero Long collectionId, 243 @PathParam(Constants.DATA_OBJECT_ID) @NotNull @PositiveOrZero Long dataObjectId, 244 @PathParam(Constants.FILE_REFERENCE_ID) @NotNull @PositiveOrZero Long fileId, 245 @QueryParam(Constants.VERSION_UID) @org.hibernate.validator.constraints.UUID String versionUID 246 ) { 247 UUID versionUUID = null; 248 if (versionUID != null) { 249 versionUUID = UUID.fromString(versionUID); 250 } 251 var ret = fileReferenceService.getFiles(collectionId, dataObjectId, fileId, versionUUID); 252 return Response.ok(ret).build(); 253 } 254 }