|
|
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);
}