Skip to content

Commit

Permalink
fli-iam#2506 : dataset tag API created (add/remove tags to a dataset …
Browse files Browse the repository at this point in the history
…only)
  • Loading branch information
DuckflipXYZ committed Dec 10, 2024
1 parent e548108 commit 762e6e1
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -351,20 +351,4 @@ ResponseEntity<ByteArrayResource> downloadStatisticsByEventId(
@PreAuthorize("hasRole('ADMIN') or (hasAnyRole('EXPERT', 'USER') and @datasetSecurityService.hasRightOnEveryDataset(#datasetIds, 'CAN_SEE_ALL'))")
ResponseEntity<List<DatasetWithDependenciesDTOInterface>> findDatasetsByIds(
@RequestParam(value = "datasetIds", required = true) List<Long> datasetIds);

@Operation(summary = "", description = "Updates the study tags of a dataset")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "dataset study tags updated"),
@ApiResponse(responseCode = "401", description = "unauthorized"),
@ApiResponse(responseCode = "403", description = "forbidden"),
@ApiResponse(responseCode = "404", description = "dataset does not exists"),
@ApiResponse(responseCode = "422", description = "bad parameters"),
@ApiResponse(responseCode = "500", description = "unexpected error") })
@PutMapping(value = "/{datasetId}/tags", produces = { "application/json" }, consumes = {
"application/json" })
@PreAuthorize("hasRole('ADMIN') or (hasRole('EXPERT') and @datasetSecurityService.hasRightOnDataset(#datasetId, 'CAN_ADMINISTRATE'))")
ResponseEntity<Void> updateDatasetTags(
@Parameter(description = "id of the dataset", required = true) @PathVariable("datasetId") Long datasetId,
@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "array of study tag ids", required = true) @RequestBody List<Long> studyTagIds,
BindingResult result) throws RestServiceException, EntityNotFoundException, SolrServerException, IOException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@
import org.shanoir.ng.shared.exception.ErrorModel;
import org.shanoir.ng.shared.exception.RestServiceException;
import org.shanoir.ng.solr.service.SolrService;
import org.shanoir.ng.tag.model.StudyTag;
import org.shanoir.ng.tag.service.StudyTagService;
import org.shanoir.ng.utils.DatasetFileUtils;
import org.shanoir.ng.utils.KeycloakUtil;
import org.slf4j.Logger;
Expand Down Expand Up @@ -147,9 +145,6 @@ public class DatasetApiController implements DatasetApi {
@Autowired
private ObjectMapper objectMapper;

@Autowired
private StudyTagService studyTagService;

@Autowired
private DatasetRepository datasetRepository;

Expand Down Expand Up @@ -272,30 +267,6 @@ public ResponseEntity<List<DatasetWithDependenciesDTOInterface>> findDatasetsByI
return new ResponseEntity<>(dtos, HttpStatus.OK);
}

@Override
public ResponseEntity<Void> updateDatasetTags(Long datasetId, List<Long> studyTagIds, BindingResult result) throws EntityNotFoundException, SolrServerException, IOException {
Dataset ds = datasetService.findById(datasetId);
if (ds == null) {
throw new EntityNotFoundException(Dataset.class, datasetId);
}

List<StudyTag> tags = studyTagService.findByIds(studyTagIds);

ds.setTags(new ArrayList<>());

for(StudyTag tag : tags){
if(tag.getStudy().getId().equals(ds.getStudyId())){
ds.getTags().add(tag);
}
}

datasetRepository.save(ds);

solrService.indexDataset(datasetId);

return new ResponseEntity<>(HttpStatus.OK);
}

@Override
public ResponseEntity<List<DatasetDTO>> findDatasetsByExaminationId(Long examinationId) {
List<Dataset> datasets = datasetService.findByExaminationId(examinationId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Shanoir NG - Import, manage and share neuroimaging data
* Copyright (C) 2009-2019 Inria - https://www.inria.fr/
* Contact us on https://project.inria.fr/shanoir/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/gpl-3.0.html
*/

package org.shanoir.ng.tag.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.solr.client.solrj.SolrServerException;
import org.shanoir.ng.shared.exception.EntityNotFoundException;
import org.shanoir.ng.shared.exception.RestServiceException;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;

@Tag(name = "studytag")
@RequestMapping("/studytag")
public interface StudyTagApi {

@Operation(summary = "addStudyTagsToDataset", description = "Add study tags to a dataset")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "dataset associated to study tags"),
@ApiResponse(responseCode = "401", description = "unauthorized"),
@ApiResponse(responseCode = "403", description = "forbidden"),
@ApiResponse(responseCode = "404", description = "dataset does not exists"),
@ApiResponse(responseCode = "422", description = "bad parameters"),
@ApiResponse(responseCode = "500", description = "unexpected error") })
@PutMapping(value = "/addStudyTagsToDataset")
@PreAuthorize("hasRole('ADMIN') or (hasRole('EXPERT') and @datasetSecurityService.hasRightOnDataset(#datasetId, 'CAN_IMPORT'))")
ResponseEntity<Void> addStudyTagsToDataset(
@Parameter(description = "id of the dataset", required = true) @RequestParam(value = "datasetId") Long datasetId,
@Parameter(description = "study tag ids", required = true) @RequestParam(value = "studyTagIds") List<Long> studyTagIds)
throws RestServiceException, EntityNotFoundException, SolrServerException, IOException;

@Operation(summary = "removeStudyTagsFromDataset", description = "Add study tags to a dataset")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "dataset associated to study tags"),
@ApiResponse(responseCode = "401", description = "unauthorized"),
@ApiResponse(responseCode = "403", description = "forbidden"),
@ApiResponse(responseCode = "404", description = "dataset does not exists"),
@ApiResponse(responseCode = "422", description = "bad parameters"),
@ApiResponse(responseCode = "500", description = "unexpected error") })
@PutMapping(value = "/removeStudyTagsFromDataset")
@PreAuthorize("hasRole('ADMIN') or (hasRole('EXPERT') and @datasetSecurityService.hasRightOnDataset(#datasetId, 'CAN_IMPORT'))")
ResponseEntity<Void> removeStudyTagsFromDataset(
@Parameter(description = "id of the dataset", required = true) @RequestParam(value = "datasetId") Long datasetId,
@Parameter(description = "study tag ids", required = true) @RequestParam(value = "studyTagIds") List<Long> studyTagIds)
throws RestServiceException, EntityNotFoundException, SolrServerException, IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
* Shanoir NG - Import, manage and share neuroimaging data
* Copyright (C) 2009-2019 Inria - https://www.inria.fr/
* Contact us on https://project.inria.fr/shanoir/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/gpl-3.0.html
*/

package org.shanoir.ng.tag.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.mail.MessagingException;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrServerException;
import org.shanoir.ng.dataset.dto.DatasetDTO;
import org.shanoir.ng.dataset.dto.DatasetWithDependenciesDTOInterface;
import org.shanoir.ng.dataset.dto.mapper.DatasetMapper;
import org.shanoir.ng.dataset.modality.EegDataset;
import org.shanoir.ng.dataset.modality.EegDatasetMapper;
import org.shanoir.ng.dataset.modality.MrDataset;
import org.shanoir.ng.dataset.modality.MrDatasetMapper;
import org.shanoir.ng.dataset.model.Dataset;
import org.shanoir.ng.dataset.model.DatasetExpressionFormat;
import org.shanoir.ng.dataset.repository.DatasetRepository;
import org.shanoir.ng.dataset.service.CreateStatisticsService;
import org.shanoir.ng.dataset.service.DatasetDownloaderServiceImpl;
import org.shanoir.ng.dataset.service.DatasetService;
import org.shanoir.ng.datasetacquisition.model.DatasetAcquisition;
import org.shanoir.ng.download.DatasetDownloadError;
import org.shanoir.ng.download.WADODownloaderService;
import org.shanoir.ng.examination.model.Examination;
import org.shanoir.ng.examination.service.ExaminationService;
import org.shanoir.ng.importer.dto.ProcessedDatasetImportJob;
import org.shanoir.ng.importer.service.ImporterService;
import org.shanoir.ng.shared.configuration.RabbitMQConfiguration;
import org.shanoir.ng.shared.error.FieldErrorMap;
import org.shanoir.ng.shared.event.ShanoirEvent;
import org.shanoir.ng.shared.event.ShanoirEventService;
import org.shanoir.ng.shared.event.ShanoirEventType;
import org.shanoir.ng.shared.exception.EntityNotFoundException;
import org.shanoir.ng.shared.exception.ErrorDetails;
import org.shanoir.ng.shared.exception.ErrorModel;
import org.shanoir.ng.shared.exception.RestServiceException;
import org.shanoir.ng.solr.service.SolrService;
import org.shanoir.ng.tag.model.StudyTag;
import org.shanoir.ng.tag.service.StudyTagService;
import org.shanoir.ng.utils.DatasetFileUtils;
import org.shanoir.ng.utils.KeycloakUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Controller
public class StudyTagApiController implements StudyTagApi {

private static final Logger LOG = LoggerFactory.getLogger(StudyTagApiController.class);

@Autowired
private DatasetService datasetService;

@Autowired
private StudyTagService studyTagService;

@Override
public ResponseEntity<Void> addStudyTagsToDataset(Long datasetId, List<Long> studyTagIds) throws EntityNotFoundException, SolrServerException, IOException {
Dataset ds = datasetService.findById(datasetId);
if (Objects.isNull(ds)) {throw new EntityNotFoundException(Dataset.class, datasetId);}

studyTagService.addStudyTagsToDataset(ds, studyTagIds);

return new ResponseEntity<>(HttpStatus.OK);
}

@Override
public ResponseEntity<Void> removeStudyTagsFromDataset(Long datasetId, List<Long> studyTagIds) throws EntityNotFoundException, SolrServerException, IOException {
Dataset ds = datasetService.findById(datasetId);
if (Objects.isNull(ds)) {throw new EntityNotFoundException(Dataset.class, datasetId);}

studyTagService.removeStudyTagsFromDataset(ds, studyTagIds);

return new ResponseEntity<>(HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,65 @@
package org.shanoir.ng.tag.service;

import org.apache.commons.collections4.IterableUtils;
import org.apache.solr.client.solrj.SolrServerException;
import org.shanoir.ng.dataset.model.Dataset;
import org.shanoir.ng.dataset.repository.DatasetRepository;
import org.shanoir.ng.shared.exception.EntityNotFoundException;
import org.shanoir.ng.solr.service.SolrService;
import org.shanoir.ng.tag.model.StudyTag;
import org.shanoir.ng.tag.repository.StudyTagRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import java.util.List;
import java.io.IOException;
import java.util.*;

@Service
public class StudyTagService {

@Autowired
private StudyTagRepository repository;

@Autowired
private DatasetRepository datasetRepository;

@Autowired
private SolrService solrService;

public List<StudyTag> findByIds(List<Long> ids){
return IterableUtils.toList(repository.findAllById(ids));
}

public boolean existsById(Long id){
return repository.existsById(id);
@Transactional
public void addStudyTagsToDataset(Dataset dataset, List<Long> studyTagIds) throws SolrServerException, IOException {
Set<StudyTag> datasetTags = new HashSet<>(dataset.getTags());

for (StudyTag tag : findByIds(studyTagIds)) {
if (tag.getStudy().getId().equals(dataset.getStudyId())) {
datasetTags.add(tag);
}
}
dataset.setTags(new ArrayList<>(datasetTags));
datasetRepository.save(dataset);
solrService.indexDataset(dataset.getId());
}

@Transactional
public void removeStudyTagsFromDataset(Dataset dataset, List<Long> studyTagIds) throws SolrServerException, IOException {
Set<StudyTag> datasetTags = new HashSet<>(dataset.getTags());

for (StudyTag tag : findByIds(studyTagIds)) {
if (tag.getStudy().getId().equals(dataset.getStudyId())) {
datasetTags.remove(tag);
}
}

dataset.setTags(new ArrayList<>(datasetTags));
datasetRepository.save(dataset);
solrService.indexDataset(dataset.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
@WebMvcTest(controllers = DatasetApiController.class)
@AutoConfigureMockMvc(addFilters = false)
@ActiveProfiles("test")
public class DatasetApiControllerTest {
public class StudyTagApiControllerTest {

private static final String REQUEST_PATH = "/datasets";
private static final String REQUEST_PATH_WITH_ID = REQUEST_PATH + "/1";
Expand Down

0 comments on commit 762e6e1

Please sign in to comment.