View Javadoc
1   package de.dlr.shepard.context.references.structureddata.services;
2   
3   import de.dlr.shepard.auth.permission.services.PermissionsService;
4   import de.dlr.shepard.auth.security.AuthenticationContext;
5   import de.dlr.shepard.auth.users.entities.User;
6   import de.dlr.shepard.auth.users.services.UserService;
7   import de.dlr.shepard.common.exceptions.InvalidAuthException;
8   import de.dlr.shepard.common.exceptions.InvalidBodyException;
9   import de.dlr.shepard.common.exceptions.InvalidPathException;
10  import de.dlr.shepard.common.exceptions.InvalidRequestException;
11  import de.dlr.shepard.common.util.DateHelper;
12  import de.dlr.shepard.context.collection.entities.DataObject;
13  import de.dlr.shepard.context.collection.services.CollectionService;
14  import de.dlr.shepard.context.collection.services.DataObjectService;
15  import de.dlr.shepard.context.references.IReferenceService;
16  import de.dlr.shepard.context.references.structureddata.daos.StructuredDataReferenceDAO;
17  import de.dlr.shepard.context.references.structureddata.entities.StructuredDataReference;
18  import de.dlr.shepard.context.references.structureddata.io.StructuredDataReferenceIO;
19  import de.dlr.shepard.context.version.services.VersionService;
20  import de.dlr.shepard.data.structureddata.daos.StructuredDataDAO;
21  import de.dlr.shepard.data.structureddata.entities.StructuredDataContainer;
22  import de.dlr.shepard.data.structureddata.entities.StructuredDataPayload;
23  import de.dlr.shepard.data.structureddata.services.StructuredDataContainerService;
24  import de.dlr.shepard.data.structureddata.services.StructuredDataService;
25  import io.quarkus.logging.Log;
26  import jakarta.enterprise.context.RequestScoped;
27  import jakarta.inject.Inject;
28  import jakarta.ws.rs.NotFoundException;
29  import java.util.ArrayList;
30  import java.util.List;
31  import java.util.UUID;
32  
33  @RequestScoped
34  public class StructuredDataReferenceService
35    implements IReferenceService<StructuredDataReference, StructuredDataReferenceIO> {
36  
37    @Inject
38    StructuredDataReferenceDAO structuredDataReferenceDAO;
39  
40    @Inject
41    DataObjectService dataObjectService;
42  
43    @Inject
44    StructuredDataDAO structuredDataDAO;
45  
46    @Inject
47    StructuredDataContainerService structuredDataContainerService;
48  
49    @Inject
50    VersionService versionService;
51  
52    @Inject
53    DateHelper dateHelper;
54  
55    @Inject
56    UserService userService;
57  
58    @Inject
59    StructuredDataService structuredDataService;
60  
61    @Inject
62    PermissionsService permissionsService;
63  
64    @Inject
65    AuthenticationContext authenticationContext;
66  
67    @Inject
68    CollectionService collectionService;
69  
70    @Override
71    public StructuredDataReference createReference(
72      long collectionShepardId,
73      long dataObjectShepardId,
74      StructuredDataReferenceIO structuredDataReference
75    ) {
76      DataObject dataObject = dataObjectService.getDataObject(collectionShepardId, dataObjectShepardId);
77      collectionService.assertIsAllowedToEditCollection(collectionShepardId);
78  
79      User user = userService.getCurrentUser();
80  
81      StructuredDataContainer container;
82      try {
83        container = structuredDataContainerService.getContainer(structuredDataReference.getStructuredDataContainerId());
84      } catch (InvalidPathException e) {
85        throw new InvalidBodyException(
86          String.format(
87            "ID ERROR - Structured Data Container with id %s is null or deleted",
88            structuredDataReference.getStructuredDataContainerId()
89          )
90        );
91      }
92  
93      var toCreate = new StructuredDataReference();
94      toCreate.setCreatedAt(dateHelper.getDate());
95      toCreate.setCreatedBy(user);
96      toCreate.setDataObject(dataObject);
97      toCreate.setName(structuredDataReference.getName());
98      toCreate.setStructuredDataContainer(container);
99  
100     // Get existing structured data
101     for (var oid : structuredDataReference.getStructuredDataOids()) {
102       var structuredData = structuredDataDAO.find(container.getId(), oid);
103       if (structuredData != null) {
104         toCreate.addStructuredData(structuredData);
105       } else {
106         Log.warnf("Could not find structured data with oid: %s", oid);
107       }
108     }
109 
110     StructuredDataReference created = structuredDataReferenceDAO.createOrUpdate(toCreate);
111     created.setShepardId(created.getId());
112     created = structuredDataReferenceDAO.createOrUpdate(created);
113     versionService.attachToVersionOfVersionableEntityAndReturnVersion(dataObject.getId(), created.getId());
114     return created;
115   }
116 
117   /**
118    * Gets Structured Data Reference list for a given dataobject.
119    *
120    * @param collectionShepardId
121    * @param dataObjectShepardId
122    * @param versionUID the version UUID
123    * @return List<StructuredDataReference>
124    * @throws InvalidPathException If collection or dataobject cannot be found, or no association between dataobject and collection exists
125    * @throws InvalidAuthException If user has no read permissions on collection or dataobject specified by request path
126    */
127   @Override
128   public List<StructuredDataReference> getAllReferencesByDataObjectId(
129     long collectionShepardId,
130     long dataObjectShepardId,
131     UUID versionUID
132   ) {
133     dataObjectService.getDataObject(collectionShepardId, dataObjectShepardId, versionUID);
134 
135     List<StructuredDataReference> references = structuredDataReferenceDAO.findByDataObjectShepardId(
136       dataObjectShepardId
137     );
138     return references;
139   }
140 
141   /**
142    * Searches the neo4j database for a StructuredDataReference
143    *
144    * @param collectionShepardId
145    * @param dataObjectShepardId
146    * @param shepardId  identifies the searched StructuredDataReference
147    * @param versionUID the collections UUID
148    * @return CollectionReference
149    * @throws InvalidPathException If collection reference with Id does not exist or is deleted, or if collection or dataobject Id of path is not valid
150    * @throws InvalidAuthException If user has no read permissions on collection or dataobject specified by request path
151    */
152   @Override
153   public StructuredDataReference getReference(
154     long collectionShepardId,
155     long dataObjectShepardId,
156     long shepardId,
157     UUID versionUID
158   ) {
159     dataObjectService.getDataObject(collectionShepardId, dataObjectShepardId, versionUID);
160 
161     StructuredDataReference structuredDataReference = structuredDataReferenceDAO.findByShepardId(shepardId, versionUID);
162     if (structuredDataReference == null || structuredDataReference.isDeleted()) {
163       String errorMsg = String.format("ID ERROR - Structured Data Reference with id %s is null or deleted", shepardId);
164       Log.errorf(errorMsg);
165       throw new InvalidPathException(errorMsg);
166     }
167 
168     if (
169       structuredDataReference.getDataObject() == null ||
170       !structuredDataReference.getDataObject().getShepardId().equals(dataObjectShepardId)
171     ) {
172       Log.error("ID ERROR - There is no association between dataObject and reference");
173       throw new InvalidPathException("ID ERROR - There is no association between dataObject and reference");
174     }
175 
176     return structuredDataReference;
177   }
178 
179   /**
180    * Deletes the Structured Data reference.
181    *
182    * @param collectionShepardId
183    * @param dataObjectShepardId
184    * @param dataObjectReferenceShepardId
185    * @throws InvalidPathException if collection or dataobject specified by their Ids are null or deleted
186    * @throws InvalidAuthException if user has no permissions to request the collection, which the reference is assigned to
187    * @throws InvalidBodyException If user has no permissions to access the referenced Structured Data or the referenced collection cannot be found
188    */
189   @Override
190   public void deleteReference(
191     long collectionShepardId,
192     long dataObjectShepardId,
193     long structuredDataReferenceShepardId
194   ) {
195     StructuredDataReference structuredDataReference = getReference(
196       collectionShepardId,
197       dataObjectShepardId,
198       structuredDataReferenceShepardId,
199       null
200     );
201     collectionService.assertIsAllowedToEditCollection(collectionShepardId);
202 
203     User user = userService.getCurrentUser();
204     structuredDataReference.setDeleted(true);
205     structuredDataReference.setUpdatedBy(user);
206     structuredDataReference.setUpdatedAt(dateHelper.getDate());
207     structuredDataReferenceDAO.createOrUpdate(structuredDataReference);
208   }
209 
210   /**
211    * Returns all structured data objects with payload.
212    *
213    * The payload attribute is null when the container is not accessible.
214    *
215    * @param structuredDataReferenceShepardId identifies the sd reference
216    * @return a list of StructuredDataPayload
217    */
218   public List<StructuredDataPayload> getAllPayloads(
219     long collectionShepardId,
220     long dataObjectShepardId,
221     long structuredDataReferenceShepardId
222   ) {
223     StructuredDataReference reference = getReference(
224       collectionShepardId,
225       dataObjectShepardId,
226       structuredDataReferenceShepardId,
227       null
228     );
229 
230     if (reference.getStructuredDataContainer() == null || reference.getStructuredDataContainer().isDeleted()) {
231       String errorMsg = String.format(
232         "StructuredData Container referenced by StructuredData Reference with Id %s is null or deleted",
233         structuredDataReferenceShepardId
234       );
235       Log.error(errorMsg);
236       throw new NotFoundException(errorMsg);
237     }
238 
239     try {
240       // check that referenced container is actually accessible
241       structuredDataContainerService.getContainer(reference.getStructuredDataContainer().getId());
242     } catch (InvalidPathException ex) {
243       throw new InvalidRequestException(ex.getMessage());
244     }
245 
246     String mongoId = reference.getStructuredDataContainer().getMongoId();
247     var result = new ArrayList<StructuredDataPayload>(reference.getStructuredDatas().size());
248     for (var structuredData : reference.getStructuredDatas()) {
249       try {
250         StructuredDataPayload payload = structuredDataService.getPayload(mongoId, structuredData.getOid());
251         result.add(payload);
252       } catch (NotFoundException ex) {
253         result.add(new StructuredDataPayload(structuredData, null));
254       }
255     }
256     return result;
257   }
258 
259   /**
260    * Returns a specific StructuredDataPayload
261    *
262    * @param structuredDataReferenceShepardId identifies the sd reference
263    * @param oid identifies the structured data
264    * @param username the current user
265    * @return StructuredDataPayload
266    * @throws InvalidRequestException when container is not accessible
267    * @throws InvalidAuthException when the user is not authorized to access the container
268    */
269   public StructuredDataPayload getPayload(
270     long collectionShepardId,
271     long dataObjectShepardId,
272     long structuredDataReferenceShepardId,
273     String oid
274   ) {
275     StructuredDataReference reference = getReference(
276       collectionShepardId,
277       dataObjectShepardId,
278       structuredDataReferenceShepardId,
279       null
280     );
281 
282     if (reference.getStructuredDataContainer() == null || reference.getStructuredDataContainer().isDeleted()) {
283       String errorMsg = String.format(
284         "Structured Data Container referenced by StructuredDataReference with id %s is deleted",
285         reference.getShepardId()
286       );
287       Log.errorf(errorMsg);
288       throw new InvalidRequestException(errorMsg);
289     }
290 
291     try {
292       structuredDataContainerService.getContainer(reference.getStructuredDataContainer().getId());
293     } catch (InvalidPathException e) {
294       throw new NotFoundException(
295         String.format(
296           "The StructuredData Container with id %d could not be found.",
297           reference.getStructuredDataContainer().getId()
298         )
299       );
300     }
301 
302     String mongoId = reference.getStructuredDataContainer().getMongoId();
303     return structuredDataService.getPayload(mongoId, oid);
304   }
305 }