View Javadoc
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 }