Skip to content
Snippets Groups Projects
Commit 86f91ae9 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Handled jobId parameter also on GetFileController and improved error handling

parent 5bd13b15
Branches
No related tags found
No related merge requests found
Pipeline #2028 passed
Showing
with 223 additions and 107 deletions
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version> <version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>it.inaf.ia2</groupId> <groupId>it.inaf.ia2</groupId>
......
...@@ -25,7 +25,7 @@ import org.springframework.web.bind.annotation.RequestBody; ...@@ -25,7 +25,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class ArchiveFileController { public class ArchiveFileController extends FileController {
@Autowired @Autowired
private ArchiveService archiveService; private ArchiveService archiveService;
...@@ -48,7 +48,7 @@ public class ArchiveFileController { ...@@ -48,7 +48,7 @@ public class ArchiveFileController {
job.setVosPaths(archiveRequest.getPaths()); job.setVosPaths(archiveRequest.getPaths());
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
archiveService.createArchive(job); handleFileJob(() -> archiveService.createArchive(job), job.getJobId());
}); });
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
...@@ -57,12 +57,12 @@ public class ArchiveFileController { ...@@ -57,12 +57,12 @@ public class ArchiveFileController {
} }
@GetMapping(value = "/archive/{fileName}") @GetMapping(value = "/archive/{fileName}")
public ResponseEntity<?> getArchiveFile(@PathVariable("fileName") String fileName) { public void getArchiveFile(@PathVariable("fileName") String fileName) {
TokenPrincipal principal = (TokenPrincipal) request.getUserPrincipal(); TokenPrincipal principal = (TokenPrincipal) request.getUserPrincipal();
File file = archiveService.getArchiveParentDir(principal).toPath().resolve(fileName).toFile(); File file = archiveService.getArchiveParentDir(principal).toPath().resolve(fileName).toFile();
return FileResponseUtil.getFileResponse(response, file); FileResponseUtil.getFileResponse(response, file);
} }
} }
...@@ -5,18 +5,28 @@ ...@@ -5,18 +5,28 @@
*/ */
package it.inaf.ia2.transfer.controller; package it.inaf.ia2.transfer.controller;
import it.inaf.ia2.transfer.exception.JobException;
import it.inaf.ia2.transfer.persistence.JobDAO;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.uws.v1.ExecutionPhase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
public abstract class FileController { public abstract class FileController {
private static final Logger LOG = LoggerFactory.getLogger(FileController.class);
@Autowired @Autowired
protected HttpServletRequest request; protected HttpServletRequest request;
@Autowired
private JobDAO jobDAO;
public String getPath() { public String getPath() {
String uri = request.getRequestURI().substring(request.getContextPath().length()); String uri = request.getRequestURI().substring(request.getContextPath().length());
...@@ -26,4 +36,26 @@ public abstract class FileController { ...@@ -26,4 +36,26 @@ public abstract class FileController {
.map(p -> URLDecoder.decode(p, StandardCharsets.UTF_8)) .map(p -> URLDecoder.decode(p, StandardCharsets.UTF_8))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
public void handleFileJob(Runnable action, String jobId) {
try {
action.run();
if (jobId != null) {
jobDAO.updateJobPhase(ExecutionPhase.COMPLETED, jobId);
}
} catch (Throwable t) {
JobException jobException;
if (t instanceof JobException) {
jobException = (JobException) t;
} else {
LOG.error("Unexpected error happened", t);
jobException = new JobException(JobException.Type.FATAL, "Internal Fault")
.setErrorDetail("InternalFault: Unexpected error happened");
}
if (jobId != null) {
jobDAO.setJobError(jobId, jobException);
}
throw t;
}
}
} }
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
*/ */
package it.inaf.ia2.transfer.controller; package it.inaf.ia2.transfer.controller;
import it.inaf.ia2.transfer.exception.FileNotFoundException;
import it.inaf.ia2.transfer.exception.JobException;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
...@@ -16,32 +18,32 @@ import java.nio.charset.StandardCharsets; ...@@ -16,32 +18,32 @@ import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import org.springframework.http.ResponseEntity;
public class FileResponseUtil { public class FileResponseUtil {
private static final Logger LOG = LoggerFactory.getLogger(FileResponseUtil.class); private static final Logger LOG = LoggerFactory.getLogger(FileResponseUtil.class);
public static ResponseEntity<?> getFileResponse(HttpServletResponse response, File file) { public static void getFileResponse(HttpServletResponse response, File file) {
return getFileResponse(response, file, null); getFileResponse(response, file, null);
} }
public static ResponseEntity<?> getFileResponse(HttpServletResponse response, File file, String fileName) { public static void getFileResponse(HttpServletResponse response, File file, String vosPath) {
String fileName = vosPath == null ? file.getName() : vosPath.substring(vosPath.lastIndexOf("/") + 1);
if (!file.exists()) { if (!file.exists()) {
LOG.error("File not found: " + file.getAbsolutePath()); LOG.error("File not found: " + file.getAbsolutePath());
return new ResponseEntity<>("File " + file.getName() + " not found", NOT_FOUND); throw new FileNotFoundException(vosPath == null ? file.getAbsolutePath() : vosPath);
} }
if (!file.canRead()) { if (!file.canRead()) {
LOG.error("File not readable: " + file.getAbsolutePath()); LOG.error("File not readable: " + file.getAbsolutePath());
return new ResponseEntity<>("File " + file.getName() + " is not readable", INTERNAL_SERVER_ERROR); throw new JobException(JobException.Type.FATAL, "Internal Fault")
.setErrorDetail("InternalFault: File " + file.getName() + " is not readable");
} }
response.setHeader("Content-Disposition", "attachment; filename=" response.setHeader("Content-Disposition", "attachment; filename="
+ URLEncoder.encode(fileName == null ? file.getName() : fileName, StandardCharsets.UTF_8)); + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
response.setHeader("Content-Length", String.valueOf(file.length())); response.setHeader("Content-Length", String.valueOf(file.length()));
response.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8");
...@@ -54,6 +56,5 @@ public class FileResponseUtil { ...@@ -54,6 +56,5 @@ public class FileResponseUtil {
} catch (IOException ex) { } catch (IOException ex) {
throw new UncheckedIOException(ex); throw new UncheckedIOException(ex);
} }
return null;
} }
} }
...@@ -7,7 +7,11 @@ package it.inaf.ia2.transfer.controller; ...@@ -7,7 +7,11 @@ package it.inaf.ia2.transfer.controller;
import it.inaf.ia2.transfer.persistence.model.FileInfo; import it.inaf.ia2.transfer.persistence.model.FileInfo;
import it.inaf.ia2.transfer.auth.TokenPrincipal; import it.inaf.ia2.transfer.auth.TokenPrincipal;
import it.inaf.ia2.transfer.exception.FileNotFoundException;
import it.inaf.ia2.transfer.exception.InvalidArgumentException;
import it.inaf.ia2.transfer.exception.PermissionDeniedException;
import it.inaf.ia2.transfer.persistence.FileDAO; import it.inaf.ia2.transfer.persistence.FileDAO;
import it.inaf.ia2.transfer.persistence.JobDAO;
import it.inaf.ia2.transfer.service.AuthorizationService; import it.inaf.ia2.transfer.service.AuthorizationService;
import java.io.File; import java.io.File;
import java.util.Optional; import java.util.Optional;
...@@ -15,10 +19,8 @@ import javax.servlet.http.HttpServletResponse; ...@@ -15,10 +19,8 @@ import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
...@@ -29,6 +31,9 @@ public class GetFileController extends FileController { ...@@ -29,6 +31,9 @@ public class GetFileController extends FileController {
@Autowired @Autowired
private FileDAO fileDAO; private FileDAO fileDAO;
@Autowired
private JobDAO jobDAO;
@Autowired @Autowired
private AuthorizationService authorizationService; private AuthorizationService authorizationService;
...@@ -36,12 +41,23 @@ public class GetFileController extends FileController { ...@@ -36,12 +41,23 @@ public class GetFileController extends FileController {
private HttpServletResponse response; private HttpServletResponse response;
@GetMapping("/**") @GetMapping("/**")
public ResponseEntity<?> getFile() { public void getFile(@RequestParam(value = "jobId", required = false) String jobId) {
String path = getPath(); String path = getPath();
LOG.debug("getFile called for path {}", path); LOG.debug("getFile called for path {}", path);
if (jobId == null) {
LOG.debug("getFile called for path {}", path);
} else {
LOG.debug("getFile called for path {} with jobId {}", path, jobId);
if (!jobDAO.isJobExisting(jobId)) {
throw new InvalidArgumentException("Job " + jobId + " not found");
}
}
handleFileJob(() -> {
Optional<FileInfo> optFileInfo = fileDAO.getFileInfo(path); Optional<FileInfo> optFileInfo = fileDAO.getFileInfo(path);
if (optFileInfo.isPresent()) { if (optFileInfo.isPresent()) {
...@@ -49,19 +65,14 @@ public class GetFileController extends FileController { ...@@ -49,19 +65,14 @@ public class GetFileController extends FileController {
FileInfo fileInfo = optFileInfo.get(); FileInfo fileInfo = optFileInfo.get();
if (!authorizationService.isDownloadable(fileInfo, (TokenPrincipal) request.getUserPrincipal())) { if (!authorizationService.isDownloadable(fileInfo, (TokenPrincipal) request.getUserPrincipal())) {
return new ResponseEntity<>("Unauthorized", UNAUTHORIZED); throw new PermissionDeniedException(path);
} }
return getFileResponse(fileInfo); File file = new File(fileInfo.getOsPath());
FileResponseUtil.getFileResponse(response, file, path);
} else { } else {
return new ResponseEntity<>("File " + path + " not found", NOT_FOUND); throw new FileNotFoundException(path);
} }
} }, jobId);
private ResponseEntity<?> getFileResponse(FileInfo fileInfo) {
File file = new File(fileInfo.getOsPath());
return FileResponseUtil.getFileResponse(response, file, fileInfo.getVirtualName());
} }
} }
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
*/ */
package it.inaf.ia2.transfer.controller; package it.inaf.ia2.transfer.controller;
import it.inaf.ia2.transfer.exception.FileNotFoundException;
import it.inaf.ia2.transfer.exception.InvalidArgumentException;
import it.inaf.ia2.transfer.persistence.model.FileInfo; import it.inaf.ia2.transfer.persistence.model.FileInfo;
import it.inaf.ia2.transfer.persistence.FileDAO; import it.inaf.ia2.transfer.persistence.FileDAO;
import it.inaf.ia2.transfer.persistence.JobDAO; import it.inaf.ia2.transfer.persistence.JobDAO;
...@@ -19,12 +21,9 @@ import java.util.regex.Matcher; ...@@ -19,12 +21,9 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter; import javax.xml.bind.DatatypeConverter;
import net.ivoa.xml.uws.v1.ExecutionPhase;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
...@@ -44,9 +43,9 @@ public class PutFileController extends FileController { ...@@ -44,9 +43,9 @@ public class PutFileController extends FileController {
private JobDAO jobDAO; private JobDAO jobDAO;
@PutMapping("/**") @PutMapping("/**")
public ResponseEntity<?> putFile(@RequestHeader(value = HttpHeaders.CONTENT_ENCODING, required = false) String contentEncoding, public void putFile(@RequestHeader(value = HttpHeaders.CONTENT_ENCODING, required = false) String contentEncoding,
@RequestParam(value = "file", required = false) MultipartFile file, @RequestParam(value = "file", required = false) MultipartFile file,
@RequestParam(value = "jobid", required = false) String jobId, @RequestParam(value = "jobId", required = false) String jobId,
HttpServletRequest request) throws IOException, NoSuchAlgorithmException { HttpServletRequest request) throws IOException, NoSuchAlgorithmException {
String path = getPath(); String path = getPath();
...@@ -57,10 +56,11 @@ public class PutFileController extends FileController { ...@@ -57,10 +56,11 @@ public class PutFileController extends FileController {
LOG.debug("putFile called for path {} with jobId {}", path, jobId); LOG.debug("putFile called for path {} with jobId {}", path, jobId);
if (!jobDAO.isJobExisting(jobId)) { if (!jobDAO.isJobExisting(jobId)) {
return new ResponseEntity<>("Job " + jobId + " not found", NOT_FOUND); throw new InvalidArgumentException("Job " + jobId + " not found");
} }
} }
handleFileJob(() -> {
Optional<FileInfo> optFileInfo = fileDAO.getFileInfo(path); Optional<FileInfo> optFileInfo = fileDAO.getFileInfo(path);
if (optFileInfo.isPresent()) { if (optFileInfo.isPresent()) {
...@@ -72,11 +72,13 @@ public class PutFileController extends FileController { ...@@ -72,11 +72,13 @@ public class PutFileController extends FileController {
} }
fileInfo.setContentEncoding(contentEncoding); fileInfo.setContentEncoding(contentEncoding);
storeGenericFile(fileInfo, in, jobId); storeGenericFile(fileInfo, in, jobId);
} catch (IOException | NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
} }
return ResponseEntity.ok().build();
} else { } else {
return new ResponseEntity<>("File " + path + " not found", NOT_FOUND); throw new FileNotFoundException(path);
} }
}, jobId);
} }
private void storeGenericFile(FileInfo fileInfo, InputStream is, String jobId) throws IOException, NoSuchAlgorithmException { private void storeGenericFile(FileInfo fileInfo, InputStream is, String jobId) throws IOException, NoSuchAlgorithmException {
...@@ -117,15 +119,6 @@ public class PutFileController extends FileController { ...@@ -117,15 +119,6 @@ public class PutFileController extends FileController {
fileInfo.getContentEncoding(), fileInfo.getContentEncoding(),
fileSize, fileSize,
md5Checksum); md5Checksum);
if (jobId != null) {
jobDAO.updateJobPhase(ExecutionPhase.COMPLETED, jobId);
}
} catch (IOException | NoSuchAlgorithmException ex) {
if (jobId != null) {
jobDAO.updateJobPhase(ExecutionPhase.ERROR, jobId);
}
throw ex;
} finally { } finally {
fileDAO.setBusy(fileInfo.getNodeId(), null); fileDAO.setBusy(fileInfo.getNodeId(), null);
} }
......
/*
* This file is part of vospace-rest
* Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package it.inaf.ia2.transfer.exception;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("${server.error.path:${error.path:/error}}")
public class ErrorController extends AbstractErrorController {
@Autowired
public ErrorController(ErrorAttributes errorAttributes) {
super(errorAttributes);
}
@RequestMapping(produces = MediaType.TEXT_XML_VALUE)
public void errorText(HttpServletRequest request, HttpServletResponse response) throws Exception {
ErrorAttributeOptions options = ErrorAttributeOptions.of(ErrorAttributeOptions.Include.MESSAGE);
Map<String, Object> errors = super.getErrorAttributes(request, options);
response.setContentType("text/plain;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
String errorMessage = (String) errors.get("message");
if (errorMessage != null) {
response.getOutputStream().write(errorMessage.getBytes(StandardCharsets.UTF_8));
}
}
@Override
public String getErrorPath() {
return null;
}
}
/*
* This file is part of vospace-file-service
* Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package it.inaf.ia2.transfer.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class FileNotFoundException extends JobException {
public FileNotFoundException(String path) {
super(Type.FATAL, "Node Not Found");
setErrorDetail("NodeNotFound Path: " + path);
}
}
/*
* This file is part of vospace-file-service
* Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package it.inaf.ia2.transfer.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class InvalidArgumentException extends JobException {
public InvalidArgumentException(String message) {
super(Type.FATAL, "Invalid Argument");
setErrorDetail("InvalidArgument: " + message);
}
}
...@@ -3,8 +3,12 @@ ...@@ -3,8 +3,12 @@
* Copyright (C) 2021 Istituto Nazionale di Astrofisica * Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
package it.inaf.ia2.transfer.persistence.model; package it.inaf.ia2.transfer.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class JobException extends RuntimeException { public class JobException extends RuntimeException {
public static enum Type { public static enum Type {
...@@ -24,10 +28,10 @@ public class JobException extends RuntimeException { ...@@ -24,10 +28,10 @@ public class JobException extends RuntimeException {
} }
private final Type type; private final Type type;
private String errorMessage;
private String errorDetail; private String errorDetail;
public JobException(Type type) { public JobException(Type type, String message) {
super(message);
this.type = type; this.type = type;
} }
...@@ -35,20 +39,11 @@ public class JobException extends RuntimeException { ...@@ -35,20 +39,11 @@ public class JobException extends RuntimeException {
return type; return type;
} }
public String getErrorMessage() {
return errorMessage;
}
public JobException setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
return this;
}
public String getErrorDetail() { public String getErrorDetail() {
return errorDetail; return errorDetail;
} }
public JobException setErrorDetail(String errorDetail) { public final JobException setErrorDetail(String errorDetail) {
this.errorDetail = errorDetail; this.errorDetail = errorDetail;
return this; return this;
} }
......
/*
* This file is part of vospace-file-service
* Copyright (C) 2021 Istituto Nazionale di Astrofisica
* SPDX-License-Identifier: GPL-3.0-or-later
*/
package it.inaf.ia2.transfer.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public class PermissionDeniedException extends JobException {
public PermissionDeniedException(String path) {
super(Type.FATAL, "Permission Denied");
setErrorDetail("PermissionDenied Path: " + path);
}
}
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
*/ */
package it.inaf.ia2.transfer.persistence; package it.inaf.ia2.transfer.persistence;
import it.inaf.ia2.transfer.persistence.model.JobException; import it.inaf.ia2.transfer.exception.JobException;
import java.sql.Types; import java.sql.Types;
import javax.sql.DataSource; import javax.sql.DataSource;
import net.ivoa.xml.uws.v1.ExecutionPhase; import net.ivoa.xml.uws.v1.ExecutionPhase;
...@@ -73,7 +73,7 @@ public class JobDAO { ...@@ -73,7 +73,7 @@ public class JobDAO {
jdbcTemplate.update(sql, ps -> { jdbcTemplate.update(sql, ps -> {
int i = 0; int i = 0;
ps.setObject(++i, ExecutionPhase.ERROR, Types.OTHER); ps.setObject(++i, ExecutionPhase.ERROR, Types.OTHER);
ps.setString(++i, jobError.getErrorMessage()); ps.setString(++i, jobError.getMessage());
ps.setObject(++i, jobError.getType().value(), Types.OTHER); ps.setObject(++i, jobError.getType().value(), Types.OTHER);
ps.setBoolean(++i, jobError.getErrorDetail() != null); ps.setBoolean(++i, jobError.getErrorDetail() != null);
ps.setString(++i, jobError.getErrorDetail()); ps.setString(++i, jobError.getErrorDetail());
......
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
package it.inaf.ia2.transfer.service; package it.inaf.ia2.transfer.service;
import it.inaf.ia2.transfer.auth.TokenPrincipal; import it.inaf.ia2.transfer.auth.TokenPrincipal;
import it.inaf.ia2.transfer.exception.JobException;
import it.inaf.ia2.transfer.exception.JobException.Type;
import it.inaf.ia2.transfer.persistence.FileDAO; import it.inaf.ia2.transfer.persistence.FileDAO;
import it.inaf.ia2.transfer.persistence.JobDAO; import it.inaf.ia2.transfer.persistence.JobDAO;
import it.inaf.ia2.transfer.persistence.LocationDAO; import it.inaf.ia2.transfer.persistence.LocationDAO;
import it.inaf.ia2.transfer.persistence.model.FileInfo; import it.inaf.ia2.transfer.persistence.model.FileInfo;
import it.inaf.ia2.transfer.persistence.model.JobException;
import it.inaf.ia2.transfer.persistence.model.JobException.Type;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
...@@ -19,6 +19,7 @@ import java.io.FileOutputStream; ...@@ -19,6 +19,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.security.Principal; import java.security.Principal;
import java.util.List; import java.util.List;
...@@ -120,18 +121,8 @@ public class ArchiveService { ...@@ -120,18 +121,8 @@ public class ArchiveService {
FileSystemUtils.deleteRecursively(supportDir); FileSystemUtils.deleteRecursively(supportDir);
} }
jobDAO.updateJobPhase(ExecutionPhase.COMPLETED, job.getJobId()); } catch (IOException ex) {
throw new UncheckedIOException(ex);
} catch (Throwable t) {
JobException jobException;
if (t instanceof JobException) {
jobException = (JobException) t;
} else {
LOG.error("Unexpected error happened creating archive", t);
jobException = new JobException(Type.FATAL).setErrorMessage("Internal Fault")
.setErrorDetail("InternalFault: Unexpected error happened creating archive");
}
jobDAO.setJobError(job.getJobId(), jobException);
} }
} }
...@@ -142,7 +133,7 @@ public class ArchiveService { ...@@ -142,7 +133,7 @@ public class ArchiveService {
if (!parentDir.exists()) { if (!parentDir.exists()) {
if (!parentDir.mkdirs()) { if (!parentDir.mkdirs()) {
LOG.error("Unable to create directory " + parentDir.getAbsolutePath()); LOG.error("Unable to create directory " + parentDir.getAbsolutePath());
throw new JobException(Type.FATAL).setErrorMessage("Internal Fault") throw new JobException(Type.FATAL, "Internal Fault")
.setErrorDetail("InternalFault: Unable to create temporary directory for job"); .setErrorDetail("InternalFault: Unable to create temporary directory for job");
} }
} }
...@@ -150,7 +141,7 @@ public class ArchiveService { ...@@ -150,7 +141,7 @@ public class ArchiveService {
File archiveFile = parentDir.toPath().resolve(job.getJobId() + "." + job.getType().getExtension()).toFile(); File archiveFile = parentDir.toPath().resolve(job.getJobId() + "." + job.getType().getExtension()).toFile();
if (!archiveFile.createNewFile()) { if (!archiveFile.createNewFile()) {
LOG.error("Unable to create file " + archiveFile.getAbsolutePath()); LOG.error("Unable to create file " + archiveFile.getAbsolutePath());
throw new JobException(Type.FATAL).setErrorMessage("Internal Fault") throw new JobException(Type.FATAL, "Internal Fault")
.setErrorDetail("InternalFault: Unable to create archive file"); .setErrorDetail("InternalFault: Unable to create archive file");
} }
...@@ -203,7 +194,7 @@ public class ArchiveService { ...@@ -203,7 +194,7 @@ public class ArchiveService {
} }
@Override @Override
public void close() throws Exception { public void close() throws IOException {
os.close(); os.close();
} }
} }
...@@ -261,7 +252,7 @@ public class ArchiveService { ...@@ -261,7 +252,7 @@ public class ArchiveService {
if (baseUrl == null) { if (baseUrl == null) {
LOG.error("Location URL not found for location " + fileInfo.getLocationId()); LOG.error("Location URL not found for location " + fileInfo.getLocationId());
throw new JobException(Type.FATAL).setErrorMessage("Internal Fault") throw new JobException(Type.FATAL, "Internal Fault")
.setErrorDetail("InternalFault: Unable to retrieve location of file " + fileInfo.getVirtualPath()); .setErrorDetail("InternalFault: Unable to retrieve location of file " + fileInfo.getVirtualPath());
} }
...@@ -291,7 +282,7 @@ public class ArchiveService { ...@@ -291,7 +282,7 @@ public class ArchiveService {
private <O extends OutputStream, E> void writeFileIntoArchive(FileInfo fileInfo, String relPath, TokenPrincipal tokenPrincipal, ArchiveHandler<O, E> handler) throws IOException { private <O extends OutputStream, E> void writeFileIntoArchive(FileInfo fileInfo, String relPath, TokenPrincipal tokenPrincipal, ArchiveHandler<O, E> handler) throws IOException {
if (!authorizationService.isDownloadable(fileInfo, tokenPrincipal)) { if (!authorizationService.isDownloadable(fileInfo, tokenPrincipal)) {
throw new JobException(Type.FATAL).setErrorMessage("Permission Denied") throw new JobException(Type.FATAL, "Permission Denied")
.setErrorDetail("PermissionDenied: " + fileInfo.getVirtualPath()); .setErrorDetail("PermissionDenied: " + fileInfo.getVirtualPath());
} }
......
...@@ -183,6 +183,6 @@ public class GetFileControllerTest { ...@@ -183,6 +183,6 @@ public class GetFileControllerTest {
mockMvc.perform(get("/path/to/myfile")) mockMvc.perform(get("/path/to/myfile"))
.andDo(print()) .andDo(print())
.andExpect(status().isUnauthorized()); .andExpect(status().isForbidden());
} }
} }
...@@ -150,7 +150,7 @@ public class PutFileControllerTest { ...@@ -150,7 +150,7 @@ public class PutFileControllerTest {
// Try with invalid jobid // Try with invalid jobid
mockMvc.perform(putMultipart("/path/to/test.txt") mockMvc.perform(putMultipart("/path/to/test.txt")
.file(fakeFile).param("jobid", "pippo10")) .file(fakeFile).param("jobId", "pippo10"))
.andDo(print()) .andDo(print())
.andExpect(status().is4xxClientError()); .andExpect(status().is4xxClientError());
...@@ -158,7 +158,7 @@ public class PutFileControllerTest { ...@@ -158,7 +158,7 @@ public class PutFileControllerTest {
// Retry with valid jobid // Retry with valid jobid
mockMvc.perform(putMultipart("/path/to/test.txt") mockMvc.perform(putMultipart("/path/to/test.txt")
.file(fakeFile).param("jobid", "pippo5")) .file(fakeFile).param("jobId", "pippo5"))
.andDo(print()) .andDo(print())
.andExpect(status().is2xxSuccessful()); .andExpect(status().is2xxSuccessful());
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
*/ */
package it.inaf.ia2.transfer.persistence; package it.inaf.ia2.transfer.persistence;
import it.inaf.ia2.transfer.persistence.model.JobException; import it.inaf.ia2.transfer.exception.JobException;
import it.inaf.ia2.transfer.persistence.model.JobException.Type; import it.inaf.ia2.transfer.exception.JobException.Type;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
...@@ -52,8 +52,7 @@ public class JobDAOTest { ...@@ -52,8 +52,7 @@ public class JobDAOTest {
assertEquals(ExecutionPhase.QUEUED, dao.getJobPhase("pippo3")); assertEquals(ExecutionPhase.QUEUED, dao.getJobPhase("pippo3"));
JobException jobError = new JobException(Type.FATAL) JobException jobError = new JobException(Type.FATAL, "Error message")
.setErrorMessage("Error message")
.setErrorDetail("Error detail"); .setErrorDetail("Error detail");
dao.setJobError("pippo3", jobError); dao.setJobError("pippo3", jobError);
......
...@@ -24,7 +24,6 @@ import java.util.Map; ...@@ -24,7 +24,6 @@ import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import net.ivoa.xml.uws.v1.ExecutionPhase;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
...@@ -41,8 +40,6 @@ import org.mockito.InjectMocks; ...@@ -41,8 +40,6 @@ import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
...@@ -203,8 +200,6 @@ public class ArchiveServiceTest { ...@@ -203,8 +200,6 @@ public class ArchiveServiceTest {
archiveService.createArchive(job); archiveService.createArchive(job);
verify(jobDAO, times(1)).updateJobPhase(eq(ExecutionPhase.COMPLETED), eq(job.getJobId()));
File result = tmpDir.toPath().resolve("user123").resolve("abcdef." + extension).toFile(); File result = tmpDir.toPath().resolve("user123").resolve("abcdef." + extension).toFile();
assertTrue(result.exists()); assertTrue(result.exists());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment