Commit 63400e9b authored by Sebastien Ponce's avatar Sebastien Ponce
Browse files

Fixed handling of requests with invalid service classes

parent adde2345
......@@ -364,7 +364,8 @@ CREATE OR REPLACE PROCEDURE jobSubRequestToDo(outSrId OUT INTEGER, outReqUuid OU
outFileClassIfForced OUT INTEGER,
outFlags OUT INTEGER, outModeBits OUT INTEGER,
outClientIpAddress OUT INTEGER,
outClientPort OUT INTEGER, outClientVersion OUT INTEGER) AS
outClientPort OUT INTEGER, outClientVersion OUT INTEGER,
outErrNo OUT INTEGER, outErrMsg OUT VARCHAR2) AS
CURSOR SRcur IS
SELECT /*+ FIRST_ROWS_10 INDEX_RS_ASC(SR I_SubRequest_RT_CT_ID) */ SR.id
FROM SubRequest PARTITION (P_STATUS_0_1_2) SR -- START, RESTART, RETRY
......@@ -379,6 +380,7 @@ CREATE OR REPLACE PROCEDURE jobSubRequestToDo(outSrId OUT INTEGER, outReqUuid OU
varUnusedMessage VARCHAR2(2048);
varUnusedStatus INTEGER;
BEGIN
outErrNo := 0;
-- Open a cursor on potential candidates
OPEN SRcur;
-- Retrieve the first candidate
......@@ -437,30 +439,35 @@ BEGIN
-- XXX be merged in a single table (partitioned by reqType) to avoid the following block.
CASE
WHEN outReqType = 40 THEN -- StagePutRequest
SELECT reqId, euid, egid, svcClass, client
INTO outReqUuid, outEuid, outEgid, varSvcClassId, varClientId
SELECT reqId, euid, egid, svcClass, svcClassName, client
INTO outReqUuid, outEuid, outEgid, varSvcClassId, outSvcClassName, varClientId
FROM StagePutRequest WHERE id = varRequestId;
WHEN outReqType = 35 THEN -- StageGetRequest
SELECT reqId, euid, egid, svcClass, client
INTO outReqUuid, outEuid, outEgid, varSvcClassId, varClientId
SELECT reqId, euid, egid, svcClass, svcClassName, client
INTO outReqUuid, outEuid, outEgid, varSvcClassId, outSvcClassName, varClientId
FROM StageGetRequest WHERE id = varRequestId;
WHEN outReqType = 37 THEN -- StagePrepareToPutRequest
SELECT reqId, euid, egid, svcClass, client
INTO outReqUuid, outEuid, outEgid, varSvcClassId, varClientId
SELECT reqId, euid, egid, svcClass, svcClassName, client
INTO outReqUuid, outEuid, outEgid, varSvcClassId, outSvcClassName, varClientId
FROM StagePrepareToPutRequest WHERE id = varRequestId;
WHEN outReqType = 36 THEN -- StagePrepareToGetRequest
SELECT reqId, euid, egid, svcClass, client
INTO outReqUuid, outEuid, outEgid, varSvcClassId, varClientId
SELECT reqId, euid, egid, svcClass, svcClassName, client
INTO outReqUuid, outEuid, outEgid, varSvcClassId, outSvcClassName, varClientId
FROM StagePrepareToGetRequest WHERE id = varRequestId;
END CASE;
SELECT ipAddress, port, version
INTO outClientIpAddress, outClientPort, outClientVersion
FROM Client WHERE id = varClientId;
SELECT FileClass.classId, SvcClass.name
INTO outFileClassIfForced, outSvcClassName
FROM SvcClass, FileClass
WHERE SvcClass.id = varSvcClassId
AND FileClass.id(+) = SvcClass.forcedFileClass;
BEGIN
SELECT FileClass.classId INTO outFileClassIfForced
FROM SvcClass, FileClass
WHERE SvcClass.id = varSvcClassId
AND FileClass.id(+) = SvcClass.forcedFileClass;
EXCEPTION WHEN NO_DATA_FOUND THEN
archiveSubReq(outSrId, dconst.SUBREQUEST_FAILED_FINISHED);
outErrno := serrno.EINVAL;
outErrMsg := 'Invalid service class ''' || outSvcClassName || '''';
END;
EXCEPTION WHEN OTHERS THEN
-- Something went really wrong, our subrequest does not have the corresponding request or client,
-- Just drop it and re-raise exception. Some rare occurrences have happened in the past,
......
......@@ -74,7 +74,7 @@ castor::stager::daemon::JobRequestSvcThread::jobSubRequestToDo()
// retrieve or create statement
bool wasCreated = false;
oracle::occi::Statement* jobSubRequestToDoStatement = dbSvc->createOrReuseOraStatement
("BEGIN jobSubRequestToDo(:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13); END;",
("BEGIN jobSubRequestToDo(:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13, :14, :15); END;",
&wasCreated);
if (wasCreated) {
jobSubRequestToDoStatement->registerOutParam(1, oracle::occi::OCCIDOUBLE);
......@@ -90,6 +90,8 @@ castor::stager::daemon::JobRequestSvcThread::jobSubRequestToDo()
jobSubRequestToDoStatement->registerOutParam(11, oracle::occi::OCCIINT);
jobSubRequestToDoStatement->registerOutParam(12, oracle::occi::OCCIINT);
jobSubRequestToDoStatement->registerOutParam(13, oracle::occi::OCCIINT);
jobSubRequestToDoStatement->registerOutParam(14, oracle::occi::OCCIINT);
jobSubRequestToDoStatement->registerOutParam(15, oracle::occi::OCCISTRING, 2048);
// also register for associated alert
oracle::occi::Statement* registerAlertStmt =
dbSvc->createOraStatement("BEGIN DBMS_ALERT.REGISTER('wakeUpJobReqSvc'); END;");
......@@ -127,6 +129,15 @@ castor::stager::daemon::JobRequestSvcThread::jobSubRequestToDo()
result->clientIpAddress = jobSubRequestToDoStatement->getInt(11);
result->clientPort = jobSubRequestToDoStatement->getInt(12);
result->clientVersion = jobSubRequestToDoStatement->getInt(13);
// did we get an error ?
int errorCode = jobSubRequestToDoStatement->getInt(14);
if (errorCode > 0) {
// answer client
bool isLastAnswer = updateAndCheckSubRequest(result->srId, SUBREQUEST_FAILED_FINISHED);
answerClient(result, 0, SUBREQUEST_FAILED, errorCode,
jobSubRequestToDoStatement->getString(15), isLastAnswer);
return 0;
}
// return
return result;
} catch (oracle::occi::SQLException &e) {
......@@ -160,7 +171,7 @@ void castor::stager::daemon::JobRequestSvcThread::process(castor::IObject* reque
int replyNeeded = handleGetOrPut(sr, cnsFileid, fileSize, stagerOpentimeInUsec);
// reply to client when needed
if (replyNeeded) {
answerClient(sr, cnsFileid, SUBREQUEST_READY, 0, "", replyNeeded > 0);
answerClient(sr, cnsFileid.fileid, SUBREQUEST_READY, 0, "", replyNeeded > 1);
}
} catch(castor::exception::Exception &ex) {
try {
......@@ -282,7 +293,7 @@ bool castor::stager::daemon::JobRequestSvcThread::updateAndCheckSubRequest
// answerClient
//-----------------------------------------------------------------------------
void castor::stager::daemon::JobRequestSvcThread::answerClient(const JobRequest *sr,
const struct Cns_fileid &cnsFileid,
u_signed64 cnsFileid,
int status,
int errorCode,
const std::string &errorMsg,
......@@ -301,7 +312,7 @@ void castor::stager::daemon::JobRequestSvcThread::answerClient(const JobRequest
Cuuid2string(uuid, CUUID_STRING_LEN+1, &sr->requestUuid);
ioResponse.setReqAssociated(uuid);
ioResponse.setCastorFileName(sr->fileName);
ioResponse.setFileId((u_signed64) cnsFileid.fileid);
ioResponse.setFileId(cnsFileid);
ioResponse.setStatus(status);
ioResponse.setErrorCode(errorCode);
ioResponse.setErrorMessage(errorMsg);
......
......@@ -122,7 +122,7 @@ namespace castor {
throw (castor::exception::Exception);
/** helper function answering the client */
void answerClient(const JobRequest *sr, const struct Cns_fileid &cnsFileid,
void answerClient(const JobRequest *sr, u_signed64 cnsFileid,
int status, int errorCode, const std::string &errorMsg,
bool isLastAnswer = false)
throw (castor::exception::Exception);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment