|
|
The Tcl Object Validation Routine will be passed three parameters;
operation invokeId objectClass objectInstance accessControl sync scope filter attributeList referenceObject actionType actionInfo
Request processor (Tcl)
proc UserRequestProcessor {osaDataString handleId bmipRequest} {# # get the list of objects we'll be operating on, send them through # a filter, and then get a count of the remaining ones. #
set objectList [keylget bmipRequest objectInstance] set objectList [OFEvaluateFilter $handleId $objectList] set listLength [llength $objectList]
if ($listLength < 1) {
# # If all the objects failed the filter, we need to send a BMIP # response to that effect back to the client. So we set the # objectInstancePtr to NULL and call OFReturnBmipResponse(). #
set bmipResponse $bmipRequest keylset bmipResponse errorParameter {} keylset bmipResponse attributeList {} keylset bmipResponse actionInfo {} keylset bmipResponse linkedId 0 keylset bmipResponse objectInstance {}
OFReturnBmipResponse $handleId $bmipResponse FALSE
return }
# # Step through the remaining object instances so we can operate on # each one and send the BMIP response back to the client that called # us. We will do this non-atomically. # # If we were to do this atomicly we would construct an array to store # all the BMIP responses in. Then we would either send them all in # at once after all the calls to OFEvaluateOperation we completed (if # none of them contained an error), or we would undo the work of the # completed operations and send in one response that contained the # error. #
foreach object $objectList {
# # OFEvaluateOperation() returns a BMIP response, send # this back to the client via OFReturnBmipResponse(). # Make sure to have the last object call the return BMIP # function with a FALSE continue flag, so that we can # inform the client we're done sending data it's way. #
OFEvaluateOperation $handleId $object bmipResponse incr listLength -1 if ($listLength < 1) { set continue FALSE } { set continue TRUE } OFReturnBmipResponse $handleId bmipResponse $continue } }
Request processor (C/C++)
void cUserRequestProcessor(errStatus_cl *errStatusPtr, int handleId, bmipRequest_pt bmipRequestPtr, void *handle) { /*--- * * Generate a list of all the objects to be evaluated * */ objectName_pt *objectList; int objectCount; int loop; bool_t tclResult = TclListSplit(bmipRequestPtr->objectInstancePtr, &objectCount, &objectList, errStatusPtr); if (tclResult == FALSE) { /* If an error is left on the stack when returning, the caller of * this function will return a BMIP response based on the BMIP * request and the current error stack. */ErrorPush(errStatusPtr, &SCO_OSA_ERR_NO_SUCH_OBJECT_INSTANCE, bmipRequestPtr->objectInstancePtr); return; }
/* Calling OFEvaluateFilter() with a filter and a list of objects will * cause the Object API to run a standard filter (using the OSA provided get * operation) and re-arange the list of objects forwarded to * OFEvaluateFilter() and re-set the value of objectCount to the number * of objects in the list that passed the filter. */ OFEvaluateFilter(errStatusPtr, handleId, bmipRequestPtr->filterPtr, &objectList, &objectCount);
if (objectCount < 1) { /* If all the objects failed the filter, we need to send a BMIP * response to that effect back to the client. So we set the * objectInstancePtr to NULL and call OFReturnBmipResponse(). */ bmipResponse_t *bmipResponsePtr; bmipResponsePtr = OFComposeBmipResponseError(errStatusPtr, bmipRequestPtr);
ErrorClear(errStatusPtr);
OFReturnBmipResponse(errStatusPtr, handleId, bmipResponsePtr, FALSE);
/* Calling OFReturnBmipResponse() will also free up bmipResponse_t. */ MemFree(objectList); return; }
/* For each object that passed the filter, have the operation evaluated * upon it and send the BMIP response returned to the client. * * If the OSA were attempting to perform atomic synchronization, then * it would prepair an array of bmipResponse_t pointers and assign each * successful call to OFEvaluateOperation() to a new pointer. Only if * all the objects were evaluated without errors would this validation * code then go ahead and call OFReturnBmipResponse() on each bmipResponse. * If any error occurred, the OSA would have to figure out how to undo the * work it had done during this session so far, and then return the lone * error message. */ for (loop = 0; loop < objectCount; ++loop) { bmipResponse_t *bmipResponsePtr; bmipResponsePtr = OFEvaluateOperation(errStatusPtr, handleId, objectList[loop]); if (ErrorIsOk(errStatusPtr) == FALSE) { /* If we were doing atomic synchronization then we would * want to examine this error, and if needed then undo all * the operations done in this session. Since we are not * doing atomic synchronization, we just let the error * (already incorporated into the current BmipResponse) be * sent back to the client. */ ErrorClear(errStatusPtr); }
/* Only the last object should have the ContinueFlag (parameter 4) * set to FALSE. This tells the client that there are no more BMIP * responses yet to arrive. * * By this same token the validation code should make sure that there * is no error left on the stack after calling the last bmip Response * in, as this error will also be processed and sent to the client. */ OFReturnBmipResponse(errStatusPtr, handleId, bmipResponsePtr, (loop + 1 == objectCount) ? FALSE : TRUE );
if (!(ErrorIsOk(errStatusPtr))) return; }
ckfree(objectList); }