Newer
Older
import it.inaf.ia2.aa.data.User;
import it.inaf.oats.vospace.persistence.JobDAO;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.uws.v1.ExecutionPhase;
import net.ivoa.xml.uws.v1.JobSummary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
Sonia Zorba
committed
import java.util.Arrays;
import java.util.HashSet;
Sonia Zorba
committed
import net.ivoa.xml.vospace.v2.Protocol;
@RestController
public class TransferController {
@Autowired
private JobDAO jobDAO;
@Autowired
private HttpServletRequest request;
@Autowired
private JobService jobService;
consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> postAsyncTransfer(@RequestBody Transfer transfer,
@RequestParam(value = "PHASE", required = false) Optional<String> phase, User principal) {
JobSummary jobSummary = newJobSummary(transfer, principal);
if (phase.isPresent()) {
jobService.setJobPhase(jobSummary, phase.get());
return getJobRedirect(jobSummary.getJobId());
}
@PostMapping(value = "/synctrans",
consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> postSyncTransfer(@RequestBody Transfer transfer, User principal) {
JobSummary jobSummary = newJobSummary(transfer, principal);
jobService.createSyncJobResult(jobSummary);
HttpHeaders headers = new HttpHeaders();
headers.set("Location", request.getContextPath() + "/transfers/" + jobSummary.getJobId() + "/results/transferDetails");
return new ResponseEntity<>(headers, HttpStatus.SEE_OTHER);
Sonia Zorba
committed
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
@GetMapping("/synctrans")
public ResponseEntity<?> syncTransferUrlParamsMode(@RequestParam("TARGET") String target,
@RequestParam("DIRECTION") String direction, @RequestParam("PROTOCOL") String protocolUris, User principal) {
Transfer transfer = new Transfer();
transfer.setTarget(target);
transfer.setDirection(direction);
// CADC client sends multiple protocol parameters and Spring join them using a comma separator.
// Some values seems to be duplicated, so a set is used to avoid the duplication
for (String protocolUri : new HashSet<>(Arrays.asList(protocolUris.split(",")))) {
Protocol protocol = new Protocol();
protocol.setUri(protocolUri);
transfer.getProtocols().add(protocol);
}
JobSummary jobSummary = newJobSummary(transfer, principal);
jobService.createSyncJobResult(jobSummary);
if (jobSummary.getErrorSummary() != null) {
// TODO: decide how to hanlde HTTP error codes
// If an error occurs with the synchronous convenience mode where the preferred endpoint
// is immediately returned as a redirect, the error information is returned directly in
// the response body with the associated HTTP status code.
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(jobSummary.getErrorSummary().getMessage());
}
// Behaves as if REQUEST=redirect was set, for compatibility with CADC client
String endpoint = transfer.getProtocols().get(0).getEndpoint();
HttpHeaders headers = new HttpHeaders();
headers.set("Location", endpoint);
return new ResponseEntity<>(headers, HttpStatus.SEE_OTHER);
}
@GetMapping(value = "/transfers/{jobId}", produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<JobSummary> getJob(@PathVariable("jobId") String jobId) {
return jobDAO.getJob(jobId).map(j -> ResponseEntity.ok(j)).orElse(ResponseEntity.notFound().build());
}
@PostMapping(value = "/transfers/{jobId}/phase")
public ResponseEntity<?> setJobPhase(@PathVariable("jobId") String jobId, @RequestParam("PHASE") String phase, User principal) {
return jobDAO.getJob(jobId).map(job -> {
if (!job.getOwnerId().equals(principal.getName())) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
jobService.setJobPhase(job, phase);
return getJobRedirect(job.getJobId());
}).orElse(ResponseEntity.notFound().build());
}
@GetMapping(value = "/transfers/{jobId}/results/transferDetails", produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> getTransferDetails(@PathVariable("jobId") String jobId, User principal) {
return jobDAO.getJob(jobId).map(job -> {
if (!job.getOwnerId().equals(principal.getName())) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
// TODO: check type
return ResponseEntity.ok((Transfer) (job.getJobInfo().getAny().get(0)));
}).orElse(ResponseEntity.notFound().build());
}
@GetMapping(value = "/transfers/{jobId}/phase", produces = MediaType.TEXT_PLAIN_VALUE)
public ResponseEntity<?> getTransferJobPhase(@PathVariable("jobId") String jobId, User principal) {
// TODO: error handling
return ResponseEntity.ok(jobDAO.getJob(jobId).get().getPhase().toString());
}
@GetMapping(value = "/transfers", produces = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<?> getTransfers(
@RequestParam(value = "PHASE", required = false) Optional<List<ExecutionPhase>> phase,
@RequestParam(value = "AFTER", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Optional<LocalDateTime> after,
@RequestParam(value = "LAST", required = false) Optional<Integer> last,
@RequestParam(value = "direction", required = false) Optional<List<JobService.JobType>> direction,
Nicola Fulvio Calabria
committed
User principal) {
if (last.isPresent()) {
if (last.get() <= 0) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
Nicola Fulvio Calabria
committed
}
}
String userId = principal.getName();
List<ExecutionPhase> phaseList;
if (phase.isPresent()) {
phaseList = phase.get();
} else {
phaseList = List.of();
}
List<JobService.JobType> directionList;
if (direction.isPresent()) {
directionList = direction.get();
} else {
directionList = List.of();
Nicola Fulvio Calabria
committed
}
Jobs jobs = jobDAO.getJobs(userId, phaseList, directionList, after, last);
return ResponseEntity.ok(jobs);
}
private JobSummary newJobSummary(Transfer transfer, User principal) {
String jobId = UUID.randomUUID().toString().replace("-", "");
Sonia Zorba
committed
JobSummary jobSummary = new JobSummary();
jobSummary.setJobId(jobId);
jobSummary.setOwnerId(principal.getName());
jobSummary.setPhase(ExecutionPhase.PENDING);
JobSummary.JobInfo jobInfo = new JobSummary.JobInfo();
jobInfo.getAny().add(transfer);
jobSummary.setJobInfo(jobInfo);
return jobSummary;
}
private ResponseEntity<?> getJobRedirect(String jobId) {
HttpHeaders headers = new HttpHeaders();
headers.set("Location", request.getContextPath() + "/transfers/" + jobId);
return new ResponseEntity<>(headers, HttpStatus.SEE_OTHER);