diff --git a/pom.xml b/pom.xml
index 4f93b6a9..2f192413 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,6 +94,11 @@
quarkus-junit5
test
+
+ io.quarkus
+ quarkus-junit5-component
+ test
+
io.quarkus
quarkus-junit5-mockito
@@ -126,36 +131,32 @@
io.quarkus
- quarkus-resteasy-multipart
+ quarkus-rest
io.quarkus
- quarkus-resteasy
+ quarkus-rest-jackson
io.quarkus
- quarkus-resteasy-client
+ quarkus-rest-client
io.quarkus
- quarkus-resteasy-client-jaxb
+ quarkus-rest-client-jaxb
io.quarkus
- quarkus-resteasy-jaxb
-
-
- io.quarkus
- quarkus-resteasy-jackson
+ quarkus-rest-client-jackson
+
io.quarkus
- quarkus-jaxb
+ quarkus-oidc
-
io.quarkus
- quarkus-oidc
+ quarkus-smallrye-jwt
@@ -260,7 +261,7 @@
org.codehaus.mojo
jaxb2-maven-plugin
- 3.1.0
+ 3.2.0
xjc
diff --git a/src/main/java/org/damap/base/enums/EDataAccessType.java b/src/main/java/org/damap/base/enums/EDataAccessType.java
index d7ce3e86..e59516ed 100644
--- a/src/main/java/org/damap/base/enums/EDataAccessType.java
+++ b/src/main/java/org/damap/base/enums/EDataAccessType.java
@@ -46,4 +46,36 @@ public static EDataAccessType getByValue(String value) {
MAP.put(type.getValue(), type);
}
}
+
+ /**
+ * Compares this {@code EDataAccessType} instance with another {@code EDataAccessType} to
+ * determine which is more restrictive. The order of restriction is defined as:
+ *
+ *
+ * - {@code CLOSED} is the most restrictive.
+ *
- {@code RESTRICTED} is more restrictive than {@code OPEN} but less restrictive than {@code
+ * CLOSED}.
+ *
- {@code OPEN} is the least restrictive.
+ *
+ *
+ * @param other the other {@code EDataAccessType} to compare to; can be {@code null}. If {@code
+ * null}, this instance is considered more restrictive.
+ * @return {@code 1} if this instance is more restrictive than {@code other}, {@code -1} if this
+ * instance is less restrictive than {@code other}, and {@code 0} if both instances are equal.
+ */
+ public int compare(EDataAccessType other) {
+ if (other == null) {
+ return 1;
+ }
+
+ if (this == other) {
+ return 0;
+ }
+
+ return switch (this) {
+ case CLOSED -> 1;
+ case RESTRICTED -> (other == CLOSED) ? -1 : 1;
+ case OPEN -> -1;
+ };
+ }
}
diff --git a/src/main/java/org/damap/base/r3data/RepositoriesRemoteResource.java b/src/main/java/org/damap/base/r3data/RepositoriesRemoteResource.java
index 80539ee3..73419262 100644
--- a/src/main/java/org/damap/base/r3data/RepositoriesRemoteResource.java
+++ b/src/main/java/org/damap/base/r3data/RepositoriesRemoteResource.java
@@ -1,14 +1,13 @@
package org.damap.base.r3data;
-import generated.Repository;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.util.List;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
-import org.jboss.resteasy.annotations.jaxrs.PathParam;
-import org.jboss.resteasy.annotations.jaxrs.QueryParam;
+import org.jboss.resteasy.reactive.RestPath;
+import org.jboss.resteasy.reactive.RestQuery;
import org.re3data.schema._2_2.Re3Data;
/** RepositoriesRemoteResource interface. */
@@ -23,7 +22,7 @@ public interface RepositoriesRemoteResource {
*/
@GET
@Path("/v1/repositories")
- List getAll();
+ generated.List getAll();
/**
* getById.
@@ -33,7 +32,7 @@ public interface RepositoriesRemoteResource {
*/
@GET
@Path("/v1/repository/{id}")
- Re3Data getById(@PathParam String id);
+ Re3Data getById(@RestPath String id);
/**
* search.
@@ -56,19 +55,19 @@ public interface RepositoriesRemoteResource {
*/
@GET
@Path("/beta/repositories")
- List search(
- @QueryParam("subjects[]") List subjects,
- @QueryParam("contentTypes[]") List contentTypes,
- @QueryParam("countries[]") List countries,
- @QueryParam("certificates[]") List certificates,
- @QueryParam("pidSystems[]") List pidSystems,
- @QueryParam("aidSystems[]") List aidSystems,
- @QueryParam("repositoryAccess[]") List repositoryAccess,
- @QueryParam("dataAccess[]") List dataAccess,
- @QueryParam("dataUpload[]") List dataUpload,
- @QueryParam("dataLicenses[]") List dataLicenses,
- @QueryParam("repositoryTypes[]") List repositoryTypes,
- @QueryParam("institutionTypes[]") List institutionTypes,
- @QueryParam("versioning[]") List versioning,
- @QueryParam("metadataStandards[]") List metadataStandards);
+ generated.List search(
+ @RestQuery("subjects[]") List subjects,
+ @RestQuery("contentTypes[]") List contentTypes,
+ @RestQuery("countries[]") List countries,
+ @RestQuery("certificates[]") List certificates,
+ @RestQuery("pidSystems[]") List pidSystems,
+ @RestQuery("aidSystems[]") List aidSystems,
+ @RestQuery("repositoryAccess[]") List repositoryAccess,
+ @RestQuery("dataAccess[]") List dataAccess,
+ @RestQuery("dataUpload[]") List dataUpload,
+ @RestQuery("dataLicenses[]") List dataLicenses,
+ @RestQuery("repositoryTypes[]") List repositoryTypes,
+ @RestQuery("institutionTypes[]") List institutionTypes,
+ @RestQuery("versioning[]") List versioning,
+ @RestQuery("metadataStandards[]") List metadataStandards);
}
diff --git a/src/main/java/org/damap/base/r3data/RepositoriesResource.java b/src/main/java/org/damap/base/r3data/RepositoriesResource.java
index 9cb8aca3..d36817a8 100644
--- a/src/main/java/org/damap/base/r3data/RepositoriesResource.java
+++ b/src/main/java/org/damap/base/r3data/RepositoriesResource.java
@@ -1,6 +1,6 @@
package org.damap.base.r3data;
-import generated.Repository;
+import generated.List.Repository;
import io.quarkus.security.Authenticated;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
@@ -14,7 +14,7 @@
import lombok.extern.jbosslog.JBossLog;
import org.damap.base.r3data.dto.RepositoryDetails;
import org.damap.base.r3data.mapper.RepositoryMapper;
-import org.jboss.resteasy.annotations.jaxrs.PathParam;
+import org.jboss.resteasy.reactive.RestPath;
/** RepositoriesResource class. */
@Path("/api/repositories")
@@ -33,7 +33,7 @@ public class RepositoriesResource {
@GET
public List getAll() {
log.info("Get all repositories");
- return repositoriesService.getAll();
+ return repositoriesService.getAll().getRepository();
}
/**
@@ -56,7 +56,7 @@ public List getRecommended() {
*/
@GET
@Path("/{id}")
- public RepositoryDetails getById(@PathParam String id) {
+ public RepositoryDetails getById(@RestPath String id) {
log.info("Get repository with id: " + id);
return RepositoryMapper.mapToRepositoryDetails(repositoriesService.getById(id), id);
}
@@ -72,6 +72,6 @@ public RepositoryDetails getById(@PathParam String id) {
public List search(@Context UriInfo uriInfo) {
log.info("Search repositories: " + uriInfo.getQueryParameters());
MultivaluedMap params = uriInfo.getQueryParameters();
- return repositoriesService.search(params);
+ return repositoriesService.search(params).getRepository();
}
}
diff --git a/src/main/java/org/damap/base/r3data/RepositoriesService.java b/src/main/java/org/damap/base/r3data/RepositoriesService.java
index 87292f6c..7eea7ac6 100644
--- a/src/main/java/org/damap/base/r3data/RepositoriesService.java
+++ b/src/main/java/org/damap/base/r3data/RepositoriesService.java
@@ -1,6 +1,5 @@
package org.damap.base.r3data;
-import generated.Repository;
import io.quarkus.cache.CacheResult;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
@@ -32,7 +31,7 @@ public class RepositoriesService {
* @return a {@link java.util.List} object
*/
@CacheResult(cacheName = "repositories")
- public List getAll() {
+ public generated.List getAll() {
return repositoriesRemoteResource.getAll();
}
@@ -78,7 +77,7 @@ public Re3Data getById(String id) {
* @param params a {@link jakarta.ws.rs.core.MultivaluedMap} object
* @return a {@link java.util.List} object
*/
- public List search(MultivaluedMap params) {
+ public generated.List search(MultivaluedMap params) {
List subjects = params.get("subjects");
List contentTypes = params.get("contentTypes");
List certificates = params.get("certificates");
diff --git a/src/main/java/org/damap/base/rest/AccessResource.java b/src/main/java/org/damap/base/rest/AccessResource.java
index 47f0d167..445f48af 100644
--- a/src/main/java/org/damap/base/rest/AccessResource.java
+++ b/src/main/java/org/damap/base/rest/AccessResource.java
@@ -11,7 +11,6 @@
import org.damap.base.rest.access.service.AccessService;
import org.damap.base.rest.dmp.domain.ContributorDO;
import org.damap.base.validation.AccessValidator;
-import org.jboss.resteasy.annotations.jaxrs.PathParam;
/** AccessResource class. */
@Path("/api/access")
diff --git a/src/main/java/org/damap/base/rest/DataManagementPlanResource.java b/src/main/java/org/damap/base/rest/DataManagementPlanResource.java
index f5ca7b0a..27987aac 100644
--- a/src/main/java/org/damap/base/rest/DataManagementPlanResource.java
+++ b/src/main/java/org/damap/base/rest/DataManagementPlanResource.java
@@ -15,7 +15,7 @@
import org.damap.base.rest.dmp.service.DmpService;
import org.damap.base.security.SecurityService;
import org.damap.base.validation.AccessValidator;
-import org.jboss.resteasy.annotations.jaxrs.PathParam;
+import org.jboss.resteasy.reactive.RestPath;
/** DataManagementPlanResource class. */
@Path("/api/dmps")
@@ -52,7 +52,7 @@ public List getAll() {
/*@GET
@Path("/person/{personId}")
@RolesAllowed("Damap Admin")
- public List getDmpListByPerson(@PathParam String personId) {
+ public List getDmpListByPerson(@RestPath String personId) {
log.info("Return dmp for person id: " + personId);
return dmpService.getDmpListByPersonId(personId);
}*/
@@ -92,7 +92,7 @@ public List getDmpsSubordinates() {
*/
@GET
@Path("/{id}")
- public DmpDO getDmpById(@PathParam String id) {
+ public DmpDO getDmpById(@RestPath String id) {
log.info("Return dmp with id: " + id);
String personId = this.getPersonId();
long dmpId = Long.parseLong(id);
@@ -126,7 +126,7 @@ public DmpDO saveDmp(@Valid DmpDO dmpDO) {
@PUT
@Path("/{id}")
@Consumes(MediaType.APPLICATION_JSON)
- public DmpDO updateDmp(@PathParam String id, @Valid DmpDO dmpDO) {
+ public DmpDO updateDmp(@RestPath String id, @Valid DmpDO dmpDO) {
log.info("Update dmp with id: " + id);
String personId = this.getPersonId();
long dmpId = Long.parseLong(id);
@@ -143,7 +143,7 @@ public DmpDO updateDmp(@PathParam String id, @Valid DmpDO dmpDO) {
*/
@DELETE
@Path("/{id}")
- public void deleteDmp(@PathParam String id) {
+ public void deleteDmp(@RestPath String id) {
log.info("Delete dmp with id: " + id);
String personId = this.getPersonId();
long dmpId = Long.parseLong(id);
@@ -169,7 +169,7 @@ private String getPersonId() {
*/
@GET
@Path("/{id}/{revision}")
- public DmpDO getDmpByIdAndRevision(@PathParam String id, @PathParam long revision) {
+ public DmpDO getDmpByIdAndRevision(@RestPath String id, @RestPath long revision) {
log.info("Return dmp with id: " + id + " and revision number: " + revision);
String personId = this.getPersonId();
long dmpId = Long.parseLong(id);
diff --git a/src/main/java/org/damap/base/rest/FitsResource.java b/src/main/java/org/damap/base/rest/FitsResource.java
index 666cbda4..6beb0f9b 100644
--- a/src/main/java/org/damap/base/rest/FitsResource.java
+++ b/src/main/java/org/damap/base/rest/FitsResource.java
@@ -9,7 +9,6 @@
import org.damap.base.rest.dmp.domain.MultipartBodyDO;
import org.damap.base.rest.dmp.mapper.DatasetDOMapper;
import org.damap.base.rest.fits.service.FitsService;
-import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
/** FitsResource class. */
@Path("/api/fits")
@@ -29,7 +28,7 @@ public class FitsResource {
*/
@POST
@Path("/examine")
- public DatasetDO examine(@MultipartForm MultipartBodyDO data) {
+ public DatasetDO examine(MultipartBodyDO data) {
log.info("Analyse file");
return DatasetDOMapper.mapEntityToDO(fitsService.analyseFile(data), new DatasetDO());
}
diff --git a/src/main/java/org/damap/base/rest/InternalStorageResource.java b/src/main/java/org/damap/base/rest/InternalStorageResource.java
index 3a34ebc5..704395ff 100644
--- a/src/main/java/org/damap/base/rest/InternalStorageResource.java
+++ b/src/main/java/org/damap/base/rest/InternalStorageResource.java
@@ -10,7 +10,7 @@
import lombok.extern.jbosslog.JBossLog;
import org.damap.base.rest.storage.InternalStorageDO;
import org.damap.base.rest.storage.InternalStorageService;
-import org.jboss.resteasy.annotations.jaxrs.PathParam;
+import org.jboss.resteasy.reactive.RestPath;
/** InternalStorageResource class. */
@Path("/api/storages")
@@ -29,7 +29,7 @@ public class InternalStorageResource {
*/
@GET
@Path("/{languageCode}")
- public List getAllByLanguage(@PathParam String languageCode) {
+ public List getAllByLanguage(@RestPath String languageCode) {
log.debug("Return all internal storage options for language " + languageCode);
return internalStorageService.getAllByLanguage(languageCode);
}
diff --git a/src/main/java/org/damap/base/rest/OpenAireResource.java b/src/main/java/org/damap/base/rest/OpenAireResource.java
index 52a1afdf..fd00ae72 100644
--- a/src/main/java/org/damap/base/rest/OpenAireResource.java
+++ b/src/main/java/org/damap/base/rest/OpenAireResource.java
@@ -10,7 +10,7 @@
import org.damap.base.rest.dmp.domain.DatasetDO;
import org.damap.base.rest.openaire.mapper.OpenAireMapper;
import org.damap.base.rest.openaire.service.OpenAireService;
-import org.jboss.resteasy.annotations.jaxrs.QueryParam;
+import org.jboss.resteasy.reactive.RestQuery;
/** OpenAireResource class. */
@Path("/api/openaire")
@@ -28,7 +28,7 @@ public class OpenAireResource {
* @return a {@link org.damap.base.rest.dmp.domain.DatasetDO} object
*/
@GET
- public DatasetDO search(@QueryParam String doi) {
+ public DatasetDO search(@RestQuery String doi) {
log.info("Search for dataset with DOI: " + doi);
return OpenAireMapper.mapAtoB(doi, openAireService.search(doi), new DatasetDO());
}
diff --git a/src/main/java/org/damap/base/rest/VersionResource.java b/src/main/java/org/damap/base/rest/VersionResource.java
index a9c7c9d8..a1565afd 100644
--- a/src/main/java/org/damap/base/rest/VersionResource.java
+++ b/src/main/java/org/damap/base/rest/VersionResource.java
@@ -12,7 +12,7 @@
import org.damap.base.rest.version.VersionService;
import org.damap.base.security.SecurityService;
import org.damap.base.validation.AccessValidator;
-import org.jboss.resteasy.annotations.jaxrs.PathParam;
+import org.jboss.resteasy.reactive.RestPath;
/** VersionResource class. */
@Path("/api/versions")
@@ -35,7 +35,7 @@ public class VersionResource {
*/
@GET
@Path("/list/{id}")
- public List getDmpVersions(@PathParam String id) {
+ public List getDmpVersions(@RestPath String id) {
log.debug("Return dmp versions for dmp with id: " + id);
String personId = this.getPersonId();
long dmpId = Long.parseLong(id);
diff --git a/src/main/java/org/damap/base/rest/dmp/domain/MultipartBodyDO.java b/src/main/java/org/damap/base/rest/dmp/domain/MultipartBodyDO.java
index 5fb824db..6444940d 100644
--- a/src/main/java/org/damap/base/rest/dmp/domain/MultipartBodyDO.java
+++ b/src/main/java/org/damap/base/rest/dmp/domain/MultipartBodyDO.java
@@ -2,13 +2,13 @@
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.core.MediaType;
-import java.io.InputStream;
-import org.jboss.resteasy.annotations.providers.multipart.PartType;
+import java.io.File;
+import org.jboss.resteasy.reactive.PartType;
/** MultipartBodyDO class. */
public class MultipartBodyDO {
@FormParam("file")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
- public InputStream file;
+ public File file;
}
diff --git a/src/main/java/org/damap/base/rest/dmp/service/DmpService.java b/src/main/java/org/damap/base/rest/dmp/service/DmpService.java
index a1bde729..3d015667 100644
--- a/src/main/java/org/damap/base/rest/dmp/service/DmpService.java
+++ b/src/main/java/org/damap/base/rest/dmp/service/DmpService.java
@@ -99,6 +99,22 @@ public DmpDO getDmpById(long dmpId) {
return DmpDOMapper.mapEntityToDO(dmpRepo.findById(dmpId), new DmpDO());
}
+ /**
+ * getDmpDOListByPersonId.
+ *
+ * @param personId a {@link java.lang.String} object
+ * @return a {@link java.util.List} object
+ */
+ @Transactional
+ public List getDmpDOListByPersonId(String personId) {
+ List accessList = accessRepo.getAllDmpByUniversityId(personId);
+
+ List dmpDOS = new ArrayList<>();
+ accessList.forEach(
+ access -> dmpDOS.add(DmpDOMapper.mapEntityToDO(access.getDmp(), new DmpDO())));
+ return dmpDOS;
+ }
+
/**
* create.
*
diff --git a/src/main/java/org/damap/base/rest/fits/dto/MultipartBodyDTO.java b/src/main/java/org/damap/base/rest/fits/dto/MultipartBodyDTO.java
index af2aaf01..7beaf0a2 100644
--- a/src/main/java/org/damap/base/rest/fits/dto/MultipartBodyDTO.java
+++ b/src/main/java/org/damap/base/rest/fits/dto/MultipartBodyDTO.java
@@ -2,9 +2,9 @@
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.core.MediaType;
-import java.io.InputStream;
-import org.jboss.resteasy.annotations.providers.multipart.PartFilename;
-import org.jboss.resteasy.annotations.providers.multipart.PartType;
+import java.io.File;
+import org.jboss.resteasy.reactive.PartFilename;
+import org.jboss.resteasy.reactive.PartType;
/** MultipartBodyDTO class. */
public class MultipartBodyDTO {
@@ -13,5 +13,5 @@ public class MultipartBodyDTO {
@PartType(MediaType.APPLICATION_OCTET_STREAM)
@PartFilename(
"filename") // Adds filename to Content-Disposition header, because request fails without one
- public InputStream file;
+ public File file;
}
diff --git a/src/main/java/org/damap/base/rest/fits/service/FitsRestService.java b/src/main/java/org/damap/base/rest/fits/service/FitsRestService.java
index 68b7bf4e..4db83820 100644
--- a/src/main/java/org/damap/base/rest/fits/service/FitsRestService.java
+++ b/src/main/java/org/damap/base/rest/fits/service/FitsRestService.java
@@ -8,7 +8,6 @@
import jakarta.ws.rs.core.MediaType;
import org.damap.base.rest.fits.dto.MultipartBodyDTO;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
-import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
/** FitsRestService interface. */
@RegisterRestClient(configKey = "rest.fits")
@@ -24,5 +23,5 @@ public interface FitsRestService {
*/
@POST
@Path("/examine")
- Fits analyseFile(@MultipartForm MultipartBodyDTO datafile);
+ Fits analyseFile(MultipartBodyDTO datafile);
}
diff --git a/src/main/java/org/damap/base/rest/invenio_damap/DMPPayload.java b/src/main/java/org/damap/base/rest/invenio_damap/DMPPayload.java
new file mode 100644
index 00000000..160292d8
--- /dev/null
+++ b/src/main/java/org/damap/base/rest/invenio_damap/DMPPayload.java
@@ -0,0 +1,13 @@
+package org.damap.base.rest.invenio_damap;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import org.damap.base.rest.madmp.dto.Dataset;
+
+@Data
+public class DMPPayload {
+ @JsonProperty("dmp_id")
+ private long dmpId;
+
+ private Dataset dataset;
+}
diff --git a/src/main/java/org/damap/base/rest/invenio_damap/InvenioDAMAPResource.java b/src/main/java/org/damap/base/rest/invenio_damap/InvenioDAMAPResource.java
new file mode 100644
index 00000000..0184218c
--- /dev/null
+++ b/src/main/java/org/damap/base/rest/invenio_damap/InvenioDAMAPResource.java
@@ -0,0 +1,73 @@
+package org.damap.base.rest.invenio_damap;
+
+import io.quarkus.resteasy.reactive.server.EndpointDisabled;
+import io.quarkus.security.ForbiddenException;
+import jakarta.enterprise.context.RequestScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MediaType;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.List;
+import lombok.extern.jbosslog.JBossLog;
+import org.damap.base.rest.dmp.domain.DmpDO;
+import org.damap.base.rest.madmp.dto.Dataset;
+import org.damap.base.security.SecurityService;
+import org.damap.base.validation.AccessValidator;
+
+@Path("/api/madmps")
+@RequestScoped
+@Produces(MediaType.APPLICATION_JSON)
+@JBossLog
+@EndpointDisabled(name = "invenio.disabled", stringValue = "true")
+public class InvenioDAMAPResource {
+
+ @Inject
+ public InvenioDAMAPResource(
+ AccessValidator accessValidator,
+ InvenioDAMAPService invenioDAMAPService,
+ SecurityService securityService) {
+ this.accessValidator = accessValidator;
+ this.invenioDAMAPService = invenioDAMAPService;
+ this.securityService = securityService;
+ }
+
+ AccessValidator accessValidator;
+ InvenioDAMAPService invenioDAMAPService;
+ SecurityService securityService;
+
+ @GET
+ public List getDmpListByPerson(@Context HttpHeaders headers) {
+ SimpleEntry, String> result =
+ invenioDAMAPService.resolveDmpsAndIds(securityService.checkIfUserIsAuthorized(headers));
+ return result.getKey();
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ public DmpDO addDataSetToDmp(@Context HttpHeaders headers, DMPPayload payload) {
+ SimpleEntry, String> result =
+ invenioDAMAPService.resolveDmpsAndIds(securityService.checkIfUserIsAuthorized(headers));
+
+ long dmpId = payload.getDmpId();
+ log.info("Add dataset to dmp with id: " + dmpId);
+ Dataset dataset = payload.getDataset();
+
+ if (result.getKey().stream().noneMatch(dmpDO -> dmpDO.getId().equals(dmpId))) {
+ throw new NotFoundException("DMP with id " + dmpId + " could not be found.");
+ }
+
+ String personId = result.getValue();
+ // Assuming all IDs provided fetch the same DMPs, check permissions.
+ if (!accessValidator.canEditDmp(dmpId, personId))
+ throw new ForbiddenException(
+ "Person " + personId + "Not authorized to access dmp with id " + dmpId);
+ return invenioDAMAPService.addDataSetToDMP(dmpId, dataset);
+ }
+}
diff --git a/src/main/java/org/damap/base/rest/invenio_damap/InvenioDAMAPService.java b/src/main/java/org/damap/base/rest/invenio_damap/InvenioDAMAPService.java
new file mode 100644
index 00000000..8f794a6a
--- /dev/null
+++ b/src/main/java/org/damap/base/rest/invenio_damap/InvenioDAMAPService.java
@@ -0,0 +1,116 @@
+package org.damap.base.rest.invenio_damap;
+
+import io.quarkus.security.UnauthorizedException;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.json.JsonObject;
+import jakarta.transaction.Transactional;
+import java.text.MessageFormat;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.Date;
+import java.util.List;
+import org.damap.base.rest.dmp.domain.DatasetDO;
+import org.damap.base.rest.dmp.domain.DmpDO;
+import org.damap.base.rest.dmp.service.DmpService;
+import org.damap.base.rest.madmp.dto.Dataset;
+import org.damap.base.rest.version.VersionDO;
+import org.damap.base.rest.version.VersionService;
+import org.eclipse.microprofile.jwt.JsonWebToken;
+
+@ApplicationScoped
+public class InvenioDAMAPService {
+
+ protected DmpService dmpService;
+ protected VersionService versionService;
+
+ @Inject
+ InvenioDAMAPService(DmpService dmpService, VersionService versionService) {
+ this.dmpService = dmpService;
+ this.versionService = versionService;
+ }
+
+ // Resolves user identity based on the DMPs and returns dmp list and list of
+ // identifiers if successful.
+ public SimpleEntry, String> resolveDmpsAndIds(JsonWebToken jwt) {
+ JsonObject invenioDamapClaim = jwt.getClaim("invenio-damap");
+ if (invenioDamapClaim == null) {
+ throw new UnauthorizedException("Missing invenio-damap claim in jwt.");
+ }
+
+ JsonObject identifiers = invenioDamapClaim.getJsonObject("identifiers");
+ if (identifiers == null || identifiers.isEmpty()) {
+ throw new UnauthorizedException("No valid authentication schema was provided.");
+ }
+
+ List personDmpList = null;
+ String matchingIdentifier = null;
+
+ for (String key : identifiers.keySet()) {
+ String identifier = identifiers.getString(key);
+ List dmps = dmpService.getDmpDOListByPersonId(identifier);
+
+ // Check if returned DMPs list is empty.
+ // If yes, no resolving can take place, move to the next identifier.
+ if (dmps.isEmpty()) continue;
+
+ // If a second identifier matches, something went wrong
+ if (matchingIdentifier == null) {
+ matchingIdentifier = identifier;
+ personDmpList = dmps;
+ } else {
+ throw new UnauthorizedException("Mismatch in resolved identities.");
+ }
+ }
+
+ // Check if identifier is null. This means that no resolving was possible.
+ if (matchingIdentifier == null)
+ throw new UnauthorizedException("Identities could not be resolved.");
+
+ return new SimpleEntry<>(personDmpList, matchingIdentifier);
+ }
+
+ @Transactional
+ public DmpDO addDataSetToDMP(long dmpId, Dataset dataset) {
+
+ DmpDO dmpDO = dmpService.getDmpById(dmpId);
+ var datasetDO =
+ dmpDO.getDatasets().stream()
+ .filter(
+ ds -> {
+ var localIdentifier = ds.getDatasetId();
+ var externalIdentifier = dataset.getDatasetId();
+
+ if (localIdentifier == null || externalIdentifier == null) {
+ return false;
+ }
+
+ return localIdentifier.getIdentifier() != null
+ && externalIdentifier.getIdentifier() != null
+ && localIdentifier.getType() != null
+ && externalIdentifier.getType() != null
+ && localIdentifier.getIdentifier().equals(externalIdentifier.getIdentifier())
+ && localIdentifier
+ .getType()
+ .toString()
+ .equalsIgnoreCase(externalIdentifier.getType().name());
+ })
+ .findFirst()
+ .orElse(null);
+
+ if (datasetDO == null) {
+ datasetDO = new DatasetDO();
+ dmpDO.getDatasets().add(datasetDO);
+ }
+ InvenioDamapResourceMapper.mapMaDMPDatasetToDatasetDO(dataset, datasetDO, dmpDO);
+ dmpDO = dmpService.update(dmpDO);
+
+ VersionDO version = new VersionDO();
+ version.setDmpId(dmpId);
+ version.setVersionName(
+ MessageFormat.format("Added dataset `{0}` from remote datasource", dataset.getTitle()));
+ version.setVersionDate(new Date());
+ versionService.create(version);
+
+ return dmpDO;
+ }
+}
diff --git a/src/main/java/org/damap/base/rest/invenio_damap/InvenioDamapResourceMapper.java b/src/main/java/org/damap/base/rest/invenio_damap/InvenioDamapResourceMapper.java
new file mode 100644
index 00000000..90896332
--- /dev/null
+++ b/src/main/java/org/damap/base/rest/invenio_damap/InvenioDamapResourceMapper.java
@@ -0,0 +1,175 @@
+package org.damap.base.rest.invenio_damap;
+
+import java.util.*;
+import lombok.experimental.UtilityClass;
+import lombok.extern.jbosslog.JBossLog;
+import org.damap.base.enums.EAccessRight;
+import org.damap.base.enums.EDataAccessType;
+import org.damap.base.enums.EDataKind;
+import org.damap.base.enums.EDataSource;
+import org.damap.base.enums.EDataType;
+import org.damap.base.enums.EIdentifierType;
+import org.damap.base.enums.ELicense;
+import org.damap.base.rest.dmp.domain.DatasetDO;
+import org.damap.base.rest.dmp.domain.DmpDO;
+import org.damap.base.rest.dmp.domain.ExternalStorageDO;
+import org.damap.base.rest.dmp.domain.IdentifierDO;
+import org.damap.base.rest.madmp.dto.Dataset;
+import org.damap.base.rest.madmp.dto.Distribution;
+import org.damap.base.rest.madmp.dto.Host;
+
+@JBossLog
+@UtilityClass
+public class InvenioDamapResourceMapper {
+ public DatasetDO mapMaDMPDatasetToDatasetDO(
+ Dataset madmpDataset, DatasetDO datasetDO, DmpDO dmpDO) {
+
+ // Disclaimer: This is by no means complete. Not all fields of the
+ // Dataset or DMP are set. Null value checks should also be performed.
+ var datasetId = madmpDataset.getDatasetId();
+ if (datasetId != null) {
+ IdentifierDO newId = new IdentifierDO();
+ newId.setIdentifier(datasetId.getIdentifier());
+ newId.setType(EIdentifierType.valueOf(datasetId.getType().name().toUpperCase()));
+ datasetDO.setDatasetId(newId);
+ }
+
+ if (datasetDO.getReferenceHash() != null) {
+ datasetDO.setReferenceHash("invenio" + new Date());
+ }
+
+ datasetDO.setDateOfDeletion(null);
+ datasetDO.setDelete(false);
+ datasetDO.setDeletionPerson(null);
+
+ if (madmpDataset.getDescription() != null && !madmpDataset.getDescription().isEmpty()) {
+ datasetDO.setDescription(madmpDataset.getDescription());
+ }
+
+ mapDistribution(madmpDataset, datasetDO, dmpDO);
+
+ if (datasetDO.getOtherProjectMembersAccess() == null) {
+ datasetDO.setOtherProjectMembersAccess(EAccessRight.READ);
+ }
+
+ if (madmpDataset.getPersonalData() != null || datasetDO.getPersonalData() == null) {
+ Boolean personalData =
+ switch (Objects.requireNonNullElse(
+ madmpDataset.getPersonalData(), Dataset.PersonalData.UNKNOWN)) {
+ case NO -> false;
+ default -> true;
+ };
+ datasetDO.setPersonalData(personalData);
+ dmpDO.setPersonalData(dmpDO.getPersonalData() || personalData);
+ }
+
+ if (datasetDO.getPublicAccess() == null) {
+ datasetDO.setPublicAccess(EAccessRight.READ);
+ }
+ if (datasetDO.getSelectedProjectMembersAccess() == null) {
+ datasetDO.setSelectedProjectMembersAccess(EAccessRight.READ);
+ }
+
+ if (madmpDataset.getSensitiveData() != null || datasetDO.getSensitiveData() == null) {
+ Boolean sensitiveData =
+ switch (Objects.requireNonNullElse(
+ madmpDataset.getSensitiveData(), Dataset.SensitiveData.UNKNOWN)) {
+ case NO -> false;
+ default -> true;
+ };
+ datasetDO.setSensitiveData(sensitiveData);
+ dmpDO.setSensitiveData(dmpDO.getSensitiveData() || sensitiveData);
+ }
+
+ // TODO: Let user decide?
+ if (datasetDO.getSource() == null) {
+ datasetDO.setSource(EDataSource.NEW);
+ // This should match the dataset. If new, setDataKind. else setReusedDataKind
+ dmpDO.setDataKind(EDataKind.SPECIFY);
+ dmpDO.setReusedDataKind(EDataKind.SPECIFY);
+ }
+
+ if (madmpDataset.getTitle() != null) {
+ datasetDO.setTitle(madmpDataset.getTitle());
+ }
+
+ if (madmpDataset.getType() != null) {
+ // Setting data type
+ EDataType type = EDataType.getByValue(madmpDataset.getType());
+ if (type == null) {
+ log.info("Could not infer EDataType from provided value: " + madmpDataset.getType());
+ } else {
+ var types = Objects.requireNonNullElse(datasetDO.getType(), new ArrayList());
+ if (!types.contains(type)) {
+ types.add(type);
+ }
+ datasetDO.setType(types);
+ }
+ }
+
+ return datasetDO;
+ }
+
+ private static void mapDistribution(Dataset madmpDataset, DatasetDO datasetDO, DmpDO dmpDO) {
+ if (madmpDataset.getDistribution() == null) {
+ return;
+ }
+
+ Set licenses = new HashSet<>();
+ for (Distribution d : madmpDataset.getDistribution()) {
+ if (d.getDataAccess() != null) {
+ var dataAccess = EDataAccessType.getByValue(d.getDataAccess().value());
+ if (dataAccess != null && dataAccess.compare(datasetDO.getDataAccess()) == 1) {
+ datasetDO.setDataAccess(dataAccess);
+ }
+ }
+ licenses.addAll(d.getLicense().stream().map(l -> l.getLicenseRef().toString()).toList());
+
+ if (d.getByteSize() != null
+ && d.getByteSize() > Objects.requireNonNullElse(datasetDO.getSize(), 0L)) {
+ datasetDO.setSize(d.getByteSize().longValue());
+ }
+
+ if (d.getHost() == null) {
+ // Nothing more to do
+ continue;
+ }
+
+ Host host = d.getHost();
+ String hostPath = host.getUrl() == null ? null : host.getUrl().getPath();
+
+ // Check if the provided storage is already set on the DMP.
+ var externalStorages = dmpDO.getExternalStorage();
+ ExternalStorageDO externalStorageDO =
+ externalStorages.stream()
+ .filter(s -> s.getUrl() != null && s.getUrl().equals(hostPath))
+ .findFirst()
+ .orElse(null);
+
+ if (externalStorageDO == null) {
+ externalStorageDO = new ExternalStorageDO();
+ externalStorageDO.setBackupFrequency(host.getBackupFrequency());
+ externalStorageDO.setStorageLocation(
+ host.getGeoLocation() != null ? host.getGeoLocation().toString() : null);
+ externalStorageDO.setTitle(host.getTitle());
+ externalStorageDO.setUrl(hostPath);
+ externalStorages.add(externalStorageDO);
+ }
+
+ var datasetHashes = externalStorageDO.getDatasets();
+ if (datasetHashes.contains(datasetDO.getReferenceHash())) {
+ datasetHashes.add(datasetDO.getReferenceHash());
+ }
+ }
+
+ // TODO: Support multiple licenses
+ for (String license : licenses) {
+ for (ELicense eLicense : ELicense.values()) {
+ if (license.equals(eLicense.getUrl())) {
+ datasetDO.setLicense(eLicense);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/org/damap/base/rest/openaire/OpenAireRemoteResource.java b/src/main/java/org/damap/base/rest/openaire/OpenAireRemoteResource.java
index 6a07ac75..529f145b 100644
--- a/src/main/java/org/damap/base/rest/openaire/OpenAireRemoteResource.java
+++ b/src/main/java/org/damap/base/rest/openaire/OpenAireRemoteResource.java
@@ -4,9 +4,9 @@
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
-import org.jboss.resteasy.annotations.jaxrs.QueryParam;
/** OpenAireRemoteResource interface. */
@RegisterRestClient(configKey = "rest.openaire")
diff --git a/src/main/java/org/damap/base/security/SecurityService.java b/src/main/java/org/damap/base/security/SecurityService.java
index b95148ed..fcf7c57e 100644
--- a/src/main/java/org/damap/base/security/SecurityService.java
+++ b/src/main/java/org/damap/base/security/SecurityService.java
@@ -1,25 +1,37 @@
package org.damap.base.security;
+import io.quarkus.arc.DefaultBean;
import io.quarkus.arc.Unremovable;
import io.quarkus.oidc.runtime.OidcJwtCallerPrincipal;
+import io.quarkus.security.UnauthorizedException;
import io.quarkus.security.identity.SecurityIdentity;
+import io.smallrye.jwt.auth.principal.JWTParser;
+import io.smallrye.jwt.auth.principal.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
+import jakarta.ws.rs.core.HttpHeaders;
import java.security.Principal;
import lombok.extern.jbosslog.JBossLog;
import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.eclipse.microprofile.jwt.JsonWebToken;
/** SecurityService class. */
@JBossLog
@Unremovable
// @UnlessBuildProfile("test")
@ApplicationScoped
+@DefaultBean
public class SecurityService {
@Inject SecurityIdentity securityIdentity;
@ConfigProperty(name = "damap.auth.user")
String authUser;
+ @ConfigProperty(name = "invenio.shared-secret")
+ String sharedSecret;
+
+ @Inject JWTParser parser;
+
/**
* getUserId.
*
@@ -51,4 +63,44 @@ public String getUserName() {
public boolean isAdmin() {
return securityIdentity.hasRole("Damap Admin");
}
+
+ /**
+ * Validates a JWT token from the X-Auth header.
+ *
+ * @param headers HttpHeaders containing the Authorization token.
+ * @return JsonWebToken if valid, null otherwise.
+ */
+ public JsonWebToken validateAuthHeader(HttpHeaders headers) {
+ String jwtToken = headers.getHeaderString("X-Auth");
+
+ if (jwtToken != null && !jwtToken.isEmpty()) {
+ try {
+ JsonWebToken jwt = parser.verify(jwtToken, sharedSecret);
+
+ long exp = jwt.getExpirationTime();
+ long currentTime = System.currentTimeMillis() / 1000;
+
+ if (currentTime >= exp) throw new UnauthorizedException("Token expired.");
+
+ return jwt;
+ } catch (ParseException e) {
+ log.error("Failed to parse JWT: ", e);
+ return null;
+ }
+ }
+ return null; // No Authorization header or not in the correct format
+ }
+
+ /**
+ * Checks if the user is authorized based on the JWT token.
+ *
+ * @param headers HttpHeaders containing the Authorization token.
+ * @return JsonWebToken if the user is authorized.
+ */
+ public JsonWebToken checkIfUserIsAuthorized(HttpHeaders headers) {
+ JsonWebToken jwt = validateAuthHeader(headers);
+ if (jwt == null) throw new UnauthorizedException("User unauthorized.");
+
+ return jwt;
+ }
}
diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml
index aeabfc20..ca37fc9e 100644
--- a/src/main/resources/application.yaml
+++ b/src/main/resources/application.yaml
@@ -32,6 +32,10 @@ damap:
query-value: 'ORCID'
class-name: 'org.damap.base.rest.persons.orcid.ORCIDPersonServiceImpl'
+invenio:
+ disabled: true
+ shared-secret: "thisIsAVerySecretKeyOfAtLeast32Chars"
+
# general config settings
quarkus:
http:
diff --git a/src/main/resources/org/damap/base/spec/re3data/re3data_index_V1-0.xsd b/src/main/resources/org/damap/base/spec/re3data/re3data_index_V1-0.xsd
index 7a41d4a4..a49f37ce 100644
--- a/src/main/resources/org/damap/base/spec/re3data/re3data_index_V1-0.xsd
+++ b/src/main/resources/org/damap/base/spec/re3data/re3data_index_V1-0.xsd
@@ -1,11 +1,27 @@
-
-
-
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
-
diff --git a/src/test/java/org/damap/base/TestProfiles.java b/src/test/java/org/damap/base/TestProfiles.java
new file mode 100644
index 00000000..2d58c6b5
--- /dev/null
+++ b/src/test/java/org/damap/base/TestProfiles.java
@@ -0,0 +1,21 @@
+package org.damap.base;
+
+import io.quarkus.test.junit.QuarkusTestProfile;
+import java.util.Collections;
+import java.util.Map;
+
+public class TestProfiles {
+ public static class InvenioDAMAPEnabledProfile implements QuarkusTestProfile {
+
+ /**
+ * Returns additional config to be applied to the test. This will override any existing config
+ * (including in application.(properties,yaml), however existing config will be merged with this
+ * (i.e. application.(properties,yaml) config will still take effect, unless a specific config
+ * key has been overridden).
+ */
+ @Override
+ public Map getConfigOverrides() {
+ return Collections.singletonMap("invenio.disabled", "false");
+ }
+ }
+}
diff --git a/src/test/java/org/damap/base/rest/InvenioDamapResourceDisabledTest.java b/src/test/java/org/damap/base/rest/InvenioDamapResourceDisabledTest.java
new file mode 100644
index 00000000..02eadc50
--- /dev/null
+++ b/src/test/java/org/damap/base/rest/InvenioDamapResourceDisabledTest.java
@@ -0,0 +1,21 @@
+package org.damap.base.rest;
+
+import static io.restassured.RestAssured.given;
+
+import io.quarkus.test.common.http.TestHTTPEndpoint;
+import io.quarkus.test.junit.QuarkusTest;
+import org.damap.base.rest.invenio_damap.InvenioDAMAPResource;
+import org.junit.jupiter.api.Test;
+
+@QuarkusTest
+@TestHTTPEndpoint(InvenioDAMAPResource.class)
+class InvenioDamapResourceDisabledTest {
+ @Test
+ void givenConfigNotEnabled_thenNoEndpointsFound() {
+ // GET DMPs endpoint
+ given().when().get().then().statusCode(404);
+
+ // POST dataset endpoint
+ given().when().post().then().statusCode(404);
+ }
+}
diff --git a/src/test/java/org/damap/base/rest/InvenioDamapResourceEnabledTest.java b/src/test/java/org/damap/base/rest/InvenioDamapResourceEnabledTest.java
new file mode 100644
index 00000000..f9d7ed9b
--- /dev/null
+++ b/src/test/java/org/damap/base/rest/InvenioDamapResourceEnabledTest.java
@@ -0,0 +1,197 @@
+package org.damap.base.rest;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.not;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.quarkus.test.common.http.TestHTTPEndpoint;
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.TestProfile;
+import io.restassured.http.Header;
+import io.smallrye.jwt.build.Jwt;
+import io.smallrye.jwt.build.JwtClaimsBuilder;
+import jakarta.inject.Inject;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.ws.rs.core.MediaType;
+import java.util.List;
+import org.damap.base.TestProfiles;
+import org.damap.base.domain.Dmp;
+import org.damap.base.repo.DmpRepo;
+import org.damap.base.rest.dmp.domain.DmpDO;
+import org.damap.base.rest.dmp.service.DmpService;
+import org.damap.base.rest.invenio_damap.DMPPayload;
+import org.damap.base.rest.invenio_damap.InvenioDAMAPResource;
+import org.damap.base.rest.madmp.dto.Dataset;
+import org.damap.base.util.TestDOFactory;
+import org.eclipse.microprofile.config.inject.ConfigProperty;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+// NOTE:
+// We could put tests for the same resource into one file and annotate sub classes with @Nested.
+// However, for some reason, this is really slow (3 Tests took 60 seconds).
+
+@QuarkusTest
+@TestProfile(TestProfiles.InvenioDAMAPEnabledProfile.class)
+@TestHTTPEndpoint(InvenioDAMAPResource.class)
+class InvenioDamapResourceEnabledTest {
+
+ @ConfigProperty(name = "invenio.shared-secret")
+ String sharedSecret;
+
+ @Inject TestDOFactory testDOFactory;
+
+ @Inject DmpRepo dmpRepo;
+
+ @Inject DmpService dmpService;
+
+ @BeforeEach
+ public void cleanup() {
+ List dmps = dmpRepo.getAll();
+ for (Dmp dmp : dmps) dmpService.delete(dmp.id);
+ }
+
+ private JsonObject createInvenioDamapClaim(String userId) {
+ return Json.createObjectBuilder()
+ .add("identifiers", Json.createObjectBuilder().add("personID", userId))
+ .build();
+ }
+
+ private String generateJwt(long expiresIn) {
+ long currentTime = System.currentTimeMillis() / 1000;
+ long exp = currentTime + expiresIn;
+ String userId = getUserId();
+ JwtClaimsBuilder claimsBuilder = Jwt.claims();
+
+ claimsBuilder
+ .subject(userId)
+ .expiresAt(exp)
+ .issuedAt(currentTime)
+ .claim("invenio-damap", createInvenioDamapClaim(userId));
+
+ return claimsBuilder.signWithSecret(sharedSecret);
+ }
+
+ private String getUserId() {
+ return "012345";
+ }
+
+ @Test
+ void getDmpsForPersonThenUnauthorized() {
+ // case where no header is passed
+ given().when().get().then().statusCode(401);
+
+ // case where empty value is included in the header
+ given().when().header("X-Auth", "").get().then().statusCode(401);
+
+ // case where wrong token is included in the header
+ given().when().header("X-Auth", "wrong-credentials").get().then().statusCode(401);
+
+ // case where token has expired
+ String jwtToken = generateJwt(0);
+ given().when().header("X-Auth", jwtToken).get().then().statusCode(401);
+ }
+
+ @Test
+ void getDmpsForPersonThenValid() {
+ Header authHeader = new Header("X-Auth", generateJwt(600));
+
+ // case where user has no DMPs (which means identity is not present in the
+ // system or identity is invalid)
+ given().when().header(authHeader).get().then().statusCode(401);
+
+ // case with DMP created
+ DmpDO dmpDO = testDOFactory.createDmp("invenio-damap", true);
+ given()
+ .when()
+ .header(authHeader)
+ .get()
+ .then()
+ .statusCode(200)
+ .body("", hasSize(1))
+ .body("[0].title", equalTo(dmpDO.getTitle()));
+ }
+
+ @Test
+ void addDataSetToDmpThenValid() throws JsonProcessingException {
+ Header authHeader = new Header("X-Auth", generateJwt(600));
+ String datasetData =
+ """
+ {
+ "dataset_id" : {
+ "type": "doi",
+ "identifier": "repository/123.456"
+ },
+ "description" : "Dataset description",
+ "distribution" : [ {
+ "access_url" : "https://repository.tugraz.at/",
+ "byte_size" : 705032704,
+ "data_access" : "open",
+ "description" : "Distribution description",
+ "format" : [ "Standard office documents", "Images", "Raw data", "Scientific and statistical data formats", "Plain text" ],
+ "host" : {
+ "description" : "An institutional repository at Graz University of Technology to enable storing, sharing and publishing research data, publications and open educational resources. It provides open access services and follows the FAIR principles.",
+ "pid_system" : [ "doi" ],
+ "storage_type" : "institutional",
+ "support_versioning" : "yes",
+ "title" : "TU Graz Repository",
+ "url" : "https://repository.tugraz.at/"
+ },
+ "license" : [ {
+ "license_ref" : "https://creativecommons.org/licenses/by-nc-sa/4.0/"
+ } ],
+ "title" : "Host title"
+ } ],
+ "personal_data" : "no",
+ "security_and_privacy" : [ ],
+ "sensitive_data" : "no",
+ "title" : "Dataset title",
+ "type" : "Standard office documents, Images, Raw data, Scientific and statistical data formats, Plain text"
+ }""";
+
+ DmpDO dmpDO = testDOFactory.createDmp("invenio-damap", true);
+ Dataset madmpDataset = (new ObjectMapper()).readValue(datasetData, Dataset.class);
+
+ DMPPayload payload1 = new DMPPayload();
+ payload1.setDmpId(dmpDO.getId());
+ payload1.setDataset(madmpDataset);
+
+ // case with dataset creation
+ given()
+ .when()
+ .contentType(MediaType.APPLICATION_JSON)
+ .header(authHeader)
+ .body(payload1)
+ .post()
+ .then()
+ .statusCode(200)
+ .body("", not(empty()))
+ .body("datasets", hasSize(3))
+ .body("datasets[2].title", equalTo(madmpDataset.getTitle()));
+
+ Dataset minimalDataset = new Dataset();
+ minimalDataset.setTitle("minimal");
+
+ DMPPayload payload2 = new DMPPayload();
+ payload2.setDmpId(dmpDO.getId());
+ payload2.setDataset(minimalDataset);
+
+ // case with minimal dataset creation
+ given()
+ .when()
+ .contentType(MediaType.APPLICATION_JSON)
+ .header(authHeader)
+ .body(payload2)
+ .post()
+ .then()
+ .statusCode(200)
+ .body("", not(empty()))
+ .body("datasets", hasSize(4))
+ .body("datasets[3].title", equalTo(minimalDataset.getTitle()));
+ }
+}