diff --git a/dmp-backend/Docker/dmp-backend.env b/dmp-backend/Docker/dmp-backend.env new file mode 100644 index 000000000..eada87b0c --- /dev/null +++ b/dmp-backend/Docker/dmp-backend.env @@ -0,0 +1 @@ +PROFILE=staging \ No newline at end of file diff --git a/dmp-backend/Dockerfile b/dmp-backend/Dockerfile index 8701a23a0..4b9954a9e 100644 --- a/dmp-backend/Dockerfile +++ b/dmp-backend/Dockerfile @@ -1,11 +1,23 @@ -FROM openjdk:8-jdk-alpine -RUN apk add --update \ - curl \ - && rm -rf /var/cache/apk/* -VOLUME /tmp -ARG PROFILE=production -ENV PROF $PROFILE -ADD web/src/main/resources/ProjectConfiguration.xml /tmp/ProjectConfiguration.xml -ADD web/src/main/resources/ExternalUrls.xml /tmp/ExternalUrls.xml -ADD web/target/web-1.0-SNAPSHOT.jar app.jar -ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom" ,"-Dspring.profiles.active=${PROF}","-jar","/app.jar"] \ No newline at end of file +FROM maven:3-jdk-8-alpine AS MAVEN_BUILD + + + +COPY pom.xml /build/ +COPY data /build/data/ +COPY elastic /build/elastic/ +COPY logging /build/logging/ +COPY queryable /build/queryable/ +COPY web /build/web/ + + + +WORKDIR /build/ +RUN mvn package + + + +FROM openjdk:8-jre-alpine +WORKDIR /app + +COPY --from=MAVEN_BUILD /build/web/target/web-1.0-SNAPSHOT.jar /app/app.jar +ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom" ,"-Dspring.profiles.active=${PROFILE}","-jar","/app/app.jar"] \ No newline at end of file diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java index b8e2c35c4..cc556701d 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java @@ -33,6 +33,7 @@ public class DatasetProfileCriteria extends Criteria { private Short filter; private UUID userId; private boolean finalized; + private Integer status; public boolean getAllVersions() { return allVersions; } public void setAllVersions(boolean allVersions) { this.allVersions = allVersions; } @@ -60,4 +61,12 @@ public class DatasetProfileCriteria extends Criteria { public void setFinalized(boolean finalized) { this.finalized = finalized; } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java index b06d5d8fd..36fcc5433 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java @@ -52,6 +52,9 @@ public class DatasetProfileDaoImpl extends DatabaseAccess implem builder.notEqual(root.get("id"), criteria.getUserId()))); } } + if (criteria.getStatus() != null) { + query.where(((builder, root) -> builder.equal(root.get("status"), criteria.getStatus()))); + } if (criteria.getFinalized()) { query.where(((builder, root) -> builder.equal(root.get("status"), DatasetProfile.Status.FINALIZED.getValue()))); } else { diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DoiFunderDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DoiFunderDao.java new file mode 100644 index 000000000..038b4b4b2 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DoiFunderDao.java @@ -0,0 +1,11 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.entities.DoiFunder; + +import java.util.UUID; + +public interface DoiFunderDao extends DatabaseAccessLayer { + + DoiFunder findFunderByName(String name); +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DoiFunderDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DoiFunderDaoImpl.java new file mode 100644 index 000000000..3e775b952 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DoiFunderDaoImpl.java @@ -0,0 +1,55 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.databaselayer.service.DatabaseService; +import eu.eudat.data.entities.DoiFunder; +import eu.eudat.queryable.QueryableList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Component("DoiFunderDao") +public class DoiFunderDaoImpl extends DatabaseAccess implements DoiFunderDao { + + @Autowired + public DoiFunderDaoImpl(DatabaseService databaseService) { + super(databaseService); + } + + @Override + public DoiFunder findFunderByName(String name) { + return this.asQueryable().toList().stream().filter(doiFunder -> name.contains(doiFunder.getName()) || doiFunder.getName().contains(name)).findFirst().orElse(null); + } + + @Override + public DoiFunder createOrUpdate(DoiFunder item) { + return this.getDatabaseService().createOrUpdate(item, DoiFunder.class); + } + + @Override + public CompletableFuture createOrUpdateAsync(DoiFunder item) { + return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); + } + + @Override + public DoiFunder find(UUID id) { + return this.getDatabaseService().getQueryable(DoiFunder.class).where(((builder, root) -> builder.equal(root.get("id"), id))).getSingle(); + } + + @Override + public DoiFunder find(UUID id, String hint) { + throw new UnsupportedOperationException(); + } + + @Override + public void delete(DoiFunder item) { + this.getDatabaseService().delete(item); + } + + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(DoiFunder.class); + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDao.java new file mode 100644 index 000000000..bd80fa49b --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDao.java @@ -0,0 +1,15 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.entities.UserAssociation; +import eu.eudat.data.entities.UserInfo; + +import java.util.List; +import java.util.UUID; + +public interface UserAssociationDao extends DatabaseAccessLayer { + + public List getAssociated(UserInfo userId); + + public Boolean areAssociated(UserInfo firstUser, UserInfo secondUser); +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDaoImpl.java new file mode 100644 index 000000000..b8ecc0668 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/UserAssociationDaoImpl.java @@ -0,0 +1,73 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.databaselayer.service.DatabaseService; +import eu.eudat.data.entities.UserAssociation; +import eu.eudat.data.entities.UserInfo; +import eu.eudat.queryable.QueryableList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Component("UserAssociationDao") +public class UserAssociationDaoImpl extends DatabaseAccess implements UserAssociationDao { + + @Autowired + public UserAssociationDaoImpl(DatabaseService databaseService) { + super(databaseService); + } + + @Override + public UserAssociation createOrUpdate(UserAssociation item) { + return this.getDatabaseService().createOrUpdate(item, UserAssociation.class); + } + + @Override + public CompletableFuture createOrUpdateAsync(UserAssociation item) { + return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); + } + + @Override + public UserAssociation find(UUID id) { + return this.getDatabaseService().getQueryable(UserAssociation.class).where(((builder, root) -> builder.equal(root.get("id"), id))).getSingle(); + } + + @Override + public UserAssociation find(UUID id, String hint) { + throw new UnsupportedOperationException(); + } + + @Override + public void delete(UserAssociation item) { + this.getDatabaseService().delete(item); + } + + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(UserAssociation.class); + } + + @Override + public List getAssociated(UserInfo userId) { + return this.getDatabaseService().getQueryable(UserAssociation.class).where(((builder, root) -> + builder.or(builder.equal(root.get("firstUser"), userId), builder.equal(root.get("secondUser"), userId)))).toList(); + } + + @Override + public Boolean areAssociated(UserInfo firstUser, UserInfo secondUser) { + return this.getDatabaseService().getQueryable(UserAssociation.class).where(((builder, root) -> + builder.or( + builder.and( + builder.equal(root.get("firstUser"), firstUser), + builder.equal(root.get("secondUser"), secondUser) + ), + builder.and( + builder.equal(root.get("secondUser"), firstUser), + builder.equal(root.get("firstUser"), secondUser) + ) + ))).count() > 0; + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DoiFunder.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DoiFunder.java new file mode 100644 index 000000000..6ee816210 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DoiFunder.java @@ -0,0 +1,61 @@ +package eu.eudat.data.entities; + +import eu.eudat.queryable.queryableentity.DataEntity; + +import javax.persistence.*; +import java.util.List; +import java.util.UUID; + +@Entity +@Table(name = "\"DoiFunder\"") +public class DoiFunder implements DataEntity { + + @Id + private UUID id; + + @Column(name = "name") + private String name; + + @Column(name = "doi") + private String doi; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDoi() { + return doi; + } + + public void setDoi(String doi) { + this.doi = doi; + } + + @Override + public void update(DoiFunder entity) { + this.name = entity.name; + this.doi = entity.doi; + } + + @Override + public UUID getKeys() { + return id; + } + + @Override + public DoiFunder buildFromTuple(List tuple, List fields, String base) { + return null; + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserAssociation.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserAssociation.java new file mode 100644 index 000000000..898bbd8a6 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserAssociation.java @@ -0,0 +1,66 @@ +package eu.eudat.data.entities; + +import eu.eudat.queryable.queryableentity.DataEntity; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import java.util.List; +import java.util.UUID; + +@Entity +@Table(name = "\"UserAssociation\"") +public class UserAssociation implements DataEntity { + + @Id + @GeneratedValue + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"firstUser\"") + private UserInfo firstUser; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"secondUser\"") + private UserInfo secondUser; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UserInfo getFirstUser() { + return firstUser; + } + + public void setFirstUser(UserInfo firstUser) { + this.firstUser = firstUser; + } + + public UserInfo getSecondUser() { + return secondUser; + } + + public void setSecondUser(UserInfo secondUser) { + this.secondUser = secondUser; + } + + @Override + public void update(UserAssociation entity) { + + } + + @Override + public UUID getKeys() { + return null; + } + + @Override + public UserAssociation buildFromTuple(List tuple, List fields, String base) { + return null; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java index 109ff34c2..62ff0fe59 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java @@ -82,13 +82,9 @@ public class DMPs extends BaseController { this.configLoader = configLoader; } - /*@Transactional - @RequestMapping(method = RequestMethod.GET, value = {"{id}/unlock"}, produces = "application/json") - public @ResponseBody - ResponseEntity> unlock(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { - this.dataManagementPlanManager.unlock(id); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Unlocked")); - }*/ + /* + * Data Retrieval + * */ @RequestMapping(method = RequestMethod.POST, value = {"/paged"}, consumes = "application/json", produces = "application/json") public @ResponseBody @@ -102,11 +98,11 @@ public class DMPs extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"{id}"}) public @ResponseBody ResponseEntity getSingle(@PathVariable String id, @RequestHeader("Content-Type") String contentType, - @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, InstantiationException, IOException { + @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { if (contentType.equals("application/xml") || contentType.equals("application/msword")) { return this.dataManagementPlanManager.getDocument(id, contentType, principal, this.configLoader); } else { - eu.eudat.models.data.dmp.DataManagementPlan dataManagementPlan = this.dataManagementPlanManager.getSingle(id, principal); + eu.eudat.models.data.dmp.DataManagementPlan dataManagementPlan = this.dataManagementPlanManager.getSingle(id, principal, false); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlan)); } } @@ -118,17 +114,11 @@ public class DMPs extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(datasetProfileTableData)); } - @RequestMapping(method = RequestMethod.GET, value = {"rda/{id}"}) - public @ResponseBody - ResponseEntity getRDAJsonDocument(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IOException { - return this.dataManagementPlanManager.getRDAJsonDocument(id, datasetManager, principal); - } - @RequestMapping(method = RequestMethod.GET, value = {"/overview/{id}"}) public @ResponseBody ResponseEntity getOverviewSingle(@PathVariable String id,@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) { try { - DataManagementPlanOverviewModel dataManagementPlan = this.dataManagementPlanManager.getOverviewSingle(id, principal); + DataManagementPlanOverviewModel dataManagementPlan = this.dataManagementPlanManager.getOverviewSingle(id, principal, false); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlan)); } catch (Exception e) { if (e instanceof UnauthorisedException) { @@ -141,26 +131,71 @@ public class DMPs extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/public/{id}"}) public @ResponseBody - ResponseEntity getSinglePublic(@PathVariable String id) { - try { - eu.eudat.models.data.dmp.DataManagementPlan dataManagementPlan = this.dataManagementPlanManager.getSinglePublic(id, this.dynamicGrantConfiguration); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlan)); - } catch (Exception ex) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message(ex.getMessage())); - } + ResponseEntity getSinglePublic(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { +// try { + eu.eudat.models.data.dmp.DataManagementPlan dataManagementPlan = this.dataManagementPlanManager.getSingle(id, principal, true); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlan)); +// } catch (Exception ex) { +// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message(ex.getMessage())); +// } } @RequestMapping(method = RequestMethod.GET, value = {"/publicOverview/{id}"}) public @ResponseBody - ResponseEntity getOverviewSinglePublic(@PathVariable String id) { - try { - DataManagementPlanOverviewModel dataManagementPlan = this.dataManagementPlanManager.getOverviewSinglePublic(id); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlan)); - } catch (Exception ex) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message(ex.getMessage())); - } + ResponseEntity getOverviewSinglePublic(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { +// try { + DataManagementPlanOverviewModel dataManagementPlan = this.dataManagementPlanManager.getOverviewSingle(id, principal, true); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlan)); +// } catch (Exception ex) { +// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message(ex.getMessage())); +// } } + @RequestMapping(method = RequestMethod.POST, value = {"/dynamic"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity>>> getWithCriteria(@RequestBody RequestItem criteriaRequestItem, Principal principal) throws InstantiationException, IllegalAccessException { + List> dataTable = this.dataManagementPlanManager.getDynamicFields(criteriaRequestItem.getCriteria().getId(), this.dynamicGrantConfiguration, criteriaRequestItem.getCriteria()); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); + } + + /* + * Data Export + * */ + + @RequestMapping(method = RequestMethod.GET, value = {"rda/{id}"}) + public @ResponseBody + ResponseEntity getRDAJsonDocument(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IOException { + return this.dataManagementPlanManager.getRDAJsonDocument(id, datasetManager, principal); + } + + @RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"}) + public @ResponseBody + ResponseEntity getPDFDocument(@PathVariable String id, @RequestHeader("Content-Type") String contentType, + @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException, InterruptedException { + FileEnvelope file = this.dataManagementPlanManager.getWordDocument(id, principal, configLoader); + String name = file.getFilename().substring(0, file.getFilename().length() - 5); + File pdffile = datasetManager.convertToPDF(file, environment); + InputStream resource = new FileInputStream(pdffile); + logger.info("Mime Type of " + name + " is " + + new MimetypesFileTypeMap().getContentType(file.getFile())); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentLength(pdffile.length()); + responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); + responseHeaders.set("Content-Disposition", "attachment;filename=" + name + ".pdf"); + responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); + responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); + + byte[] content = org.apache.poi.util.IOUtils.toByteArray(resource); + resource.close(); + Files.deleteIfExists(file.getFile().toPath()); + Files.deleteIfExists(pdffile.toPath()); + return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); + } + + /* + * Data Management + * */ + @Transactional @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") public @ResponseBody @@ -199,37 +234,6 @@ public class DMPs extends BaseController { } } - @RequestMapping(method = RequestMethod.POST, value = {"/dynamic"}, consumes = "application/json", produces = "application/json") - public @ResponseBody - ResponseEntity>>> getWithCriteria(@RequestBody RequestItem criteriaRequestItem, Principal principal) throws InstantiationException, IllegalAccessException { - List> dataTable = this.dataManagementPlanManager.getDynamicFields(criteriaRequestItem.getCriteria().getId(), this.dynamicGrantConfiguration, criteriaRequestItem.getCriteria()); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); - } - - @RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"}) - public @ResponseBody - ResponseEntity getPDFDocument(@PathVariable String id, @RequestHeader("Content-Type") String contentType, - @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException, InterruptedException { - FileEnvelope file = this.dataManagementPlanManager.getWordDocument(id, principal, configLoader); - String name = file.getFilename().substring(0, file.getFilename().length() - 5); - File pdffile = datasetManager.convertToPDF(file, environment); - InputStream resource = new FileInputStream(pdffile); - logger.info("Mime Type of " + name + " is " + - new MimetypesFileTypeMap().getContentType(file.getFile())); - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setContentLength(pdffile.length()); - responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); - responseHeaders.set("Content-Disposition", "attachment;filename=" + name + ".pdf"); - responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); - responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); - - byte[] content = org.apache.poi.util.IOUtils.toByteArray(resource); - resource.close(); - Files.deleteIfExists(file.getFile().toPath()); - Files.deleteIfExists(pdffile.toPath()); - return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); - } - @RequestMapping(method = RequestMethod.POST, value = {"/upload"}) public ResponseEntity dmpUpload(@RequestParam("file") MultipartFile[] files, Principal principal) throws Exception { if (files[0].getContentType().equals(APPLICATION_JSON.toString())) { @@ -241,29 +245,6 @@ public class DMPs extends BaseController { .status(ApiMessageCode.SUCCESS_MESSAGE)); } - @RequestMapping(method = RequestMethod.POST, value = {"/public/paged"}, consumes = "application/json", produces = "application/json") - public @ResponseBody - ResponseEntity>> getPublicPaged(@RequestBody DataManagmentPlanPublicTableRequest dmpTableRequest, - @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal, - @RequestParam String fieldsGroup) throws Exception { - DataTableData dmp = this.dataManagementPlanManager.getPublicPaged(dmpTableRequest, fieldsGroup, principal); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dmp)); - } - - @RequestMapping(method = RequestMethod.POST, value = {"/test"}, consumes = "application/json", produces = "application/json") - public @ResponseBody - ResponseEntity>> test(@RequestBody DMPCriteria criteria, @ClaimedAuthorities(claims = {Authorities.ANONYMOUS}) Principal principal) throws Exception { - DatabaseRepository dbRepo = this.getApiContext().getOperationsContext().getDatabaseRepository(); - - DMPQuery query = criteria.buildQuery(dbRepo); - - List models = query.getQuery().toListWithFields(); - DataTableData dmp = new DataTableData<>(); - dmp.setData(models); - dmp.setTotalCount(query.getQuery().count()); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dmp)); - } - @RequestMapping(method = RequestMethod.GET, value = {"/makepublic/{id}"}) public ResponseEntity> makePublic(@PathVariable String id, Principal principal) { try { @@ -285,6 +266,10 @@ public class DMPs extends BaseController { } } + /* + * DOI Generation + * */ + @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/createZenodoDoi/{id}"}) public ResponseEntity> createZenodoDoi(@PathVariable String id, Principal principal) { @@ -297,7 +282,11 @@ public class DMPs extends BaseController { } } - @javax.transaction.Transactional + /* + * Data Index + * */ + + @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/index"}) public @ResponseBody ResponseEntity> generateIndex(Principal principal) throws Exception { @@ -305,11 +294,45 @@ public class DMPs extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Generated").payload(null)); } - @javax.transaction.Transactional + @Transactional @RequestMapping(method = RequestMethod.DELETE, value = {"/index"}) public @ResponseBody ResponseEntity> clearIndex(Principal principal) throws Exception { this.dataManagementPlanManager.clearIndex(principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Cleared").payload(null)); } + + /* + * Misc + * */ + + @RequestMapping(method = RequestMethod.POST, value = {"/test"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity>> test(@RequestBody DMPCriteria criteria, @ClaimedAuthorities(claims = {Authorities.ANONYMOUS}) Principal principal) throws Exception { + DatabaseRepository dbRepo = this.getApiContext().getOperationsContext().getDatabaseRepository(); + + DMPQuery query = criteria.buildQuery(dbRepo); + + List models = query.getQuery().toListWithFields(); + DataTableData dmp = new DataTableData<>(); + dmp.setData(models); + dmp.setTotalCount(query.getQuery().count()); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dmp)); + } + + /*@RequestMapping(method = RequestMethod.POST, value = {"/public/paged"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity>> getPublicPaged(@RequestBody DataManagmentPlanPublicTableRequest dmpTableRequest, + @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal, + @RequestParam String fieldsGroup) throws Exception { + DataTableData dmp = this.dataManagementPlanManager.getPublicPaged(dmpTableRequest, fieldsGroup, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dmp)); + }*/ + /*@Transactional + @RequestMapping(method = RequestMethod.GET, value = {"{id}/unlock"}, produces = "application/json") + public @ResponseBody + ResponseEntity> unlock(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { + this.dataManagementPlanManager.unlock(id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Unlocked")); + }*/ } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserInvitationController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserInvitationController.java index 3e09dd43b..b6d045a67 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserInvitationController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserInvitationController.java @@ -48,8 +48,8 @@ public class UserInvitationController extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/getUsers"}, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity>> getUsers(@RequestBody UserInfoRequestItem userInfoRequestItem) throws IllegalAccessException, InstantiationException { - List users = invitationsManager.getUsers(userInfoRequestItem); + ResponseEntity>> getUsers(Principal principal) throws IllegalAccessException, InstantiationException { + List users = invitationsManager.getUsers(principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.SUCCESS_MESSAGE).payload(users)); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/exceptions/security/ForbiddenException.java b/dmp-backend/web/src/main/java/eu/eudat/exceptions/security/ForbiddenException.java new file mode 100644 index 000000000..dfd623dae --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/exceptions/security/ForbiddenException.java @@ -0,0 +1,19 @@ +package eu.eudat.exceptions.security; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.FORBIDDEN) +public class ForbiddenException extends RuntimeException { + public ForbiddenException() { + super(); + } + + public ForbiddenException(String message) { + super(message); + } + + public ForbiddenException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 5473eb0e8..a2815c328 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -25,6 +25,7 @@ import eu.eudat.elastic.entities.Organization; import eu.eudat.elastic.entities.Tag; import eu.eudat.exceptions.datamanagementplan.DMPNewVersionException; import eu.eudat.exceptions.datamanagementplan.DMPWithDatasetsDeleteException; +import eu.eudat.exceptions.security.ForbiddenException; import eu.eudat.exceptions.security.NonValidTokenException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.builders.entity.UserInfoBuilder; @@ -125,6 +126,10 @@ public class DataManagementPlanManager { this.userManager = userManager; } + /* + * Data Retrieval + * */ + public DataTableData getPaged(DataManagementPlanTableRequest dataManagementPlanTableRequest, Principal principal, String fieldsGroup) throws Exception { UUID principalID = principal.getId(); List dmps = null; @@ -161,8 +166,7 @@ public class DataManagementPlanManager { item.setDataset( item.getDataset().stream() .filter(dataset -> !dataset.getStatus().equals(Dataset.Status.DELETED.getValue()) && !dataset.getStatus().equals(Dataset.Status.CANCELED.getValue())).collect(Collectors.toList()).stream() - .filter(dataset -> dataset.getDmp().getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getId().equals(principalID) - || dataset.getDmp().getUsers().stream() + .filter(dataset -> dataset.getDmp().getUsers().stream() .filter(x -> x.getUser().getId().equals(principalID)) .collect(Collectors.toList()).size() > 0) .collect(Collectors.toSet())); @@ -194,237 +198,22 @@ public class DataManagementPlanManager { return dataTable; } - public DataTableData getPublicPaged(DataManagmentPlanPublicTableRequest dataManagementPlanPublicTableRequest, String fieldsGroup, Principal principal) throws Exception { - dataManagementPlanPublicTableRequest.setQuery(databaseRepository.getDmpDao().asQueryable().withHint(HintedModelFactory.getHint(DataManagementPlanListingModel.class))); - QueryableList items = dataManagementPlanPublicTableRequest.applyCriteria(); - - if (principal.getId() != null && dataManagementPlanPublicTableRequest.getCriteria().getRole() != null) { - items.where((builder, root) -> { - Join userJoin = root.join("users", JoinType.LEFT); - return builder.and(builder.equal(userJoin.join("user", JoinType.LEFT).get("id"), principal.getId()), builder.equal(userJoin.get("role"), dataManagementPlanPublicTableRequest.getCriteria().getRole())); - }); - } - QueryableList pagedItems = PaginationManager.applyPaging(items, dataManagementPlanPublicTableRequest); - - DataTableData dataTable = new DataTableData<>(); - - CompletableFuture itemsFuture; - if (fieldsGroup.equals("listing")) { - itemsFuture = pagedItems.withHint(HintedModelFactory.getHint(DataManagementPlanListingModel.class)) - .selectAsync(item -> { - item.setDataset( - item.getDataset().stream() - .filter(dataset -> dataset.getStatus().equals(Dataset.Status.FINALISED.getValue())).collect(Collectors.toSet())); - return new DataManagementPlanListingModel().fromDataModelDatasets(item); - }) - .whenComplete((resultList, throwable) -> dataTable.setData(resultList)); - } else { - itemsFuture = pagedItems - .selectAsync(item -> new DataManagementPlanListingModel().fromDataModel(item)) - .whenComplete((resultList, throwable) -> dataTable.setData(resultList)); - } - - CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> { - dataTable.setTotalCount(count); - }); - CompletableFuture.allOf(itemsFuture, countFuture).join(); - return dataTable; - } - - public void unlock(UUID uuid) throws Exception { - apiContext.getOperationsContext().getDatabaseRepository().getDmpDao() - .asQueryable().where((builder, root) -> builder.equal(root.get("id"), uuid)) - .update(root -> root.get("status"), DMP.DMPStatus.ACTIVE.getValue()); - return; - } - - public FileEnvelope getWordDocument(String id, Principal principal, ConfigLoader configLoader) throws IOException { - return this.getWordDocument(id, principal, configLoader, false); - } - - public FileEnvelope getWordDocument(String id, Principal principal, ConfigLoader configLoader, Boolean versioned) throws IOException { - WordBuilder wordBuilder = new WordBuilder(); - VisibilityRuleService visibilityRuleService = this.utilitiesService.getVisibilityRuleService(); - DatasetWizardModel dataset = new DatasetWizardModel(); - XWPFDocument document = configLoader.getDocument(); - - eu.eudat.data.entities.DMP dmpEntity = databaseRepository.getDmpDao().find(UUID.fromString(id)); - if (!dmpEntity.isPublic() && dmpEntity.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()).collect(Collectors.toList()).size() == 0) - throw new UnauthorisedException(); - - // DMP info on top of the document. - wordBuilder.addParagraphContent("Data Management Plan Information", document, ParagraphStyle.HEADER1, BigInteger.ZERO); - // DMP title custom style. - wordBuilder.addParagraphContent(dmpEntity.getLabel(), document, ParagraphStyle.HEADER2, BigInteger.ZERO); - wordBuilder.addParagraphContent(dmpEntity.getDescription(), document, ParagraphStyle.TEXT, BigInteger.ZERO); - - wordBuilder.addParagraphContent("Funder", document, ParagraphStyle.HEADER3, BigInteger.ZERO); - if (dmpEntity.getGrant().getFunder() != null) - wordBuilder.addParagraphContent(dmpEntity.getGrant().getFunder().getLabel(), document, ParagraphStyle.TEXT, BigInteger.ZERO); - - wordBuilder.addParagraphContent("Grant", document, ParagraphStyle.HEADER3, BigInteger.ZERO); - wordBuilder.addParagraphContent(dmpEntity.getGrant().getLabel(), document, ParagraphStyle.TEXT, BigInteger.ZERO); - - wordBuilder.addParagraphContent("Organisations", document, ParagraphStyle.HEADER3, BigInteger.ZERO); - if (dmpEntity.getOrganisations().size() > 0) { - wordBuilder.addParagraphContent(dmpEntity.getOrganisations().stream().map(Organisation::getLabel).collect(Collectors.joining(", ")) - , document, ParagraphStyle.TEXT, BigInteger.ZERO); - } - - wordBuilder.addParagraphContent("Researchers", document, ParagraphStyle.HEADER3, BigInteger.ZERO); - if (dmpEntity.getResearchers().size() > 0) { - wordBuilder.addParagraphContent(dmpEntity.getResearchers().stream().map(Researcher::getLabel).collect(Collectors.joining(", ")) - , document, ParagraphStyle.TEXT, BigInteger.ZERO); - } - - /*wordBuilder.addParagraphContent("DMP Profile", document, ParagraphStyle.HEADER2, BigInteger.ZERO); - if (dmpEntity.getProfile() != null){ - wordBuilder.addParagraphContent(dmpEntity.getProfile().getLabel(), document, ParagraphStyle.TEXT, BigInteger.ZERO); - }*/ - - // Page break at the end of the DMP title. - XWPFParagraph parBreakDMP = document.createParagraph(); - parBreakDMP.setPageBreak(true); - - wordBuilder.addParagraphContent("Datasets", document, ParagraphStyle.HEADER1, BigInteger.ZERO); - // Space below Datasets. - XWPFParagraph parBreakDatasets = document.createParagraph(); - dmpEntity.getDataset().stream() - .filter(item -> item.getStatus() != Dataset.Status.CANCELED.getValue()) - .filter(item -> item.getStatus() != Dataset.Status.DELETED.getValue()) - .forEach(datasetEntity -> { - Map properties = new HashMap<>(); - if (datasetEntity.getProperties() != null) { - JSONObject jObject = new JSONObject(datasetEntity.getProperties()); - properties = jObject.toMap(); - } - - // Custom style for the Dataset title. - //wordBuilder.addParagraphContent("Title: " + datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO); - XWPFParagraph datasetLabelParagraph = document.createParagraph(); - datasetLabelParagraph.setStyle("Heading2"); - XWPFRun runDatasetTitle1 = datasetLabelParagraph.createRun(); - runDatasetTitle1.setText("Title: "); - runDatasetTitle1.setBold(true); - runDatasetTitle1.setFontSize(12); - XWPFRun runDatasetTitle = datasetLabelParagraph.createRun(); - runDatasetTitle.setText(datasetEntity.getLabel()); - runDatasetTitle.setColor("2E75B6"); - runDatasetTitle.setBold(true); - runDatasetTitle.setFontSize(12); - - XWPFParagraph datasetTemplateParagraph = document.createParagraph(); - datasetTemplateParagraph.setStyle("Heading3"); - XWPFRun runDatasetTemplate1 = datasetTemplateParagraph.createRun(); - runDatasetTemplate1.setText("Template: "); - runDatasetTemplate1.setBold(true); - runDatasetTemplate1.setFontSize(12); - XWPFRun runDatasetTemplate = datasetTemplateParagraph.createRun(); - runDatasetTemplate.setText(datasetEntity.getProfile().getLabel()); - runDatasetTemplate.setColor("2E75B6"); - runDatasetTemplate.setBold(true); - runDatasetTemplate.setFontSize(12); - - XWPFParagraph externalReferencesParagraph = document.createParagraph(); - externalReferencesParagraph.setStyle("Heading3"); - XWPFRun externalReferencesRun = externalReferencesParagraph.createRun(); - externalReferencesRun.setText("External References"); - externalReferencesRun.setColor("2E75B6"); - externalReferencesRun.setBold(true); - externalReferencesRun.setFontSize(12); - - wordBuilder.addParagraphContent("Data Repositories", document, ParagraphStyle.HEADER4, BigInteger.ZERO); - if (datasetEntity.getDatasetDataRepositories().size() > 0) { - wordBuilder.addParagraphContent(datasetEntity.getDatasetDataRepositories().stream().map(DatasetDataRepository::getDataRepository).map(DataRepository::getLabel).collect(Collectors.joining(", ")) - , document, ParagraphStyle.TEXT, BigInteger.ZERO); - } - wordBuilder.addParagraphContent("External Datasets", document, ParagraphStyle.HEADER4, BigInteger.ZERO); - if (datasetEntity.getDatasetExternalDatasets().size() > 0) { - wordBuilder.addParagraphContent(datasetEntity.getDatasetExternalDatasets().stream().map(DatasetExternalDataset::getExternalDataset).map(ExternalDataset::getLabel).collect(Collectors.joining(", ")) - , document, ParagraphStyle.TEXT, BigInteger.ZERO); - } - wordBuilder.addParagraphContent("Registries", document, ParagraphStyle.HEADER4, BigInteger.ZERO); - if (datasetEntity.getRegistries().size() > 0) { - wordBuilder.addParagraphContent(datasetEntity.getRegistries().stream().map(Registry::getLabel).collect(Collectors.joining(", ")) - , document, ParagraphStyle.TEXT, BigInteger.ZERO); - } - wordBuilder.addParagraphContent("Services", document, ParagraphStyle.HEADER4, BigInteger.ZERO); - if (datasetEntity.getServices().size() > 0) { - wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) - , document, ParagraphStyle.TEXT, BigInteger.ZERO); - } - /*wordBuilder.addParagraphContent("Tags", document, ParagraphStyle.HEADER3, BigInteger.ZERO); - if (datasetEntity.().size() > 0) { - wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) - , document, ParagraphStyle.HEADER4, BigInteger.ZERO); - }*/ - - - wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.TEXT, BigInteger.ZERO); - - // Dataset Description custom style. - XWPFParagraph datasetDescriptionParagraph = document.createParagraph(); - datasetDescriptionParagraph.setStyle("Heading3"); - XWPFRun datasetDescriptionRun = datasetDescriptionParagraph.createRun(); - datasetDescriptionRun.setText("Dataset Description"); - datasetDescriptionRun.setColor("2E75B6"); - datasetDescriptionRun.setBold(true); - datasetDescriptionRun.setFontSize(12); - - PagedDatasetProfile pagedDatasetProfile = datasetManager.getPagedProfile(dataset, datasetEntity); - visibilityRuleService.setProperties(properties); - visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); - try { - wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - // Page break at the end of the Dataset. - XWPFParagraph parBreakDataset = document.createParagraph(); - }); - - // Removes the top empty headings. - for (int i = 0; i < 6; i++) { - document.removeBodyElement(0); - } - - String fileName = ""; - if (versioned) { - fileName = dmpEntity.getLabel() + " v" + dmpEntity.getVersion(); - } else { - fileName = dmpEntity.getLabel(); - } - fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", ""); - FileEnvelope exportEnvelope = new FileEnvelope(); - exportEnvelope.setFilename(fileName + ".docx"); - String uuid = UUID.randomUUID().toString(); - File exportFile = new File(this.environment.getProperty("temp.temp") + uuid + ".docx"); - FileOutputStream out = new FileOutputStream(exportFile); - document.write(out); - out.close(); - exportEnvelope.setFile(exportFile); - - return exportEnvelope; - } - - /*public File getPdfDocument(String id) throws InstantiationException, IllegalAccessException, InterruptedException, IOException { - File file = this.getWordDocument(id); - String fileName = file.getName(); - if (fileName.endsWith(".docx")){ - fileName = fileName.substring(0, fileName.length() - 5); - } - return this.datasetManager.convertToPDF(file, environment, fileName); - }*/ - - public eu.eudat.models.data.dmp.DataManagementPlan getSingle(String id, Principal principal) { + public eu.eudat.models.data.dmp.DataManagementPlan getSingle(String id, Principal principal, boolean isPublic) throws Exception { + eu.eudat.models.data.dmp.DataManagementPlan dataManagementPlan = new eu.eudat.models.data.dmp.DataManagementPlan(); DMP dataManagementPlanEntity = databaseRepository.getDmpDao().find(UUID.fromString(id)); - if (dataManagementPlanEntity.getUsers().stream().noneMatch(userInfo -> userInfo.getUser().getId() == principal.getId())) { + if (!isPublic && principal == null) { + throw new UnauthorisedException(); + } else if (!isPublic && (dataManagementPlanEntity.getUsers().stream().noneMatch(userInfo -> userInfo.getUser().getId() == principal.getId()))) { if (!dataManagementPlanEntity.isPublic()) { throw new UnauthorisedException(); } + } else if (isPublic && !dataManagementPlanEntity.isPublic()) { + throw new ForbiddenException("Selected DMP is not public"); } - eu.eudat.models.data.dmp.DataManagementPlan dataManagementPlan = new eu.eudat.models.data.dmp.DataManagementPlan(); dataManagementPlan.fromDataModel(dataManagementPlanEntity); + if (isPublic) { + dataManagementPlan.setDatasets(dataManagementPlan.getDatasets().stream().filter(dataset -> dataset.getStatus() == Dataset.Status.FINALISED.getValue()).collect(Collectors.toList())); + } Map dmpProperties = dataManagementPlanEntity.getDmpProperties() != null ? new org.json.JSONObject(dataManagementPlanEntity.getDmpProperties()).toMap() : null; if (dmpProperties != null && dataManagementPlan.getDynamicFields() != null) @@ -436,72 +225,29 @@ public class DataManagementPlanManager { return dataManagementPlan; } - public DataManagementPlanOverviewModel getOverviewSingle(String id, Principal principal) throws Exception { + public DataManagementPlanOverviewModel getOverviewSingle(String id, Principal principal, boolean isPublic) throws Exception { DMP dataManagementPlanEntity = databaseRepository.getDmpDao().find(UUID.fromString(id)); if (dataManagementPlanEntity.getStatus() == DMP.DMPStatus.DELETED.getValue()) { throw new Exception("DMP is deleted."); } - if (dataManagementPlanEntity.getUsers() - .stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()) - .collect(Collectors.toList()).size() == 0) + if (!isPublic && principal == null) { throw new UnauthorisedException(); + } else + if (!isPublic && dataManagementPlanEntity.getUsers() + .stream().noneMatch(userInfo -> userInfo.getUser().getId() == principal.getId())) { + throw new UnauthorisedException(); + } else if (isPublic && !dataManagementPlanEntity.isPublic()) { + throw new ForbiddenException("Selected DMP is not public"); + } DataManagementPlanOverviewModel datamanagementPlan = new DataManagementPlanOverviewModel(); datamanagementPlan.fromDataModelDatasets(dataManagementPlanEntity); + if (isPublic) { + datamanagementPlan.setDatasets(datamanagementPlan.getDatasets().stream().filter(dataset -> dataset.getStatus() == Dataset.Status.FINALISED.getValue()).collect(Collectors.toList())); + } return datamanagementPlan; } - public eu.eudat.models.data.dmp.DataManagementPlan getSinglePublic(String id, DynamicGrantConfiguration dynamicGrantConfiguration) throws Exception { - DMP dataManagementPlanEntity = databaseRepository.getDmpDao().find(UUID.fromString(id)); - - if (dataManagementPlanEntity != null && dataManagementPlanEntity.getStatus() == 1) { - eu.eudat.models.data.dmp.DataManagementPlan datamanagementPlan = new eu.eudat.models.data.dmp.DataManagementPlan(); - datamanagementPlan.fromDataModel(dataManagementPlanEntity); - datamanagementPlan.setDatasets(datamanagementPlan.getDatasets().stream().filter(dataset -> dataset.getStatus() == Dataset.Status.FINALISED.getValue()).collect(Collectors.toList())); - Map dmpProperties = dataManagementPlanEntity.getDmpProperties() != null ? new org.json.JSONObject(dataManagementPlanEntity.getDmpProperties()).toMap() : null; -// datamanagementPlan.setDynamicFields(dynamicGrantConfiguration.getFields().stream().map(item -> { -// DynamicFieldWithValue fieldWithValue = new DynamicFieldWithValue(); -// fieldWithValue.setId(item.getId()); -// fieldWithValue.setDependencies(item.getDependencies()); -// fieldWithValue.setName(item.getName()); -// fieldWithValue.setQueryProperty(item.getQueryProperty()); -// fieldWithValue.setRequired(item.getRequired()); -// return fieldWithValue; -// }).collect(Collectors.toList())); - - if (dmpProperties != null && datamanagementPlan.getDynamicFields() != null) - datamanagementPlan.getDynamicFields().forEach(item -> { - Map properties = (Map) dmpProperties.get(item.getId()); - if (properties != null) - item.setValue(new Tuple<>(properties.get("id"), properties.get("label"))); - }); - return datamanagementPlan; - } else { - throw new Exception("Selected DMP is not public"); - } - } - - public DataManagementPlanOverviewModel getOverviewSinglePublic(String id) throws Exception { - DMP dataManagementPlanEntity = databaseRepository.getDmpDao().find(UUID.fromString(id)); - if (dataManagementPlanEntity != null && dataManagementPlanEntity.getStatus() == 1) { - DataManagementPlanOverviewModel datamanagementPlan = new DataManagementPlanOverviewModel(); - datamanagementPlan.fromDataModelDatasets(dataManagementPlanEntity); - datamanagementPlan.setDatasets(datamanagementPlan.getDatasets().stream().filter(dataset -> dataset.getStatus() == Dataset.Status.FINALISED.getValue()).collect(Collectors.toList())); - return datamanagementPlan; - } else { - throw new Exception("Selected DMP is not public"); - } - } - - public List getWithCriteria(DMPDao dmpsRepository, DataManagementPlanCriteriaRequest dataManagementPlanCriteria, Principal principal) throws IllegalAccessException, InstantiationException { - UUID principalID = principal.getId(); - QueryableList items = dmpsRepository.getWithCriteria(dataManagementPlanCriteria.getCriteria()).withHint(HintedModelFactory.getHint(DataManagementPlan.class)); - List roles = new LinkedList<>(); - QueryableList authenticatedItems = dmpsRepository.getAuthenticated(items, principalID, roles); - List datamanagementPlans = authenticatedItems.select(item -> new DataManagementPlan().fromDataModel(item)); - return datamanagementPlans; - } - public List> getDynamicFields(String id, DynamicGrantConfiguration dynamicGrantConfiguration, DynamicFieldsCriteria criteria) throws IllegalAccessException, InstantiationException { List> result = new LinkedList<>(); RestTemplate restTemplate = new RestTemplate(); @@ -511,13 +257,13 @@ public class DataManagementPlanManager { HttpEntity entity = new HttpEntity<>("parameters", headers); Property property = dynamicGrantConfiguration.getConfiguration().getConfigurationProperties().stream() - .filter(item -> item.getId().equals(id)).findFirst().orElse(null); + .filter(item -> item.getId().equals(id)).findFirst().orElse(null); StringBuilder stringBuilder = new StringBuilder(); if (criteria.getLike() != null) stringBuilder.append("?search=" + criteria.getLike()); if (property.getDependencies() != null && !property.getDependencies().isEmpty() && criteria.getDynamicFields() != null && !criteria.getDynamicFields().isEmpty()) { property.getDependencies().stream().forEach(item -> { DynamicFieldsCriteria.DynamicFieldDependencyCriteria dependencyCriteria = criteria.getDynamicFields().stream().filter(dfield -> dfield.getProperty().equals(item.getId())) - .findFirst().orElse(null); + .findFirst().orElse(null); if (dependencyCriteria != null) { if (criteria.getLike() != null || property.getDependencies().indexOf(item) > 0) stringBuilder.append("&"); @@ -545,6 +291,24 @@ public class DataManagementPlanManager { return result; } + public DataTableData getDatasetProfilesUsedByDMP(DatasetProfileTableRequestItem datasetProfileTableRequestItem, Principal principal) { + datasetProfileTableRequestItem.getCriteria().setFilter(DatasetProfileCriteria.DatasetProfileFilter.DMPs.getValue()); + datasetProfileTableRequestItem.getCriteria().setUserId(principal.getId()); + + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); + List listingModels = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); + + DataTableData data = new DataTableData<>(); + data.setData(listingModels); + data.setTotalCount((long) listingModels.size()); + + return data; + } + + /* + * Data Management + * */ + public DMP createOrUpdate(ApiContext apiContext, DataManagementPlanEditorModel dataManagementPlan, Principal principal) throws Exception { boolean setNotification = false; if (dataManagementPlan.getId() != null) { @@ -558,8 +322,8 @@ public class DataManagementPlanManager { } List datasetList = new ArrayList<>(dmp1.getDataset()); for (Dataset dataset : datasetList) { - if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getId())).findAny().orElse(null) == null) - throw new Exception("Dataset Template for Dataset Description is missing from the DMP."); + if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getId())).findAny().orElse(null) == null) + throw new Exception("Dataset Template for Dataset Description is missing from the DMP."); } if (dataManagementPlan.getStatus() == (int) DMP.DMPStatus.FINALISED.getValue() && dmp1.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) throw new Exception("DMP is finalized, therefore cannot be edited."); @@ -589,7 +353,7 @@ public class DataManagementPlanManager { newDmp.setCreated(dmp.getCreated() == null ? new Date() : dmp.getCreated()); if (newDmp.getUsers()!= null && newDmp.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()) - .collect(Collectors.toList()).size() == 0) { + .collect(Collectors.toList()).size() == 0) { List userDMPList = new ArrayList<>(newDmp.getUsers()); for (UserInfoListingModel userInfoListingModel : dataManagementPlan.getUsers()) { for (UserDMP userDMP : userDMPList) { @@ -612,8 +376,8 @@ public class DataManagementPlanManager { if (dataManagementPlan.getStatus() == DMP.DMPStatus.FINALISED.getValue()) { if (dataManagementPlan.getDatasetsToBeFinalized() != null && !dataManagementPlan.getDatasetsToBeFinalized().isEmpty()) { apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() - .asQueryable().where((builder, root) -> root.get("id").in(dataManagementPlan.getDatasetsToBeFinalized())) - .update(root -> root.get("status"), Dataset.Status.FINALISED.getValue()); + .asQueryable().where((builder, root) -> root.get("id").in(dataManagementPlan.getDatasetsToBeFinalized())) + .update(root -> root.get("status"), Dataset.Status.FINALISED.getValue()); List datasetsToBeCanceled = new LinkedList<>(); for (DatasetListingModel dataset : dataManagementPlan.getDatasets()) { @@ -623,8 +387,8 @@ public class DataManagementPlanManager { } if (!datasetsToBeCanceled.isEmpty()) apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() - .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeCanceled)) - .update(root -> root.get("status"), Dataset.Status.CANCELED.getValue()); + .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeCanceled)) + .update(root -> root.get("status"), Dataset.Status.CANCELED.getValue()); } else { List datasetsToBeCanceled = new LinkedList<>(); for (DatasetListingModel dataset : dataManagementPlan.getDatasets()) { @@ -634,8 +398,8 @@ public class DataManagementPlanManager { } if (!datasetsToBeCanceled.isEmpty()) apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() - .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeCanceled)) - .update(root -> root.get("status"), Dataset.Status.CANCELED.getValue()); + .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeCanceled)) + .update(root -> root.get("status"), Dataset.Status.CANCELED.getValue()); } } @@ -655,56 +419,6 @@ public class DataManagementPlanManager { return newDmp; } - private void sendNotification(DMP dmp, UserInfo user, NotificationType notificationType) { - List userDMPS = databaseRepository.getUserDmpDao().asQueryable().where(((builder, root) -> builder.equal(root.get("dmp").get("id"), dmp.getId()))).toList(); - for (UserDMP userDMP : userDMPS) { - if (!userDMP.getUser().getId().equals(user.getId())) { - Notification notification = new Notification(); - notification.setUserId(user); - notification.setType(notificationType); - notification.setNotifyState(NotifyState.PENDING); - notification.setIsActive(ActiveStatus.ACTIVE); - notification.setData("{" + - "\"userId\": \"" + userDMP.getUser().getId() + "\"" + - ", \"id\": \"" + userDMP.getDmp().getId() + "\"" + - ", \"name\": \"" + userDMP.getDmp().getLabel() + "\"" + - ", \"path\": \"" + notificationPaths.get(notificationType) +"\"" + - "}"); - notification.setCreatedAt(new Date()); - notification.setUpdatedAt(notification.getCreatedAt()); - notification.setContactTypeHint(ContactType.EMAIL); - notification.setContactHint(userDMP.getUser().getEmail()); - databaseRepository.getNotificationDao().createOrUpdate(notification); - } - } - - } - - private void assignUser(DMP dmp, UserInfo userInfo) { - UserDMP userDMP = new UserDMP(); - userDMP.setDmp(dmp); - userDMP.setUser(userInfo); - userDMP.setRole(UserDMP.UserDMPRoles.OWNER.getValue()); - databaseRepository.getUserDmpDao().createOrUpdate(userDMP); - } - - private void updateGroupIndex(UUID groupId) { - DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); - criteria.setGroupIds(Collections.singletonList(groupId)); - criteria.setAllVersions(true); - List dmps = databaseRepository.getDmpDao().getWithCriteria(criteria).toList(); - for (DMP dmp: dmps) { - try { - if (dmp.getUsers() != null) { - logger.info(dmp.getUsers().toString()); - } - this.updateIndex(dmp); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - } - } - public void newVersion(UUID uuid, DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception { DMP oldDmp = databaseRepository.getDmpDao().find(uuid); if (!isUserOwnerOfDmp(oldDmp, principal)) { @@ -851,11 +565,21 @@ public class DataManagementPlanManager { private void createOrganisationsIfTheyDontExist(DMP newDmp, OrganisationDao organisationRepository) { if (newDmp.getOrganisations() != null && !newDmp.getOrganisations().isEmpty()) { for (eu.eudat.data.entities.Organisation organisation : newDmp.getOrganisations()) { - OrganisationCriteria criteria = new OrganisationCriteria(); - criteria.setLike(organisation.getReference()); - List entries = organisationRepository.getWithCriteria(criteria).toList(); - if (entries != null && !entries.isEmpty()) organisation.setId(entries.get(0).getId()); - else organisationRepository.createOrUpdate(organisation); + boolean createNew = false; + if (organisation.getReference() != null) { + OrganisationCriteria criteria = new OrganisationCriteria(); + criteria.setLike(organisation.getReference()); + List entries = organisationRepository.getWithCriteria(criteria).toList(); + if (entries != null && !entries.isEmpty()) organisation.setId(entries.get(0).getId()); + else createNew = true; + } else { + createNew = true; + } + + if (createNew) { + organisation.setReference("Internal:" + UUID.randomUUID().toString()); + organisationRepository.createOrUpdate(organisation); + } } } } @@ -922,51 +646,6 @@ public class DataManagementPlanManager { } } - private void checkIfUserCanEditGrant(DMP dmp, UserInfo user) throws Exception{ - if (dmp.getGrant().getId() != null) { - Grant grant = apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().find(dmp.getGrant().getId()); - if (grant.getFunder() != null && dmp.getGrant().getFunder() != null - && !grant.getFunder().getId().equals(dmp.getGrant().getFunder().getId())) { - if (grant.getCreationUser() == null) { - throw new Exception("Grant has no user, therefore, cannot be edited."); - } - if (!grant.getCreationUser().getId().equals(user.getId())) { - throw new Exception("User is not the owner of the Grant, therefore, cannot edit it."); - } - } - } - } - - private void checkDmpValidationRules(DMP dmp) throws Exception { - if (dmp.getLabel() == null || dmp.getLabel().trim().isEmpty()) { - throw new Exception("DMP has no label."); - } - if (dmp.getAssociatedDmps().size() == 0) { - throw new Exception("DMP does not contain Dataset Templates."); - } - if (dmp.getGrant() == null) { - throw new Exception("DMP has no Grant assigned."); - } - } - - private void assignGrandUserIfInternal(DMP dmp, UserInfo user) { - if (dmp.getGrant().getCreationUser() == null && (dmp.getGrant().getReference() != null && dmp.getGrant().getReference().startsWith("dmp:"))) { - dmp.getGrant().setCreationUser(user); - } - } - - private void assignFunderUserIfInternal(DMP dmp, UserInfo user) { - if (dmp.getGrant().getFunder().getCreationUser() == null && ( dmp.getGrant().getFunder().getReference() != null && dmp.getGrant().getFunder().getReference().startsWith("dmp:"))) { - dmp.getGrant().getFunder().setCreationUser(user); - } - } - - private void assignProjectUserIfInternal(DMP dmp, UserInfo user) { - if (dmp.getProject().getCreationUser() == null && (dmp.getProject().getReference() != null && dmp.getProject().getReference().startsWith("dmp:"))) { - dmp.getProject().setCreationUser(user); - } - } - private void copyDatasets(DMP newDmp, DatasetDao datasetDao) { List> futures = new LinkedList<>(); for (Dataset dataset : newDmp.getDataset()) { @@ -986,58 +665,58 @@ public class DataManagementPlanManager { logger.error(e.getMessage(), e); } datasetDao.asQueryable().withHint(HintedModelFactory.getHint(DatasetListingModel.class)).where((builder, root) -> builder.equal(root.get("id"), dataset.getId())).getSingleAsync() - .thenApplyAsync(entityDataset -> { - Dataset newDataset = new Dataset(); - newDataset.update(entityDataset); - newDataset.setDmp(newDmp); - newDataset.setStatus(Dataset.Status.SAVED.getValue()); - if (newDataset.getDatasetDataRepositories() != null) { - newDataset.setDatasetDataRepositories(newDataset.getDatasetDataRepositories().stream().map(item -> { - DataRepository dataRepository = new DataRepository(); - dataRepository.setId(item.getDataRepository().getId()); + .thenApplyAsync(entityDataset -> { + Dataset newDataset = new Dataset(); + newDataset.update(entityDataset); + newDataset.setDmp(newDmp); + newDataset.setStatus(Dataset.Status.SAVED.getValue()); + if (newDataset.getDatasetDataRepositories() != null) { + newDataset.setDatasetDataRepositories(newDataset.getDatasetDataRepositories().stream().map(item -> { + DataRepository dataRepository = new DataRepository(); + dataRepository.setId(item.getDataRepository().getId()); - DatasetDataRepository datasetDataRepository = new DatasetDataRepository(); - datasetDataRepository.setDataRepository(dataRepository); - datasetDataRepository.setDataset(newDataset); - datasetDataRepository.setData(item.getData()); - return datasetDataRepository; - }).collect(Collectors.toSet())); - } + DatasetDataRepository datasetDataRepository = new DatasetDataRepository(); + datasetDataRepository.setDataRepository(dataRepository); + datasetDataRepository.setDataset(newDataset); + datasetDataRepository.setData(item.getData()); + return datasetDataRepository; + }).collect(Collectors.toSet())); + } - if (newDataset.getDatasetExternalDatasets() != null) { - newDataset.setDatasetExternalDatasets(newDataset.getDatasetExternalDatasets().stream().map(item -> { - ExternalDataset externalDataset = new ExternalDataset(); - externalDataset.setId(item.getExternalDataset().getId()); - DatasetExternalDataset datasetExternalDataset = new DatasetExternalDataset(); - datasetExternalDataset.setExternalDataset(externalDataset); - datasetExternalDataset.setDataset(newDataset); - datasetExternalDataset.setData(item.getData()); - return datasetExternalDataset; - }).collect(Collectors.toSet())); - } + if (newDataset.getDatasetExternalDatasets() != null) { + newDataset.setDatasetExternalDatasets(newDataset.getDatasetExternalDatasets().stream().map(item -> { + ExternalDataset externalDataset = new ExternalDataset(); + externalDataset.setId(item.getExternalDataset().getId()); + DatasetExternalDataset datasetExternalDataset = new DatasetExternalDataset(); + datasetExternalDataset.setExternalDataset(externalDataset); + datasetExternalDataset.setDataset(newDataset); + datasetExternalDataset.setData(item.getData()); + return datasetExternalDataset; + }).collect(Collectors.toSet())); + } - if (newDataset.getRegistries() != null) { - newDataset.setRegistries(newDataset.getRegistries().stream().map(item -> { - Registry registry = new Registry(); - registry.setId(item.getId()); - return registry; - }).collect(Collectors.toSet())); - } + if (newDataset.getRegistries() != null) { + newDataset.setRegistries(newDataset.getRegistries().stream().map(item -> { + Registry registry = new Registry(); + registry.setId(item.getId()); + return registry; + }).collect(Collectors.toSet())); + } - if (newDataset.getServices() != null) { - newDataset.setServices(newDataset.getServices().stream().map(item -> { - Service service = new Service(); - service.setId(item.getId()); - DatasetService datasetService = new DatasetService(); - datasetService.setService(service); - datasetService.setDataset(newDataset); - datasetService.setData(item.getData()); - return datasetService; - }).collect(Collectors.toSet())); - } - newDataset.setCreated(new Date()); - return newDataset; - }).thenApplyAsync(item -> { + if (newDataset.getServices() != null) { + newDataset.setServices(newDataset.getServices().stream().map(item -> { + Service service = new Service(); + service.setId(item.getId()); + DatasetService datasetService = new DatasetService(); + datasetService.setService(service); + datasetService.setDataset(newDataset); + datasetService.setData(item.getData()); + return datasetService; + }).collect(Collectors.toSet())); + } + newDataset.setCreated(new Date()); + return newDataset; + }).thenApplyAsync(item -> { futures.add(datasetDao.createOrUpdateAsync(item).whenComplete(((dataset1, throwable) -> { eu.eudat.elastic.entities.Dataset datasetElastic = new eu.eudat.elastic.entities.Dataset(); datasetElastic.setId(dataset1.getId().toString()); @@ -1052,7 +731,7 @@ public class DataManagementPlanManager { datasetElastic.setCollaborators(dataset1.getDmp().getUsers().stream().map(user -> { Collaborator collaborator = new Collaborator(); collaborator.setId(user.getId().toString()); - // collaborator.setName(user.getUser().getName()); + // collaborator.setName(user.getUser().getName()); return collaborator; }).collect(Collectors.toList())); } @@ -1086,12 +765,270 @@ public class DataManagementPlanManager { } } + public void makePublic(UUID id, Principal principal) throws Exception { + DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(id); + // Check if dmp is finalized and if user is owner. + if (!isUserOwnerOfDmp(dmp, principal)) + throw new Exception("User does not have the privilege to do this action."); + if (!dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) + throw new Exception("DMP is not finalized"); + dmp.setPublic(true); + apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); + this.updateIndex(dmp); + DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); + criteria.setGroupIds(Collections.singletonList(dmp.getGroupId())); + criteria.setAllVersions(true); + apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getWithCriteria(criteria).toList().stream().forEach(dmp1 -> { + dmp1.getDataset().forEach(dataset -> { + try { + List tags = new ArrayList<>(); + eu.eudat.elastic.entities.Dataset elastic = apiContext.getOperationsContext().getElasticRepository().getDatasetRepository().findDocument(dataset.getId().toString()); + if (elastic != null) { + tags = elastic.getTags(); + } + this.datasetManager.updateTags(dataset, tags); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + }); + }); + UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); + sendNotification(dmp, user, NotificationType.DMP_PUBLISH); + this.createZenodoDoi(dmp.getId(), principal, null); + } + + public void makeFinalize(UUID id, Principal principal, DatasetsToBeFinalized datasetsToBeFinalized) throws Exception { + DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(id); + if (!isUserOwnerOfDmp(dmp, principal)) + throw new Exception("User does not have the privilege to do this action."); + if (dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) + throw new Exception("DMP is already finalized"); + dmp.setStatus(DMP.DMPStatus.FINALISED.getValue()); + apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); + this.updateIndex(dmp); + List indexDatasets = new ArrayList<>(); + if (datasetsToBeFinalized != null && datasetsToBeFinalized.getUuids() != null && !datasetsToBeFinalized.getUuids().isEmpty()) { + apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() + .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeFinalized.getUuids())) + .update(root -> root.get("status"), Dataset.Status.FINALISED.getValue()); + List finalizedDatasets = dmp.getDataset().stream().filter(dataset -> datasetsToBeFinalized.getUuids().contains(dataset.getId())).collect(Collectors.toList()); + finalizedDatasets.forEach(dataset -> dataset.setStatus(Dataset.Status.FINALISED.getValue())); + indexDatasets.addAll(finalizedDatasets); + List datasetsToBeCanceled = new LinkedList<>(); + for (Dataset dataset : dmp.getDataset()) { + if (!dataset.getStatus().equals(Dataset.Status.FINALISED.getValue()) && !datasetsToBeFinalized.getUuids().contains(dataset.getId())) { + datasetsToBeCanceled.add(dataset.getId()); + } + } + if (!datasetsToBeCanceled.isEmpty()) { + apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() + .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeCanceled)) + .update(root -> root.get("status"), Dataset.Status.CANCELED.getValue()); + List cancelledDatasets = dmp.getDataset().stream().filter(dataset -> datasetsToBeCanceled.contains(dataset.getId())).collect(Collectors.toList()); + cancelledDatasets.forEach(dataset -> dataset.setStatus(Dataset.Status.CANCELED.getValue())); + indexDatasets.addAll(cancelledDatasets); + } + } else { + List datasetsToBeCanceled = new LinkedList<>(); + for (Dataset dataset : dmp.getDataset()) { + if (!dataset.getStatus().equals(Dataset.Status.FINALISED.getValue())) { + datasetsToBeCanceled.add(dataset.getId()); + } + } + if (!datasetsToBeCanceled.isEmpty()) { + apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() + .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeCanceled)) + .update(root -> root.get("status"), Dataset.Status.CANCELED.getValue()); + List cancelledDatasets = dmp.getDataset().stream().filter(dataset -> datasetsToBeCanceled.contains(dataset.getId())).collect(Collectors.toList()); + cancelledDatasets.forEach(dataset -> dataset.setStatus(Dataset.Status.CANCELED.getValue())); + indexDatasets.addAll(cancelledDatasets); + } + + UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); + sendNotification(dmp, user, NotificationType.DMP_FINALISED); + } + this.updateDatasetsIndex(indexDatasets); + } + + /* + * Export Data + * */ + + public FileEnvelope getWordDocument(String id, Principal principal, ConfigLoader configLoader) throws IOException { + return this.getWordDocument(id, principal, configLoader, false); + } + + public FileEnvelope getWordDocument(String id, Principal principal, ConfigLoader configLoader, Boolean versioned) throws IOException { + WordBuilder wordBuilder = new WordBuilder(); + VisibilityRuleService visibilityRuleService = this.utilitiesService.getVisibilityRuleService(); + DatasetWizardModel dataset = new DatasetWizardModel(); + XWPFDocument document = configLoader.getDocument(); + + eu.eudat.data.entities.DMP dmpEntity = databaseRepository.getDmpDao().find(UUID.fromString(id)); + if (!dmpEntity.isPublic() && dmpEntity.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()).collect(Collectors.toList()).size() == 0) + throw new UnauthorisedException(); + + // DMP info on top of the document. + wordBuilder.addParagraphContent("Data Management Plan Information", document, ParagraphStyle.HEADER1, BigInteger.ZERO); + // DMP title custom style. + wordBuilder.addParagraphContent(dmpEntity.getLabel(), document, ParagraphStyle.HEADER2, BigInteger.ZERO); + wordBuilder.addParagraphContent(dmpEntity.getDescription(), document, ParagraphStyle.TEXT, BigInteger.ZERO); + + wordBuilder.addParagraphContent("Funder", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (dmpEntity.getGrant().getFunder() != null) + wordBuilder.addParagraphContent(dmpEntity.getGrant().getFunder().getLabel(), document, ParagraphStyle.TEXT, BigInteger.ZERO); + + wordBuilder.addParagraphContent("Grant", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + wordBuilder.addParagraphContent(dmpEntity.getGrant().getLabel(), document, ParagraphStyle.TEXT, BigInteger.ZERO); + + wordBuilder.addParagraphContent("Organisations", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (dmpEntity.getOrganisations().size() > 0) { + wordBuilder.addParagraphContent(dmpEntity.getOrganisations().stream().map(Organisation::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + + wordBuilder.addParagraphContent("Researchers", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (dmpEntity.getResearchers().size() > 0) { + wordBuilder.addParagraphContent(dmpEntity.getResearchers().stream().map(Researcher::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + + /*wordBuilder.addParagraphContent("DMP Profile", document, ParagraphStyle.HEADER2, BigInteger.ZERO); + if (dmpEntity.getProfile() != null){ + wordBuilder.addParagraphContent(dmpEntity.getProfile().getLabel(), document, ParagraphStyle.TEXT, BigInteger.ZERO); + }*/ + + // Page break at the end of the DMP title. + XWPFParagraph parBreakDMP = document.createParagraph(); + parBreakDMP.setPageBreak(true); + + wordBuilder.addParagraphContent("Datasets", document, ParagraphStyle.HEADER1, BigInteger.ZERO); + // Space below Datasets. + XWPFParagraph parBreakDatasets = document.createParagraph(); + dmpEntity.getDataset().stream() + .filter(item -> item.getStatus() != Dataset.Status.CANCELED.getValue()) + .filter(item -> item.getStatus() != Dataset.Status.DELETED.getValue()) + .forEach(datasetEntity -> { + Map properties = new HashMap<>(); + if (datasetEntity.getProperties() != null) { + JSONObject jObject = new JSONObject(datasetEntity.getProperties()); + properties = jObject.toMap(); + } + + // Custom style for the Dataset title. + //wordBuilder.addParagraphContent("Title: " + datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO); + XWPFParagraph datasetLabelParagraph = document.createParagraph(); + datasetLabelParagraph.setStyle("Heading2"); + XWPFRun runDatasetTitle1 = datasetLabelParagraph.createRun(); + runDatasetTitle1.setText("Title: "); + runDatasetTitle1.setBold(true); + runDatasetTitle1.setFontSize(12); + XWPFRun runDatasetTitle = datasetLabelParagraph.createRun(); + runDatasetTitle.setText(datasetEntity.getLabel()); + runDatasetTitle.setColor("2E75B6"); + runDatasetTitle.setBold(true); + runDatasetTitle.setFontSize(12); + + XWPFParagraph datasetTemplateParagraph = document.createParagraph(); + datasetTemplateParagraph.setStyle("Heading3"); + XWPFRun runDatasetTemplate1 = datasetTemplateParagraph.createRun(); + runDatasetTemplate1.setText("Template: "); + runDatasetTemplate1.setBold(true); + runDatasetTemplate1.setFontSize(12); + XWPFRun runDatasetTemplate = datasetTemplateParagraph.createRun(); + runDatasetTemplate.setText(datasetEntity.getProfile().getLabel()); + runDatasetTemplate.setColor("2E75B6"); + runDatasetTemplate.setBold(true); + runDatasetTemplate.setFontSize(12); + + XWPFParagraph externalReferencesParagraph = document.createParagraph(); + externalReferencesParagraph.setStyle("Heading3"); + XWPFRun externalReferencesRun = externalReferencesParagraph.createRun(); + externalReferencesRun.setText("External References"); + externalReferencesRun.setColor("2E75B6"); + externalReferencesRun.setBold(true); + externalReferencesRun.setFontSize(12); + + wordBuilder.addParagraphContent("Data Repositories", document, ParagraphStyle.HEADER4, BigInteger.ZERO); + if (datasetEntity.getDatasetDataRepositories().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getDatasetDataRepositories().stream().map(DatasetDataRepository::getDataRepository).map(DataRepository::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + wordBuilder.addParagraphContent("External Datasets", document, ParagraphStyle.HEADER4, BigInteger.ZERO); + if (datasetEntity.getDatasetExternalDatasets().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getDatasetExternalDatasets().stream().map(DatasetExternalDataset::getExternalDataset).map(ExternalDataset::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + wordBuilder.addParagraphContent("Registries", document, ParagraphStyle.HEADER4, BigInteger.ZERO); + if (datasetEntity.getRegistries().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getRegistries().stream().map(Registry::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + wordBuilder.addParagraphContent("Services", document, ParagraphStyle.HEADER4, BigInteger.ZERO); + if (datasetEntity.getServices().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.TEXT, BigInteger.ZERO); + } + /*wordBuilder.addParagraphContent("Tags", document, ParagraphStyle.HEADER3, BigInteger.ZERO); + if (datasetEntity.().size() > 0) { + wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) + , document, ParagraphStyle.HEADER4, BigInteger.ZERO); + }*/ + + + wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.TEXT, BigInteger.ZERO); + + // Dataset Description custom style. + XWPFParagraph datasetDescriptionParagraph = document.createParagraph(); + datasetDescriptionParagraph.setStyle("Heading3"); + XWPFRun datasetDescriptionRun = datasetDescriptionParagraph.createRun(); + datasetDescriptionRun.setText("Dataset Description"); + datasetDescriptionRun.setColor("2E75B6"); + datasetDescriptionRun.setBold(true); + datasetDescriptionRun.setFontSize(12); + + PagedDatasetProfile pagedDatasetProfile = datasetManager.getPagedProfile(dataset, datasetEntity); + visibilityRuleService.setProperties(properties); + visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); + try { + wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + // Page break at the end of the Dataset. + XWPFParagraph parBreakDataset = document.createParagraph(); + }); + + // Removes the top empty headings. + for (int i = 0; i < 6; i++) { + document.removeBodyElement(0); + } + + String fileName = ""; + if (versioned) { + fileName = dmpEntity.getLabel() + " v" + dmpEntity.getVersion(); + } else { + fileName = dmpEntity.getLabel(); + } + fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", ""); + FileEnvelope exportEnvelope = new FileEnvelope(); + exportEnvelope.setFilename(fileName + ".docx"); + String uuid = UUID.randomUUID().toString(); + File exportFile = new File(this.environment.getProperty("temp.temp") + uuid + ".docx"); + FileOutputStream out = new FileOutputStream(exportFile); + document.write(out); + out.close(); + exportEnvelope.setFile(exportFile); + + return exportEnvelope; + } + private FileEnvelope getXmlDocument(String id, Principal principal) throws InstantiationException, IllegalAccessException, IOException { ExportXmlBuilder xmlBuilder = new ExportXmlBuilder(); VisibilityRuleService visibilityRuleService = utilitiesService.getVisibilityRuleService(); eu.eudat.data.entities.DMP dmp = databaseRepository.getDmpDao().find(UUID.fromString(id)); - if (!dmp.isPublic() && dmp.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()).collect(Collectors.toList()).size() == 0) - throw new UnauthorisedException(); + if (!dmp.isPublic() && dmp.getUsers().stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()).collect(Collectors.toList()).size() == 0) + throw new UnauthorisedException(); List datasets = dmp.getDataset().stream().collect(Collectors.toList()); /*String fileName = dmp.getLabel(); fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", "");*/ @@ -1224,13 +1161,13 @@ public class DataManagementPlanManager { public ResponseEntity getRDAJsonDocument(String id, DatasetManager datasetManager, Principal principal) throws IOException { eu.eudat.data.entities.DMP dmp = databaseRepository.getDmpDao().find(UUID.fromString(id)); - if (!dmp.isPublic() && dmp.getUsers().stream().noneMatch(userInfo -> userInfo.getUser().getId() == principal.getId())) - throw new UnauthorisedException(); + if (!dmp.isPublic() && dmp.getUsers().stream().noneMatch(userInfo -> userInfo.getUser().getId() == principal.getId())) + throw new UnauthorisedException(); // RDAExportModel rdaExportModel = new RDAExportModel().fromDataModel(dmp, datasetManager, principal); String result = rdaManager.convertToRDA(dmp); - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + /*ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);*/ String fileName = dmp.getLabel(); fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", ""); String uuid = UUID.randomUUID().toString(); @@ -1287,6 +1224,10 @@ public class DataManagementPlanManager { HttpStatus.OK); } + /* + * Data Import + * */ + public List createDmpFromXml(ApiContext apiContext, MultipartFile[] files, Principal principal) throws IOException, JAXBException, Exception { List dataManagementPlans = new ArrayList<>(); // Jaxb approach. @@ -1383,22 +1324,22 @@ public class DataManagementPlanManager { dm.setDefinition(dmpProfile); //createOrUpdate(apiContext, dm, principal); - DMP dmp = this.createOrUpdate(apiContext, dm, principal); - if (dmp.getOrganisations() == null) { - dmp.setOrganisations(new HashSet<>()); - } - if (dmp.getResearchers() == null) { - dmp.setResearchers(new HashSet<>()); - } - if (dmp.getDataset() == null) { - dmp.setDataset(new HashSet<>()); - } - if (dmp.getUsers() == null) { - dmp.setUsers(new HashSet<>()); - } - if (dmp.getAssociatedDmps() == null) { - dmp.setAssociatedDmps(new HashSet<>()); - } + DMP dmp = this.createOrUpdate(apiContext, dm, principal); + if (dmp.getOrganisations() == null) { + dmp.setOrganisations(new HashSet<>()); + } + if (dmp.getResearchers() == null) { + dmp.setResearchers(new HashSet<>()); + } + if (dmp.getDataset() == null) { + dmp.setDataset(new HashSet<>()); + } + if (dmp.getUsers() == null) { + dmp.setUsers(new HashSet<>()); + } + if (dmp.getAssociatedDmps() == null) { + dmp.setAssociatedDmps(new HashSet<>()); + } List datasets = new LinkedList<>(); for (DatasetImportModels das: dataManagementPlans.get(0).getDatasetImportModels()) { @@ -1416,7 +1357,7 @@ public class DataManagementPlanManager { datasetWizard.setDatasetProfileDefinition(this.datasetManager.getPagedProfile(datasetWizard, dataset)); datasetWizard.fromDataModel(dataset); this.datasetManager.createOrUpdate(datasetWizard, principal); - // datasets.add(new DatasetListingModel().fromDataModel(dataset)); + // datasets.add(new DatasetListingModel().fromDataModel(dataset)); } logger.info(dm.toString()); @@ -1485,49 +1426,55 @@ public class DataManagementPlanManager { return result; } - public DataTableData getDatasetProfilesUsedByDMP(DatasetProfileTableRequestItem datasetProfileTableRequestItem, Principal principal) { - datasetProfileTableRequestItem.getCriteria().setFilter(DatasetProfileCriteria.DatasetProfileFilter.DMPs.getValue()); - datasetProfileTableRequestItem.getCriteria().setUserId(principal.getId()); + /* + * Data assignments + * */ - QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); - List listingModels = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); - - DataTableData data = new DataTableData<>(); - data.setData(listingModels); - data.setTotalCount((long) listingModels.size()); - - return data; + private void assignUser(DMP dmp, UserInfo userInfo) { + UserDMP userDMP = new UserDMP(); + userDMP.setDmp(dmp); + userDMP.setUser(userInfo); + userDMP.setRole(UserDMP.UserDMPRoles.OWNER.getValue()); + databaseRepository.getUserDmpDao().createOrUpdate(userDMP); } - public void makePublic(UUID id, Principal principal) throws Exception { - DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(id); - // Check if dmp is finalized and if user is owner. - if (!isUserOwnerOfDmp(dmp, principal)) - throw new Exception("User does not have the privilege to do this action."); - if (!dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) - throw new Exception("DMP is not finalized"); - dmp.setPublic(true); - apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); - this.updateIndex(dmp); + private void assignGrandUserIfInternal(DMP dmp, UserInfo user) { + if (dmp.getGrant().getCreationUser() == null && (dmp.getGrant().getReference() != null && dmp.getGrant().getReference().startsWith("dmp:"))) { + dmp.getGrant().setCreationUser(user); + } + } + + private void assignFunderUserIfInternal(DMP dmp, UserInfo user) { + if (dmp.getGrant().getFunder().getCreationUser() == null && ( dmp.getGrant().getFunder().getReference() != null && dmp.getGrant().getFunder().getReference().startsWith("dmp:"))) { + dmp.getGrant().getFunder().setCreationUser(user); + } + } + + private void assignProjectUserIfInternal(DMP dmp, UserInfo user) { + if (dmp.getProject().getCreationUser() == null && (dmp.getProject().getReference() != null && dmp.getProject().getReference().startsWith("dmp:"))) { + dmp.getProject().setCreationUser(user); + } + } + + /* + * Data Index + * */ + + private void updateGroupIndex(UUID groupId) { DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); - criteria.setGroupIds(Collections.singletonList(dmp.getGroupId())); + criteria.setGroupIds(Collections.singletonList(groupId)); criteria.setAllVersions(true); - apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().getWithCriteria(criteria).toList().stream().forEach(dmp1 -> { - dmp1.getDataset().forEach(dataset -> { - try { - List tags = new ArrayList<>(); - eu.eudat.elastic.entities.Dataset elastic = apiContext.getOperationsContext().getElasticRepository().getDatasetRepository().findDocument(dataset.getId().toString()); - if (elastic != null) { - tags = elastic.getTags(); - } - this.datasetManager.updateTags(dataset, tags); - } catch (Exception e) { - logger.error(e.getMessage(), e); + List dmps = databaseRepository.getDmpDao().getWithCriteria(criteria).toList(); + for (DMP dmp: dmps) { + try { + if (dmp.getUsers() != null) { + logger.info(dmp.getUsers().toString()); } - }); - }); - UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); - sendNotification(dmp, user, NotificationType.DMP_PUBLISH); + this.updateIndex(dmp); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + } } private void updateDatasetsIndex(List datasets) { @@ -1547,63 +1494,72 @@ public class DataManagementPlanManager { }); } - public void makeFinalize(UUID id, Principal principal, DatasetsToBeFinalized datasetsToBeFinalized) throws Exception { - DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(id); - if (!isUserOwnerOfDmp(dmp, principal)) - throw new Exception("User does not have the privilege to do this action."); - if (dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) - throw new Exception("DMP is already finalized"); - dmp.setStatus(DMP.DMPStatus.FINALISED.getValue()); - apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); - this.updateIndex(dmp); - List indexDatasets = new ArrayList<>(); - if (datasetsToBeFinalized != null && datasetsToBeFinalized.getUuids() != null && !datasetsToBeFinalized.getUuids().isEmpty()) { - apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() - .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeFinalized.getUuids())) - .update(root -> root.get("status"), Dataset.Status.FINALISED.getValue()); - List finalizedDatasets = dmp.getDataset().stream().filter(dataset -> datasetsToBeFinalized.getUuids().contains(dataset.getId())).collect(Collectors.toList()); - finalizedDatasets.forEach(dataset -> dataset.setStatus(Dataset.Status.FINALISED.getValue())); - indexDatasets.addAll(finalizedDatasets); - List datasetsToBeCanceled = new LinkedList<>(); - for (Dataset dataset : dmp.getDataset()) { - if (!dataset.getStatus().equals(Dataset.Status.FINALISED.getValue()) && !datasetsToBeFinalized.getUuids().contains(dataset.getId())) { - datasetsToBeCanceled.add(dataset.getId()); - } - } - if (!datasetsToBeCanceled.isEmpty()) { - apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() - .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeCanceled)) - .update(root -> root.get("status"), Dataset.Status.CANCELED.getValue()); - List cancelledDatasets = dmp.getDataset().stream().filter(dataset -> datasetsToBeCanceled.contains(dataset.getId())).collect(Collectors.toList()); - cancelledDatasets.forEach(dataset -> dataset.setStatus(Dataset.Status.CANCELED.getValue())); - indexDatasets.addAll(cancelledDatasets); - } - } else { - List datasetsToBeCanceled = new LinkedList<>(); - for (Dataset dataset : dmp.getDataset()) { - if (!dataset.getStatus().equals(Dataset.Status.FINALISED.getValue())) { - datasetsToBeCanceled.add(dataset.getId()); - } - } - if (!datasetsToBeCanceled.isEmpty()) { - apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao() - .asQueryable().where((builder, root) -> root.get("id").in(datasetsToBeCanceled)) - .update(root -> root.get("status"), Dataset.Status.CANCELED.getValue()); - List cancelledDatasets = dmp.getDataset().stream().filter(dataset -> datasetsToBeCanceled.contains(dataset.getId())).collect(Collectors.toList()); - cancelledDatasets.forEach(dataset -> dataset.setStatus(Dataset.Status.CANCELED.getValue())); - indexDatasets.addAll(cancelledDatasets); - } + private void updateIndex(DMP dmp) throws IOException { + DmpMapper mapper = new DmpMapper(apiContext, datasetManager); + Dmp elastic = mapper.toElastic(dmp); + apiContext.getOperationsContext().getElasticRepository().getDmpRepository().createOrUpdate(elastic); + } - UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); - sendNotification(dmp, user, NotificationType.DMP_FINALISED); + public void generateIndex(Principal principal) { + if (principal.getAuthorities().contains(Authorities.ADMIN.getValue())) { + if (apiContext.getOperationsContext().getElasticRepository().getDmpRepository().createIndex()) { + List dmps = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().asQueryable().toList(); + dmps.forEach(dmp -> { + try { + this.updateIndex(dmp); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + }); + } + } + } + + public void clearIndex(Principal principal) throws IOException { + if (principal.getAuthorities().contains(Authorities.ADMIN.getValue())) { + apiContext.getOperationsContext().getElasticRepository().getDmpRepository().clear(); + } + } + + /* + * Data Checkup + * */ + + private void checkIfUserCanEditGrant(DMP dmp, UserInfo user) throws Exception{ + if (dmp.getGrant().getId() != null) { + Grant grant = apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().find(dmp.getGrant().getId()); + if (grant.getFunder() != null && dmp.getGrant().getFunder() != null + && !grant.getFunder().getId().equals(dmp.getGrant().getFunder().getId())) { + if (grant.getCreationUser() == null) { + throw new Exception("Grant has no user, therefore, cannot be edited."); + } + if (!grant.getCreationUser().getId().equals(user.getId())) { + throw new Exception("User is not the owner of the Grant, therefore, cannot edit it."); + } + } + } + } + + private void checkDmpValidationRules(DMP dmp) throws Exception { + if (dmp.getLabel() == null || dmp.getLabel().trim().isEmpty()) { + throw new Exception("DMP has no label."); + } + if (dmp.getAssociatedDmps().size() == 0) { + throw new Exception("DMP does not contain Dataset Templates."); + } + if (dmp.getGrant() == null) { + throw new Exception("DMP has no Grant assigned."); } - this.updateDatasetsIndex(indexDatasets); } private boolean isUserOwnerOfDmp(DMP dmp, Principal principal) { return (dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getId()).equals(principal.getId()); } + /* + * DOI Generation + * */ + private String getPreviousDOI(UUID groupId, UUID selfId) { DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); List groupIds = new ArrayList<>(); @@ -1655,8 +1611,8 @@ public class DataManagementPlanManager { throw new Exception("User is not authorized to invoke this action"); if (!dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) throw new Exception("DMP is not finalized"); - if (dmp.getDoi() != null) - throw new Exception("DMP already has a DOI"); + /*if (dmp.getDoi() != null) + throw new Exception("DMP already has a DOI");*/ String zenodoToken = ""; try { @@ -1671,18 +1627,59 @@ public class DataManagementPlanManager { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.setContentType(MediaType.APPLICATION_JSON); - String createData = "{\n" + - " \"metadata\": {\n" + - " \"title\": \"" + dmp.getLabel() + "\",\n" + - " \"upload_type\": \"publication\",\n" + - " \"publication_type\": \"datamanagementplan\",\n" + - " \"description\": \"" + (dmp.getDescription() != null && !dmp.getDescription().isEmpty() ? dmp.getDescription() : "

") + "\",\n" + - " \"version\": \"" + dmp.getVersion() + "\",\n" + - " \"creators\": [{\n" + - " \t\t\"name\": \"" + dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getName() + "\",\n" + - " \t\t\"affiliation\": \"OpenDMP\"}]\n" + - " }\n" + - "}"; + String createData = null; + StringBuilder dataBuilder = new StringBuilder(); + dataBuilder.append("{\n \"metadata\": {\n"); + dataBuilder.append( " \"title\": \"").append(dmp.getLabel()).append("\",\n"); + dataBuilder.append(" \"upload_type\": \"publication\",\n"); + dataBuilder.append(" \"publication_type\": \"datamanagementplan\",\n"); + dataBuilder.append(" \"description\": \"").append((dmp.getDescription() != null && !dmp.getDescription().isEmpty() ? dmp.getDescription() : "

")).append("\",\n"); + dataBuilder.append(" \"version\": \"").append(dmp.getVersion()).append("\",\n"); + dataBuilder.append(" \"related_identifiers\": [{\n"); + dataBuilder.append(" \t\t\"identifier\": \"").append((this.environment.getProperty("dmp.domain") + "/explore-plans/publicOverview/" + id.toString())).append("\",\n"); + dataBuilder.append(" \t\t\"relation\": \"isIdenticalTo\"}],\n"); + dataBuilder.append(" \"contributors\": ["); + int i = 0; + for(UserDMP userDMP: dmp.getUsers()) { + if (i > 0) { + dataBuilder.append(",\n"); + } + dataBuilder.append("{\n"); + dataBuilder.append(" \t\t\"name\": \"").append(userDMP.getUser().getName()).append("\",\n"); + dataBuilder.append(" \t\t\"type\": \"").append("ProjectMember").append("\",\n"); + dataBuilder.append(" \t\t\"affiliation\": \"OpenDMP\"\n}"); + i++; + } + for(Researcher researcher: dmp.getResearchers()) { + if (i > 0) { + dataBuilder.append(",\n"); + } + dataBuilder.append("{\n"); + dataBuilder.append(" \t\t\"name\": \"").append(researcher.getLabel()).append("\",\n"); + dataBuilder.append(" \t\t\"type\": \"").append("Researcher").append("\",\n"); + String referenceHead = researcher.getReference().split(":")[0]; + String referenceTail = researcher.getReference().replace(referenceHead + ":", ""); + dataBuilder.append(" \t\t\"affiliation\": \"" + referenceHead + "\""); + if (referenceHead.toUpperCase().equals("ORCID")) { + dataBuilder.append(",\n \t\t\"orcid\": \"" + referenceTail + "\""); + } + dataBuilder.append("\n}"); + i++; + } + dataBuilder.append("],\n"); + String grantReferenceHead = dmp.getGrant().getReference().split(":")[0]; + if (grantReferenceHead.equals("openaire")) { + String grantReferenceTail = dmp.getGrant().getReference().split(":")[3]; + DoiFunder doiFunder = this.apiContext.getOperationsContext().getDatabaseRepository().getDoiFunderDao().findFunderByName(dmp.getGrant().getFunder().getLabel()); + String finalId = doiFunder.getDoi() + "::" + grantReferenceTail; + dataBuilder.append(" \"grants\": [{\n"); + dataBuilder.append(" \t\t\"id\": \"").append(finalId).append("\"\n}],\n"); + } + dataBuilder.append(" \"creators\": [{\n"); + dataBuilder.append(" \t\t\"name\": \"").append(dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getName()).append("\",\n"); + dataBuilder.append(" \t\t\"affiliation\": \"OpenDMP\"}]\n"); + dataBuilder.append(" }\n").append("}"); + createData = dataBuilder.toString(); JsonNode createDataJSON = new ObjectMapper().readTree(createData); HttpEntity request = new HttpEntity<>(createDataJSON, headers); Map createResponse = null; @@ -1690,76 +1687,84 @@ public class DataManagementPlanManager { String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId()); String unpublishedUrl = null; String publishUrl = null; + String finalDoi = null; try { - if (previousDOI == null) { - String createUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?access_token=" + zenodoToken; - createResponse = restTemplate.postForEntity(createUrl, request, Map.class).getBody(); - links = (LinkedHashMap) createResponse.get("links"); - } else { - unpublishedUrl = this.getUnpublishedDOI(previousDOI, zenodoToken, dmp.getVersion()); - if (unpublishedUrl == null) { - //It requires more than one step to create a new version - //First, get the deposit related to the concept DOI - String listUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken; - ResponseEntity listResponses = restTemplate.getForEntity(listUrl, Map[].class); - createResponse = listResponses.getBody()[0]; + if (previousDOI == null) { + String createUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?access_token=" + zenodoToken; + createResponse = restTemplate.postForEntity(createUrl, request, Map.class).getBody(); links = (LinkedHashMap) createResponse.get("links"); - //Second, make the new version (not in the links?) - String newVersionUrl = links.get("self") + "/actions/newversion" + "?access_token=" + zenodoToken; - createResponse = restTemplate.postForObject(newVersionUrl, null, Map.class); - links = (LinkedHashMap) createResponse.get("links"); - //Third, get the new deposit - String latestDraftUrl = links.get("latest_draft") + "?access_token=" + zenodoToken; - createResponse = restTemplate.getForObject(latestDraftUrl, Map.class); - links = (LinkedHashMap) createResponse.get("links"); - //At this point it might fail to perform the next requests so enclose them with try catch - try { - //Forth, update the new deposit's metadata - String updateUrl = links.get("self") + "?access_token=" + zenodoToken; - restTemplate.put(updateUrl, request); - //And finally remove pre-existing files from it - String fileListUrl = links.get("self") + "/files" + "?access_token=" + zenodoToken; - ResponseEntity fileListResponse = restTemplate.getForEntity(fileListUrl, Map[].class); - for (Map file : fileListResponse.getBody()) { - String fileDeleteUrl = links.get("self") + "/files/" + file.get("id") + "?access_token=" + zenodoToken; - restTemplate.delete(fileDeleteUrl); + finalDoi = (String) createResponse.get("conceptdoi"); + } else { + unpublishedUrl = this.getUnpublishedDOI(previousDOI, zenodoToken, dmp.getVersion()); + if (unpublishedUrl == null) { + //It requires more than one step to create a new version + //First, get the deposit related to the concept DOI + String listUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken; + ResponseEntity listResponses = restTemplate.getForEntity(listUrl, Map[].class); + createResponse = listResponses.getBody()[0]; + links = (LinkedHashMap) createResponse.get("links"); + //Second, make the new version (not in the links?) + String newVersionUrl = links.get("self") + "/actions/newversion" + "?access_token=" + zenodoToken; + createResponse = restTemplate.postForObject(newVersionUrl, null, Map.class); + links = (LinkedHashMap) createResponse.get("links"); + //Third, get the new deposit + String latestDraftUrl = links.get("latest_draft") + "?access_token=" + zenodoToken; + createResponse = restTemplate.getForObject(latestDraftUrl, Map.class); + links = (LinkedHashMap) createResponse.get("links"); + finalDoi = (String) createResponse.get("conceptdoi"); + //At this point it might fail to perform the next requests so enclose them with try catch + try { + //Forth, update the new deposit's metadata + String updateUrl = links.get("self") + "?access_token=" + zenodoToken; + restTemplate.put(updateUrl, request); + //And finally remove pre-existing files from it + String fileListUrl = links.get("self") + "/files" + "?access_token=" + zenodoToken; + ResponseEntity fileListResponse = restTemplate.getForEntity(fileListUrl, Map[].class); + for (Map file : fileListResponse.getBody()) { + String fileDeleteUrl = links.get("self") + "/files/" + file.get("id") + "?access_token=" + zenodoToken; + restTemplate.delete(fileDeleteUrl); + } + } catch (Exception e) { + //In case the last two steps fail delete the latest Deposit it in order to create a new one (only one at a time is allowed) + restTemplate.delete(latestDraftUrl); + throw e; } - } catch (Exception e) { - //In case the last two steps fail delete the latest Deposit it in order to create a new one (only one at a time is allowed) - restTemplate.delete(latestDraftUrl); - throw e; } } - } - if (unpublishedUrl == null) { - // Second step, add the file to the entry. - HttpHeaders fileHeaders = new HttpHeaders(); - fileHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); - LinkedMultiValueMap addFileMap = new LinkedMultiValueMap<>(); + if (unpublishedUrl == null) { + // Second step, add the file to the entry. + HttpHeaders fileHeaders = new HttpHeaders(); + fileHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); + LinkedMultiValueMap addFileMap = new LinkedMultiValueMap<>(); - FileEnvelope file = getWordDocument(id.toString(), principal, configLoader); - addFileMap.add("filename", file.getFilename()); - FileSystemResource fileSystemResource = new FileSystemResource(file.getFile()); - addFileMap.add("file", fileSystemResource); - HttpEntity> addFileMapRequest = new HttpEntity<>(addFileMap, fileHeaders); + FileEnvelope file = getWordDocument(id.toString(), principal, configLoader); + addFileMap.add("filename", file.getFilename()); + FileSystemResource fileSystemResource = new FileSystemResource(file.getFile()); + addFileMap.add("file", fileSystemResource); + HttpEntity> addFileMapRequest = new HttpEntity<>(addFileMap, fileHeaders); - String addFileUrl = links.get("files") + "?access_token=" + zenodoToken; - ResponseEntity addFileResponse = restTemplate.postForEntity(addFileUrl, addFileMapRequest, String.class); - Files.deleteIfExists(file.getFile().toPath()); + String addFileUrl = links.get("files") + "?access_token=" + zenodoToken; + ResponseEntity addFileResponse = restTemplate.postForEntity(addFileUrl, addFileMapRequest, String.class); + Files.deleteIfExists(file.getFile().toPath()); - // Third post call to Zenodo to publish the entry and return the DOI. - publishUrl = links.get("publish") + "?access_token=" + zenodoToken; - } else { - publishUrl = unpublishedUrl + "?access_token=" + zenodoToken; - } - Map publishResponce = restTemplate.postForObject(publishUrl, "", Map.class); + // Third post call to Zenodo to publish the entry and return the DOI. + publishUrl = links.get("publish") + "?access_token=" + zenodoToken; + } else { + publishUrl = unpublishedUrl + "?access_token=" + zenodoToken; + } + if (dmp.isPublic()) { + Map publishResponce = restTemplate.postForObject(publishUrl, "", Map.class); + finalDoi = (String) publishResponce.get("conceptdoi"); + } - dmp.setDoi((String) publishResponce.get("conceptdoi")); - apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); - return (String) publishResponce.get("conceptdoi"); + if (finalDoi != null) { + dmp.setDoi(finalDoi); + apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); + } + return finalDoi; } catch (HttpClientErrorException | HttpServerErrorException ex) { ObjectMapper ob = new ObjectMapper(); Map parsedException = ob.readValue(ex.getResponseBodyAsString(), HashMap.class); @@ -1767,30 +1772,133 @@ public class DataManagementPlanManager { } } - private void updateIndex(DMP dmp) throws IOException { - DmpMapper mapper = new DmpMapper(apiContext, datasetManager); - Dmp elastic = mapper.toElastic(dmp); - apiContext.getOperationsContext().getElasticRepository().getDmpRepository().createOrUpdate(elastic); - } + /* + * Misc + * */ - public void generateIndex(Principal principal) { - if (principal.getAuthorities().contains(Authorities.ADMIN.getValue())) { - if (apiContext.getOperationsContext().getElasticRepository().getDmpRepository().createIndex()) { - List dmps = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().asQueryable().toList(); - dmps.forEach(dmp -> { - try { - this.updateIndex(dmp); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - }); + private void sendNotification(DMP dmp, UserInfo user, NotificationType notificationType) { + List userDMPS = databaseRepository.getUserDmpDao().asQueryable().where(((builder, root) -> builder.equal(root.get("dmp").get("id"), dmp.getId()))).toList(); + for (UserDMP userDMP : userDMPS) { + if (!userDMP.getUser().getId().equals(user.getId())) { + Notification notification = new Notification(); + notification.setUserId(user); + notification.setType(notificationType); + notification.setNotifyState(NotifyState.PENDING); + notification.setIsActive(ActiveStatus.ACTIVE); + notification.setData("{" + + "\"userId\": \"" + userDMP.getUser().getId() + "\"" + + ", \"id\": \"" + userDMP.getDmp().getId() + "\"" + + ", \"name\": \"" + userDMP.getDmp().getLabel() + "\"" + + ", \"path\": \"" + notificationPaths.get(notificationType) +"\"" + + "}"); + notification.setCreatedAt(new Date()); + notification.setUpdatedAt(notification.getCreatedAt()); + notification.setContactTypeHint(ContactType.EMAIL); + notification.setContactHint(userDMP.getUser().getEmail()); + databaseRepository.getNotificationDao().createOrUpdate(notification); } } + } - public void clearIndex(Principal principal) throws IOException { - if (principal.getAuthorities().contains(Authorities.ADMIN.getValue())) { - apiContext.getOperationsContext().getElasticRepository().getDmpRepository().clear(); + /*public DataTableData getPublicPaged(DataManagmentPlanPublicTableRequest dataManagementPlanPublicTableRequest, String fieldsGroup, Principal principal) throws Exception { + dataManagementPlanPublicTableRequest.setQuery(databaseRepository.getDmpDao().asQueryable().withHint(HintedModelFactory.getHint(DataManagementPlanListingModel.class))); + QueryableList items = dataManagementPlanPublicTableRequest.applyCriteria(); + + if (principal.getId() != null && dataManagementPlanPublicTableRequest.getCriteria().getRole() != null) { + items.where((builder, root) -> { + Join userJoin = root.join("users", JoinType.LEFT); + return builder.and(builder.equal(userJoin.join("user", JoinType.LEFT).get("id"), principal.getId()), builder.equal(userJoin.get("role"), dataManagementPlanPublicTableRequest.getCriteria().getRole())); + }); + } + QueryableList pagedItems = PaginationManager.applyPaging(items, dataManagementPlanPublicTableRequest); + + DataTableData dataTable = new DataTableData<>(); + + CompletableFuture itemsFuture; + if (fieldsGroup.equals("listing")) { + itemsFuture = pagedItems.withHint(HintedModelFactory.getHint(DataManagementPlanListingModel.class)) + .selectAsync(item -> { + item.setDataset( + item.getDataset().stream() + .filter(dataset -> dataset.getStatus().equals(Dataset.Status.FINALISED.getValue())).collect(Collectors.toSet())); + return new DataManagementPlanListingModel().fromDataModelDatasets(item); + }) + .whenComplete((resultList, throwable) -> dataTable.setData(resultList)); + } else { + itemsFuture = pagedItems + .selectAsync(item -> new DataManagementPlanListingModel().fromDataModel(item)) + .whenComplete((resultList, throwable) -> dataTable.setData(resultList)); + } + + CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> { + dataTable.setTotalCount(count); + }); + CompletableFuture.allOf(itemsFuture, countFuture).join(); + return dataTable; + } +*/ + /*public void unlock(UUID uuid) throws Exception { + apiContext.getOperationsContext().getDatabaseRepository().getDmpDao() + .asQueryable().where((builder, root) -> builder.equal(root.get("id"), uuid)) + .update(root -> root.get("status"), DMP.DMPStatus.ACTIVE.getValue()); + return; + }*/ + /*public File getPdfDocument(String id) throws InstantiationException, IllegalAccessException, InterruptedException, IOException { + File file = this.getWordDocument(id); + String fileName = file.getName(); + if (fileName.endsWith(".docx")){ + fileName = fileName.substring(0, fileName.length() - 5); + } + return this.datasetManager.convertToPDF(file, environment, fileName); + }*/ + /*public eu.eudat.models.data.dmp.DataManagementPlan getSinglePublic(String id, DynamicGrantConfiguration dynamicGrantConfiguration) throws Exception { + DMP dataManagementPlanEntity = databaseRepository.getDmpDao().find(UUID.fromString(id)); + + if (dataManagementPlanEntity != null && dataManagementPlanEntity.getStatus() == 1) { + eu.eudat.models.data.dmp.DataManagementPlan datamanagementPlan = new eu.eudat.models.data.dmp.DataManagementPlan(); + datamanagementPlan.fromDataModel(dataManagementPlanEntity); + datamanagementPlan.setDatasets(datamanagementPlan.getDatasets().stream().filter(dataset -> dataset.getStatus() == Dataset.Status.FINALISED.getValue()).collect(Collectors.toList())); + Map dmpProperties = dataManagementPlanEntity.getDmpProperties() != null ? new org.json.JSONObject(dataManagementPlanEntity.getDmpProperties()).toMap() : null; +// datamanagementPlan.setDynamicFields(dynamicGrantConfiguration.getFields().stream().map(item -> { +// DynamicFieldWithValue fieldWithValue = new DynamicFieldWithValue(); +// fieldWithValue.setId(item.getId()); +// fieldWithValue.setDependencies(item.getDependencies()); +// fieldWithValue.setName(item.getName()); +// fieldWithValue.setQueryProperty(item.getQueryProperty()); +// fieldWithValue.setRequired(item.getRequired()); +// return fieldWithValue; +// }).collect(Collectors.toList())); + + if (dmpProperties != null && datamanagementPlan.getDynamicFields() != null) + datamanagementPlan.getDynamicFields().forEach(item -> { + Map properties = (Map) dmpProperties.get(item.getId()); + if (properties != null) + item.setValue(new Tuple<>(properties.get("id"), properties.get("label"))); + }); + return datamanagementPlan; + } else { + throw new Exception("Selected DMP is not public"); } } + + public DataManagementPlanOverviewModel getOverviewSinglePublic(String id) throws Exception { + DMP dataManagementPlanEntity = databaseRepository.getDmpDao().find(UUID.fromString(id)); + if (dataManagementPlanEntity != null && dataManagementPlanEntity.getStatus() == 1) { + DataManagementPlanOverviewModel datamanagementPlan = new DataManagementPlanOverviewModel(); + datamanagementPlan.fromDataModelDatasets(dataManagementPlanEntity); + datamanagementPlan.setDatasets(datamanagementPlan.getDatasets().stream().filter(dataset -> dataset.getStatus() == Dataset.Status.FINALISED.getValue()).collect(Collectors.toList())); + return datamanagementPlan; + } else { + throw new Exception("Selected DMP is not public"); + } + }*/ + /*public List getWithCriteria(DMPDao dmpsRepository, DataManagementPlanCriteriaRequest dataManagementPlanCriteria, Principal principal) throws IllegalAccessException, InstantiationException { + UUID principalID = principal.getId(); + QueryableList items = dmpsRepository.getWithCriteria(dataManagementPlanCriteria.getCriteria()).withHint(HintedModelFactory.getHint(DataManagementPlan.class)); + List roles = new LinkedList<>(); + QueryableList authenticatedItems = dmpsRepository.getAuthenticated(items, principalID, roles); + List datamanagementPlans = authenticatedItems.select(item -> new DataManagementPlan().fromDataModel(item)); + return datamanagementPlans; + }*/ } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/InvitationsManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/InvitationsManager.java index eea0d1c41..2191298a2 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/InvitationsManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/InvitationsManager.java @@ -1,6 +1,7 @@ package eu.eudat.logic.managers; import eu.eudat.data.entities.DMP; +import eu.eudat.data.entities.UserAssociation; import eu.eudat.data.entities.UserDMP; import eu.eudat.data.entities.UserInfo; import eu.eudat.exceptions.security.UnauthorisedException; @@ -38,15 +39,28 @@ public class InvitationsManager { UserDMP userDMP = new UserDMP(); userDMP.setUser(userInfo); userInfoToUserDmp.add(userDMP); + if (!apiContext.getOperationsContext().getDatabaseRepository().getUserAssociationDao().areAssociated(principalUser, userInfo)) { + UserAssociation userAssociation = new UserAssociation(); + userAssociation.setFirstUser(principalUser); + userAssociation.setSecondUser(userInfo); + apiContext.getOperationsContext().getDatabaseRepository().getUserAssociationDao().createOrUpdate(userAssociation); + } } DMP dataManagementPlan = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(invitation.getDataManagementPlan()); apiContext.getUtilitiesService().getInvitationService().createInvitations(apiContext.getOperationsContext().getDatabaseRepository().getInvitationDao(), apiContext.getUtilitiesService().getMailService(), invitation.getUsers().stream().map(item -> item.toDataModel()).collect(Collectors.toList()), dataManagementPlan, principalUser); apiContext.getUtilitiesService().getInvitationService().assignToDmp(apiContext.getOperationsContext().getDatabaseRepository().getDmpDao(), userInfoToUserDmp, dataManagementPlan); } - public List getUsers(UserInfoRequestItem userInfoRequestItem) throws InstantiationException, IllegalAccessException { - QueryableList users = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().getWithCriteria(userInfoRequestItem.getCriteria()); - List userModels = users.select(item -> new UserInfoInvitationModel().fromDataModel(item)); + public List getUsers(Principal principal) throws InstantiationException, IllegalAccessException { + UserInfo principalUser = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); + List users = apiContext.getOperationsContext().getDatabaseRepository().getUserAssociationDao().getAssociated(principalUser).stream().map(userAssociation -> { + if (userAssociation.getFirstUser().getId().equals(principal.getId())) { + return userAssociation.getSecondUser(); + } else { + return userAssociation.getFirstUser(); + } + }).collect(Collectors.toList()); + List userModels = users.stream().map(userInfo -> new UserInfoInvitationModel().fromDataModel(userInfo)).collect(Collectors.toList()); return userModels; } @@ -60,6 +74,12 @@ public class InvitationsManager { userDMP.setUser(invitedUser); userDMP.setDmp(invitation.getDmp()); userDMP.setRole(UserDMP.UserDMPRoles.USER.getValue()); + if (!apiContext.getOperationsContext().getDatabaseRepository().getUserAssociationDao().areAssociated(invitedUser, invitation.getUser())) { + UserAssociation userAssociation = new UserAssociation(); + userAssociation.setFirstUser(invitedUser); + userAssociation.setSecondUser(invitation.getUser()); + apiContext.getOperationsContext().getDatabaseRepository().getUserAssociationDao().createOrUpdate(userAssociation); + } DMP datamanagementPlan = invitation.getDmp(); apiContext.getOperationsContext().getDatabaseRepository().getUserDmpDao().createOrUpdate(userDMP); apiContext.getUtilitiesService().getInvitationService().assignToDmp(apiContext.getOperationsContext().getDatabaseRepository().getDmpDao(), userDMP, datamanagementPlan); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/RDAManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/RDAManager.java index ff194455e..f7c9efde8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/RDAManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/RDAManager.java @@ -32,7 +32,7 @@ public class RDAManager { ObjectMapper mapper = new ObjectMapper(); mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss Z")); - result = mapper.writeValueAsString(rdaDmp); + result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rdaDmp); return result; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index cd29be9e8..05f966bac 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -169,9 +169,13 @@ public class RemoteFetcher { completedPath = completedPath.replace("{like}", ""); } if (externalUrlCriteria.getFunderId() != null) { - String funderId = externalUrlCriteria.getFunderId(); + String funderPrefix = externalUrlCriteria.getFunderId().split(":")[0]; + String funderId = externalUrlCriteria.getFunderId().replace(funderPrefix + ":", ""); + if (funderId.toCharArray()[0] == ':') { + funderId = externalUrlCriteria.getFunderId(); + } try { - funderId = URLEncoder.encode(externalUrlCriteria.getFunderId(), "UTF-8"); + funderId = URLEncoder.encode(funderId, "UTF-8"); } catch (UnsupportedEncodingException e) { logger.error(e.getMessage(), e); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java index 539e417a6..ff6518354 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java @@ -56,5 +56,9 @@ public interface DatabaseRepository { NotificationDao getNotificationDao(); + UserAssociationDao getUserAssociationDao(); + + DoiFunderDao getDoiFunderDao(); + void detachEntity(T entity); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java index a87ba7734..01aa5093a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java @@ -37,6 +37,8 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { private FunderDao funderDao; private LockDao lockDao; private NotificationDao notificationDao; + private UserAssociationDao userAssociationDao; + private DoiFunderDao doiFunderDao; private EntityManager entityManager; @@ -290,6 +292,26 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { return notificationDao; } + @Override + public UserAssociationDao getUserAssociationDao() { + return userAssociationDao; + } + + @Override + public DoiFunderDao getDoiFunderDao() { + return doiFunderDao; + } + + @Autowired + public void setDoiFunderDao(DoiFunderDao doiFunderDao) { + this.doiFunderDao = doiFunderDao; + } + + @Autowired + public void setUserAssociationDao(UserAssociationDao userAssociationDao) { + this.userAssociationDao = userAssociationDao; + } + @Autowired public void setNotificationDao(NotificationDao notificationDao) { this.notificationDao = notificationDao; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java index 78c6a9830..6d08acb0c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java @@ -134,10 +134,10 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer .name(profile.getName()).verified_email(profile.getIsVerified()) .email(profile.getEmail()).created(new Date()).lastloggedin(new Date()) .additionalinfo("{\"data\":{\"avatar\":{\"url\":\"" + profile.getAvatarUrl() - + "\"}},{\"zenodoToken\":\"" + profile.getZenodoId() - + "\", \"expirationDate\": \"" + Instant.now().plusSeconds(profile.getZenodoExpire()).toEpochMilli() + + "\"},\"zenodoToken\":\"" + profile.getZenodoId() + + "\", \"expirationDate\": \"" + Instant.now().plusSeconds((profile.getZenodoExpire() != null ? profile.getZenodoExpire(): 0)).toEpochMilli() + "\", \"zenodoRefresh\": \"" + profile.getZenodoRefresh() - + (profile.getProvider() == TokenValidatorFactoryImpl.LoginProvider.ZENODO ? "\", \"zenodoEmail\": \"" + profile.getEmail() : "") +"\"}") + + (profile.getProvider() == TokenValidatorFactoryImpl.LoginProvider.ZENODO ? "\", \"zenodoEmail\": \"" + profile.getEmail() : "") +"\"}}") .authorization_level((short) 1).usertype((short) 1) .build(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/Organisation.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/Organisation.java index 0cb2b1296..5c87d7ebd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/Organisation.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/Organisation.java @@ -68,18 +68,22 @@ public class Organisation implements DataModel - /files/logs/openDMP.log + /app/logs/openDMP.log - /files/logs/openDMP-%d{yyyy-MM-dd}.%i.log + /app/logs/openDMP-%d{yyyy-MM-dd}.%i.log 100MB diff --git a/dmp-backend/web/src/main/resources/logging/logback-staging.xml b/dmp-backend/web/src/main/resources/logging/logback-staging.xml index f1e40e210..143e8a18f 100644 --- a/dmp-backend/web/src/main/resources/logging/logback-staging.xml +++ b/dmp-backend/web/src/main/resources/logging/logback-staging.xml @@ -7,9 +7,9 @@ - /files/logs/openDMP.log + /app/logs/openDMP.log - /files/logs/openDMP-%d{yyyy-MM-dd}.%i.log + /app/logs/openDMP-%d{yyyy-MM-dd}.%i.log 100MB diff --git a/dmp-db-scema/Docker/dmp-db.env b/dmp-db-scema/Docker/dmp-db.env new file mode 100644 index 000000000..d79f408eb --- /dev/null +++ b/dmp-db-scema/Docker/dmp-db.env @@ -0,0 +1,5 @@ +ADMIN_USERNAME=admin +ADMIN_PASSWORD=CHANGEME +POSTGRES_DB=dmptool +POSTGRES_USER=dmptool +POSTGRES_PASSWORD=CHANGEME \ No newline at end of file diff --git a/dmp-db-scema/initdb.sh b/dmp-db-scema/initdb.sh new file mode 100644 index 000000000..5ea5aa8be --- /dev/null +++ b/dmp-db-scema/initdb.sh @@ -0,0 +1,7 @@ +psql -d dmptool -U dmptool -f main/DataManagementPlanDB.sql; +for j in $(ls updates); do + for i in $(ls updates/$j/*.sql); do + echo $i + psql --set=ADMIN_USERNAME="$ADMIN_USERNAME" --set=ADMIN_PASSWORD="$ADMIN_PASSWORD" -d dmptool -U dmptool -f $i; + done +done \ No newline at end of file diff --git a/dmp-db-scema/DataManagementPlanDB.sql b/dmp-db-scema/main/DataManagementPlanDB.sql similarity index 99% rename from dmp-db-scema/DataManagementPlanDB.sql rename to dmp-db-scema/main/DataManagementPlanDB.sql index 7c49dfbb8..9cad64fc8 100644 --- a/dmp-db-scema/DataManagementPlanDB.sql +++ b/dmp-db-scema/main/DataManagementPlanDB.sql @@ -34,7 +34,7 @@ DROP table if exists "UserAuth" cascade; -- CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; --- CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; SET search_path = public, pg_catalog; @@ -550,8 +550,8 @@ ALTER TABLE "UserDMP" OWNER TO dmptool; REVOKE ALL ON SCHEMA public FROM PUBLIC; -REVOKE ALL ON SCHEMA public FROM postgres; -GRANT ALL ON SCHEMA public TO postgres; +-- REVOKE ALL ON SCHEMA public FROM postgres; +-- GRANT ALL ON SCHEMA public TO postgres; GRANT ALL ON SCHEMA public TO PUBLIC; diff --git a/dmp-db-scema/updates/01/DMPUser DMPDatasetprofile DMPFinalizedDate .sql b/dmp-db-scema/updates/01/01_DMPUser_DMPDatasetprofile_DMPFinalizedDate.sql similarity index 56% rename from dmp-db-scema/updates/01/DMPUser DMPDatasetprofile DMPFinalizedDate .sql rename to dmp-db-scema/updates/01/01_DMPUser_DMPDatasetprofile_DMPFinalizedDate.sql index 06d569813..8ed97954d 100644 --- a/dmp-db-scema/updates/01/DMPUser DMPDatasetprofile DMPFinalizedDate .sql +++ b/dmp-db-scema/updates/01/01_DMPUser_DMPDatasetprofile_DMPFinalizedDate.sql @@ -1,12 +1,12 @@ INSERT INTO public."UserDMP"( usr, dmp, role) SELECT "Creator", "ID", 0 - FROM public."DMP" + FROM public."DMP"; DELETE FROM public."UserDMP" as us1 using public."UserDMP" as us2 -where us1."id" < us2."id" AND us1."dmp" = us2."dmp" +where us1."id" < us2."id" AND us1."dmp" = us2."dmp"; @@ -31,30 +31,31 @@ WITH ( TABLESPACE pg_default; ALTER TABLE public."DMPDatasetProfile" - OWNER to dmtadm; - +-- OWNER to dmtadm; + OWNER to dmptool; ALTER TABLE public."UserDMP" - OWNER to dmtadm; +-- OWNER to dmtadm; + OWNER to dmptool; -INSERT INTO public."DMPDatasetProfile"( - dmp, datasetprofile) - SELECT "ID", unnest(xpath('/profiles/profile/@profileId', dmpp."AssociatedDmps"::xml)::text[]::UUID[]) - FROM public."DMP" as dmpp +--INSERT INTO public."DMPDatasetProfile"( +-- dmp, datasetprofile) +-- SELECT "ID", unnest(xpath('/profiles/profile/@profileId', dmpp."AssociatedDmps"::xml)::text[]::UUID[]) +-- FROM public."DMP" as dmpp; -Alter table public."DMP" -add "FinalizedDat" timestamp(6) with time zone +ALTER TABLE public."DMP" +ADD "FinalizedDat" timestamp(6) WITH time zone; -update public."DMP" SET "FinalizedDat" = "Modified" -where "Status" = 1 +UPDATE public."DMP" SET "FinalizedDat" = "Modified" +WHERE "Status" = 1; -Alter table public."Dataset" -add "FinalizedDat" timestamp(6) with time zone +ALTER TABLE public."Dataset" +ADD "FinalizedDat" timestamp(6) WITH time zone; -update public."Dataset" SET "FinalizedDat" = "Modified" -where "Status" = 1 +UPDATE public."Dataset" SET "FinalizedDat" = "Modified" +WHERE "Status" = 1; diff --git a/dmp-db-scema/updates/01/DMPisPublic.sql b/dmp-db-scema/updates/01/03_DMPisPublic.sql similarity index 84% rename from dmp-db-scema/updates/01/DMPisPublic.sql rename to dmp-db-scema/updates/01/03_DMPisPublic.sql index aef4dca4d..dab69e4d9 100644 --- a/dmp-db-scema/updates/01/DMPisPublic.sql +++ b/dmp-db-scema/updates/01/03_DMPisPublic.sql @@ -3,5 +3,5 @@ Add "isPublic" boolean NOT NULL Default False; UPDATE public."DMP" SET "isPublic" = True - WHERE "Status" = 1 + WHERE "Status" = 1; \ No newline at end of file diff --git a/dmp-db-scema/updates/01/RenameDatasetColumnFinalizedDat.sql b/dmp-db-scema/updates/01/04_RenameDatasetColumnFinalizedDat.sql similarity index 100% rename from dmp-db-scema/updates/01/RenameDatasetColumnFinalizedDat.sql rename to dmp-db-scema/updates/01/04_RenameDatasetColumnFinalizedDat.sql diff --git a/dmp-db-scema/updates/01/DMPPublishedDat.sql b/dmp-db-scema/updates/01/05_DMPPublishedDat.sql similarity index 53% rename from dmp-db-scema/updates/01/DMPPublishedDat.sql rename to dmp-db-scema/updates/01/05_DMPPublishedDat.sql index 541efc62f..d823b5134 100644 --- a/dmp-db-scema/updates/01/DMPPublishedDat.sql +++ b/dmp-db-scema/updates/01/05_DMPPublishedDat.sql @@ -1,6 +1,6 @@ ALTER TABLE public."DMP" -ADD "PublishedAt" timestamp(6) with time zone +ADD "PublishedAt" timestamp(6) WITH time zone; UPDATE public."DMP" SET "PublishedAt" = "FinalizedDat" -where "isPublic" = True \ No newline at end of file +where "isPublic" = True; \ No newline at end of file diff --git a/dmp-db-scema/updates/01/RenameDMPColumnsFinalizedDatPublishedDat.sql b/dmp-db-scema/updates/01/06_RenameDMPColumnsFinalizedDatPublishedDat.sql similarity index 100% rename from dmp-db-scema/updates/01/RenameDMPColumnsFinalizedDatPublishedDat.sql rename to dmp-db-scema/updates/01/06_RenameDMPColumnsFinalizedDatPublishedDat.sql diff --git a/dmp-db-scema/updates/01/DMPCreateDOI.sql b/dmp-db-scema/updates/01/07_DMPCreateDOI.sql similarity index 53% rename from dmp-db-scema/updates/01/DMPCreateDOI.sql rename to dmp-db-scema/updates/01/07_DMPCreateDOI.sql index 470304b4c..5e97960c0 100644 --- a/dmp-db-scema/updates/01/DMPCreateDOI.sql +++ b/dmp-db-scema/updates/01/07_DMPCreateDOI.sql @@ -1,2 +1,2 @@ ALTER TABLE public."DMP" -ADD COLUMN "DOI" text \ No newline at end of file +ADD COLUMN "DOI" text; \ No newline at end of file diff --git a/dmp-db-scema/updates/01/08_Create_content.sql b/dmp-db-scema/updates/01/08_Create_content.sql new file mode 100644 index 000000000..89c6190b9 --- /dev/null +++ b/dmp-db-scema/updates/01/08_Create_content.sql @@ -0,0 +1,15 @@ +CREATE TABLE public."Content" ( + "Id" uuid NOT NULL, + "Filename" character varying NOT NULL, + "Extension" character varying NOT NULL, + "ParentType" numeric NOT NULL, + "Uri" character varying NOT NULL, + "LocationType" numeric NOT NULL +); + + +ALTER TABLE public."Content" OWNER TO dmptool; + +ALTER TABLE ONLY public."Content" + ADD CONSTRAINT "Content_pkey" PRIMARY KEY ("Id"); + diff --git a/dmp-db-scema/updates/01/Removes DatasetIsPublic.sql b/dmp-db-scema/updates/01/Removes DatasetIsPublic.sql deleted file mode 100644 index 3734d4198..000000000 --- a/dmp-db-scema/updates/01/Removes DatasetIsPublic.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE public."Dataset" -DROP COLUMN "IsPublic" \ No newline at end of file diff --git a/dmp-db-scema/updates/02/CreateLoginConfirmationEmail.sql b/dmp-db-scema/updates/02/01_CreateLoginConfirmationEmail.sql similarity index 90% rename from dmp-db-scema/updates/02/CreateLoginConfirmationEmail.sql rename to dmp-db-scema/updates/02/01_CreateLoginConfirmationEmail.sql index 458b1b572..cf3807730 100644 --- a/dmp-db-scema/updates/02/CreateLoginConfirmationEmail.sql +++ b/dmp-db-scema/updates/02/01_CreateLoginConfirmationEmail.sql @@ -14,4 +14,5 @@ WITH ( TABLESPACE pg_default; ALTER TABLE public."LoginConfirmationEmail" - OWNER to dmtadm; \ No newline at end of file +-- OWNER to dmtadm; + OWNER to dmptool; \ No newline at end of file diff --git a/dmp-db-scema/updates/02/UserInfo email drop null.sql b/dmp-db-scema/updates/02/02_UserInfo_email_drop_null.sql similarity index 100% rename from dmp-db-scema/updates/02/UserInfo email drop null.sql rename to dmp-db-scema/updates/02/02_UserInfo_email_drop_null.sql diff --git a/dmp-db-scema/updates/03/01. DatasetProfile_Description_value_set_empty_text.sql b/dmp-db-scema/updates/03/01_DatasetProfile_Description_value_set_empty_text.sql similarity index 100% rename from dmp-db-scema/updates/03/01. DatasetProfile_Description_value_set_empty_text.sql rename to dmp-db-scema/updates/03/01_DatasetProfile_Description_value_set_empty_text.sql diff --git a/dmp-db-scema/updates/03/02. DatasetProfile_adds_null_constraints_description.sql b/dmp-db-scema/updates/03/02_DatasetProfile_adds_null_constraints_description.sql similarity index 100% rename from dmp-db-scema/updates/03/02. DatasetProfile_adds_null_constraints_description.sql rename to dmp-db-scema/updates/03/02_DatasetProfile_adds_null_constraints_description.sql diff --git a/dmp-db-scema/updates/03/05. Renames-Project-to-Grant.sql b/dmp-db-scema/updates/03/03_Renames-Project-to-Grant.sql similarity index 100% rename from dmp-db-scema/updates/03/05. Renames-Project-to-Grant.sql rename to dmp-db-scema/updates/03/03_Renames-Project-to-Grant.sql diff --git a/dmp-db-scema/updates/03/03. Funder-create.sql b/dmp-db-scema/updates/03/04_Funder-create.sql similarity index 100% rename from dmp-db-scema/updates/03/03. Funder-create.sql rename to dmp-db-scema/updates/03/04_Funder-create.sql diff --git a/dmp-db-scema/updates/03/04. Grant-add-column-Funder.sql b/dmp-db-scema/updates/03/05_Grant-add-column-Funder.sql similarity index 100% rename from dmp-db-scema/updates/03/04. Grant-add-column-Funder.sql rename to dmp-db-scema/updates/03/05_Grant-add-column-Funder.sql diff --git a/dmp-db-scema/updates/03/06_Renames-Grant-fk-Constraint.sql b/dmp-db-scema/updates/03/06_Renames-Grant-fk-Constraint.sql new file mode 100644 index 000000000..9c4dd0602 --- /dev/null +++ b/dmp-db-scema/updates/03/06_Renames-Grant-fk-Constraint.sql @@ -0,0 +1,9 @@ +ALTER TABLE public."Grant" +ADD COLUMN "Content" uuid; + + +ALTER TABLE public."Grant" +ADD CONSTRAINT fk_grant_content FOREIGN KEY ("Content") + REFERENCES public."Content" ("Id") MATCH SIMPLE + ON UPDATE NO ACTION + ON DELETE NO ACTION; \ No newline at end of file diff --git a/dmp-db-scema/updates/03/07. Renames-Grant-fk-creator-Constraint.sql b/dmp-db-scema/updates/03/07_Renames-Grant-fk-creator-Constraint.sql similarity index 100% rename from dmp-db-scema/updates/03/07. Renames-Grant-fk-creator-Constraint.sql rename to dmp-db-scema/updates/03/07_Renames-Grant-fk-creator-Constraint.sql diff --git a/dmp-db-scema/updates/03/08. Renames-Grant-fk-Constraint.sql b/dmp-db-scema/updates/03/08. Renames-Grant-fk-Constraint.sql deleted file mode 100644 index 493d9af69..000000000 --- a/dmp-db-scema/updates/03/08. Renames-Grant-fk-Constraint.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE public."Grant" -RENAME CONSTRAINT "fk_project_content" TO "fk_grant_content"; \ No newline at end of file diff --git a/dmp-db-scema/updates/03/06. Renames-Grant-pKey-Constraint.sql b/dmp-db-scema/updates/03/08_Renames-Grant-pKey-Constraint.sql similarity index 100% rename from dmp-db-scema/updates/03/06. Renames-Grant-pKey-Constraint.sql rename to dmp-db-scema/updates/03/08_Renames-Grant-pKey-Constraint.sql diff --git a/dmp-db-scema/updates/03/09. Rename-Dmps-Project-to_Grant.sql b/dmp-db-scema/updates/03/09_Rename-Dmps-Project-to_Grant.sql similarity index 100% rename from dmp-db-scema/updates/03/09. Rename-Dmps-Project-to_Grant.sql rename to dmp-db-scema/updates/03/09_Rename-Dmps-Project-to_Grant.sql diff --git a/dmp-db-scema/updates/03/10. Project-create.sql b/dmp-db-scema/updates/03/10_Project-create.sql similarity index 100% rename from dmp-db-scema/updates/03/10. Project-create.sql rename to dmp-db-scema/updates/03/10_Project-create.sql diff --git a/dmp-db-scema/updates/03/11. DMP-add-column-project.sql b/dmp-db-scema/updates/03/11_DMP-add-column-project.sql similarity index 100% rename from dmp-db-scema/updates/03/11. DMP-add-column-project.sql rename to dmp-db-scema/updates/03/11_DMP-add-column-project.sql diff --git a/dmp-db-scema/updates/03/12_Remove_xml_types.sql b/dmp-db-scema/updates/03/12_Remove_xml_types.sql new file mode 100644 index 000000000..5bfb2a5f8 --- /dev/null +++ b/dmp-db-scema/updates/03/12_Remove_xml_types.sql @@ -0,0 +1,18 @@ +ALTER TABLE public."Grant" +ALTER COLUMN "Reference" TYPE character varying(255); + +ALTER TABLE public."Grant" +ALTER COLUMN "Definition" TYPE character varying; + +ALTER TABLE public."Registry" +ALTER COLUMN "Reference" TYPE character varying; + +ALTER TABLE public."Service" +ALTER COLUMN "Reference" TYPE character varying; + +ALTER TABLE public."Researcher" +ALTER COLUMN "Reference" TYPE character varying; + +ALTER TABLE public."DataRepository" +ALTER COLUMN "Reference" TYPE character varying; + diff --git a/dmp-db-scema/updates/04/01_Funder_add_column_CreationUser.sql b/dmp-db-scema/updates/04/01_Funder_add_column_CreationUser.sql new file mode 100644 index 000000000..04aa6f4d3 --- /dev/null +++ b/dmp-db-scema/updates/04/01_Funder_add_column_CreationUser.sql @@ -0,0 +1,2 @@ +ALTER TABLE "Funder" +ADD COLUMN "CreationUser" uuid; \ No newline at end of file diff --git a/dmp-db-scema/updates/04/Funder_update_CreationUser_values.sql b/dmp-db-scema/updates/04/02_Funder_update_CreationUser_values.sql similarity index 71% rename from dmp-db-scema/updates/04/Funder_update_CreationUser_values.sql rename to dmp-db-scema/updates/04/02_Funder_update_CreationUser_values.sql index 130130ab9..2d7085f3e 100644 --- a/dmp-db-scema/updates/04/Funder_update_CreationUser_values.sql +++ b/dmp-db-scema/updates/04/02_Funder_update_CreationUser_values.sql @@ -1,4 +1,4 @@ Update "Funder" as funder set "CreationUser" = grant1."CreationUser" from "Grant" as grant1 - where funder."ID" = grant1."Funder" \ No newline at end of file + where funder."ID" = grant1."Funder" ; \ No newline at end of file diff --git a/dmp-db-scema/updates/04/03_Create_External_Datasets.sql b/dmp-db-scema/updates/04/03_Create_External_Datasets.sql new file mode 100644 index 000000000..5c55bcb70 --- /dev/null +++ b/dmp-db-scema/updates/04/03_Create_External_Datasets.sql @@ -0,0 +1,15 @@ +CREATE TABLE public."ExternalDataset" ( + "Id" uuid DEFAULT public.uuid_generate_v4() NOT NULL, + "Label" character varying NOT NULL, + "Abbreviation" character varying, + "Reference" character varying NOT NULL, + "Created" timestamp(4) with time zone NOT NULL, + "Modified" timestamp(4) with time zone NOT NULL +); + + +ALTER TABLE public."ExternalDataset" OWNER TO dmptool; + +ALTER TABLE ONLY public."ExternalDataset" + ADD CONSTRAINT "ExternalDataset_pkey" PRIMARY KEY ("Id"); + diff --git a/dmp-db-scema/updates/04/04_Add_creationUser_on_DataRepository_ExternalDataset_Registry_Service.sql b/dmp-db-scema/updates/04/04_Add_creationUser_on_DataRepository_ExternalDataset_Registry_Service.sql new file mode 100644 index 000000000..fd8dc380d --- /dev/null +++ b/dmp-db-scema/updates/04/04_Add_creationUser_on_DataRepository_ExternalDataset_Registry_Service.sql @@ -0,0 +1,11 @@ +ALTER TABLE "DataRepository" +ADD COLUMN "CreationUser" uuid; + +ALTER TABLE "ExternalDataset" +ADD COLUMN "CreationUser" uuid; + +ALTER TABLE "Registry" +ADD COLUMN "CreationUser" uuid; + +ALTER TABLE "Service" +ADD COLUMN "CreationUser" uuid; \ No newline at end of file diff --git a/dmp-db-scema/updates/04/05_Researcher_add_column_CreationUser.sql b/dmp-db-scema/updates/04/05_Researcher_add_column_CreationUser.sql new file mode 100644 index 000000000..d9627e5bf --- /dev/null +++ b/dmp-db-scema/updates/04/05_Researcher_add_column_CreationUser.sql @@ -0,0 +1,2 @@ +ALTER TABLE "Researcher" +ADD COLUMN "CreationUser" uuid; \ No newline at end of file diff --git a/dmp-db-scema/updates/04/Add_creationUser_on_DataRepository_ExternalDataset_Registry_Service.sql b/dmp-db-scema/updates/04/Add_creationUser_on_DataRepository_ExternalDataset_Registry_Service.sql deleted file mode 100644 index 4cc036bdb..000000000 --- a/dmp-db-scema/updates/04/Add_creationUser_on_DataRepository_ExternalDataset_Registry_Service.sql +++ /dev/null @@ -1,11 +0,0 @@ -ALTER TABLE "DataRepository" -ADD COLUMN "CreationUser" uuid - -ALTER TABLE "ExternalDataset" -ADD COLUMN "CreationUser" uuid - -ALTER TABLE "Registry" -ADD COLUMN "CreationUser" uuid - -ALTER TABLE "Service" -ADD COLUMN "CreationUser" uuid \ No newline at end of file diff --git a/dmp-db-scema/updates/04/Funder_add_column_CreationUser.sql b/dmp-db-scema/updates/04/Funder_add_column_CreationUser.sql deleted file mode 100644 index 7c84eb69f..000000000 --- a/dmp-db-scema/updates/04/Funder_add_column_CreationUser.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "Funder" -ADD COLUMN "CreationUser" uuid \ No newline at end of file diff --git a/dmp-db-scema/updates/04/Researcher_add_column_CreationUser.sql b/dmp-db-scema/updates/04/Researcher_add_column_CreationUser.sql deleted file mode 100644 index 55b7a4542..000000000 --- a/dmp-db-scema/updates/04/Researcher_add_column_CreationUser.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "Researcher" -ADD COLUMN "CreationUser" uuid \ No newline at end of file diff --git a/dmp-db-scema/updates/05/External_References_Reference_Prefix_Update.sql b/dmp-db-scema/updates/05/01_External_References_Reference_Prefix_Update.sql similarity index 100% rename from dmp-db-scema/updates/05/External_References_Reference_Prefix_Update.sql rename to dmp-db-scema/updates/05/01_External_References_Reference_Prefix_Update.sql diff --git a/dmp-db-scema/updates/05/Grant_Funder_Project_Reference_Prefix_Update.sql b/dmp-db-scema/updates/05/02_Grant_Funder_Project_Reference_Prefix_Update.sql similarity index 100% rename from dmp-db-scema/updates/05/Grant_Funder_Project_Reference_Prefix_Update.sql rename to dmp-db-scema/updates/05/02_Grant_Funder_Project_Reference_Prefix_Update.sql diff --git a/dmp-db-scema/updates/06/04_Update_Researcher_Reference_First_Character_To_Lower_Where_Capital.sql b/dmp-db-scema/updates/06/04_Update_Researcher_Reference_First_Character_To_Lower_Where_Capital.sql deleted file mode 100644 index 8c3bcc984..000000000 --- a/dmp-db-scema/updates/06/04_Update_Researcher_Reference_First_Character_To_Lower_Where_Capital.sql +++ /dev/null @@ -1,6 +0,0 @@ -UPDATE "Researcher" -SET "Reference" = CONCAT(LOWER(LEFT("Reference", 1)), SUBSTRING("Reference", 2)) -WHERE "ID" in ( - SELECT "ID" FROM "Researcher" - WHERE ASCII(LEFT("Reference", 1)) BETWEEN ASCII('A') AND ASCII('Z') -) \ No newline at end of file diff --git a/dmp-db-scema/updates/08/02_Add_missing_columns.sql b/dmp-db-scema/updates/08/02_Add_missing_columns.sql new file mode 100644 index 000000000..2cecd31cb --- /dev/null +++ b/dmp-db-scema/updates/08/02_Add_missing_columns.sql @@ -0,0 +1,23 @@ +ALTER TABLE public."DMP" +ADD COLUMN "DmpProperties" text; + +ALTER TABLE public."DMP" +ADD COLUMN "GroupId" uuid; + +ALTER TABLE public."DMP" +ADD COLUMN "Properties" text; + +ALTER TABLE public."DatasetProfile" +ADD COLUMN "GroupId" uuid; + +ALTER TABLE public."DatasetProfile" +ADD COLUMN "Version" integer; + +ALTER TABLE public."Grant" +ADD COLUMN "Type" numeric NOT NULL; + +ALTER TABLE public."DatasetDataRepository" +ADD COLUMN "Data" character varying; + +ALTER TABLE public."DatasetService" +ADD COLUMN "Data" character varying; \ No newline at end of file diff --git a/dmp-db-scema/updates/08/03_Create_Credentials.sql b/dmp-db-scema/updates/08/03_Create_Credentials.sql new file mode 100644 index 000000000..0ffbf0f46 --- /dev/null +++ b/dmp-db-scema/updates/08/03_Create_Credentials.sql @@ -0,0 +1,25 @@ +CREATE TABLE public."Credential" ( + "Id" uuid NOT NULL, + "Status" numeric NOT NULL, + "Provider" numeric NOT NULL, + "Public" character varying NOT NULL, + "Secret" character varying NOT NULL, + "CreationTime" timestamp(4) with time zone NOT NULL, + "LastUpdateTime" timestamp(4) with time zone NOT NULL, + "UserId" uuid NOT NULL, + "ExternalId" character varying NOT NULL +); + + +ALTER TABLE public."Credential" OWNER TO dmptool; + +ALTER TABLE ONLY public."Credential" + ADD CONSTRAINT "Credential_pkey" PRIMARY KEY ("Id"); + +ALTER TABLE ONLY public."Credential" + ADD CONSTRAINT fkey_credential_user FOREIGN KEY ("UserId") REFERENCES public."UserInfo"(id); + +INSERT INTO public."UserInfo"(email, authorization_level, usertype, name, created, additionalinfo) VALUES ('fake@email.org', 1, 1, :'ADMIN_USERNAME', now(), '{}'); + +INSERT INTO public."Credential" VALUES (uuid_generate_v4(), 0, 5, :'ADMIN_USERNAME', :'ADMIN_PASSWORD', now(), now(), (SELECT public."UserInfo"."id" FROM public."UserInfo" WHERE name = 'admin'), 'dmp'); + diff --git a/dmp-db-scema/updates/08/04_Create_UserToken.sql b/dmp-db-scema/updates/08/04_Create_UserToken.sql new file mode 100644 index 000000000..85ff8103a --- /dev/null +++ b/dmp-db-scema/updates/08/04_Create_UserToken.sql @@ -0,0 +1,16 @@ +CREATE TABLE public."UserToken" ( + "Token" uuid NOT NULL, + "UserId" uuid NOT NULL, + "IssuedAt" timestamp(4) with time zone NOT NULL, + "ExpiresAt" timestamp(4) with time zone NOT NULL +); + + +ALTER TABLE public."UserToken" OWNER TO dmptool; + +ALTER TABLE ONLY public."UserToken" + ADD CONSTRAINT "UserToken_pkey" PRIMARY KEY ("Token"); + +ALTER TABLE ONLY public."UserToken" + ADD CONSTRAINT fkey_usetoken_user FOREIGN KEY ("UserId") REFERENCES public."UserInfo"(id); + diff --git a/dmp-db-scema/updates/08/05_Create_UserRole.sql b/dmp-db-scema/updates/08/05_Create_UserRole.sql new file mode 100644 index 000000000..0db9f39d0 --- /dev/null +++ b/dmp-db-scema/updates/08/05_Create_UserRole.sql @@ -0,0 +1,18 @@ +CREATE TABLE public."UserRole" ( + "Id" uuid DEFAULT public.uuid_generate_v4() NOT NULL, + "Role" numeric DEFAULT 0 NOT NULL, + "UserId" uuid NOT NULL +); + + +ALTER TABLE public."UserRole" OWNER TO dmptool; + +ALTER TABLE ONLY public."UserRole" + ADD CONSTRAINT "UserRole_pkey" PRIMARY KEY ("Id"); + +ALTER TABLE ONLY public."UserRole" + ADD CONSTRAINT "UserRole_userId_fkey" FOREIGN KEY ("UserId") REFERENCES public."UserInfo"(id); + + +INSERT INTO public."UserRole"("Role", "UserId") VALUES (2, (SELECT public."UserInfo"."id" FROM public."UserInfo" WHERE name = 'admin')); + diff --git a/dmp-db-scema/updates/08/06_Remove_UserAuth.sql b/dmp-db-scema/updates/08/06_Remove_UserAuth.sql new file mode 100644 index 000000000..5ed59655c --- /dev/null +++ b/dmp-db-scema/updates/08/06_Remove_UserAuth.sql @@ -0,0 +1 @@ +DROP TABLE IF EXISTS "UserAuth" CASCADE; \ No newline at end of file diff --git a/dmp-db-scema/updates/08/07_Remove_no_null_requirement.sql b/dmp-db-scema/updates/08/07_Remove_no_null_requirement.sql new file mode 100644 index 000000000..8cda5cf9c --- /dev/null +++ b/dmp-db-scema/updates/08/07_Remove_no_null_requirement.sql @@ -0,0 +1,2 @@ +AlTER TABLE "DMP" +ALTER COLUMN "Creator" DROP NOT NULL; \ No newline at end of file diff --git a/dmp-db-scema/updates/08/08_create_datasetexternaldataset.sql b/dmp-db-scema/updates/08/08_create_datasetexternaldataset.sql new file mode 100644 index 000000000..76e84fe22 --- /dev/null +++ b/dmp-db-scema/updates/08/08_create_datasetexternaldataset.sql @@ -0,0 +1,19 @@ +CREATE TABLE public."DatasetExternalDataset" ( + "Id" uuid DEFAULT public.uuid_generate_v4() NOT NULL, + "Dataset" uuid NOT NULL, + "ExternalDataset" uuid NOT NULL, + "Role" numeric, + "Data" character varying +); + +ALTER TABLE public."DatasetExternalDataset" OWNER TO dmptool; + +ALTER TABLE ONLY public."DatasetExternalDataset" + ADD CONSTRAINT "DatasetExternalDataset_pkey" PRIMARY KEY ("Id"); + +ALTER TABLE ONLY public."DatasetExternalDataset" + ADD CONSTRAINT fkey_datasetexternaldataset_dataset FOREIGN KEY ("Dataset") REFERENCES public."Dataset"("ID"); + +ALTER TABLE ONLY public."DatasetExternalDataset" + ADD CONSTRAINT fkey_datasetexternaldataset_externaldataset FOREIGN KEY ("ExternalDataset") REFERENCES public."ExternalDataset"("Id"); + diff --git a/dmp-db-scema/updates/08/09_Create_Invitation.sql b/dmp-db-scema/updates/08/09_Create_Invitation.sql new file mode 100644 index 000000000..c820248b1 --- /dev/null +++ b/dmp-db-scema/updates/08/09_Create_Invitation.sql @@ -0,0 +1,23 @@ +CREATE TABLE public."Invitation" ( + "Id" uuid NOT NULL, + "InvitationEmail" character varying NOT NULL, + "Token" uuid NOT NULL, + "CreationUser" uuid NOT NULL, + "Dmp" uuid NOT NULL, + "Properties" xml, + "AcceptedInvitation" boolean +); + + +ALTER TABLE public."Invitation" OWNER TO dmptool; + +ALTER TABLE ONLY public."Invitation" + ADD CONSTRAINT "Invitation_pkey" PRIMARY KEY ("Id"); + + +ALTER TABLE ONLY public."Invitation" + ADD CONSTRAINT fk_invitation_creator FOREIGN KEY ("CreationUser") REFERENCES public."UserInfo"(id); + + +ALTER TABLE ONLY public."Invitation" + ADD CONSTRAINT fk_invitation_dmp FOREIGN KEY ("Dmp") REFERENCES public."DMP"("ID"); \ No newline at end of file diff --git a/dmp-db-scema/updates/08/10_Create_User_preference.sql b/dmp-db-scema/updates/08/10_Create_User_preference.sql new file mode 100644 index 000000000..edae5bb93 --- /dev/null +++ b/dmp-db-scema/updates/08/10_Create_User_preference.sql @@ -0,0 +1,16 @@ +CREATE TABLE public."UserPreference" ( + "Id" uuid NOT NULL, + "UserId" uuid NOT NULL, + "Data" json NOT NULL, + "PreferenceType" smallint NOT NULL +); + + +ALTER TABLE public."UserPreference" OWNER TO dmptool; + +ALTER TABLE ONLY public."UserPreference" + ADD CONSTRAINT "UserPreference_pkey" PRIMARY KEY ("Id"); + + +ALTER TABLE ONLY public."UserPreference" + ADD CONSTRAINT userpreference_user_fk FOREIGN KEY ("UserId") REFERENCES public."UserInfo"(id); diff --git a/dmp-db-scema/updates/09/01_create_user_association.sql b/dmp-db-scema/updates/09/01_create_user_association.sql new file mode 100644 index 000000000..c569ca2fe --- /dev/null +++ b/dmp-db-scema/updates/09/01_create_user_association.sql @@ -0,0 +1,21 @@ +CREATE TABLE public."UserAssociation" ( + id uuid NOT NULL, + "firstUser" uuid NOT NULL, + "secondUser" uuid NOT NULL +); + + +ALTER TABLE public."UserAssociation" OWNER TO dmptool; + +ALTER TABLE ONLY public."UserAssociation" + ADD CONSTRAINT pk_user_association PRIMARY KEY (id); + +ALTER TABLE ONLY public."UserAssociation" + ADD CONSTRAINT fk_userinfo_user_association_1 FOREIGN KEY ("firstUser") REFERENCES public."UserInfo"(id); + +ALTER TABLE ONLY public."UserAssociation" + ADD CONSTRAINT fk_userinfo_user_association_2 FOREIGN KEY ("secondUser") REFERENCES public."UserInfo"(id); + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.002', '2020-05-04 13:42:00.000000+03', now(), 'Add User Association'); + + diff --git a/dmp-db-scema/updates/09/02_doifunder.sql b/dmp-db-scema/updates/09/02_doifunder.sql new file mode 100644 index 000000000..cb6742516 --- /dev/null +++ b/dmp-db-scema/updates/09/02_doifunder.sql @@ -0,0 +1,24 @@ +CREATE TABLE public."DoiFunder" ( + id uuid DEFAULT public.uuid_generate_v4() NOT NULL, + name character varying, + doi character varying +); + + +ALTER TABLE ONLY public."DoiFunder" + ADD CONSTRAINT "DoiFunder_pkey" PRIMARY KEY (id); + +ALTER TABLE public."DoiFunder" OWNER TO dmptool; + +INSERT INTO public."DoiFunder"(name, doi) VALUES ('Australian Research Council', '10.13039/501100000923'); +INSERT INTO public."DoiFunder"(name, doi) VALUES ('European Commission', '10.13039/501100000780'); +INSERT INTO public."DoiFunder"(name, doi) VALUES ('Fundação para a Ciência e a Tecnologia', '10.13039/501100001871'); +INSERT INTO public."DoiFunder"(name, doi) VALUES ('Ministarstvo Prosvete, Nauke i Tehnološkog Razvoja', '10.13039/501100004564'); +INSERT INTO public."DoiFunder"(name, doi) VALUES ('Ministarstvo Znanosti, Obrazovanja i Sporta', '10.13039/501100006588'); +INSERT INTO public."DoiFunder"(name, doi) VALUES ('National Health and Medical Research Council', '10.13039/501100000925'); +INSERT INTO public."DoiFunder"(name, doi) VALUES ('National Science Foundation','10.13039/100000001'); +INSERT INTO public."DoiFunder"(name, doi) VALUES ('Nederlandse Organisatie voor Wetenschappelijk Onderzoek', '10.13039/501100003246'); +INSERT INTO public."DoiFunder"(name, doi) VALUES ('Wellcome Trust', '10.13039/100004440'); + + + diff --git a/dmp-frontend/Dockerfile b/dmp-frontend/Dockerfile index a1aaa80d3..5e6fe52b2 100644 --- a/dmp-frontend/Dockerfile +++ b/dmp-frontend/Dockerfile @@ -1,17 +1,32 @@ -FROM johnpapa/angular-cli as angular -WORKDIR /app -COPY package.json /app/ -RUN npm cache clear --force && npm install +# stage1 as builder +FROM node:12-alpine as builder -COPY ./ /app/ -ARG env=dev -ARG aot=--no-aot -RUN echo $env -RUN echo $aot -RUN if [ "$env" = "prod" ]; then ng build --$env --$aot; else ng build --$aot; fi +WORKDIR /page -# Stage 1, based on Nginx, to have only the compiled app, ready for production with Nginx -FROM nginx:1.13 -COPY --from=angular /app/dist/ /usr/share/nginx/html -COPY --from=angular /app/static/ /usr/share/nginx/static -COPY ./nginx-custom.conf /etc/nginx/conf.d/default.conf +# copy the package.json to install dependencies +COPY package.json /page + +# Install the dependencies and make the folder +RUN npm install + +COPY . /page + +# Build the project and copy the files +RUN npm run ng build -- --deploy-url=/ --prod + +FROM nginx:alpine + +#!/bin/sh + +COPY nginx.conf /etc/nginx +COPY mime.types /etc/nginx + +## Remove default nginx index page +RUN rm -rf /usr/share/nginx/html/* + +# Copy from the stahg 1 +COPY --from=builder /page/dist /usr/share/nginx/html + +EXPOSE 4200 + +ENTRYPOINT ["nginx", "-g", "daemon off;", "-p", "/usr/share/nginx"] diff --git a/dmp-frontend/mime.types b/dmp-frontend/mime.types new file mode 100644 index 000000000..62bd4b668 --- /dev/null +++ b/dmp-frontend/mime.types @@ -0,0 +1,48 @@ +types { + text/html html htm shtml; + text/css css; + text/xml xml rss; + image/gif gif; + image/jpeg jpeg jpg; + application/x-javascript js; + text/plain txt; + text/x-component htc; + text/mathml mml; + image/png png; + image/x-icon ico; + image/x-jng jng; + image/vnd.wap.wbmp wbmp; + application/java-archive jar war ear; + application/mac-binhex40 hqx; + application/pdf pdf; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/zip zip; + application/octet-stream deb; + application/octet-stream bin exe dll; + application/octet-stream dmg; + application/octet-stream eot; + application/octet-stream iso img; + application/octet-stream msi msp msm; + audio/mpeg mp3; + audio/x-realaudio ra; + video/mpeg mpeg mpg; + video/quicktime mov; + video/x-flv flv; + video/x-msvideo avi; + video/x-ms-wmv wmv; + video/x-ms-asf asx asf; + video/x-mng mng; +} \ No newline at end of file diff --git a/dmp-frontend/nginx.conf b/dmp-frontend/nginx.conf new file mode 100644 index 000000000..7b29b4cb8 --- /dev/null +++ b/dmp-frontend/nginx.conf @@ -0,0 +1,35 @@ + +events { + worker_connections 4096; ## Default: 1024 +} + +http { + include ./mime.types; + server { + + listen 4200; + + sendfile on; + + gzip on; + gzip_http_version 1.1; + gzip_disable "MSIE [1-6]\."; + gzip_min_length 1100; + gzip_vary on; + gzip_proxied expired no-cache no-store private auth; + gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript; + gzip_comp_level 9; + + + + + + location / { + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html =404; + add_header Cache-Control "no-store, no-cache, must-revalidate"; + } + + } + +} diff --git a/dmp-frontend/src/app/core/model/dmp/dmp.ts b/dmp-frontend/src/app/core/model/dmp/dmp.ts index 721c42608..15f226b0a 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp.ts @@ -1,4 +1,4 @@ -import { Status } from "../../common/enum/Status"; +import { Status } from "../../common/enum/status"; import { DmpProfile, DmpProfileDefinition } from "../dmp-profile/dmp-profile"; import { OrganizationModel } from "../organisation/organization"; import { GrantListingModel } from "../grant/grant-listing"; diff --git a/dmp-frontend/src/app/core/model/funder/funder.ts b/dmp-frontend/src/app/core/model/funder/funder.ts index 8a0046dfb..a266d90ea 100644 --- a/dmp-frontend/src/app/core/model/funder/funder.ts +++ b/dmp-frontend/src/app/core/model/funder/funder.ts @@ -1,4 +1,4 @@ -import { Status } from "../../common/enum/Status"; +import { Status } from "../../common/enum/status"; export class FunderModel { id: string; diff --git a/dmp-frontend/src/app/core/model/grant/grant-listing.ts b/dmp-frontend/src/app/core/model/grant/grant-listing.ts index 9573ae4b6..d6d2fba85 100644 --- a/dmp-frontend/src/app/core/model/grant/grant-listing.ts +++ b/dmp-frontend/src/app/core/model/grant/grant-listing.ts @@ -1,6 +1,6 @@ import { UrlListingItem } from "../../../library/url-listing/url-listing-item"; import { GrantType } from '../../common/enum/grant-type'; -import { Status } from '../../common/enum/Status'; +import { Status } from '../../common/enum/status'; export interface GrantListingModel { id?: string; diff --git a/dmp-frontend/src/app/core/model/organisation/organization.ts b/dmp-frontend/src/app/core/model/organisation/organization.ts index 5fd54c7ab..9cdc13e05 100644 --- a/dmp-frontend/src/app/core/model/organisation/organization.ts +++ b/dmp-frontend/src/app/core/model/organisation/organization.ts @@ -1,4 +1,4 @@ -import { Status } from "../../common/enum/Status"; +import { Status } from "../../common/enum/status"; export interface OrganizationModel { id: string; diff --git a/dmp-frontend/src/app/core/model/project/project.ts b/dmp-frontend/src/app/core/model/project/project.ts index 6f401f312..bd467a575 100644 --- a/dmp-frontend/src/app/core/model/project/project.ts +++ b/dmp-frontend/src/app/core/model/project/project.ts @@ -1,4 +1,4 @@ -import { Status } from "../../common/enum/Status"; +import { Status } from "../../common/enum/status"; import { UrlListingItem } from "../../../library/url-listing/url-listing-item"; import { ProjectType } from "../../common/enum/project-type"; diff --git a/dmp-frontend/src/app/core/services/auth/auth.service.ts b/dmp-frontend/src/app/core/services/auth/auth.service.ts index a50261ba0..9b61514c4 100644 --- a/dmp-frontend/src/app/core/services/auth/auth.service.ts +++ b/dmp-frontend/src/app/core/services/auth/auth.service.ts @@ -5,7 +5,7 @@ import { MatSnackBar } from '@angular/material/snack-bar'; import { Router } from '@angular/router'; import { Credential } from '@app/core/model/auth/credential'; import { LoginInfo } from '@app/core/model/auth/login-info'; -import { Principal } from '@app/core/model/auth/Principal'; +import { Principal } from '@app/core/model/auth/principal'; import { ConfigurableProvider } from '@app/core/model/configurable-provider/configurableProvider'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { BaseService } from '@common/base/base.service'; diff --git a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts index e95d87773..8ede16604 100644 --- a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts +++ b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts @@ -57,6 +57,16 @@ export class ConfigurationService extends BaseComponent { return this._guideAssets; } + private _allowOrganizationCreator: boolean; + get allowOrganizationCreator():boolean { + return this._allowOrganizationCreator; + } + + private _doiLink: string; + get doiLink(): string { + return this._doiLink; + } + public loadConfiguration(): Promise { return new Promise((r, e) => { @@ -92,6 +102,8 @@ export class ConfigurationService extends BaseComponent { this._logging = Logging.parseValue(config.logging); this._lockInterval = config.lockInterval; this._guideAssets = config.guideAssets; + this._allowOrganizationCreator = config.allowOrganizationCreator; + this._doiLink = config.doiLink; } } diff --git a/dmp-frontend/src/app/core/services/lock/lock.service.ts b/dmp-frontend/src/app/core/services/lock/lock.service.ts index a816163e5..3404f1cc0 100644 --- a/dmp-frontend/src/app/core/services/lock/lock.service.ts +++ b/dmp-frontend/src/app/core/services/lock/lock.service.ts @@ -17,18 +17,18 @@ export class LockService { } checkLockStatus(id: string): Observable { - return this.http.get(`${this.actionUrl}target/status/${id}`, {headers: this.headers}); + return this.http.get(`${this.actionUrl}target/status/${id}`, { headers: this.headers }); } unlockTarget(id: string): Observable { - return this.http.delete(`${this.actionUrl}target/unlock/${id}`, {headers: this.headers}); + return this.http.delete(`${this.actionUrl}target/unlock/${id}`, { headers: this.headers }); } getSingle(id: string): Observable { - return this.http.get(`${this.actionUrl}target/${id}`, {headers: this.headers}); + return this.http.get(`${this.actionUrl}target/${id}`, { headers: this.headers }); } createOrUpdate(lock: LockModel): Observable { - return this.http.post(`${this.actionUrl}`, lock, {headers: this.headers}); + return this.http.post(`${this.actionUrl}`, lock, { headers: this.headers }); } } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/dataset-profile.module.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/dataset-profile.module.ts index 1e7c9eb19..af103eebc 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/dataset-profile.module.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/dataset-profile.module.ts @@ -27,6 +27,7 @@ import { DialodConfirmationUploadDatasetProfiles } from '@app/ui/admin/dataset-p import { DatasetProfileListingComponent } from '@app/ui/admin/dataset-profile/listing/dataset-profile-listing.component'; import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; +import { ParseStatus } from './listing/pipe/parse-status.pipe'; @NgModule({ imports: [ @@ -59,7 +60,8 @@ import { CommonUiModule } from '@common/ui/common-ui.module'; DatasetProfileEditorInternalDmpEntitiesFieldComponent, DatasetProfileEditorResearchersAutoCompleteFieldComponent, DatasetProfileEditorDatasetsAutoCompleteFieldComponent, - DatasetProfileEditorDmpsAutoCompleteFieldComponent + DatasetProfileEditorDmpsAutoCompleteFieldComponent, + ParseStatus ], entryComponents: [ DialodConfirmationUploadDatasetProfiles diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component.html index 8026e4251..c303267ef 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dataset-profile.component.html @@ -5,6 +5,13 @@ + + + {{'DATASET-PROFILE-STATUS.NONE' | translate}} + {{'DATASET-PROFILE-STATUS.DRAFT' | translate}} + {{'DATASET-PROFILE-STATUS.FINALIZED' | translate}} + +
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html index 44a5c5adf..b0e01d2c1 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html @@ -27,6 +27,13 @@ {{row.created | date:'shortDate'}} + + + {{'DATASET-PROFILE-LISTING.COLUMNS.STATUS' | + translate}} + {{ (row.status | parseStatus) | translate}} + + {{'DATASET-PROFILE-LISTING.COLUMNS.ACTIONS' | translate}} diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts index 8f903dedd..230ebf16f 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts @@ -30,7 +30,7 @@ export class DatasetProfileListingComponent extends BaseComponent implements OnI breadCrumbs: Observable; dataSource: DatasetDataSource | null; - displayedColumns: String[] = ['label', 'description', 'created', 'actions']; + displayedColumns: String[] = ['label', 'description', 'created', 'status', 'actions']; pageEvent: PageEvent; titlePrefix: String; dmpId: String; diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/pipe/parse-status.pipe.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/pipe/parse-status.pipe.ts new file mode 100644 index 000000000..33cbd4b8c --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/pipe/parse-status.pipe.ts @@ -0,0 +1,16 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'parseStatus', + pure: true +}) +export class ParseStatus implements PipeTransform { + transform(value: any, ...args: any[]) { + return this.parseStatus(value); + } + + + parseStatus(status: number): string { + return status != 0 ? 'DATASET-PROFILE-STATUS.FINALIZED' : 'DATASET-PROFILE-STATUS.DRAFT'; + } +} diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts index 6e9b89b8b..bff497006 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts @@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material'; import { Router } from '@angular/router'; import { RecentActivityType } from '@app/core/common/enum/recent-activity-type'; -import { Principal } from '@app/core/model/auth/Principal'; +import { Principal } from '@app/core/model/auth/principal'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; import { DmpListingModel } from '@app/core/model/dmp/dmp-listing'; import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria'; @@ -10,7 +10,7 @@ import { AuthService } from '@app/core/services/auth/auth.service'; import { DmpService } from '@app/core/services/dmp/dmp.service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; -import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { BaseComponent } from '@common/base/base.component'; import { TranslateService } from '@ngx-translate/core'; import * as FileSaver from 'file-saver'; diff --git a/dmp-frontend/src/app/ui/dmp/dmp.module.ts b/dmp-frontend/src/app/ui/dmp/dmp.module.ts index 0f72ed78f..d331894da 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.module.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.module.ts @@ -31,6 +31,7 @@ import { CommonFormsModule } from '@common/forms/common-forms.module'; import { FormValidationErrorsDialogModule } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; import { MultipleChoiceDialogModule } from '@common/modules/multiple-choice-dialog/multiple-choice-dialog.module'; +import { AddOrganizationComponent } from './editor/add-organization/add-organization.component'; @NgModule({ imports: [ @@ -67,14 +68,16 @@ import { MultipleChoiceDialogModule } from '@common/modules/multiple-choice-dial PeopleTabComponent, GrantTabComponent, DatasetsTabComponent, - DmpCloneComponent + DmpCloneComponent, + AddOrganizationComponent ], entryComponents: [ DmpInvitationDialogComponent, AddResearcherComponent, AvailableProfilesComponent, DmpFinalizeDialogComponent, - DmpUploadDialogue + DmpUploadDialogue, + AddOrganizationComponent ] }) export class DmpModule { } diff --git a/dmp-frontend/src/app/ui/dmp/editor/add-organization/add-organization.component.html b/dmp-frontend/src/app/ui/dmp/editor/add-organization/add-organization.component.html new file mode 100644 index 000000000..382d9d04d --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/add-organization/add-organization.component.html @@ -0,0 +1,19 @@ +
+

{{'ADDORGANIZATION-EDITOR.TITLE' | translate}}

+
+ + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + +
+
+
+
+
+
+
+
diff --git a/dmp-frontend/src/app/ui/dmp/editor/add-organization/add-organization.component.ts b/dmp-frontend/src/app/ui/dmp/editor/add-organization/add-organization.component.ts new file mode 100644 index 000000000..517cb2158 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/add-organization/add-organization.component.ts @@ -0,0 +1,43 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { ExternalResearcherService } from '@app/core/services/external-sources/researcher/external-researcher.service'; +import { BaseComponent } from '@common/base/base.component'; +import { takeUntil } from 'rxjs/operators'; +import { OrganizationEditorModel } from './add-organization.model'; + +@Component({ + selector: 'app-add-organization-component', + templateUrl: 'add-organization.component.html', +}) +export class AddOrganizationComponent extends BaseComponent implements OnInit { + + public formGroup: FormGroup; + + constructor( + private externalResearcherService: ExternalResearcherService, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) { super(); } + + ngOnInit(): void { + const researcher = new OrganizationEditorModel(); + this.formGroup = researcher.buildForm(); + } + + send(value: any) { + this.externalResearcherService.createResearcher(this.formGroup.value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + null, null, () => this.dialogRef.close() + ); + } + + addOrganization() { + this.dialogRef.close(this.formGroup.value); + } + + isFormValid() { + return this.formGroup.valid; + } +} diff --git a/dmp-frontend/src/app/ui/dmp/editor/add-organization/add-organization.model.ts b/dmp-frontend/src/app/ui/dmp/editor/add-organization/add-organization.model.ts new file mode 100644 index 000000000..444b3ae7c --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/add-organization/add-organization.model.ts @@ -0,0 +1,33 @@ +import { FormBuilder, FormGroup } from '@angular/forms'; +import { ResearcherModel } from '@app/core/model/researcher/researcher'; +import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; +import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { ValidationContext } from '@common/forms/validation/validation-context'; +import { OrganizationModel } from '@app/core/model/organisation/organization'; + +export class OrganizationEditorModel { + public id: String; + public name: String; + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + + fromModel(item: OrganizationModel): OrganizationEditorModel { + this.id = item.id; + this.name = item.name; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } + const formGroup = new FormBuilder().group({ + name: [{ value: this.name, disabled: disabled }, context.getValidation('name').validators] + }); + + return formGroup; + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'name', validators: [BackendErrorValidator(this.validationErrorModel, 'name')] }); + return baseContext; + } +} diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts index 889b303b5..1a03c4a27 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts @@ -34,7 +34,7 @@ import { TranslateService } from '@ngx-translate/core'; import * as FileSaver from 'file-saver'; import { Observable, of as observableOf, interval } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; -import { Principal } from "@app/core/model/auth/Principal"; +import { Principal } from "@app/core/model/auth/principal"; import { Role } from "@app/core/common/enum/role"; import { LockService } from '@app/core/services/lock/lock.service'; import { Location } from '@angular/common'; @@ -109,7 +109,7 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC // displayFn: (item) => item['label'], // titleFn: (item) => item['label'] // }; - switch(tabToNav) { + switch (tabToNav) { case 'general': this.selectedTab = 0; break; @@ -130,52 +130,52 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC .subscribe(async data => { this.lockService.checkLockStatus(data.id).pipe(takeUntil(this._destroyed)).subscribe(lockStatus => { this.lockStatus = lockStatus; - this.dmp = new DmpEditorModel(); - this.dmp.grant = new GrantTabModel(); - this.dmp.project = new ProjectFormModel(); - this.dmp.funder = new FunderFormModel(); - this.dmp.fromModel(data); - this.formGroup = this.dmp.buildForm(); - this.setIsUserOwner(); - if (!this.isUserOwner) { - this.isFinalized = true; - this.formGroup.disable(); - } + this.dmp = new DmpEditorModel(); + this.dmp.grant = new GrantTabModel(); + this.dmp.project = new ProjectFormModel(); + this.dmp.funder = new FunderFormModel(); + this.dmp.fromModel(data); + this.formGroup = this.dmp.buildForm(); + this.setIsUserOwner(); + if (!this.isUserOwner) { + this.isFinalized = true; + this.formGroup.disable(); + } - //this.registerFormEventsForDmpProfile(this.dmp.definition); - if (!this.editMode || this.dmp.status === DmpStatus.Finalized || lockStatus) { - this.isFinalized = true; - this.formGroup.disable(); - } + //this.registerFormEventsForDmpProfile(this.dmp.definition); + if (!this.editMode || this.dmp.status === DmpStatus.Finalized || lockStatus) { + this.isFinalized = true; + this.formGroup.disable(); + } - if (this.isAuthenticated) { - if (!lockStatus) { - this.lock = new LockModel(data.id, this.getUserFromDMP()); + if (this.isAuthenticated) { + if (!lockStatus) { + this.lock = new LockModel(data.id, this.getUserFromDMP()); - this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => { - this.lock.id = Guid.parse(result); - interval(this.configurationService.lockInterval).pipe(takeUntil(this._destroyed)).subscribe(() => this.pumpLock()); + this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => { + this.lock.id = Guid.parse(result); + interval(this.configurationService.lockInterval).pipe(takeUntil(this._destroyed)).subscribe(() => this.pumpLock()); + }); + } + // if (!this.isAuthenticated) { + const breadCrumbs = []; + breadCrumbs.push({ + parentComponentName: null, + label: this.language.instant('NAV-BAR.MY-DMPS'), + url: "/plans" }); + breadCrumbs.push({ + parentComponentName: 'DmpListingComponent', + label: this.dmp.label, + url: '/plans/edit/' + this.dmp.id, + // notFoundResolver: [await this.grantService.getSingle(this.dmp.grant.id).map(x => ({ label: x.label, url: '/grants/edit/' + x.id }) as BreadcrumbItem).toPromise()] + } + ); + this.breadCrumbs = observableOf(breadCrumbs); } - // if (!this.isAuthenticated) { - const breadCrumbs = []; - breadCrumbs.push({ - parentComponentName: null, - label: this.language.instant('NAV-BAR.MY-DMPS'), - url: "/plans" - }); - breadCrumbs.push({ - parentComponentName: 'DmpListingComponent', - label: this.dmp.label, - url: '/plans/edit/' + this.dmp.id, - // notFoundResolver: [await this.grantService.getSingle(this.dmp.grant.id).map(x => ({ label: x.label, url: '/grants/edit/' + x.id }) as BreadcrumbItem).toPromise()] - } - ); - this.breadCrumbs = observableOf(breadCrumbs); - } - this.associatedUsers = data.associatedUsers; - this.people = data.users; - }) + this.associatedUsers = data.associatedUsers; + this.people = data.users; + }) }); } else if (publicId != null) { this.isNew = false; @@ -567,7 +567,7 @@ export class DmpEditorComponent extends BaseComponent implements OnInit, IBreadC private pumpLock() { this.lock.touchedAt = new Date(); - this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe( async result => this.lock.id = Guid.parse(result)); + this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => this.lock.id = Guid.parse(result)); } // advancedClicked() { diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html index a1090650e..620a27cb4 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.html @@ -46,6 +46,9 @@ {{'GENERAL.VALIDATION.REQUIRED' | translate}} {{'DMP-EDITOR.FIELDS.ORGANISATIONS-HINT' | translate}} +
diff --git a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts index 4330d7332..1435dfaef 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/general-tab/general-tab.component.ts @@ -20,6 +20,9 @@ import { BaseComponent } from '@common/base/base.component'; import { TranslateService } from '@ngx-translate/core'; import { Observable } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; +import { AddOrganizationComponent } from '../add-organization/add-organization.component'; +import { isNullOrUndefined } from 'util'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; @Component({ selector: 'app-general-tab', @@ -69,7 +72,8 @@ export class GeneralTabComponent extends BaseComponent implements OnInit { private externalSourcesService: ExternalSourcesService, private _service: DmpService, private dialog: MatDialog, - private language: TranslateService + private language: TranslateService, + private configurationService: ConfigurationService ) { super(); } @@ -170,6 +174,40 @@ export class GeneralTabComponent extends BaseComponent implements OnInit { }); } + addOrganization(event: MouseEvent) { + event.stopPropagation(); + const dialogRef = this.dialog.open(AddOrganizationComponent, { + data: this.formGroup.get('organisations') + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + const fullName = result.name; + const newItem = { + label: null, + name: fullName, + id: null, + status: 0, + key: "Internal", + }; + const organizationsArray = this.formGroup.get('organisations').value || []; + organizationsArray.push(newItem); + this.formGroup.get('organisations').setValue(organizationsArray); + } + }); + } + + showOrganizationCreator(): boolean { + return this.configurationService.allowOrganizationCreator; + } + + canAddOrganizations(): boolean { + if (!isNullOrUndefined(this.formGroup.get('organizations'))) { + return this.formGroup.get('organiztions').disabled; + } else { + return false; + } + } + availableProfiles(event: MouseEvent) { event.stopPropagation(); const dialogRef = this.dialog.open(AvailableProfilesComponent, { diff --git a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/funder-form-model.ts b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/funder-form-model.ts index 76adf4e24..4ad0c6e7d 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/funder-form-model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/funder-form-model.ts @@ -1,5 +1,5 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Status } from '@app/core/common/enum/Status'; +import { Status } from '@app/core/common/enum/status'; import { FunderModel } from '@app/core/model/funder/funder'; import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; diff --git a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/grant-tab-model.ts b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/grant-tab-model.ts index afba9fce2..4c01cfbfc 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/grant-tab-model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/grant-tab-model.ts @@ -1,5 +1,5 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Status } from '@app/core/common/enum/Status'; +import { Status } from '@app/core/common/enum/status'; import { GrantListingModel } from '@app/core/model/grant/grant-listing'; import { ValidJsonValidator } from '@app/library/auto-complete/auto-complete-custom-validator'; import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; diff --git a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/project-form-model.ts b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/project-form-model.ts index 797dfee69..826221b30 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/project-form-model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/project-form-model.ts @@ -1,5 +1,5 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Status } from '@app/core/common/enum/Status'; +import { Status } from '@app/core/common/enum/status'; import { ProjectModel } from '@app/core/model/project/project'; import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; diff --git a/dmp-frontend/src/app/ui/dmp/editor/people-tab/people-tab.component.ts b/dmp-frontend/src/app/ui/dmp/editor/people-tab/people-tab.component.ts index 1c303c446..e5f6b992c 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/people-tab/people-tab.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/people-tab/people-tab.component.ts @@ -3,7 +3,7 @@ import { FormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { TranslateService } from '@ngx-translate/core'; -import { Principal } from '../../../../core/model/auth/Principal'; +import { Principal } from '../../../../core/model/auth/principal'; import { UserInfoListingModel } from '../../../../core/model/user/user-info-listing'; import { AuthService } from '../../../../core/services/auth/auth.service'; import { DmpService } from '../../../../core/services/dmp/dmp.service'; diff --git a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts index 77f63bd4d..0f20ccc2d 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts @@ -5,7 +5,7 @@ import { DmpInvitationDialogComponent } from '../../invitation/dmp-invitation.co import { Router, ActivatedRoute } from '@angular/router'; import { DatasetService } from '../../../../core/services/dataset/dataset.service'; import { AuthService } from '../../../../core/services/auth/auth.service'; -import { Principal } from '../../../../core/model/auth/Principal'; +import { Principal } from '../../../../core/model/auth/principal'; import { TranslateService } from '@ngx-translate/core'; import { DmpStatus } from '../../../../core/common/enum/dmp-status'; diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html index cb45ad27f..5151ecd9b 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html @@ -71,7 +71,7 @@
- {{ 'DMP-EDITOR.TITLE.SUBTITLE' | translate }}: {{ dmp.doi }} + {{ 'DMP-EDITOR.TITLE.SUBTITLE' | translate }}: {{ dmp.doi }}
diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index 1bbe67bae..c363c8595 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -4,7 +4,7 @@ import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { DatasetStatus } from '@app/core/common/enum/dataset-status'; import { DmpStatus } from '@app/core/common/enum/dmp-status'; -import { Principal } from '@app/core/model/auth/Principal'; +import { Principal } from '@app/core/model/auth/principal'; import { DatasetOverviewModel } from '@app/core/model/dataset/dataset-overview'; import { DatasetsToBeFinalized } from '@app/core/model/dataset/datasets-toBeFinalized'; import { DmpOverviewModel } from '@app/core/model/dmp/dmp-overview'; @@ -106,10 +106,10 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { this.breadCrumbs = observableOf(breadCrumbs); }, (error: any) => { if (error.status === 404) { - return this.onFetchingDeletedCallbackError('/plans/'); + return this.onFetchingDeletedCallbackError('/explore-plans'); } if (error.status === 403) { - return this.onFetchingForbiddenCallbackError('/plans/'); + return this.onFetchingForbiddenCallbackError('/explore-plans'); } }); } @@ -357,7 +357,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { maxWidth: '600px', restoreFocus: false, data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ZENODO-DOI', { 'username': this.hasDOIToken ? this.authentication.current().zenodoEmail : 'default'}), + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ZENODO-DOI', { 'username': this.hasDOIToken ? this.authentication.current().zenodoEmail : 'default' }), confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), } @@ -522,6 +522,12 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { this.router.navigate(['/datasets/new/' + rowId]); } + createDoiLink(doi: string): string { + const doiarr = doi.split('.'); + const id = doiarr[doiarr.length - 1]; + return this.configurationService.doiLink + id; + } + // advancedClicked() { // const dialogRef = this.dialog.open(ExportMethodDialogComponent, { // maxWidth: '500px', diff --git a/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard-editor.model.ts b/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard-editor.model.ts index 4582e91e8..7edeacf8d 100644 --- a/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard-editor.model.ts +++ b/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard-editor.model.ts @@ -1,5 +1,5 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms"; -import { Status } from '@app/core/common/enum/Status'; +import { Status } from '@app/core/common/enum/status'; import { DmpProfile, DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile'; import { DmpModel } from '@app/core/model/dmp/dmp'; import { DmpDynamicField } from '@app/core/model/dmp/dmp-dynamic-field'; diff --git a/dmp-frontend/src/app/ui/explore-dmp/listing-item/explore-dmp-listing-item.component.ts b/dmp-frontend/src/app/ui/explore-dmp/listing-item/explore-dmp-listing-item.component.ts index 468b239d6..327bc33be 100644 --- a/dmp-frontend/src/app/ui/explore-dmp/listing-item/explore-dmp-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/explore-dmp/listing-item/explore-dmp-listing-item.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { DmpListingModel } from '../../../core/model/dmp/dmp-listing'; -import { Principal } from '../../../core/model/auth/Principal'; +import { Principal } from '../../../core/model/auth/principal'; import { AuthService } from '../../../core/services/auth/auth.service'; import { TranslateService } from '@ngx-translate/core'; import { Router, ActivatedRoute } from '@angular/router'; @@ -21,7 +21,7 @@ export class ExploreDmpListingItemComponent implements OnInit { private translate: TranslateService, private router: Router, private route: ActivatedRoute - ) { } + ) { } ngOnInit() { } diff --git a/dmp-frontend/src/app/ui/grant/editor/grant-editor.model.ts b/dmp-frontend/src/app/ui/grant/editor/grant-editor.model.ts index 8b783111c..28769e4a8 100644 --- a/dmp-frontend/src/app/ui/grant/editor/grant-editor.model.ts +++ b/dmp-frontend/src/app/ui/grant/editor/grant-editor.model.ts @@ -3,7 +3,7 @@ import { BackendErrorValidator } from '@common/forms/validation/custom-validator import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { ValidationContext } from '@common/forms/validation/validation-context'; import { GrantType } from '../../../core/common/enum/grant-type'; -import { Status } from '../../../core/common/enum/Status'; +import { Status } from '../../../core/common/enum/status'; import { ContentFile, GrantListingModel } from '../../../core/model/grant/grant-listing'; export class GrantEditorModel { diff --git a/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.ts b/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.ts index 326dd5280..21d7e79bc 100644 --- a/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.ts +++ b/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.ts @@ -2,7 +2,7 @@ import { Component, Inject, OnInit } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { Router } from '@angular/router'; -import { Principal } from '../../../../core/model/auth/Principal'; +import { Principal } from '../../../../core/model/auth/principal'; import { AuthService } from '../../../../core/services/auth/auth.service'; @Component({ diff --git a/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts b/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts index fa213f870..3ec776427 100644 --- a/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts +++ b/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts @@ -1,5 +1,5 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms'; -import { Status } from '@app/core/common/enum/Status'; +import { Status } from '@app/core/common/enum/status'; import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; import { DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile'; import { DmpModel } from '@app/core/model/dmp/dmp'; diff --git a/dmp-frontend/src/app/ui/quick-wizard/grant-editor/grant-editor-wizard-model.ts b/dmp-frontend/src/app/ui/quick-wizard/grant-editor/grant-editor-wizard-model.ts index b8f30cc6e..90cbdd8ae 100644 --- a/dmp-frontend/src/app/ui/quick-wizard/grant-editor/grant-editor-wizard-model.ts +++ b/dmp-frontend/src/app/ui/quick-wizard/grant-editor/grant-editor-wizard-model.ts @@ -1,5 +1,5 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms"; -import { Status } from '@app/core/common/enum/Status'; +import { Status } from '@app/core/common/enum/status'; import { GrantListingModel } from '@app/core/model/grant/grant-listing'; import { ValidJsonValidator } from '@app/library/auto-complete/auto-complete-custom-validator'; import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts index 9321cb07c..39335f81d 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts @@ -3,7 +3,7 @@ import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { AuthService } from '../../core/services/auth/auth.service'; import { UserDialogComponent } from '../misc/navigation/user-dialog/user-dialog.component'; -import { Principal } from '../../core/model/auth/Principal'; +import { Principal } from '../../core/model/auth/principal'; import { AppRole } from '../../core/common/enum/app-role'; import { Router } from '@angular/router'; import { Location } from '@angular/common'; @@ -51,8 +51,8 @@ export const ADMIN_ROUTES: RouteInfo[] = [ { path: '/dmp-profiles', title: 'SIDE-BAR.DMP-TEMPLATES', icon: 'library_books' }, { path: '/dataset-profiles', title: 'SIDE-BAR.DATASET-TEMPLATES', icon: 'library_books' }, { path: '/users', title: 'SIDE-BAR.USERS', icon: 'people' }, - { path: '/language-editor', title: 'SIDE-BAR.LANGUAGE-EDITOR', icon: 'language'}, - { path: '/user-guide-editor', title: 'SIDE-BAR.GUIDE-EDITOR', icon: 'import_contacts'} + { path: '/language-editor', title: 'SIDE-BAR.LANGUAGE-EDITOR', icon: 'language' }, + { path: '/user-guide-editor', title: 'SIDE-BAR.GUIDE-EDITOR', icon: 'import_contacts' } ]; // export const HISTORY_ROUTES: RouteInfo[] = [ // { path: '/typography', title: 'SIDE-BAR.HISTORY-VISITED', icon: 'visibility'}, diff --git a/dmp-frontend/src/assets/config/config.json b/dmp-frontend/src/assets/config/config.json index 1c32e5676..09730c8b9 100644 --- a/dmp-frontend/src/assets/config/config.json +++ b/dmp-frontend/src/assets/config/config.json @@ -1,6 +1,6 @@ { "production": false, - "Server": "http://localhost:8080/api/", + "Server": "http://localhost:8081/api/", "App": "http://localhost:4200/", "HelpService": { "Enabled": false, @@ -49,5 +49,7 @@ "logLevels": ["debug", "info", "warning", "error"] }, "lockInterval": 60000, - "guideAssets": "assets/images/guide" + "guideAssets": "assets/images/guide", + "allowOrganizationCreator": true, + "doiLink": "https://sandbox.zenodo.org/record/" } diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index d357a19b0..64210103d 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -128,7 +128,7 @@ "FILE-TYPES": { "PDF": "PDF", "XML": "XML", - "JSON": "JSON", + "JSON": "RDA JSON", "DOC": "Document" }, "LANGUAGES": { @@ -765,7 +765,8 @@ } }, "DATASET-PROFILE": { - "LIKE": "Search" + "LIKE": "Search", + "STATUS": "Status" }, "DATA-SETS": { "PERIOD-FROM": "Start", @@ -953,6 +954,14 @@ "CANCEL": "Cancel" } }, + "ADDORGANIZATION-EDITOR": { + "TITLE": "Add an Organization", + "NAME": "Name", + "ACTIONS": { + "SAVE": "Save", + "CANCEL": "Cancel" + } + }, "DMP-WIZARD": { "FIRST-STEP": { "DMP": "DMP Editor", @@ -1253,5 +1262,10 @@ } }, "HINT": "(Suggested Default Name)" + }, + "DATASET-PROFILE-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized" } } diff --git a/dmp-frontend/src/assets/i18n/es.json b/dmp-frontend/src/assets/i18n/es.json index 5716873cb..7db704b15 100644 --- a/dmp-frontend/src/assets/i18n/es.json +++ b/dmp-frontend/src/assets/i18n/es.json @@ -128,7 +128,7 @@ "FILE-TYPES": { "PDF": "PDF", "XML": "XML", - "JSON": "JSON", + "JSON": "RDA JSON", "DOC": "Documento" }, "LANGUAGES": { @@ -525,6 +525,10 @@ "ERROR": { "DELETED-DMP": "El PGD solicitado está borrado", "FORBIDEN-DMP": "You are not allowed to access this DMP" + }, + "MULTIPLE-DIALOG": { + "ZENODO-LOGIN": "Login with Zenodo", + "USE-DEFAULT": "Use Default Token" } }, "DATASET-LISTING": { @@ -825,7 +829,8 @@ "ACTIONS": { "SAVE": "Grabar", "CANCEL": "Cancelar", - "DELETE": "Borrar" + "DELETE": "Borrar", + "UPDATE": "Update" }, "VERSION-DIALOG": { "ABOUT": "Versionado es automático.", @@ -948,6 +953,14 @@ "CANCEL": "Cancelar" } }, + "ADDORGANIZATION-EDITOR": { + "TITLE": "Add an Organization", + "NAME": "Name", + "ACTIONS": { + "SAVE": "Save", + "CANCEL": "Cancel" + } + }, "DMP-WIZARD": { "FIRST-STEP": { "DMP": "Editor PGD", @@ -1086,6 +1099,12 @@ "SHOW-ALL": "Mostrar todo", "CREATOR": "Creador", "MEMBER": "Miembro" + }, + "ZENODO": { + "LOGIN": "Login to Zenodo", + "LOGOUT": "Remove Zenodo", + "TITLE": "Zenodo Account", + "DESCRIPTION": "Linked Zenodo Account:" } }, "DATASET-REFERENCED-MODELS": { diff --git a/docker-compose.yml b/docker-compose.yml index 1b94552b3..18412a920 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,212 +1,62 @@ ---- -version: '3' +version: "2.4" + services: - # The environment variable "TAG" is used throughout this file to - # specify the version of the images to run. The default is set in the - # '.env' file in this folder. It can be overridden with any normal - # technique for setting environment variables, for example: - # - # TAG=6.0.0-beta1 docker-compose up - # - # REF: https://docs.docker.com/compose/compose-file/#variable-substitution - # - # Also be sure to set the ELASTIC_VERSION variable. For released versions, - # ${TAG} and ${ELASTIC_VERSION} will be identical, but for pre-release - # versions, ${TAG} might contain an extra build identifier, like - # "6.0.0-beta1-3eab5b40", so a full invocation might look like: - # - # ELASTIC_VERSION=6.0.0-beta1 TAG=6.0.0-beta1-3eab5b40 docker-compose up - # - -##########################DMP###################################################################### + dmp-db: + image: postgres + container_name: opendmp-db + restart: unless-stopped + ports: + - "5001:5432" + expose: + - "5432" + volumes: + - dmpdata:/var/lib/postgresql/data + - ./dmp-db-scema:/docker-entrypoint-initdb.d/ + - ./dmp-db-scema/main:/main + - ./dmp-db-scema/updates:/updates + env_file: ./dmp-db-scema/Docker/dmp-db.env + networks: + - opendmp-backend-network dmp-backend: build: - context: ./dmp-backend - args: - PROFILE: ${PROFILE} - container_name: dmp-backend - ports: ['0.0.0.0:8080:8080'] - links: - # - logstash:logstash - - elasticsearch-dmp:elasticsearch-dmp - networks: ['stack','elasticsearch-dmp'] + context: ./dmp-backend + container_name: opendmp-backend + env_file: ./dmp-backend/Docker/dmp-backend.env + restart: unless-stopped + mem_limit: 2048m + ports: + - "8081:8081" + networks: + - opendmp-backend-network + volumes: + - ./openDMP/dmp-backend/config:/app/config + - ./openDMP/dmp-backend/user-guide:/app/user-guide + - ./openDMP/dmp-backend/i18n:/app/i18n + - ./openDMP/dmp-backend/externalUrls:/app/externalUrls + - ./openDMP/dmp-backend/templates:/app/templates + - ./openDMP/dmp-backend/opendmp-logs:/app/logs + - ./openDMP/dmp-backend/tmp:/app/tmp + - ./openDMP/dmp-backend/logging:/app/logging + - ./openDMP/dmp-backend/documents:/app/documents dmp-frontend: build: - context: ./dmp-frontend - args: - env: ${ENV} - aot: ${AOT} - container_name: dmp-frontend + context: ./dmp-frontend + container_name: opendmp-frontend + mem_limit: 2048m + restart: unless-stopped + ports: + - "8080:4200" volumes: - - ./static:/usr/share/nginx/static - - /srv/docker/wwwcert:/usr/share/nginx/wwwcert - ports: ['0.0.0.0:80:80'] - networks: ['stack'] - -##########################ELASTIC###################################################################### - elasticsearch-dmp: - image: docker.elastic.co/elasticsearch/elasticsearch:${TAG} - container_name: elasticsearch-dmp - volumes: - - ./elastic-config/elasticsearch-custom.yml:/usr/share/elasticsearch/config/elasticsearch.yml - environment: ['http.host=0.0.0.0','transport.host=0.0.0.0','discovery.type=single-node'] - ports: ['0.0.0.0:9201:9200','0.0.0.0:9301:9300'] - networks: ['elasticsearch-dmp'] - volumes: - - esdata-dmp:/usr/share/elasticsearch/data - -##########################ELK-STACK###################################################################### - - elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:${TAG} - container_name: elasticsearch - environment: ['http.host=0.0.0.0', 'transport.host=127.0.0.1', 'ELASTIC_PASSWORD=${ELASTIC_PASSWORD}','discovery.type=single-node'] - ports: ['0.0.0.0:9200:9200'] - networks: ['stack'] - volumes: - - esdata:/usr/share/elasticsearch/data - - kibana: - image: docker.elastic.co/kibana/kibana:${TAG} - container_name: kibana - ports: ['0.0.0.0:5601:5601'] - networks: ['stack'] - depends_on: ['elasticsearch'] - - logstash: - image: docker.elastic.co/logstash/logstash:${TAG} - container_name: logstash - volumes: - - ./ELK.Docker/config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf - ports: ['0.0.0.0:31311:31311'] - - networks: ['stack'] - depends_on: ['elasticsearch', 'setup_logstash'] - - #filebeat: - # image: docker.elastic.co/beats/filebeat:${TAG} - # container_name: filebeat - # command: -e -E 'output.elasticsearch.password=${ELASTIC_PASSWORD}' - # networks: ['stack'] - # depends_on: ['elasticsearch', 'setup_filebeat'] - - #heartbeat: - # image: docker.elastic.co/beats/heartbeat:${TAG} - # container_name: heartbeat - # command: -e -E 'output.elasticsearch.password=${ELASTIC_PASSWORD}' - # networks: ['stack'] - # depends_on: ['elasticsearch', 'setup_heartbeat'] - - # Run a short-lived container to set up Logstash. - setup_logstash: - image: centos:7 - container_name: setup_logstash - volumes: ['./ELK.Docker/scripts/setup-logstash.sh:/usr/local/bin/setup-logstash.sh:ro'] - command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-logstash.sh | tr -d "\r" | bash'] - environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] - networks: ['stack'] - depends_on: ['elasticsearch'] - - setup_kibana: - image: centos:7 - container_name: setup_kibana - volumes: ['./ELK.Docker/scripts/setup-kibana.sh:/usr/local/bin/setup-kibana.sh:ro'] - command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-kibana.sh | tr -d "\r" | bash'] - environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] - networks: ['stack'] - depends_on: ['elasticsearch'] - - #setup_filebeat: - # image: docker.elastic.co/beats/filebeat:${TAG} - # container_name: setup_filebeat - # volumes: ['./ELK.Docker/scripts/setup-beat.sh:/usr/local/bin/setup-beat.sh:ro'] - # command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-beat.sh | tr -d "\r" | bash -s filebeat'] - # environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] - # networks: ['stack'] - # depends_on: ['kibana'] - - #setup_heartbeat: - # image: docker.elastic.co/beats/heartbeat:${TAG} - # container_name: setup_heartbeat - # volumes: ['./ELK.Docker/scripts/setup-beat.sh:/usr/local/bin/setup-beat.sh:ro'] - # command: ['/bin/bash', '-c', 'cat /usr/local/bin/setup-beat.sh | tr -d "\r" | bash -s heartbeat'] - # environment: ['ELASTIC_PASSWORD=${ELASTIC_PASSWORD}'] - # networks: ['stack'] - # depends_on: ['kibana'] - -##########################DOCSBOX###################################################################### - # web: - # restart: always - # build: ./docsbox-master/docsbox - # expose: - # - "8000" - # links: - # - redis:redis - # volumes: - # - docsbox:/home/docsbox - # - media:/home/docsbox/media - # command: gunicorn -b :8000 docsbox:app - # networks: ['stack'] - - # rqworker: - # restart: always - # build: ./docsbox-master/docsbox - # links: - # - redis:redis - # volumes: - # - web - # command: rq worker -c docsbox.settings - # networks: ['stack'] - - # rqscheduler: - # restart: always - # build: ./docsbox-master/docsbox - # links: - # - redis:redis - # volumes: - # - web - # command: rqscheduler -H redis -p 6379 -d 0 - # networks: ['stack'] - - # nginx: - # restart: always - # build: ./docsbox-master/nginx/ - # ports: - # - "81:80" - # volumes: - # - web - # links: - # - web:web - # networks: ['stack'] - - # redis: - # restart: always - # image: redis:latest - # expose: - # - "6379" - # volumes: - # - redisdata:/data - # networks: ['stack'] - - -##########################SETTINGS###################################################################### - -volumes: - esdata: - driver: local - esdata-dmp: - driver: local - #redisdata: - # driver: local - # docsbox: - # driver: local - # media: - # driver: local -networks: - stack: {} - elasticsearch-dmp: {} - - + - ./openDMP/dmp-frontend/static-files:/usr/share/nginx/static + - ./openDMP/dmp-frontend/webapp/config:/usr/share/nginx/html/assets/config + networks: + - opendmp-frontend-network +networks: + opendmp-frontend-network: + opendmp-backend-network: +volumes: + dmpdata: + external: true diff --git a/openDMP/dmp-backend/opendmp-logs/.gitkeep b/openDMP/dmp-backend/opendmp-logs/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/openDMP/dmp-backend/tmp/.gitkeep b/openDMP/dmp-backend/tmp/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/openDMP/dmp-frontend/static-files/.gitkeep b/openDMP/dmp-frontend/static-files/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/openDMP/dmp-frontend/webapp/.gitkeep b/openDMP/dmp-frontend/webapp/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/guide/UserGuideDRAFT.html b/user-guide/UserGuideDRAFT.html similarity index 100% rename from guide/UserGuideDRAFT.html rename to user-guide/UserGuideDRAFT.html