use of org.dcache.srm.v2_2.TStatusCode.SRM_EXCEED_ALLOCATION in project dcache by dCache.
the class Storage method prepareToPut.
@Override
public CheckedFuture<String, ? extends SRMException> prepareToPut(final SRMUser srmUser, URI surl, Long size, String accessLatency, String retentionPolicy, String spaceToken, boolean overwrite) {
try {
DcacheUser user = asDcacheUser(srmUser);
Subject subject = user.getSubject();
Restriction restriction = user.getRestriction();
FsPath fullPath = getPath(surl);
if (spaceToken != null) {
if (!_isSpaceManagerEnabled) {
return immediateFailedCheckedFuture(new SRMNotSupportedException(SPACEMANAGER_DISABLED_MESSAGE));
}
/* This check could and maybe should be done on the SRM side of AbstractStorageElement:
* The targetSpaceToken is the same for all SURLs in an srmPrepareToPut request, and the
* SRM_EXCEED_ALLOCATION should also be returned if the entire srmPrepareToPut request
* is larger than available space in the reservation - that's a check we cannot possibly
* to on an individual SURL.
*/
try {
Optional<Space> optionalSpace = spaces.get(spaceToken);
if (!optionalSpace.isPresent()) {
return immediateFailedCheckedFuture(new SRMInvalidRequestException("The space token " + spaceToken + " does not refer to an existing known space reservation."));
}
Space space = optionalSpace.get();
if (space.getExpirationTime() != null && space.getExpirationTime() < System.currentTimeMillis()) {
return immediateFailedCheckedFuture(new SRMSpaceLifetimeExpiredException("Space reservation associated with the space token " + spaceToken + " is expired."));
}
if (size != null && space.getAvailableSpaceInBytes() < size) {
return immediateFailedCheckedFuture(new SRMExceedAllocationException("Space associated with the space token " + spaceToken + " is not enough to hold SURL."));
}
} catch (ExecutionException e) {
return immediateFailedCheckedFuture(new SRMException("Failure while querying space reservation: " + e.getCause().getMessage()));
}
}
AccessLatency al = (accessLatency != null) ? AccessLatency.valueOf(accessLatency) : null;
RetentionPolicy rp = (retentionPolicy != null) ? RetentionPolicy.valueOf(retentionPolicy) : null;
EnumSet<CreateOption> options = EnumSet.noneOf(CreateOption.class);
if (overwrite) {
options.add(CreateOption.OVERWRITE_EXISTING);
}
if (config.isRecursiveDirectoryCreation()) {
options.add(CreateOption.CREATE_PARENTS);
}
PnfsCreateUploadPath msg = new PnfsCreateUploadPath(subject, restriction, fullPath, user.getRoot(), size, al, rp, spaceToken, options);
final SettableFuture<String> future = SettableFuture.create();
CellStub.addCallback(_pnfsStub.send(msg), new AbstractMessageCallback<PnfsCreateUploadPath>() {
int failures = 0;
@Override
public void success(PnfsCreateUploadPath message) {
future.set(message.getUploadPath().toString());
}
@Override
public void failure(int rc, Object error) {
failures++;
String msg = Objects.toString(error, "");
switch(rc) {
case CacheException.PERMISSION_DENIED:
future.setException(new SRMAuthorizationException(msg));
break;
case CacheException.FILE_EXISTS:
future.setException(new SRMDuplicationException(msg));
break;
case CacheException.FILE_NOT_FOUND:
case CacheException.NOT_DIR:
future.setException(new SRMInvalidPathException(msg));
break;
case CacheException.LOCKED:
if (failures < 3) {
/* Usually due to concurrent uploads to the same non-existing target
* directory. Retry a few times.
*/
PnfsCreateUploadPath retry = new PnfsCreateUploadPath(subject, restriction, fullPath, user.getRoot(), size, al, rp, spaceToken, options);
CellStub.addCallback(_pnfsStub.send(retry), this, _executor);
} else {
future.setException(new SRMInternalErrorException(msg));
}
break;
case CacheException.TIMEOUT:
default:
future.setException(new SRMInternalErrorException(msg));
break;
}
}
}, _executor);
return Futures.makeChecked(future, new ToSRMException());
} catch (SRMAuthorizationException | SRMInvalidPathException e) {
return immediateFailedCheckedFuture(e);
}
}
Aggregations