Skip to content

Commit

Permalink
srm: Fix srmAbortFiles and srmAbortRequest implementations
Browse files Browse the repository at this point in the history
srmAbortFiles and srmAbortRequest are not at all compliant with the
SRM 2.2 spec. One symptom is that one may get failurs like

23 Sep 2013 23:06:57 (SRM-dcache-vm) [127.0.0.1:39844 t+Q:1:srm2:abortFiles:-2147482647] Illegal State Transition : Illegal state transition from Done to Canceled

when aborting requests that have already completed.

Another big fault is that the SURL return status used is that of
the file request, whereas the spec defines it to be the return
status of the abort operation, with only three legal return
values.

Finally, the return status of the entire request doesn't reflect the
return status of the individual SURLs.

These problems are addresses by this patch. A utility method for computing
a summary return status for the request has been added and a number of
otherwise unrelated classes are modified to make use of the utility method.

Target: trunk
Require-book: no
Require-notes: yes
Acked-by: Paul Millar <paul.millar@desy.de>
Acked-by: Dmitry Litvintsev <litvinse@fnal.gov>
Patch: http://rb.dcache.org/r/6040/
  • Loading branch information
gbehrmann committed Sep 29, 2013
1 parent cddd8ae commit 154f09d
Show file tree
Hide file tree
Showing 15 changed files with 414 additions and 350 deletions.
@@ -0,0 +1,37 @@
package org.dcache.srm.handler;

import org.dcache.srm.v2_2.TReturnStatus;
import org.dcache.srm.v2_2.TSURLReturnStatus;
import org.dcache.srm.v2_2.TStatusCode;

public class ReturnStatuses
{
private ReturnStatuses()
{
}

public static TReturnStatus getSummaryReturnStatus(TSURLReturnStatus[] returnStatuses)
{
boolean hasFailure = false;
boolean hasSuccess = false;
for (TSURLReturnStatus returnStatus : returnStatuses) {
if (returnStatus.getStatus().getStatusCode() == TStatusCode.SRM_SUCCESS) {
hasSuccess = true;
} else {
hasFailure = true;
}
}
return getSummaryReturnStatus(hasFailure, hasSuccess);
}

public static TReturnStatus getSummaryReturnStatus(boolean hasFailure, boolean hasSuccess)
{
if (!hasFailure) {
return new TReturnStatus(TStatusCode.SRM_SUCCESS, null);
} else if (!hasSuccess) {
return new TReturnStatus(TStatusCode.SRM_FAILURE, "The operation failed for all SURLs");
} else {
return new TReturnStatus(TStatusCode.SRM_PARTIAL_SUCCESS, "The operation failed for some SURLs");
}
}
}
@@ -1,183 +1,112 @@
/*
* SrmLs.java
*
* Created on October 4, 2005, 3:40 PM
*/

package org.dcache.srm.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.net.URISyntaxException;

import org.dcache.srm.AbstractStorageElement;
import org.dcache.srm.SRM;
import org.dcache.srm.SRMException;
import org.dcache.srm.SRMFileRequestNotFoundException;
import org.dcache.srm.SRMInvalidRequestException;
import org.dcache.srm.SRMUser;
import org.dcache.srm.request.ContainerRequest;
import org.dcache.srm.request.FileRequest;
import org.dcache.srm.request.Job;
import org.dcache.srm.request.Request;
import org.dcache.srm.request.RequestCredential;
import org.dcache.srm.scheduler.IllegalStateTransition;
import org.dcache.srm.scheduler.Scheduler;
import org.dcache.srm.scheduler.State;
import org.dcache.srm.util.Configuration;
import org.dcache.srm.util.JDC;
import org.dcache.srm.v2_2.ArrayOfAnyURI;
import org.dcache.srm.v2_2.ArrayOfTSURLReturnStatus;
import org.dcache.srm.v2_2.SrmAbortFilesRequest;
import org.dcache.srm.v2_2.SrmAbortFilesResponse;
import org.dcache.srm.v2_2.TReturnStatus;
import org.dcache.srm.v2_2.TSURLReturnStatus;
import org.dcache.srm.v2_2.TStatusCode;

import static org.dcache.srm.handler.ReturnStatuses.getSummaryReturnStatus;

/**
*
* @author timur
*/
public class SrmAbortFiles {

private static Logger logger =
LoggerFactory.getLogger(SrmAbortFiles.class);
public class SrmAbortFiles
{
private final SrmAbortFilesRequest request;
private SrmAbortFilesResponse response;

private final static String SFN_STRING="?SFN=";
AbstractStorageElement storage;
SrmAbortFilesRequest srmAbortFilesRequest;
SrmAbortFilesResponse response;
Scheduler getScheduler;
SRMUser user;
RequestCredential credential;
Configuration configuration;
private int results_num;
private int max_results_num;
int numOfLevels;
/** Creates a new instance of SrmLs */
public SrmAbortFiles(
SRMUser user,
RequestCredential credential,
SrmAbortFilesRequest srmAbortFilesRequest,
SrmAbortFilesRequest request,
AbstractStorageElement storage,
SRM srm,
String client_host) {
this.srmAbortFilesRequest = srmAbortFilesRequest;
this.user = user;
this.credential = credential;
this.storage = storage;
this.getScheduler = srm.getGetRequestScheduler();
this.configuration = srm.getConfiguration();
}

boolean longFormat;
String servicePathAndSFNPart = "";
int port;
String host;
public SrmAbortFilesResponse getResponse() {
if(response != null ) {
return response;
}
try {
response = srmAbortFiles();
} catch(URISyntaxException mue) {
logger.debug(" malformed uri : "+mue.getMessage());
response = getFailedResponse(" malformed uri : "+mue.getMessage(),
TStatusCode.SRM_INVALID_REQUEST);
} catch(SRMInvalidRequestException ire) {
logger.debug(" invalid request : "+ire.getMessage());
response = getFailedResponse(" invalid request : "+ire.getMessage(),
TStatusCode.SRM_INVALID_REQUEST);
} catch(SRMException srme) {
logger.error(srme.toString());
response = getFailedResponse(srme.toString());
} catch(IllegalStateTransition ist) {
logger.error("Illegal State Transition : " +ist.getMessage());
response = getFailedResponse("Illegal State Transition : " +ist.getMessage());
}
return response;
}

public static final SrmAbortFilesResponse getFailedResponse(String error) {
return getFailedResponse(error,null);
String clientHost)
{
this.request = request;
}

public static final SrmAbortFilesResponse getFailedResponse(String error,TStatusCode statusCode) {
if(statusCode == null) {
statusCode =TStatusCode.SRM_FAILURE;
}
TReturnStatus status = new TReturnStatus(statusCode, error);
public static SrmAbortFilesResponse getFailedResponse(String error,
TStatusCode statusCode)
{
SrmAbortFilesResponse srmAbortFilesResponse = new SrmAbortFilesResponse();
srmAbortFilesResponse.setReturnStatus(status);
srmAbortFilesResponse.setReturnStatus(new TReturnStatus(statusCode, error));
return srmAbortFilesResponse;
}

private static URI[] toUris(org.apache.axis.types.URI[] uris)
throws URISyntaxException
private SrmAbortFilesResponse abortFiles()
throws SRMInvalidRequestException
{
URI[] result = new URI[uris.length];
for (int i = 0; i < uris.length; i++) {
result[i] = new URI(uris[i].toString());
ContainerRequest<?> requestToAbort =
Request.getRequest(this.request.getRequestToken(), ContainerRequest.class);
try (JDC ignored = requestToAbort.applyJdc()) {
org.apache.axis.types.URI[] surls = getSurls();

TSURLReturnStatus[] surlReturnStatusArray = new TSURLReturnStatus[surls.length];
for (int i = 0; i < surls.length; i++) {
TReturnStatus returnStatus = abortSurl(requestToAbort, surls[i]);
surlReturnStatusArray[i] = new TSURLReturnStatus(surls[i], returnStatus);
}

// we do this to make the srm update the status of the request if it changed
requestToAbort.getTReturnStatus();

return new SrmAbortFilesResponse(
getSummaryReturnStatus(surlReturnStatusArray),
new ArrayOfTSURLReturnStatus(surlReturnStatusArray));
}
return result;
}

/**
* implementation of srm ls
*/
public SrmAbortFilesResponse srmAbortFiles()
throws SRMException,URISyntaxException,
IllegalStateTransition
private TReturnStatus abortSurl(ContainerRequest<?> request, org.apache.axis.types.URI surl)
{
String requestToken = srmAbortFilesRequest.getRequestToken();
if( requestToken == null ) {
return getFailedResponse("request contains no request token");
}
long requestId;
try {
requestId = Long.parseLong(requestToken);
} catch (NumberFormatException nfe){
return getFailedResponse(" requestToken \""+
requestToken+"\"is not valid",
TStatusCode.SRM_INVALID_REQUEST);
request.getFileRequestBySurl(new URI(surl.toString())).abort();
return new TReturnStatus(TStatusCode.SRM_SUCCESS, null);
} catch (SRMFileRequestNotFoundException | URISyntaxException e) {
return new TReturnStatus(TStatusCode.SRM_INVALID_PATH,
"SURL does match any existing file request associated with the request token");
} catch (IllegalStateTransition e) {
return new TReturnStatus(TStatusCode.SRM_FAILURE, e.getMessage());
}
}

ContainerRequest<?> request = Job.getJob(requestId, ContainerRequest.class);
request.applyJdc();

URI[] surls;
if( srmAbortFilesRequest.getArrayOfSURLs() == null ){
return getFailedResponse("request does not contain any SURLs",
TStatusCode.SRM_INVALID_REQUEST);

} else {
surls = toUris(srmAbortFilesRequest.getArrayOfSURLs().getUrlArray());
}
if(surls.length == 0) {
return getFailedResponse("0 length SiteURLs array",
TStatusCode.SRM_INVALID_REQUEST);
}
for (URI surl: surls) {
FileRequest<?> fileRequest = request.getFileRequestBySurl(surl);
fileRequest.setState(State.CANCELED,"SrmAbortFiles called");
private org.apache.axis.types.URI[] getSurls() throws SRMInvalidRequestException
{
ArrayOfAnyURI arrayOfSURLs = request.getArrayOfSURLs();
if (arrayOfSURLs == null || arrayOfSURLs.getUrlArray().length == 0) {
throw new SRMInvalidRequestException("Request contains no SURL");
}
return arrayOfSURLs.getUrlArray();
}

SrmAbortFilesResponse srmAbortFilesResponse = new SrmAbortFilesResponse();
srmAbortFilesResponse.setReturnStatus(new TReturnStatus(TStatusCode.SRM_SUCCESS, null));
TSURLReturnStatus[] surlReturnStatusArray = request.getArrayOfTSURLReturnStatus(surls);
for (TSURLReturnStatus surlReturnStatus:surlReturnStatusArray) {
if(surlReturnStatus.getStatus().getStatusCode() == TStatusCode.SRM_ABORTED) {
surlReturnStatus.getStatus().setStatusCode(TStatusCode.SRM_SUCCESS);
public SrmAbortFilesResponse getResponse()
{
if (response == null) {
try {
response = abortFiles();
} catch (SRMInvalidRequestException e) {
response = getFailedResponse(e.getMessage(), TStatusCode.SRM_INVALID_REQUEST);
}
}

srmAbortFilesResponse.setArrayOfFileStatuses(
new ArrayOfTSURLReturnStatus(surlReturnStatusArray));
// we do this to make the srm update the status of the request if it changed
request.getTReturnStatus();

return srmAbortFilesResponse;

return response;
}


public static SrmAbortFilesResponse getFailedResponse(String error)
{
return getFailedResponse(error, TStatusCode.SRM_FAILURE);
}
}

0 comments on commit 154f09d

Please sign in to comment.