Commit 7828e959 authored by jcorvi's avatar jcorvi
Browse files

Merge branch 'develop' into 'master'

Develop

See merge request !22
parents 4c26efaa 1fb6a261
Pipeline #27860 passed with stage
in 5 minutes and 41 seconds
......@@ -5,7 +5,8 @@ variables:
DOCKER_REGISTRY: registry.gitlab.bsc.es
#any doubts regarind gitlab ci cd enviroment variables go to
#https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
IMAGE_FULL_PATH: $DOCKER_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_NAME
#IMAGE_FULL_PATH: $DOCKER_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_NAME
IMAGE_FULL_PATH: $DOCKER_REGISTRY/$CI_PROJECT_PATH:latest_develop
stages:
- build
build_docker_image:
......
......@@ -21,7 +21,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<version>2.5.0</version>
</parent>
<dependencies>
......@@ -29,11 +29,46 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
......@@ -47,15 +82,16 @@
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
......
......@@ -20,7 +20,7 @@ import es.bsc.inb.ades.rest.api.services.DocumentService;
@RestController
@CrossOrigin()
@CrossOrigin(origins="*")
public class DocumentController {
@Autowired
......
package es.bsc.inb.ades.rest.api.controllers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import es.bsc.inb.ades.rest.api.model.FileMessage;
import es.bsc.inb.ades.rest.api.model.FileModel;
import es.bsc.inb.ades.rest.api.services.FileService;
@Controller
@CrossOrigin("*")
public class FileController {
@Autowired
FileService fileService;
@PostMapping("/upload")
public ResponseEntity<List<String>> uploadFiles(@RequestParam("files")MultipartFile[] files, @RequestParam("allow_duplicates")Boolean allow_duplicates){
try{
List<String> fileNames = new ArrayList<>();
List<String> errors = fileService.validate(files, allow_duplicates);
if(errors.size()==0) {
Arrays.asList(files).stream().forEach(file->{
fileService.save(file);
fileNames.add(file.getOriginalFilename());
});
}else {
errors.add("Validation fail, no document was uploaded.");
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(errors);
}
List<String> messages = new ArrayList<String>();
messages.add("The documents with their annotations were uploaded correctly.");
return ResponseEntity.status(HttpStatus.OK).body(messages);
}catch (Exception e){
e.printStackTrace();
List<String> messages = new ArrayList<String>();
messages.add("An error occurred while uploading documents.");
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(messages);
}
}
@GetMapping("/files")
public ResponseEntity<List<FileModel>> getFiles(){
List<FileModel> fileInfos = fileService.loadAll().map(path -> {
String filename = path.getFileName().toString();
String url = MvcUriComponentsBuilder.fromMethodName(FileController.class, "getFile",
path.getFileName().toString()).build().toString();
return new FileModel(filename, url);
}).collect(Collectors.toList());
return ResponseEntity.status(HttpStatus.OK).body(fileInfos);
}
@GetMapping("/files/{filename:.+}")
public ResponseEntity<Resource> getFile(@PathVariable String filename){
Resource file = fileService.load(filename);
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\""+file.getFilename() + "\"").body(file);
}
@GetMapping("/delete/{filename:.+}")
public ResponseEntity<FileMessage> deleteFile(@PathVariable String filename) {
String message = "";
try {
message = fileService.deleteFile(filename);
return ResponseEntity.status(HttpStatus.OK).body(new FileMessage(message));
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new FileMessage(message));
}
}
}
package es.bsc.inb.ades.rest.api.controllers;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@CrossOrigin("*")
@RestController
public class LivenessController {
@GetMapping(path = "/liveness")
public String liveness() {
return "true";
}
@GetMapping(path = "/readiness")
public String readeness() {
return "true";
}
@GetMapping(path = "/hello")
public String hello() {
return "holita";
}
}
package es.bsc.inb.ades.rest.api.model;
public class FileMessage {
private String message;
public FileMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package es.bsc.inb.ades.rest.api.model;
/**
* File model
* @author javi
*
*/
public class FileModel {
private String name;
private String url;
public FileModel() {
}
public FileModel(String name, String url) {
this.name = name;
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
......@@ -13,7 +13,7 @@ public interface DocumentRepository extends DocumentRepositoryCustom, MongoRepos
Document findBy_id(ObjectId _id);
Document findByName(String name);
List<Document> findByName(String name);
Document findByDocumentId(Long id);
......
......@@ -33,8 +33,8 @@ public class DocumentRepositoryImpl implements DocumentRepositoryCustom{
query.fields().include("name");
query.fields().include("processDate");
query.fields().include("status");
Sort sort = new Sort(Sort.Direction.ASC, "name");
query.with(sort);
//Sort sort = new Sort(Sort.Direction.ASC, "name");
//query.with(sort);
List<Document> documents = mongoTemplate.find(query, Document.class);
return documents;
}
......
......@@ -7,15 +7,19 @@ import org.springframework.security.config.annotation.authentication.builders.Au
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
//@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().
//http.csrf().disable().
authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll().anyRequest().authenticated()
authorizeRequests().
antMatchers(HttpMethod.OPTIONS, "/**").permitAll().
antMatchers(HttpMethod.GET, "/liveness").permitAll().
antMatchers(HttpMethod.GET, "/readiness").permitAll().anyRequest().authenticated()
.and().httpBasic();
}
@Autowired
......
package es.bsc.inb.ades.rest.api.security.pkce;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.headers().frameOptions().sameOrigin();
httpSecurity
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/liveness").permitAll()
.antMatchers(HttpMethod.GET, "/readiness").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.cors()
.and()
.csrf()
.disable()
.oauth2ResourceServer()
.jwt();
}
}
......@@ -16,6 +16,8 @@ public interface DocumentService {
Document findByDocumentId2(Long id);
List<Document> findByDocumentsName(String name);
//String findTextSnippetByDocumentIdAndFindingId2(Long id, Integer findingId);
String findFindingEvidenceByDocumentIdAndFindingId(Long id, Integer findingId);
......
......@@ -87,24 +87,9 @@ public class DocumentServiceImpl implements DocumentService {
return documentRepository.findByDocumentId(id);
}
// @Override
// public String findTextSnippetByDocumentIdAndFindingId2(Long id, Integer findingId) {
// DocumentAnnotations documentAnnotations = this.findDocumentAnnotationsByDocumentId(id);
// Document document = this.findByDocumentId(id);
// Finding findingSelected = null;
// for (Finding finding : documentAnnotations.getFindings()) {
// if(finding.getFindingId().equals(findingId)) {
// findingSelected = finding;
// break;
// }
// }
//
// if(findingSelected!=null) {
// return this.generateFindingSnippet2(document.getText(), findingSelected);
// }
// return "";
// }
public List<Document> findByDocumentsName(String name) {
return documentRepository.findByName(name);
}
@Override
public Boolean setFindingValidation(Long id, Integer findingId, String status) {
......@@ -251,10 +236,12 @@ public class DocumentServiceImpl implements DocumentService {
public String findFindingEvidenceByDocumentIdAndFindingId(Long id, Integer findingId) {
DocumentAnnotations documentAnnotations = this.findDocumentAnnotationsByDocumentId(id);
Finding findingSelected = null;
Annotation sentenceRelevantText = null;
for (Annotation annotation : documentAnnotations.getRelevantSentences()) {
for (Finding finding : annotation.getFindings()) {
if(finding.getFindingId().equals(findingId)) {
findingSelected = finding;
sentenceRelevantText = annotation;
break;
}
}
......@@ -276,7 +263,10 @@ public class DocumentServiceImpl implements DocumentService {
// annotation.setStartOffset(start_off + Constants.POINTS_INT);
// annotation.setEndOffset(start_off + Constants.POINTS_INT + text_size);
// return this.generateFindingSnippet3(subtext, findingSelected, start_annotation_aux);
Annotation annotation = findingSelected.getRelevant_text();
//I removed relevant text as atribute so ...
//Annotation annotation = findingSelected.getRelevant_text();
Annotation annotation = sentenceRelevantText;
int text_size = annotation.getEndOffset() - annotation.getStartOffset();
int start_ = 0;
int start_off = 0;
......
package es.bsc.inb.ades.rest.api.services;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Stream;
public interface FileService {
/*
Metodo para crear la carpeta donde vamos a guardar los archivos
*/
public void init();
/*
Metodo para guardar los archivos
*/
public void save(MultipartFile file);
/*
Metodo para cargar un archivo
*/
public Resource load(String filename);
/*
Metodo para borrar todos los archivos cada vez que se inicie el servidor
*/
public void deleteAll();
/*
Metodo para Cargar todos los archivos
*/
public Stream<Path> loadAll();
/*
Metodo para Borrar un archivo
*/
public String deleteFile(String filename);
/**
*
* @param files
* @return
*/
public List<String> validate(MultipartFile[] files, Boolean allow_duplicates);
}
package es.bsc.inb.ades.rest.api.services;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
@Service
public class FileServiceImp implements FileService {
//Nombre de la carpeta donde vamos a almacenar los archivos
//Se crea a nivel de raiz la carpeta
private final Path root = Paths.get("uploads");
@Autowired
MongoTemplate mongoTemplate;
@Autowired
DocumentService documentService;
@Override
public void init() {
try {
Files.createDirectory(root);
} catch (IOException e) {
throw new RuntimeException("No se puede inicializar la carpeta uploads");
}
}
/**
* Execute process in a document
* @param file
* @param outputGATEFile
* @throws ResourceInstantiationException
* @throws IOException
* @throws JsonGenerationException
* @throws InvalidOffsetException
*/
public void save(MultipartFile file){
try {
String collectionName = "annotations";
if(file.getOriginalFilename().endsWith("documents.json")) {
collectionName = "documents";
}
ByteArrayInputStream stream = new ByteArrayInputStream(file.getBytes());
String jsonString = IOUtils.toString(stream, "UTF-8");
Document doc = Document.parse(jsonString);
mongoTemplate.save(doc, collectionName);
doc.clear();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* return if document id exist in database.
* @param doc
*/
private Boolean documentIdExist(Document doc) {
Long documentId = doc.getLong("id");
es.bsc.inb.ades.rest.api.model.Document document = documentService.findByDocumentId(documentId);
if(document!=null) {
return true;
}
return false;
}
/**
* Return if document name already exist in database.
* @param doc
*/
private Boolean documentNameExist(Document doc) {
String name = doc.getString("name");
List<es.bsc.inb.ades.rest.api.model.Document> documents = documentService.findByDocumentsName(name);
if(documents!=null && documents.size()>0) {
return true;
}
return false;
}
@Override
public Resource load(String filename) {
try {
Path file = root.resolve(filename);
Resource resource = new UrlResource(file.toUri());
if(resource.exists() || resource.isReadable()){
return resource;
}else{
throw new RuntimeException("No se puede leer el archivo ");
}