View Javadoc
1   package de.dlr.shepard.data.structureddata.services;
2   
3   import static com.mongodb.client.model.Filters.eq;
4   
5   import com.mongodb.MongoException;
6   import com.mongodb.client.MongoCollection;
7   import com.mongodb.client.MongoDatabase;
8   import de.dlr.shepard.common.exceptions.InvalidBodyException;
9   import de.dlr.shepard.common.util.DateHelper;
10  import de.dlr.shepard.data.structureddata.entities.StructuredData;
11  import de.dlr.shepard.data.structureddata.entities.StructuredDataPayload;
12  import io.quarkus.logging.Log;
13  import jakarta.enterprise.context.RequestScoped;
14  import jakarta.inject.Inject;
15  import jakarta.inject.Named;
16  import jakarta.ws.rs.InternalServerErrorException;
17  import jakarta.ws.rs.NotFoundException;
18  import java.util.UUID;
19  import org.bson.Document;
20  import org.bson.json.JsonParseException;
21  import org.bson.types.ObjectId;
22  
23  @RequestScoped
24  public class StructuredDataService {
25  
26    @Inject
27    DateHelper dateHelper;
28  
29    @Inject
30    @Named("mongoDatabase")
31    MongoDatabase mongoDatabase;
32  
33    private static final String ID_ATTR = "_id";
34    private static final String META_OBJECT = "_meta";
35  
36    public String createStructuredDataContainer() {
37      String mongoId = "StructuredDataContainer" + UUID.randomUUID().toString();
38      mongoDatabase.createCollection(mongoId);
39      return mongoId;
40    }
41  
42    public StructuredData createStructuredData(String mongoId, StructuredDataPayload payload) {
43      MongoCollection<Document> collection;
44      try {
45        collection = mongoDatabase.getCollection(mongoId);
46      } catch (IllegalArgumentException e) {
47        String errorMsg = String.format("Could not find container with mongoId: %s", mongoId);
48        Log.error(errorMsg);
49        throw new NotFoundException(errorMsg);
50      }
51      Document toInsert;
52      try {
53        toInsert = Document.parse(payload.getPayload());
54      } catch (JsonParseException e) {
55        Log.errorf("Could not parse json: %s", payload.getPayload());
56        throw new InvalidBodyException("The specified payload is not json parsable");
57      }
58  
59      // Remove fields beginning with an underscore (protected)
60      var forbidden = toInsert.keySet().stream().filter(k -> k.startsWith("_")).toList();
61      forbidden.forEach(toInsert::remove);
62  
63      // Add meta data
64      var newName = payload.getStructuredData() != null ? payload.getStructuredData().getName() : null;
65      var structuredData = new StructuredData(newName, dateHelper.getDate());
66      toInsert.append(META_OBJECT, structuredData);
67      try {
68        collection.insertOne(toInsert);
69      } catch (MongoException e) {
70        String errorMsg = String.format("Could not write to mongodb: %s", e.toString());
71        Log.error(errorMsg);
72        throw new InternalServerErrorException(errorMsg);
73      }
74      structuredData.setOid(toInsert.getObjectId(ID_ATTR).toHexString());
75      return structuredData;
76    }
77  
78    public void deleteStructuredDataContainer(String mongoId) {
79      MongoCollection<Document> toDelete;
80      try {
81        toDelete = mongoDatabase.getCollection(mongoId);
82      } catch (IllegalArgumentException e) {
83        String errorMsg = String.format("Could not delete container with mongoId: %s", mongoId);
84        Log.error(errorMsg);
85        throw new NotFoundException(errorMsg);
86      }
87      toDelete.drop();
88    }
89  
90    public StructuredDataPayload getPayload(String mongoId, String oid) {
91      MongoCollection<Document> collection;
92      try {
93        collection = mongoDatabase.getCollection(mongoId);
94      } catch (IllegalArgumentException e) {
95        String errorMsg = String.format("Could not find container with mongoId: %s", mongoId);
96        Log.error(errorMsg);
97        throw new NotFoundException(errorMsg);
98      }
99  
100     Document payloadDocument;
101     try {
102       payloadDocument = collection.find(eq(ID_ATTR, new ObjectId(oid))).first();
103       if (payloadDocument == null) {
104         String errorMsg = String.format("Could not find document with oid: %s", oid);
105         Log.error(errorMsg);
106         throw new NotFoundException(errorMsg);
107       }
108     } catch (Exception e) {
109       String errorMsg = String.format("Could not find document with oid: %s", oid);
110       Log.error(e);
111       Log.error(errorMsg);
112       throw new NotFoundException(errorMsg);
113     }
114 
115     var structuredDataDocument = payloadDocument.get(META_OBJECT, Document.class);
116     var structuredData = structuredDataDocument != null
117       ? new StructuredData(structuredDataDocument)
118       : new StructuredData();
119     structuredData.setOid(oid);
120     var payload = new StructuredDataPayload(structuredData, payloadDocument.toJson());
121     return payload;
122   }
123 
124   public void deletePayload(String mongoId, String oid) {
125     MongoCollection<Document> collection;
126     try {
127       collection = mongoDatabase.getCollection(mongoId);
128     } catch (IllegalArgumentException e) {
129       String errorMsg = String.format("Could not find container with mongoId: %s", mongoId);
130       Log.error(errorMsg);
131       throw new NotFoundException(errorMsg);
132     }
133     var doc = collection.findOneAndDelete(eq(ID_ATTR, new ObjectId(oid)));
134     if (doc == null) {
135       String errorMsg = String.format("Could not delete document with oid: %s", oid);
136       Log.error(errorMsg);
137       throw new NotFoundException(errorMsg);
138     }
139   }
140 }