449 lines
11 KiB
C++
449 lines
11 KiB
C++
|
#include "WLBS_Provider.h"
|
||
|
#include "WLBS_ParticipatingNode.h"
|
||
|
#include "ClusterWrapper.h"
|
||
|
#include "ControlWrapper.h"
|
||
|
#include "utils.h"
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CWLBS_ParticipatingNode::CWLBS_ParticipatingNode
|
||
|
//
|
||
|
// Purpose: Constructor
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
CWLBS_ParticipatingNode::CWLBS_ParticipatingNode(CWbemServices* a_pNameSpace,
|
||
|
IWbemObjectSink* a_pResponseHandler)
|
||
|
: CWlbs_Root( a_pNameSpace, a_pResponseHandler ), m_pNode(NULL)
|
||
|
{
|
||
|
|
||
|
m_pNode = new CWLBS_Node ( a_pNameSpace, a_pResponseHandler );
|
||
|
if( !m_pNode )
|
||
|
throw _com_error( WBEM_E_OUT_OF_MEMORY );
|
||
|
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CWLBS_ParticipatingNode::~CWLBS_ParticipatingNode
|
||
|
//
|
||
|
// Purpose: Destructor
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
CWLBS_ParticipatingNode::~CWLBS_ParticipatingNode()
|
||
|
{
|
||
|
|
||
|
if( m_pNode )
|
||
|
delete m_pNode;
|
||
|
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CWLBS_ParticipatingNode::Create
|
||
|
//
|
||
|
// Purpose: This instantiates this class and is invoked from an array of
|
||
|
// function pointers.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
CWlbs_Root* CWLBS_ParticipatingNode::Create
|
||
|
(
|
||
|
CWbemServices* a_pNameSpace,
|
||
|
IWbemObjectSink* a_pResponseHandler
|
||
|
)
|
||
|
{
|
||
|
|
||
|
g_pWlbsControl->CheckMembership();
|
||
|
|
||
|
CWlbs_Root* pRoot = new CWLBS_ParticipatingNode( a_pNameSpace, a_pResponseHandler );
|
||
|
|
||
|
if( !pRoot )
|
||
|
throw _com_error( WBEM_E_OUT_OF_MEMORY );
|
||
|
|
||
|
return pRoot;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CWLBS_ParticipatingNode::GetInstance
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CWLBS_ParticipatingNode::GetInstance
|
||
|
(
|
||
|
const ParsedObjectPath* /* a_pParsedPath */,
|
||
|
long /* a_lFlags */,
|
||
|
IWbemContext* /* a_pIContex */
|
||
|
)
|
||
|
{
|
||
|
IWbemClassObject* pWlbsInstance = NULL;
|
||
|
HRESULT hRes = 0;
|
||
|
|
||
|
try {
|
||
|
|
||
|
//TODO: remove
|
||
|
throw _com_error( WBEM_E_NOT_SUPPORTED );
|
||
|
/*
|
||
|
//get the node
|
||
|
FindInstance( &pWlbsInstance, a_pParsedPath );
|
||
|
|
||
|
//send the results back to WinMgMt
|
||
|
m_pResponseHandler->Indicate( 1, &pWlbsInstance );
|
||
|
|
||
|
if( pWlbsInstance ) {
|
||
|
pWlbsInstance->Release();
|
||
|
pWlbsInstance = NULL;
|
||
|
}
|
||
|
|
||
|
m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
|
||
|
*/
|
||
|
hRes = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
catch(CErrorWlbsControl Err) {
|
||
|
|
||
|
IWbemClassObject* pWbemExtStat = NULL;
|
||
|
|
||
|
CreateExtendedStatus( m_pNameSpace,
|
||
|
&pWbemExtStat,
|
||
|
Err.Error(),
|
||
|
(PWCHAR)(Err.Description()) );
|
||
|
|
||
|
m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
|
||
|
|
||
|
if( pWbemExtStat )
|
||
|
pWbemExtStat->Release();
|
||
|
|
||
|
if( pWlbsInstance )
|
||
|
pWlbsInstance->Release();
|
||
|
|
||
|
//do not return WBEM_E_FAILED, this causes a race condition
|
||
|
hRes = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
catch(_com_error HResErr ) {
|
||
|
|
||
|
m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
|
||
|
|
||
|
if( pWlbsInstance )
|
||
|
pWlbsInstance->Release();
|
||
|
|
||
|
hRes = HResErr.Error();
|
||
|
}
|
||
|
|
||
|
catch(...) {
|
||
|
|
||
|
if( pWlbsInstance )
|
||
|
pWlbsInstance->Release();
|
||
|
|
||
|
throw;
|
||
|
|
||
|
}
|
||
|
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CWLBS_ParticipatingNode::EnumInstances
|
||
|
//
|
||
|
// Purpose: Queries WLBS for desired node instances then constructs an
|
||
|
// an associator for each node found.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CWLBS_ParticipatingNode::EnumInstances
|
||
|
(
|
||
|
BSTR /* a_bstrClass */,
|
||
|
long /* a_lFlags */,
|
||
|
IWbemContext* /* a_pIContex */
|
||
|
)
|
||
|
{
|
||
|
IWbemClassObject** ppWlbsInstance = NULL;
|
||
|
WLBS_RESPONSE* pResponse = NULL;
|
||
|
HRESULT hRes = 0;
|
||
|
|
||
|
long nNumNodes = 0;
|
||
|
|
||
|
try {
|
||
|
|
||
|
DWORD dwNumClusters = 0;
|
||
|
CWlbsClusterWrapper** ppCluster = NULL;
|
||
|
|
||
|
g_pWlbsControl->EnumClusters(ppCluster, &dwNumClusters);
|
||
|
if (dwNumClusters == 0)
|
||
|
{
|
||
|
throw _com_error( WBEM_E_NOT_FOUND );
|
||
|
}
|
||
|
|
||
|
//declare an IWbemClassObject smart pointer
|
||
|
IWbemClassObjectPtr pWlbsClass;
|
||
|
|
||
|
//get the MOF class object
|
||
|
hRes = m_pNameSpace->GetObject(
|
||
|
_bstr_t( MOF_PARTICIPATINGNODE::szName ),
|
||
|
0,
|
||
|
NULL,
|
||
|
&pWlbsClass,
|
||
|
NULL );
|
||
|
|
||
|
if( FAILED( hRes ) ) {
|
||
|
throw _com_error( hRes );
|
||
|
}
|
||
|
|
||
|
for (DWORD iCluster=0; iCluster<dwNumClusters; iCluster++)
|
||
|
{
|
||
|
|
||
|
//call the API query function to find the nodes
|
||
|
try {
|
||
|
m_pNode->FindAllInstances(ppCluster[iCluster], &pResponse, nNumNodes );
|
||
|
} catch (CErrorWlbsControl Err) {
|
||
|
|
||
|
//
|
||
|
// Skip this cluster
|
||
|
//
|
||
|
TRACE_ERROR1("CWLBS_ParticipatingNode::EnumInstances skiped cluster %x",
|
||
|
ppCluster[iCluster]->GetClusterIP());
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
//spawn an instance of the participating node associator
|
||
|
//for each node found
|
||
|
ppWlbsInstance = new IWbemClassObject *[nNumNodes];
|
||
|
|
||
|
if( !ppWlbsInstance )
|
||
|
throw _com_error( WBEM_E_OUT_OF_MEMORY );
|
||
|
|
||
|
//initialize array
|
||
|
ZeroMemory( ppWlbsInstance, nNumNodes * sizeof(IWbemClassObject *) );
|
||
|
|
||
|
for(int i = 0; i < nNumNodes; i ++ ) {
|
||
|
hRes = pWlbsClass->SpawnInstance( 0, &ppWlbsInstance[i] );
|
||
|
|
||
|
if( FAILED( hRes ) )
|
||
|
throw _com_error( hRes );
|
||
|
|
||
|
FillWbemInstance(ppCluster[iCluster], *(ppWlbsInstance + i), pResponse + i );
|
||
|
}
|
||
|
|
||
|
//send the results back to WinMgMt
|
||
|
hRes = m_pResponseHandler->Indicate( nNumNodes, ppWlbsInstance );
|
||
|
|
||
|
if( FAILED( hRes ) ) {
|
||
|
throw _com_error( hRes );
|
||
|
}
|
||
|
|
||
|
if( ppWlbsInstance ) {
|
||
|
for( i = 0; i < nNumNodes; i++ ) {
|
||
|
if( ppWlbsInstance[i] ) {
|
||
|
ppWlbsInstance[i]->Release();
|
||
|
}
|
||
|
}
|
||
|
delete [] ppWlbsInstance;
|
||
|
}
|
||
|
|
||
|
if( pResponse )
|
||
|
delete [] pResponse;
|
||
|
}
|
||
|
|
||
|
m_pResponseHandler->SetStatus( 0, WBEM_S_NO_ERROR, NULL, NULL );
|
||
|
|
||
|
hRes = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
catch(CErrorWlbsControl Err) {
|
||
|
|
||
|
IWbemClassObject* pWbemExtStat = NULL;
|
||
|
|
||
|
CreateExtendedStatus( m_pNameSpace,
|
||
|
&pWbemExtStat,
|
||
|
Err.Error(),
|
||
|
(PWCHAR)(Err.Description()) );
|
||
|
|
||
|
m_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
|
||
|
|
||
|
if( pWbemExtStat )
|
||
|
pWbemExtStat->Release();
|
||
|
|
||
|
if( ppWlbsInstance ) {
|
||
|
for(int i = 0; i < nNumNodes; i++ ) {
|
||
|
if( ppWlbsInstance[i] ) {
|
||
|
ppWlbsInstance[i]->Release();
|
||
|
}
|
||
|
}
|
||
|
delete [] ppWlbsInstance;
|
||
|
}
|
||
|
|
||
|
if( pResponse )
|
||
|
delete [] pResponse;
|
||
|
|
||
|
//do not return WBEM_E_FAILED, this causes a race condition
|
||
|
hRes = WBEM_S_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
catch(_com_error HResErr ) {
|
||
|
|
||
|
m_pResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
|
||
|
|
||
|
if( ppWlbsInstance ) {
|
||
|
for(int i = 0; i < nNumNodes; i++ ) {
|
||
|
if( ppWlbsInstance[i] ) {
|
||
|
ppWlbsInstance[i]->Release();
|
||
|
}
|
||
|
}
|
||
|
delete [] ppWlbsInstance;
|
||
|
}
|
||
|
|
||
|
if( pResponse )
|
||
|
delete [] pResponse;
|
||
|
|
||
|
hRes = HResErr.Error();
|
||
|
}
|
||
|
|
||
|
catch(...) {
|
||
|
|
||
|
if( ppWlbsInstance ) {
|
||
|
for(int i = 0; i < nNumNodes; i++ ) {
|
||
|
if( ppWlbsInstance[i] ) {
|
||
|
ppWlbsInstance[i]->Release();
|
||
|
}
|
||
|
}
|
||
|
delete [] ppWlbsInstance;
|
||
|
}
|
||
|
|
||
|
if( pResponse )
|
||
|
delete [] pResponse;
|
||
|
|
||
|
throw;
|
||
|
|
||
|
}
|
||
|
|
||
|
return hRes;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CWLBS_ParticipatingNode::FindInstance
|
||
|
//
|
||
|
// Purpose: This routine determines if a host is within the local cluster. If
|
||
|
// it is, then the requested associator is returned.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
void CWLBS_ParticipatingNode::FindInstance
|
||
|
|
||
|
(
|
||
|
IWbemClassObject** /* a_ppWbemInstance */,
|
||
|
const ParsedObjectPath* /* a_pParsedPath */
|
||
|
)
|
||
|
|
||
|
{
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// CWLBS_ParticipatingNode::FillWbemInstance
|
||
|
//
|
||
|
// Purpose: This constructs the ParticipatingNode wbem associator.
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////
|
||
|
void CWLBS_ParticipatingNode::FillWbemInstance
|
||
|
(
|
||
|
CWlbsClusterWrapper* pCluster,
|
||
|
IWbemClassObject* a_pWbemInstance,
|
||
|
WLBS_RESPONSE* a_pResponse
|
||
|
)
|
||
|
{
|
||
|
namespace PNODE = MOF_PARTICIPATINGNODE;
|
||
|
|
||
|
ASSERT( a_pWbemInstance );
|
||
|
ASSERT( a_pResponse );
|
||
|
|
||
|
|
||
|
ParsedObjectPath NodePath;
|
||
|
ParsedObjectPath ClusterPath;
|
||
|
LPWSTR szNodePath = NULL;
|
||
|
LPWSTR szClusterPath = NULL;
|
||
|
|
||
|
try {
|
||
|
|
||
|
//set the names of the classes
|
||
|
if( !NodePath.SetClassName( MOF_NODE::szName ) )
|
||
|
throw _com_error( WBEM_E_FAILED );
|
||
|
|
||
|
if( !ClusterPath.SetClassName( MOF_CLUSTER::szName ) )
|
||
|
throw _com_error( WBEM_E_FAILED );
|
||
|
|
||
|
//Get the node name
|
||
|
|
||
|
wstring wstrHostName;
|
||
|
ConstructHostName( wstrHostName, pCluster->GetClusterIpOrIndex(g_pWlbsControl),
|
||
|
a_pResponse->id );
|
||
|
|
||
|
//Get the cluster name
|
||
|
wstring wstrClusterName;
|
||
|
AddressToString( pCluster->GetClusterIpOrIndex(g_pWlbsControl), wstrClusterName );
|
||
|
|
||
|
//set the keys for the node and cluster
|
||
|
if( !NodePath.AddKeyRef( MOF_NODE::pProperties[MOF_NODE::NAME],
|
||
|
&_variant_t(wstrHostName.c_str()) ) )
|
||
|
throw _com_error( WBEM_E_FAILED );
|
||
|
|
||
|
|
||
|
if( !ClusterPath.AddKeyRef( MOF_CLUSTER::pProperties[MOF_CLUSTER::NAME],
|
||
|
&_variant_t(wstrClusterName.c_str())) )
|
||
|
throw _com_error( WBEM_E_FAILED );
|
||
|
|
||
|
//convert parsed object paths to strings
|
||
|
if (CObjectPathParser::Unparse(&NodePath, &szNodePath) != CObjectPathParser::NoError)
|
||
|
throw _com_error( WBEM_E_FAILED );
|
||
|
if (CObjectPathParser::Unparse(&ClusterPath, &szClusterPath) != CObjectPathParser::NoError)
|
||
|
throw _com_error( WBEM_E_FAILED );
|
||
|
|
||
|
//Node reference
|
||
|
HRESULT hRes = a_pWbemInstance->Put
|
||
|
(
|
||
|
|
||
|
_bstr_t( PNODE::pProperties[PNODE::NODE] ),
|
||
|
0,
|
||
|
&_variant_t(szNodePath),
|
||
|
NULL
|
||
|
);
|
||
|
if( FAILED( hRes ) )
|
||
|
throw _com_error( hRes );
|
||
|
|
||
|
//Cluster reference
|
||
|
hRes = a_pWbemInstance->Put
|
||
|
(
|
||
|
_bstr_t( PNODE::pProperties[PNODE::CLUSTER] ),
|
||
|
0,
|
||
|
&_variant_t(szClusterPath),
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if( FAILED( hRes ) )
|
||
|
throw _com_error( hRes );
|
||
|
|
||
|
//free resources
|
||
|
ClusterPath.ClearKeys();
|
||
|
NodePath.ClearKeys();
|
||
|
|
||
|
if( szNodePath )
|
||
|
delete (szNodePath);
|
||
|
|
||
|
if( szClusterPath )
|
||
|
delete (szClusterPath);
|
||
|
|
||
|
} catch (...) {
|
||
|
|
||
|
ClusterPath.ClearKeys();
|
||
|
NodePath.ClearKeys();
|
||
|
|
||
|
if( szNodePath )
|
||
|
delete (szNodePath);
|
||
|
|
||
|
if( szClusterPath )
|
||
|
delete (szClusterPath);
|
||
|
|
||
|
throw;
|
||
|
}
|
||
|
}
|