OpenClovis Logo

API Usage Examples
Clovis Object Repository (COR)

Code Examples. More...

Code Examples.

COR Object Manipulation Functions

While the necessary blue-print is created during OpenClovis ASP initialization, COR object manipulation happens at run-time, and mainly through through three functions:

These three functions use transactions to perform the desired object related operation(s). After the MO class tree is created during COR initialization, you can create the MO/MSO, set an attribute of that MO/MSO or delete an MO/MSO using these Object manipulation functions.

The object creation, attribute-set and object deletion can be queued in one transaction. These operations when queued in the transaction are identified by a transaction ID. Each transaction ID can have multiple transaction jobs operating on an MO/MSO which can be identified by the object handle or moId and the attrPath (containment path). Once all COR object manipulations have been performed, the clCorTxnSessionCommit() function is called. The COR client packs the transaction jobs and makes an RMD to the server through the clCorTxnSessionCommit() function. The transaction jobs are packed in the network format.

At the server side, the information of the components (for which the transaction manager will initiate the transaction callbacks) is obtained from COR's route list. This is a list of stations that need to be visited. Also if the peer COR is up and running then it will also be a part of transaction. After adding all the transaction jobs for the transaction ID and its list of components, COR starts the transaction.

COR performs all the object-related operations in the commit phase of the transaction. For a given transaction ID, all the transaction jobs are walked and specific operations are performed. The clCorTxnJobWalk() function is called with a callback which performs the necessary operations based on the opType obtained from each transaction job.

Sample Code for the Object Create/Set/Delete using single as well as complex transaction.

// Object Manipulation APIs that will Create/Set/Delete an MO.
ClRcT cor_test_object_manipulation ()
{
ClCorMOIdPtrT moId = NULL;
ClRcT rc = CL_OK;
// MoId Allocation.
// MoId Append . \0x100:1
clCorMoIdAppend(moId, 0x100, 1);
// Simple transaction for object-create
// Simple transaction for object-delete
// Beginning a complex transaction. Initializing tid to zero,
// which will be passed as first parameter to all the object
// manipulation calls until the clCorTxnSessionCommit()
// function is called.
clCorMoIdAppend(moId, 0x100, 2);
// MO creation queued in transaction.
clCorObjectCreate(&tid, moId, &handle);
clCorMoIdAppend(moId, 0x200, 1);
// MO Creation queued in transaction.
clCorObjectCreate(&tid, moId, &handle);
clCorMoIdAppend(moId, 0x300, 1);
// MO Creation queued in transaction.
clCorObjectCreate(&tid, moId, &handle);
clCorMoIdSet(moId, 3, 0x300, 2);
// MO creation queued in transaction.
clCorObjectCreate(&tid, moId, &handle);
// MSO creation queued in transaction.
clCorObjectCreate(&tid, moId, &handle);
// Committing the complex transaction with the created MOs and MSOs.
clCorObjectHandleToMoIdGet(handle, moId, &serviceId);
// TC2 : Multiple Sets
ClUint16T value16 = 0;
ClUint32T value32 = 0;
ClUint64T value64 = 0;
ClUint32T size16 = sizeof(ClUint16T);
ClUint32T size32 = sizeof(ClUint32T);
ClUint32T size64 = sizeof(ClUint64T);
ClCorAttrPathPtrT pAttrPath;
clCorAttrPathAlloc(&pAttrPath);
value64 = 1;
// Object Attribute set queued in transaction using simple transaction.
0x301, -1, (void *)&value64, size64);
value64 = 1;
// About to begin one more complex transaction, hence setting
// the transaction ID as zero.
tid = 0;
// Object Attribute set queued in transaction.
rc = clCorObjectAttributeSet(&tid, handle, NULL, 0x301, -1,
(void *)&value64, size64);
clCorAttrPathAppend(pAttrPath, 0x303, 0);
value32 = 3;
// Object Attribute set with containment path queued in transaction.
clCorObjectAttributeSet(&tid, handle, pAttrPath, 0x201, -1,
(void *)&value32, size32);
// moId creating here is \0x100:2\0x200:1\0x300:1 for deletion.
rc = clCorMoIdInitialize(moId);
rc = clCorMoIdAppend(moId, 0x100, 2);
rc = clCorMoIdAppend(moId, 0x200, 1);
rc = clCorMoIdAppend(moId, 0x300, 1);
rc = clCorObjectHandleGet(moId, &handle, &svcId);
// Object-Delete function queued in transaction.
rc = clCorObjectDelete(&tid, handle);
// Committing a complex transaction having two attribute-set
// operations and one object-delete operation.
clCorAttrPathFree(pAttrPath);
return rc;
}

COR Transaction APIs

COR Transaction APIs are used by components that participate in a transaction. A component participating in a transaction obtains a transaction handle ( txnHandle) through the callback functions for validate,commit and rollback which can be used in the COR transaction APIs to validate the transaction. A transaction can contain various COR operations related to one or more Managed Objects (MO). The operations related to an MO are considered as one transaction job. Within a transaction job there can be multiple COR operations which can be obtained by using the COR-Transaction APIs.

A transaction can consist of one or more object-create/set/delete operations or a combination of these operations as well. COR creates one COR-Transaction ID for a combination of MOID and attrpath. For a given COR-Transaction ID, COR creates one COR-Job ID for each attributeId. (that is being set for a particular MOID + attrPath). These jobs are linked together in the COR-job-list.

Following steps are performed to obtain COR-job-list and to perform a walk operation.

  1. When a transaction validate/commit/rollback is called, the COR-job-list ID can be obtained from the COR-transaction ID via the API clCorTxnJobHandleToCorTxnIdGet(). This function returns ClCorTxnIdT.
  2. clCorTxnJobWalk() function performs the walk operation corresponding to above COR-transaction ID. This function invokes a callback for every COR-job in the COR-job-list.
  3. The callback function takes in COR-Transaction ID and COR-job ID as parameters. COR provides a function to obtain information about the MOID if it is a create/delete operation. COR provides an API to obtain information about the attribute (MOID,attrpath.index, size, value) for a set operation, based on COR-Transaction ID and COR-job ID. For instance, the API clCorTxnJobSetParamsGet() returns attrId, index, value and size corresponding to a COR-Transaction ID and COR-job ID.

A sample validate function:

clTxnTestValidate( CL_IN ClTxnTransactionHandleT txnHandle,
CL_IN ClTxnJobDefnHandleT jobDefn,
CL_IN ClUint32T jobDefnSize,
CL_INOUT ClTxnAgentCookieT* pCookie )
{
ClRcT rc = CL_OK;
ClCorTxnIdT corTxnId;
// Obtain the COR-Transaction ID
rc = clCorTxnJobHandleToCorTxnIdGet(jobDefn, jobDefnSize, &corTxnId);
// Perform a walk on all the COR-Jobs associated with this
// COR-Transaction ID.
rc = clCorTxnJobWalk(corTxnId, clTxnTestJobWalk,
(void *)CL_PROV_VALIDATE_STATE );
// Free the space corTxnId.
clCorTxnIdTxnFree(corTxnId);
return rc;
}
ClRcT clTxnTestJobWalk( ClCorTxnIdT corTxnId,
void *arg )
{
ClRcT rc = CL_OK;
ClCorMOIdT moId;
ClCorOpsT corOp = CL_COR_OP_RESERVED;
ClCorAttrTypeT attrType = 0;
ClCorAttrIdT attrId = 0;
void* pValue = NULL;
ClUint32T valueSize = 0;
ClInt32T index = 0;
ClCorAttrPathPtrT attrPath = NULL;
// Obtain the MOID corresponding to COR-Transaction ID
rc = clCorTxnJobMoIdGet(corTxnId, &moId);
// Obtain the Operation i.e. creation/deletion/Set associated
// with COR-Transaction and COR-Job ID.
rc = clCorTxnJobOperationGet(corTxnId, jobId, &corOp);
switch ( ( ClUint32T )corOp )
{
break ;
// Obtain the AttrPath from the COR-Transaction ID and COR-Job ID
rc = clCorTxnJobAttrPathGet(corTxnId, jobId, &attrPath);
// Obtain the attrId,index, value, size from the COR-Transaction
// ID and COR-Job ID
rc = clCorTxnJobSetParamsGet(corTxnId, jobId, &attrId, &index,
&pValue, &valueSize);
break ;
break ;
}
return CL_OK;
}

COR Bundle Get

The COR bundle feature is used to perform get operation on multiple attributes in a single request to COR. The bundle-get can take list of attributes belonging to the same or different MO. These attributes can either be configuration or the runtime attributes. The user need to add all the get requests in the same bundle which will be send to COR server as a single request. There it will populate the value for configuration attributes and for the value of runtime attributes it will get it from the primary OI. After getting the response the OIs it will aggregates the information and send the response. Here is a sample code to demonstrate both the synchronous and asynchronous version of bundle get.

ClUint32T val_1 = 0, val_2 = 0, val_3 = 0, val_4 = 0;
ClCorJobStatusT jobStatus_1 = 0, jobStatus_2 = 0,
jobStatus_3 = 0, jobStatus_4 = 0;
//The helper function to display the information obtained from server.
void clCorTestDataDisplay()
{
if(jobStatus_1 != CL_OK)
clOsalPrintf("The Value for the attribute 0x201 is [%d] \n", val_1);
else
clOsalPrintf("The get on attribute 0x201 failed with error [0x%x] \n",
jobStatus_1);
if(jobStatus_2 != CL_OK)
clOsalPrintf("The Value for the attribute 0x202 is [%d] \n", val_2);
else
clOsalPrintf("The get on attribute 0x201 failed with error [0x%x] \n",
jobStatus_2);
if(jobStatus_3 != CL_OK)
clOsalPrintf("The Value for the attribute 0x205 is [%d] \n", val_3);
else
clOsalPrintf("The get on attribute 0x203 failed with error [0x%x] \n",
jobStatus_3);
if(jobStatus_4 != CL_OK)
clOsalPrintf("The Value for the attribute 0x302 is [%d] \n", val_4);
else
clOsalPrintf("The get on attribute 0x301 failed with error [0x%x] \n",
jobStatus_4);
}
// The following code example assumes that the MO class tree and the
// object tree exists in COR.
ClRcT clCorTestPrepareBundle(ClCorBundleHandlePtrT pBundleHandle)
{
ClRcT rc = CL_OK;
ClCorAttrValueDescriptorT attrInfo[3] = {{0}}, attrInfo1 = {0};
ClCorMOIdT moId;
ClCorObjectHandleT objH = {{0}};
// Initializing the MOID.
rc = clCorMoIdInitialize(&moId);
// Appending the MOID, /0x100:0
rc = clCorMoIdAppend(&moId, 0x100, 0);
// Appending the MOID, /0x100:0/0x200:3
rc = clCorMoIdAppend(&moId, 0x200, 3);
// Setting the service Id of the provisioning, we want to perform
// bundle get on provisioning attributes.
// Get the object handle from the MOID obtained after appending
// the required classIds and instanceIds.
rc = clCorObjectHandleGet(&moId, &objH);
if (CL_OK != rc) {
// Handle the error appropriately.
return rc;
}
// Initializing the bundle. This will give the bundle handle.
// The bundle here is a non-transactional bundle.
// The transactional bundle is not supported in this release.
rc = clCorBundleInitialize(pBundleHandle, &bundleConfig);
if(CL_OK != rc)
{
clLogError("COR", "GET",
"Failed to initialize the bundle. rc[0x%x]", rc);
return rc;
}
// Attribute Path is not support in this release.
// This should be NULL as of now.
attrInfo[0].pAttrPath = NULL;
// First Attribute Id on which the get has to be done.
// This is a simple attribute of 32 bit.
attrInfo[0].attrId = 0x201;
// Index is the array index whose value is needed.
// It should be -1 for simple attribute.
attrInfo[0].index = -1;
// pointer to the value. This is made as global to be accessed
// in the bundle callback for async bundle.
attrInfo[0].bufferPtr = &val_1;
// Size of the attribute. This should be exactly equal to the
// actaul size of attribute.
attrInfo[0].bufferSize = sizeof(ClUint32T);
// This is the status of the job. This will be populated once
// the response is obtained from server.
attrInfo[0].pJobStatus = &jobStatus_1;
attrInfo[1].pAttrPath = NULL;
// This is an array attribute.
attrInfo[1].attrId = 0x202;
// The index is given as 3 to get the index 3 of the array.
attrInfo[1].index = 3;
attrInfo[1].bufferPtr = &val_2;
attrInfo[1].bufferSize = sizeof(ClUint32T);
attrInfo[1].pJobStatus = &jobStatus_2;
attrInfo[2].pAttrPath = NULL;
// This is an array attribute.
attrInfo[2].attrId = 0x205;
// The index is given as 3 to get the index 3 of the array.
attrInfo[2].index = -1;
attrInfo[2].bufferPtr = &val_3;
attrInfo[2].bufferSize = sizeof(ClUint32T);
attrInfo[2].pJobStatus = &jobStatus_3;
attrList.numOfDescriptor = 3;
attrList.pAttrDescriptor = attrInfo;
rc = clCorBundleObjectGet(*pBundleHandle, &this, &attrList);
if(CL_OK != rc)
{
clLogError("COR", "GET",
"Failed to add the job in the bundle. rc[0x%x]",
rc);
clCorBundleFinalize(*pBundleFinalize);
goto handleError;
}
// Appending the MOID, /0x100:0/0x200:3/0x300:1
rc = clCorMoIdAppend(&moId, 0x300, 1);
if (CL_OK != rc) {
// Handle the error appropriately.
clCorBundleFinalize(*pBundleFinalize);
goto handleError;
}
attrInfo1.pAttrPath = NULL;
// This is an array attribute.
attrInfo1.attrId = 0x302;
// The index is given as 3 to get the index 3 of the array.
attrInfo1.index = -1;
attrInfo1.bufferPtr = &val_4;
attrInfo1.bufferSize = sizeof(ClUint32T);
attrInfo1.pJobStatus = &jobStatus_4;
// Get the object handle from the MOID obtained after
// appending the required classIds and instanceIds.
rc = clCorObjectHandleGet(&moId, &objH);
if (CL_OK != rc)
{
clCorBundleFinalize(*pBundleFinalize);
goto handleError;
}
attrList.numOfDescriptor = 1;
attrList.pAttrDescriptor = &attrInfo1;
rc = clCorBundleObjectGet(*pBundleHandle, &this, &attrList);
if(CL_OK != rc)
{
jobStatus = rc;
clLogError("COR", "GET",
"Failed to add the job in the bundle. rc[0x%x]",
rc);
clCorBundleFinalize(*pBundleFinalize);
goto handleError;
}
handleError:
return rc;
}
ClRcT _clCorTestBundleCallback (ClCorBundleHandleT bundleHandle,
ClPtrT cookie)
{
ClRcT rc = CL_OK;
clCorTestDataDisplay();
// For the async bundle the finalize can happen in the callback
// if the same bundle is not needed anymore. Otherwise it can be
// done while component terminate.
rc = clCorBundleFinalize(bundleHandle);
if(CL_OK != rc)
{
clLogError("COR", "GET",
"Failed while finalizing the bundle. rc[0x%x]",
rc);
return rc;
}
return rc;
}
ClRcT _clCorTestBundleGetAsync()
{
ClRcT rc = CL_OK;
ClCorBundleHandleT bundleHandle = 0;
rc = clCorTestPrepareBundle(&bundleHandle);
if (CL_OK != rc) {
clLogError("COR", "GET",
"Failed while preparing the bundle for get. rc[0x%x]",
rc);
return rc;
}
//This is asynchronous version of bundle apply. This will register
//the callback which will be once the reponse for the server arrives
//after filling the data.
rc = clCorBundleApplyAsync(bundleHandle, _clCorTestBundleCallback, NULL);
if(CL_OK != rc)
{
clLogError("COR", "GET",
"Failed while applying the bundle. rc[0x%x]",
rc);
goto handleError;
}
// Function to use the information returned by the bundle get api.
_clCorTestDataDisplay()
handleError:
// Finalize the bundle in case of an error while applying the bundle.
rc = clCorBundleFinalize(bundleHandle);
if(CL_OK != rc)
{
clLogError("COR", "GET",
"Failed while finalizing the bundle. rc[0x%x]",
rc);
return rc;
}
return rc;
}
ClRcT _clCorTestBundleGetSync()
{
ClRcT rc = CL_OK;
ClCorBundleHandleT bundleHandle;
rc = clCorTestPrepareBundle(&bundleHandle);
if (CL_OK != rc)
{
clLogError("COR", "GET",
"Failed while preparing the bundle for get. rc[0x%x]",
rc);
return rc;
}
//Synchronous version of bundle apply. This will wait here till
//the response from the server arrives.
rc = clCorBundleApply(bundleHandle);
if(CL_OK != rc)
{
clLogError("COR", "GET",
"Failed while applying the bundle. rc[0x%x]",
rc);
goto handleError;
}
// Function to use the information returned by the bundle get api.
_clCorTestDataDisplay()
handleError:
rc = clCorBundleFinalize(bundleHandle);
if(CL_OK != rc)
{
clLogError("COR", "GET",
"Failed while finalizing the bundle. rc[0x%x]",
rc);
return rc;
}
return rc;
}

Cor Create and Set

The clCorObjectCreateAndSet() is an additional function to the COR session capability. This API should be used to create the objects of the MO-Class which has intialized attributes modeled. The initialized attributes are key attribute which should be provided while creating an instance of the class. Inorder to create instance for this class, the API clCorObjectCreateAndSet() should be used which allows providing the attribute list and their values while creating the object. This API can be used to create an object without any key attributes as well. As this function is part of COR's session capability, so all the features of session are applicable to this API as well. Here is the sample code which shows the usage of this API.

ClRcT _clCorTestCreateAndSetUsage()
{
ClRcT rc = CL_OK;
ClCorObjectHandleT objH = {{0}}, objH1 = {{0}};
ClCorAttributeValueT attrDesc[2] = {{0}};
ClCorAttributeValueListT attrList = {0};
ClCorMOIdT moId ;
ClUint32T val_1 = 10, val_2 = 20;
//Initializing the MOID
rc = clCorMoIdInitialize(&moId);
// Appending the class and intance to MOId.
// The MOId has become /0x100:0
rc = clCorMoIdAppend(&moId, 0x100, 0);
// This class doesn't have any initialized attributes.
// So using the create and set api here.
// This creation is done is a simple session manner.
rc = clCorObjectCreateAndSet(CL_COR_TXN_MODE_SIMPLE,
&moId, NULL, &objH);
// The MOID now becomes /0x100:0/0x200:1
rc = clCorMoIdAppend(&moId, 0x200, 1);
// The creation of object can be done in a complex cor-transaction.
// This will create the transaction and add the first job in it.
rc = clCorObjectCreateAndSet(&tid, &moId, NULL, &objH);
// The Moid now is /0x100:0/0x200:2
rc = clCorMoIdInstanceSet(&moId, 0x200, 2);
// This will add the second job to the transaction.
rc = clCorObjectCreateAndSet(&tid, &moId, NULL, &objH1);
// Committing the complex transaction.
if( CL_OK != rc)
{
// Handle the failure. Can get the failed jobs using
// clCorTxnFailedJobGet()
return rc;
}
//The MOID is now /0x100:0/0x200:2/0x300:2.
rc = clCorMoIdAppend(&moId, 0x300, 2);
// The class 0x300 has two initialized attributes: 0x301, 0x302.
// So filling the details for supplying it to create and set api.
attrDesc[0].pAttrPath = NULL;
attrDesc[0].attrId = 0x301;
attrDesc[0].index = -1;
attrDesc[0].bufferPtr = &val_1;
attrDesc[0].bufferSize = sizeof(ClUint32T);
attrDesc[1].pAttrPath = NULL;
attrDesc[1].attrId = 0x302;
attrDesc[1].index = -1;
attrDesc[1].bufferPtr = &val_2;
attrDesc[1].bufferSize = sizeof(ClUint32T);
attrList.numOfDescriptor = 2;
attrList.pAttrDescriptor = attrInfo;
// Calling create and set API for creating the object and setting
// the key attributes.
rc = clCorObjectCreateAndSet(CL_COR_TXN_MODE_SIMPLE, &moId,
&attrList, &objH);
if(CL_OK != rc) {
//Handle the error appropriately.
return rc;
}
return rc;
}

Generated on Tue Jan 10 10:29:15 PST 2012 for OpenClovis SDK using Doxygen