Newer
Older
import it.inaf.ia2.aa.ServletRapClient;
import it.inaf.ia2.aa.data.User;
import it.inaf.ia2.rap.client.call.TokenExchangeRequest;
Nicola Fulvio Calabria
committed
import it.inaf.oats.vospace.JobService.JobType;
import it.inaf.oats.vospace.datamodel.NodeProperties;
Nicola Fulvio Calabria
committed
import it.inaf.oats.vospace.datamodel.NodeUtils;
import static it.inaf.oats.vospace.datamodel.NodeUtils.urlEncodePath;
import it.inaf.oats.vospace.exception.InternalFaultException;
import it.inaf.oats.vospace.exception.NodeNotFoundException;
import it.inaf.oats.vospace.exception.PermissionDeniedException;
Nicola Fulvio Calabria
committed
import it.inaf.oats.vospace.exception.ProtocolNotSupportedException;
import it.inaf.oats.vospace.exception.NodeBusyException;
import it.inaf.oats.vospace.persistence.LocationDAO;
import it.inaf.oats.vospace.persistence.NodeDAO;
import it.inaf.oats.vospace.persistence.model.Location;
import it.inaf.oats.vospace.persistence.model.LocationType;
import java.net.MalformedURLException;
import java.net.URL;
Nicola Fulvio Calabria
committed
import java.util.Arrays;
Nicola Fulvio Calabria
committed
import java.util.Optional;
import javax.servlet.http.HttpServletRequest;
import net.ivoa.xml.uws.v1.JobSummary;
import net.ivoa.xml.uws.v1.ResultReference;
import net.ivoa.xml.vospace.v2.Node;
Nicola Fulvio Calabria
committed
import net.ivoa.xml.vospace.v2.Param;
import net.ivoa.xml.vospace.v2.Protocol;
import net.ivoa.xml.vospace.v2.Transfer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class UriService {
@Value("${vospace-authority}")
private String authority;
@Value("${file-service-url}")
private String fileServiceUrl;
@Autowired
private NodeDAO nodeDao;
Nicola Fulvio Calabria
committed
@Autowired
private LocationDAO locationDAO;
@Autowired
private HttpServletRequest servletRequest;
@Autowired
private ServletRapClient rapClient;
public void setTransferJobResult(JobSummary job, Transfer transfer) {
List<ResultReference> results = new ArrayList<>();
Nicola Fulvio Calabria
committed
ResultReference result = new ResultReference();
result.setHref(getEndpoint(job, transfer));
results.add(result);
job.setResults(results);
Nicola Fulvio Calabria
committed
// Moved phase setting to caller method for ERROR management
// job.setPhase(ExecutionPhase.COMPLETED);
public void setSyncTransferEndpoints(JobSummary job) {
Transfer transfer = getTransfer(job);
Protocol protocol = transfer.getProtocols().get(0);
if (!"ivo://ivoa.net/vospace/core#httpget".equals(protocol.getUri())
&& !"ivo://ivoa.net/vospace/core#httpput".equals(protocol.getUri())) {
Nicola Fulvio Calabria
committed
// throw new IllegalStateException("Unsupported protocol " + protocol.getUri());
throw new ProtocolNotSupportedException(protocol.getUri());
protocol.setEndpoint(getEndpoint(job, transfer));
private String getEndpoint(JobSummary job, Transfer transfer) {
String relativePath = transfer.getTarget().substring("vos://".length() + authority.length());
Node node = nodeDao.listNode(relativePath).orElseThrow(() -> new NodeNotFoundException(relativePath));
Nicola Fulvio Calabria
committed
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
User user = (User) servletRequest.getUserPrincipal();
String creator = user.getName();
List<String> groups = user.getGroups();
// Check privileges write or read according to job type
JobService.JobType jobType = JobType.valueOf(transfer.getDirection());
switch (jobType) {
case pushToVoSpace:
case pullToVoSpace:
if (!NodeUtils.checkIfWritable(node, creator, groups)) {
throw new PermissionDeniedException(relativePath);
}
break;
case pullFromVoSpace:
if (!NodeUtils.checkIfReadable(node, creator, groups)) {
throw new PermissionDeniedException(relativePath);
}
break;
default:
throw new InternalFaultException("No job direction specified");
}
if (NodeUtils.getIsBusy(node)) {
throw new NodeBusyException(relativePath);
}
Location location = locationDAO.getNodeLocation(relativePath).orElse(null);
if (location != null && location.getType() == LocationType.PORTAL) {
String fileName = nodeDao.getNodeOsName(relativePath);
endpoint = "http://" + location.getSource().getHostname() + location.getSource().getBaseUrl();
if (!endpoint.endsWith("/")) {
endpoint += "/";
}
endpoint += fileName;
} else {
endpoint = fileServiceUrl + urlEncodePath(relativePath);
}
endpoint += "?jobId=" + job.getJobId();
if (!"true".equals(NodeProperties.getNodePropertyByURI(node, NodeProperties.PUBLIC_READ_URI))) {
endpoint += "&token=" + getEndpointToken(fileServiceUrl + relativePath);
}
return endpoint;
}
private String getEndpointToken(String endpoint) {
String token = ((User) servletRequest.getUserPrincipal()).getAccessToken();
if (token == null) {
throw new PermissionDeniedException("Token is null");
}
TokenExchangeRequest exchangeRequest = new TokenExchangeRequest()
.setSubjectToken(token)
.setResource(endpoint);
// TODO: add audience and scope
return rapClient.exchangeToken(exchangeRequest, servletRequest);
}
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
public void setNodeRemoteLocation(String nodeUri, String contentUri) {
URL url;
try {
url = new URL(contentUri);
} catch (MalformedURLException ex) {
throw new InternalFaultException(ex);
}
Location location = locationDAO.findPortalLocation(url.getHost()).orElseThrow(()
-> new InternalFaultException("No registered location found for host " + url.getHost()));
String vosPath = nodeUri.replaceAll("vos://[^/]+", "");
String fileName = url.getPath().substring(url.getPath().lastIndexOf("/") + 1);
nodeDao.setNodeLocation(vosPath, location.getId(), fileName);
}
public Transfer getTransfer(JobSummary job) {
List<Object> jobPayload = job.getJobInfo().getAny();
if (jobPayload.isEmpty()) {
throw new IllegalStateException("Empty job payload for job " + job.getJobId());
}
if (jobPayload.size() > 1) {
throw new IllegalStateException("Multiple objects in job payload not supported");
}
if (!(jobPayload.get(0) instanceof Transfer)) {
throw new IllegalStateException(jobPayload.get(0).getClass().getCanonicalName()
+ " not supported as job payload. Job id: " + job.getJobId());
}
return (Transfer) job.getJobInfo().getAny().get(0);
}