use of org.dcache.srm.SRMException in project dcache by dCache.
the class Storage method srmGetSpaceMetaData.
/**
* @param spaceTokens
* @return
* @throws SRMException
*/
@Override
public TMetaDataSpace[] srmGetSpaceMetaData(SRMUser user, String[] spaceTokens) throws SRMException {
guardSpaceManagerEnabled();
GetSpaceMetaData getSpaces = new GetSpaceMetaData(spaceTokens);
try {
getSpaces = _spaceManagerStub.sendAndWait(getSpaces);
} catch (TimeoutCacheException e) {
throw new SRMInternalErrorException("Space manager timeout", e);
} catch (NoRouteToCellException e) {
throw new SRMNotSupportedException("Space manager is unavailable", e);
} catch (InterruptedException e) {
throw new SRMInternalErrorException("Operation interrupted", e);
} catch (CacheException e) {
_log.warn("GetSpaceMetaData failed with rc={} error={}", e.getRc(), e.getMessage());
throw new SRMException("Space manager failure: " + e.getMessage(), e);
}
Space[] spaces = getSpaces.getSpaces();
TMetaDataSpace[] spaceMetaDatas = new TMetaDataSpace[spaces.length];
for (int i = 0; i < spaceMetaDatas.length; ++i) {
Space space = spaces[i];
TMetaDataSpace metaDataSpace = new TMetaDataSpace();
TReturnStatus status;
if (space != null) {
Long expirationTime = space.getExpirationTime();
if (expirationTime == null) {
metaDataSpace.setLifetimeAssigned(-1);
metaDataSpace.setLifetimeLeft(-1);
} else {
long lifetimeleft = Math.max(0, MILLISECONDS.toSeconds(expirationTime - System.currentTimeMillis()));
metaDataSpace.setLifetimeAssigned((int) MILLISECONDS.toSeconds(expirationTime - space.getCreationTime()));
metaDataSpace.setLifetimeLeft((int) lifetimeleft);
}
RetentionPolicy retentionPolicy = space.getRetentionPolicy();
TRetentionPolicy policy = retentionPolicy.equals(RetentionPolicy.CUSTODIAL) ? TRetentionPolicy.CUSTODIAL : retentionPolicy.equals(RetentionPolicy.OUTPUT) ? TRetentionPolicy.OUTPUT : TRetentionPolicy.REPLICA;
AccessLatency accessLatency = space.getAccessLatency();
TAccessLatency latency = accessLatency.equals(AccessLatency.ONLINE) ? TAccessLatency.ONLINE : TAccessLatency.NEARLINE;
UnsignedLong totalSize = new UnsignedLong(space.getSizeInBytes());
UnsignedLong unusedSize = new UnsignedLong(space.getSizeInBytes() - space.getUsedSizeInBytes());
metaDataSpace.setRetentionPolicyInfo(new TRetentionPolicyInfo(policy, latency));
metaDataSpace.setTotalSize(totalSize);
metaDataSpace.setGuaranteedSize(totalSize);
metaDataSpace.setUnusedSize(unusedSize);
SpaceState spaceState = space.getState();
switch(spaceState) {
case RESERVED:
status = new TReturnStatus(TStatusCode.SRM_SUCCESS, null);
break;
case EXPIRED:
status = new TReturnStatus(TStatusCode.SRM_SPACE_LIFETIME_EXPIRED, "The lifetime on the space that is associated with the spaceToken has expired already");
break;
default:
status = new TReturnStatus(TStatusCode.SRM_FAILURE, "Space has been released");
break;
}
metaDataSpace.setOwner("VoGroup=" + space.getVoGroup() + " VoRole=" + space.getVoRole());
} else {
status = new TReturnStatus(TStatusCode.SRM_INVALID_REQUEST, "No such space");
}
metaDataSpace.setStatus(status);
metaDataSpace.setSpaceToken(spaceTokens[i]);
spaceMetaDatas[i] = metaDataSpace;
}
return spaceMetaDatas;
}
use of org.dcache.srm.SRMException in project dcache by dCache.
the class Storage method removeDirectory.
@Override
public void removeDirectory(SRMUser user, URI surl, boolean recursive) throws SRMException {
Subject subject = asDcacheUser(user).getSubject();
Restriction restriction = asDcacheUser(user).getRestriction();
FsPath path = getPath(surl);
if (path.isRoot()) {
throw new SRMAuthorizationException("Permission denied");
}
if (recursive) {
removeSubdirectories(subject, restriction, path);
}
try {
PnfsHandler pnfs = new PnfsHandler(_pnfs, subject, restriction);
pnfs.deletePnfsEntry(path.toString(), EnumSet.of(FileType.DIR));
} catch (TimeoutCacheException e) {
throw new SRMInternalErrorException("Name space timeout");
} catch (FileNotFoundCacheException ignored) {
throw new SRMInvalidPathException("No such file or directory");
} catch (NotDirCacheException e) {
throw new SRMInvalidPathException("Not a directory");
} catch (PermissionDeniedCacheException e) {
throw new SRMAuthorizationException("Permission denied", e);
} catch (CacheException e) {
try {
int count = _listSource.printDirectory(subject, restriction, new NullListPrinter(), path, null, Range.<Integer>all());
if (count > 0) {
throw new SRMNonEmptyDirectoryException("Directory is not empty", e);
}
} catch (InterruptedException | CacheException suppressed) {
e.addSuppressed(suppressed);
}
_log.error("Failed to delete {}: {}", path, e.getMessage());
throw new SRMException("Name space failure (" + e.getMessage() + ")", e);
}
}
use of org.dcache.srm.SRMException 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);
}
}
use of org.dcache.srm.SRMException in project dcache by dCache.
the class ReservationCaches method buildOwnerDescriptionLookupCache.
/**
* Builds a loading cache for looking up space tokens by owner and description.
*/
public static LoadingCache<GetSpaceTokensKey, long[]> buildOwnerDescriptionLookupCache(CellStub spaceManager, Executor executor) {
return CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(30, SECONDS).refreshAfterWrite(10, SECONDS).recordStats().build(new CacheLoader<GetSpaceTokensKey, long[]>() {
@Override
public long[] load(GetSpaceTokensKey key) throws Exception {
try {
return spaceManager.sendAndWait(createRequest(key)).getSpaceTokens();
} catch (TimeoutCacheException e) {
throw new SRMInternalErrorException("Space manager timeout", e);
} catch (InterruptedException e) {
throw new SRMInternalErrorException("Operation interrupted", e);
} catch (CacheException e) {
LOGGER.warn("GetSpaceTokens failed with rc={} error={}", e.getRc(), e.getMessage());
throw new SRMException("GetSpaceTokens failed with rc=" + e.getRc() + " error=" + e.getMessage(), e);
}
}
private GetSpaceTokens createRequest(GetSpaceTokensKey key) {
GetSpaceTokens message = new GetSpaceTokens(key.description);
message.setSubject(new Subject(true, key.principals, Collections.emptySet(), Collections.emptySet()));
return message;
}
@Override
public ListenableFuture<long[]> reload(GetSpaceTokensKey key, long[] oldValue) throws Exception {
final SettableFuture<long[]> future = SettableFuture.create();
CellStub.addCallback(spaceManager.send(createRequest(key)), new AbstractMessageCallback<GetSpaceTokens>() {
@Override
public void success(GetSpaceTokens message) {
future.set(message.getSpaceTokens());
}
@Override
public void failure(int rc, Object error) {
CacheException exception = CacheExceptionFactory.exceptionOf(rc, Objects.toString(error, null));
future.setException(exception);
}
}, executor);
return future;
}
});
}
use of org.dcache.srm.SRMException in project dcache by dCache.
the class SrmMv method srmMv.
private SrmMvResponse srmMv() {
TReturnStatus returnStatus;
try {
URI to_surl = URI.create(request.getToSURL().toString());
URI from_surl = URI.create(request.getFromSURL().toString());
// SURL is busy.
if (srm.isFileBusy(from_surl)) {
returnStatus = new TReturnStatus(TStatusCode.SRM_FILE_BUSY, "The source SURL is being used by another client.");
} else if (srm.isFileBusy(to_surl)) {
returnStatus = new TReturnStatus(TStatusCode.SRM_DUPLICATION_ERROR, "The target SURL is being used by another client.");
} else {
storage.moveEntry(user, from_surl, to_surl);
returnStatus = new TReturnStatus(TStatusCode.SRM_SUCCESS, null);
}
} catch (SRMDuplicationException e) {
returnStatus = new TReturnStatus(TStatusCode.SRM_DUPLICATION_ERROR, e.getMessage());
} catch (SRMInternalErrorException e) {
LOGGER.error(e.toString());
returnStatus = new TReturnStatus(TStatusCode.SRM_INTERNAL_ERROR, e.getMessage());
} catch (SRMInvalidPathException e) {
returnStatus = new TReturnStatus(TStatusCode.SRM_INVALID_PATH, e.getMessage());
} catch (SRMAuthorizationException e) {
LOGGER.warn(e.toString());
returnStatus = new TReturnStatus(TStatusCode.SRM_AUTHORIZATION_FAILURE, e.getMessage());
} catch (SRMException e) {
LOGGER.error(e.toString());
returnStatus = new TReturnStatus(TStatusCode.SRM_FAILURE, e.getMessage());
}
return new SrmMvResponse(returnStatus);
}
Aggregations