package org.dcache.srm.handler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.dcache.srm.AbstractStorageElement; import org.dcache.srm.SRM; import org.dcache.srm.SRMUser; import org.dcache.srm.SrmReleaseSpaceCallback; import org.dcache.srm.v2_2.SrmReleaseSpaceRequest; import org.dcache.srm.v2_2.SrmReleaseSpaceResponse; import org.dcache.srm.v2_2.TReturnStatus; import org.dcache.srm.v2_2.TStatusCode; import static com.google.common.base.Preconditions.checkNotNull; import static java.util.concurrent.TimeUnit.MINUTES; public class SrmReleaseSpace { private static final Logger LOGGER = LoggerFactory.getLogger(SrmReleaseSpace.class); private static final long TIMEOUT = MINUTES.toMillis(1); private final AbstractStorageElement storage; private final SrmReleaseSpaceRequest request; private final SRMUser user; private SrmReleaseSpaceResponse response; public SrmReleaseSpace(SRMUser user, SrmReleaseSpaceRequest request, AbstractStorageElement storage, SRM srm, String clientHost) { this.request = checkNotNull(request); this.user = checkNotNull(user); this.storage = checkNotNull(storage); } public SrmReleaseSpaceResponse getResponse() { if (response == null) { response = releaseSpace(); } return response; } private SrmReleaseSpaceResponse releaseSpace() { String token = request.getSpaceToken(); Callback callback = new Callback(); storage.srmReleaseSpace(user, token, null, callback); TReturnStatus status = callback.waitResult(TIMEOUT); return new SrmReleaseSpaceResponse(status); } private class Callback implements SrmReleaseSpaceCallback { private final CountDownLatch latch = new CountDownLatch(1); private TReturnStatus status; public TReturnStatus waitResult(long timeout) { try { if (!latch.await(timeout, TimeUnit.MILLISECONDS)) { return new TReturnStatus(TStatusCode.SRM_INTERNAL_ERROR, "Operation timed out"); } } catch (InterruptedException e) { return new TReturnStatus(TStatusCode.SRM_INTERNAL_ERROR, "Operation interrupted"); } return status; } private void completed(TReturnStatus status) { this.status = status; latch.countDown(); } @Override public void failed(String reason) { completed(new TReturnStatus(TStatusCode.SRM_FAILURE, reason)); } @Override public void internalError(String reason) { completed(new TReturnStatus(TStatusCode.SRM_INTERNAL_ERROR, reason)); } @Override public void invalidRequest(String reason) { completed(new TReturnStatus(TStatusCode.SRM_INVALID_REQUEST, reason)); } @Override public void success(String spaceReservationToken, long remainingSpaceSize) { completed(new TReturnStatus(TStatusCode.SRM_SUCCESS, null)); } } public static SrmReleaseSpaceResponse getFailedResponse(String text) { return getFailedResponse(text, TStatusCode.SRM_FAILURE); } public static SrmReleaseSpaceResponse getFailedResponse(String text, TStatusCode statusCode) { return new SrmReleaseSpaceResponse(new TReturnStatus(statusCode, text)); } }