Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
108
109
/*
* 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.service;
import it.inaf.ia2.transfer.persistence.FileDAO;
import it.inaf.ia2.transfer.persistence.model.FileInfo;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.kamranzafar.jtar.TarEntry;
import org.kamranzafar.jtar.TarOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class ArchiveService {
private static final Logger LOG = LoggerFactory.getLogger(ArchiveService.class);
private final static int BUFFER_SIZE = 100 * 1024;
@Autowired
private FileDAO fileDAO;
@Autowired
private AuthorizationService authorizationService;
private final File generatedDir;
public ArchiveService(@Value("${generated.dir}") String generatedDir) {
this.generatedDir = new File(generatedDir);
if (!this.generatedDir.exists()) {
if (!this.generatedDir.mkdirs()) {
throw new IllegalStateException("Unable to create directory " + this.generatedDir.getAbsolutePath());
}
}
}
public void createArchive(ArchiveJob job) {
LOG.trace("Started archive job " + job.getJobId());
try {
// TODO: check total size limit
// TODO: switch on archive type
File parentDir = generatedDir.toPath().resolve(job.getPrincipal().getName()).toFile();
if (!parentDir.exists()) {
if (!parentDir.mkdirs()) {
throw new IllegalStateException("Unable to create directory " + parentDir.getAbsolutePath());
}
}
File archiveFile = parentDir.toPath().resolve(job.getJobId() + ".tar").toFile();
if (!archiveFile.createNewFile()) {
throw new IllegalStateException("Unable to create file " + archiveFile.getAbsolutePath());
}
try ( TarOutputStream tos = new TarOutputStream(
new BufferedOutputStream(new FileOutputStream(archiveFile)))) {
for (FileInfo fileInfo : fileDAO.getArchiveFileInfos(job.getVosPaths())) {
// TODO: handle different locations
if (!authorizationService.isDownloadable(fileInfo, job.getPrincipal())) {
// TODO: proper exception type
throw new RuntimeException("Unauthorized");
}
File file = new File(fileInfo.getOsPath());
LOG.trace("Adding file " + file.getAbsolutePath() + " to tar archive");
writeFileIntoTarArchive(file, tos);
}
}
// TODO: update job status
} catch (Throwable t) {
LOG.error("Error happened creating archive", t);
}
}
private void writeFileIntoTarArchive(File file, TarOutputStream tos) throws IOException {
TarEntry tarEntry = new TarEntry(file, file.getName());
try ( InputStream is = new FileInputStream(file)) {
tos.putNextEntry(tarEntry);
try ( BufferedInputStream origin = new BufferedInputStream(is)) {
int count;
byte data[] = new byte[BUFFER_SIZE];
while ((count = origin.read(data)) != -1) {
tos.write(data, 0, count);
}
tos.flush();
}
}
}
}