package org.dcache.srm.handler; import com.google.common.collect.ImmutableMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URI; import java.util.concurrent.TimeUnit; import org.dcache.srm.AbstractStorageElement; import org.dcache.srm.SRM; import org.dcache.srm.SRMInternalErrorException; import org.dcache.srm.SRMInvalidRequestException; import org.dcache.srm.SRMNotSupportedException; import org.dcache.srm.SRMUser; import org.dcache.srm.request.CopyRequest; import org.dcache.srm.request.RequestCredential; import org.dcache.srm.scheduler.IllegalStateTransition; import org.dcache.srm.util.Configuration; import org.dcache.srm.util.JDC; import org.dcache.srm.util.Lifetimes; import org.dcache.srm.v2_2.ArrayOfTExtraInfo; import org.dcache.srm.v2_2.SrmCopyRequest; import org.dcache.srm.v2_2.SrmCopyResponse; import org.dcache.srm.v2_2.TAccessLatency; import org.dcache.srm.v2_2.TCopyFileRequest; import org.dcache.srm.v2_2.TExtraInfo; import org.dcache.srm.v2_2.TOverwriteMode; import org.dcache.srm.v2_2.TRetentionPolicy; import org.dcache.srm.v2_2.TReturnStatus; import org.dcache.srm.v2_2.TStatusCode; import static com.google.common.base.Preconditions.checkNotNull; public class SrmCopy implements CredentialAwareHandler { private static final Logger LOGGER = LoggerFactory.getLogger(SrmCopy.class); private final SrmCopyRequest request; private final SRMUser user; private final SRM srm; private final Configuration configuration; private final String clientHost; private RequestCredential credential; private SrmCopyResponse response; public SrmCopy(SRMUser user, SrmCopyRequest request, AbstractStorageElement storage, SRM srm, String clientHost) { this.request = checkNotNull(request); this.user = checkNotNull(user); this.configuration = srm.getConfiguration(); this.clientHost = clientHost; this.srm = checkNotNull(srm); } @Override public void setCredential(RequestCredential credential) { this.credential = checkNotNull(credential); } public SrmCopyResponse getResponse() { if (response == null) { try { response = srmCopy(); } catch (SRMInvalidRequestException e) { response = getFailedResponse(e.getMessage(), TStatusCode.SRM_INVALID_REQUEST); } catch (SRMNotSupportedException e) { response = getFailedResponse(e.getMessage(), TStatusCode.SRM_NOT_SUPPORTED); } catch (SRMInternalErrorException e) { LOGGER.error(e.getMessage()); response = getFailedResponse(e.getMessage(), TStatusCode.SRM_INTERNAL_ERROR); } } return response; } private SrmCopyResponse srmCopy() throws SRMInvalidRequestException, SRMNotSupportedException, SRMInternalErrorException { TCopyFileRequest[] arrayOfFileRequests = getFileRequests(request); long lifetime = Lifetimes.calculateLifetime(request.getDesiredTotalRequestTime(), configuration.getCopyLifetime()); String spaceToken = request.getTargetSpaceToken(); URI from_urls[] = new URI[arrayOfFileRequests.length]; URI to_urls[] = new URI[arrayOfFileRequests.length]; for (int i = 0; i < arrayOfFileRequests.length; i++) { from_urls[i] = URI.create(arrayOfFileRequests[i].getSourceSURL().toString()); to_urls[i] = URI.create(arrayOfFileRequests[i].getTargetSURL().toString()); } TRetentionPolicy targetRetentionPolicy = null; TAccessLatency targetAccessLatency = null; if (request.getTargetFileRetentionPolicyInfo() != null) { targetRetentionPolicy = request.getTargetFileRetentionPolicyInfo().getRetentionPolicy(); targetAccessLatency = request.getTargetFileRetentionPolicyInfo().getAccessLatency(); } TOverwriteMode overwriteMode = getOverwriteMode(request); ImmutableMap<String,String> extraInfo = getExtraInfo(request); credential.acceptAlternative(extraInfo.get("credential")); CopyRequest r = new CopyRequest( user, credential.getId(), from_urls, to_urls, spaceToken, lifetime, configuration.getCopyMaxPollPeriod(), request.getTargetFileStorageType(), targetRetentionPolicy, targetAccessLatency, request.getUserRequestDescription(), clientHost, overwriteMode, extraInfo); try (JDC ignored = r.applyJdc()) { srm.schedule(r); return r.getSrmCopyResponse(); } catch (InterruptedException e) { throw new SRMInternalErrorException("Operation interrupted", e); } catch (IllegalStateTransition e) { throw new SRMInternalErrorException("Scheduling failure", e); } } private static ImmutableMap<String,String> getExtraInfo(SrmCopyRequest request) { ArrayOfTExtraInfo sourceStorageSystemInfo = request.getSourceStorageSystemInfo(); if (sourceStorageSystemInfo == null) { return ImmutableMap.of(); } TExtraInfo[] extraInfoArray = sourceStorageSystemInfo.getExtraInfoArray(); if (extraInfoArray == null || extraInfoArray.length <= 0) { return ImmutableMap.of(); } ImmutableMap.Builder<String,String> builder = ImmutableMap.builder(); for (TExtraInfo extraInfo : extraInfoArray) { builder.put(extraInfo.getKey(), extraInfo.getValue()); } return builder.build(); } private static TOverwriteMode getOverwriteMode(SrmCopyRequest request) throws SRMNotSupportedException { TOverwriteMode overwriteMode = request.getOverwriteOption(); if (overwriteMode != null && overwriteMode.equals(TOverwriteMode.WHEN_FILES_ARE_DIFFERENT)) { throw new SRMNotSupportedException("Overwrite Mode WHEN_FILES_ARE_DIFFERENT is not supported"); } return overwriteMode; } private static TCopyFileRequest[] getFileRequests(SrmCopyRequest request) throws SRMInvalidRequestException { if (request.getArrayOfFileRequests() == null) { throw new SRMInvalidRequestException("ArrayOfFileRequests is null"); } TCopyFileRequest[] arrayOfFileRequests = request.getArrayOfFileRequests().getRequestArray(); if (arrayOfFileRequests == null) { throw new SRMInvalidRequestException("null array of file requests"); } if (arrayOfFileRequests.length == 0) { throw new SRMInvalidRequestException("empty array of file requests"); } return arrayOfFileRequests; } public static final SrmCopyResponse getFailedResponse(String text) { return getFailedResponse(text, TStatusCode.SRM_FAILURE); } public static final SrmCopyResponse getFailedResponse(String text, TStatusCode statusCode) { SrmCopyResponse response = new SrmCopyResponse(); response.setReturnStatus(new TReturnStatus(statusCode, text)); return response; } }