diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 08911d0a310150d70d5b081a483a381a61405e05..94195ee8e9833ea0cc5c6bca58ef9c7832e68e7a 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -34,6 +34,7 @@ #include "util.h" #include "uuid.h" #include "virterror_internal.h" +#include "xml.h" #include "esx_vi.h" #include "esx_vi_methods.h" #include "esx_util.h" @@ -479,7 +480,8 @@ ESX_VI__TEMPLATE__FREE(RemoteRequest, int esxVI_RemoteRequest_Execute(virConnectPtr conn, esxVI_Context *ctx, esxVI_RemoteRequest *remoteRequest, - esxVI_RemoteResponse **remoteResponse) + esxVI_RemoteResponse **remoteResponse, + esxVI_Boolean expectList) { virBuffer buffer = VIR_BUFFER_INITIALIZER; esxVI_Fault *fault = NULL; @@ -566,16 +568,24 @@ esxVI_RemoteRequest_Execute(virConnectPtr conn, esxVI_Context *ctx, BAD_CAST "urn:vim25"); if ((*remoteResponse)->responseCode == 500) { - (*remoteResponse)->xpathObject = - xmlXPathEval(BAD_CAST - "/soapenv:Envelope/soapenv:Body/soapenv:Fault", - (*remoteResponse)->xpathContext); - - if (esxVI_RemoteResponse_DeserializeXPathObject - (conn, *remoteResponse, - (esxVI_RemoteResponse_DeserializeFunc) - esxVI_Fault_Deserialize, - (void **)&fault) < 0) { + (*remoteResponse)->node = + virXPathNode(conn, "/soapenv:Envelope/soapenv:Body/soapenv:Fault", + (*remoteResponse)->xpathContext); + + if ((*remoteResponse)->node == NULL) { + ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "HTTP response code %d. VI Fault is unknown, " + "XPath evaluation failed", + (int)(*remoteResponse)->responseCode); + goto failure; + } + + if (esxVI_Fault_Deserialize(conn, (*remoteResponse)->node, + &fault) < 0) { + ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "HTTP response code %d. VI Fault is unknown, " + "deserialization failed", + (int)(*remoteResponse)->responseCode); goto failure; } @@ -585,10 +595,37 @@ esxVI_RemoteRequest_Execute(virConnectPtr conn, esxVI_Context *ctx, fault->faultcode, fault->faultstring); goto failure; + } else if (expectList == esxVI_Boolean_True) { + xmlNodePtr *nodeSet = NULL; + int nodeSet_size; + + nodeSet_size = virXPathNodeSet(conn, remoteRequest->xpathExpression, + (*remoteResponse)->xpathContext, + &nodeSet); + + if (nodeSet_size < 0) { + ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "XPath evaluation of '%s' failed", + remoteRequest->xpathExpression); + goto failure; + } else if (nodeSet_size == 0) { + (*remoteResponse)->node = NULL; + } else { + (*remoteResponse)->node = nodeSet[0]; + } + + VIR_FREE(nodeSet); } else { - (*remoteResponse)->xpathObject = - xmlXPathEval(BAD_CAST remoteRequest->xpathExpression, + (*remoteResponse)->node = + virXPathNode(conn, remoteRequest->xpathExpression, (*remoteResponse)->xpathContext); + + if ((*remoteResponse)->node == NULL) { + ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, + "XPath evaluation of '%s' failed", + remoteRequest->xpathExpression); + goto failure; + } } } else if ((*remoteResponse)->responseCode != 200) { ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, @@ -627,7 +664,6 @@ ESX_VI__TEMPLATE__FREE(RemoteResponse, { VIR_FREE(item->response); - xmlXPathFreeObject(item->xpathObject); xmlXPathFreeContext(item->xpathContext); if (item->document != NULL) { @@ -635,112 +671,6 @@ ESX_VI__TEMPLATE__FREE(RemoteResponse, } }); -int -esxVI_RemoteResponse_DeserializeXPathObject - (virConnectPtr conn, esxVI_RemoteResponse *remoteResponse, - esxVI_RemoteResponse_DeserializeFunc deserializeFunc, void **item) -{ - xmlNodePtr node = NULL; - - if (remoteResponse->xpathObject != NULL && - remoteResponse->xpathObject->type == XPATH_NODESET) { - if (remoteResponse->xpathObject->nodesetval->nodeNr != 1) { - ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "Expecting 1 XML node but found '%d'", - remoteResponse->xpathObject->nodesetval->nodeNr); - return -1; - } - - node = remoteResponse->xpathObject->nodesetval->nodeTab[0]; - - if (node->type != XML_ELEMENT_NODE) { - ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "Wrong XML element type %d", node->type); - return -1; - } - - if (deserializeFunc(conn, node, item) < 0) { - return -1; - } - } else { - ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "XPath error"); - return -1; - } - - return 0; -} - -int -esxVI_RemoteResponse_DeserializeXPathObjectList - (virConnectPtr conn, esxVI_RemoteResponse *remoteResponse, - esxVI_RemoteResponse_DeserializeListFunc deserializeListFunc, - esxVI_List **list) -{ - xmlNodePtr node = NULL; - - if (remoteResponse->xpathObject != NULL && - remoteResponse->xpathObject->type == XPATH_NODESET) { - if (remoteResponse->xpathObject->nodesetval->nodeNr > 0) { - node = remoteResponse->xpathObject->nodesetval->nodeTab[0]; - - if (node->type != XML_ELEMENT_NODE) { - ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "Wrong XML element type %d", node->type); - return -1; - } - } else { - node = NULL; - } - - if (deserializeListFunc(conn, node, list) < 0) { - return -1; - } - } else { - ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "XPath error"); - return -1; - } - - return 0; -} - -int -esxVI_RemoteResponse_DeserializeXPathObjectAsManagedObjectReference - (virConnectPtr conn, esxVI_RemoteResponse *remoteResponse, - esxVI_ManagedObjectReference **managedObjectReference, - const char *expectedType) -{ - xmlNodePtr node = NULL; - - if (remoteResponse->xpathObject != NULL && - remoteResponse->xpathObject->type == XPATH_NODESET) { - if (remoteResponse->xpathObject->nodesetval->nodeNr != 1) { - ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "Expecting 1 XML node but found '%d'", - remoteResponse->xpathObject->nodesetval->nodeNr); - return -1; - } - - node = remoteResponse->xpathObject->nodesetval->nodeTab[0]; - - if (node->type != XML_ELEMENT_NODE) { - ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, - "Wrong XML element type %d", node->type); - return -1; - } - - if (esxVI_ManagedObjectReference_Deserialize(conn, node, - managedObjectReference, - expectedType) < 0) { - return -1; - } - } else { - ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "XPath error"); - return -1; - } - - return 0; -} - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * @@ -1669,10 +1599,10 @@ esxVI_StartVirtualMachineTask(virConnectPtr conn, esxVI_Context *ctx, goto failure; } - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObjectAsManagedObjectReference - (conn, remoteResponse, task, "Task") < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0 || + esxVI_ManagedObjectReference_Deserialize + (conn, remoteResponse->node, task, "Task") < 0) { goto failure; } @@ -1789,8 +1719,8 @@ esxVI_SimpleVirtualMachineMethod(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->request = virBufferContentAndReset(&buffer); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0) { goto failure; } diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h index efb9bffe7d8813152ddb3e96ccbc63bdc26a9a9c..bed4a901dc105025b686056a600be102f2a7b10c 100644 --- a/src/esx/esx_vi.h +++ b/src/esx/esx_vi.h @@ -105,7 +105,8 @@ int esxVI_RemoteRequest_Alloc(virConnectPtr conn, void esxVI_RemoteRequest_Free(esxVI_RemoteRequest **remoteRequest); int esxVI_RemoteRequest_Execute(virConnectPtr conn, esxVI_Context *ctx, esxVI_RemoteRequest *remoteRequest, - esxVI_RemoteResponse **remoteResponse); + esxVI_RemoteResponse **remoteResponse, + esxVI_Boolean expectList); @@ -118,30 +119,12 @@ struct _esxVI_RemoteResponse { char *response; /* required */ xmlDocPtr document; /* optional */ xmlXPathContextPtr xpathContext; /* optional */ - xmlXPathObjectPtr xpathObject; /* optional */ + xmlNodePtr node; /* optional, list */ }; -typedef int (*esxVI_RemoteResponse_DeserializeFunc) (virConnectPtr conn, - xmlNodePtr node, - void **item); -typedef int (*esxVI_RemoteResponse_DeserializeListFunc) (virConnectPtr conn, - xmlNodePtr node, - esxVI_List **list); - int esxVI_RemoteResponse_Alloc(virConnectPtr conn, esxVI_RemoteResponse **remoteResponse); void esxVI_RemoteResponse_Free(esxVI_RemoteResponse **remoteResponse); -int esxVI_RemoteResponse_DeserializeXPathObject - (virConnectPtr conn, esxVI_RemoteResponse *remoteResponse, - esxVI_RemoteResponse_DeserializeFunc deserializeFunc, void **item); -int esxVI_RemoteResponse_DeserializeXPathObjectList - (virConnectPtr conn, esxVI_RemoteResponse *remoteResponse, - esxVI_RemoteResponse_DeserializeListFunc deserializeListFunc, - esxVI_List **list); -int esxVI_RemoteResponse_DeserializeXPathObjectAsManagedObjectReference - (virConnectPtr conn, esxVI_RemoteResponse *remoteResponse, - esxVI_ManagedObjectReference **managedObjectReference, - const char *expectedType); diff --git a/src/esx/esx_vi_methods.c b/src/esx/esx_vi_methods.c index 9a659dfb5a9dd3b2239bcab31b8276395e815822..4462063601f7e0634ec94677ce7ef235bdf7e7b6 100644 --- a/src/esx/esx_vi_methods.c +++ b/src/esx/esx_vi_methods.c @@ -91,13 +91,10 @@ esxVI_RetrieveServiceContent(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("RetrieveServiceContent"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObject - (conn, remoteResponse, - (esxVI_RemoteResponse_DeserializeFunc) - esxVI_ServiceContent_Deserialize, - (void **)serviceContent) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0 || + esxVI_ServiceContent_Deserialize(conn, remoteResponse->node, + serviceContent) < 0) { goto failure; } @@ -170,13 +167,10 @@ esxVI_Login(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->request = virBufferContentAndReset(&buffer); remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("Login"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObject - (conn, remoteResponse, - (esxVI_RemoteResponse_DeserializeFunc) - esxVI_UserSession_Deserialize, - (void **)userSession) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0 || + esxVI_UserSession_Deserialize(conn, remoteResponse->node, + userSession) < 0) { goto failure; } @@ -238,8 +232,8 @@ esxVI_Logout(virConnectPtr conn, esxVI_Context *ctx) remoteRequest->request = virBufferContentAndReset(&buffer); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0) { goto failure; } @@ -306,17 +300,9 @@ esxVI_SessionIsActive(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("SessionIsActive"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObject - (conn, remoteResponse, - /* - * FIXME: esxVI_Boolean_Deserialize expects *boolean, - * esxVI_RemoteResponse_DeserializeFunc expects void **, - * passing *boolean casted to void * to it - */ - (esxVI_RemoteResponse_DeserializeFunc)esxVI_Boolean_Deserialize, - (void *)active) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0 || + esxVI_Boolean_Deserialize(conn, remoteResponse->node, active) < 0) { goto failure; } @@ -390,13 +376,10 @@ esxVI_RetrieveProperties(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("RetrieveProperties"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObjectList - (conn, remoteResponse, - (esxVI_RemoteResponse_DeserializeListFunc) - esxVI_ObjectContent_DeserializeList, - (esxVI_List **)objectContentList) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_True) < 0 || + esxVI_ObjectContent_DeserializeList(conn, remoteResponse->node, + objectContentList) < 0) { goto failure; } @@ -625,10 +608,10 @@ esxVI_CreateFilter(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("CreateFilter"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObjectAsManagedObjectReference - (conn, remoteResponse, propertyFilter, "PropertyFilter") < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0 || + esxVI_ManagedObjectReference_Deserialize + (conn, remoteResponse->node, propertyFilter, "PropertyFilter") < 0) { goto failure; } @@ -690,8 +673,8 @@ esxVI_DestroyPropertyFilter(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->request = virBufferContentAndReset(&buffer); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0) { goto failure; } @@ -755,12 +738,10 @@ esxVI_WaitForUpdates(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("WaitForUpdates"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObject - (conn, remoteResponse, - (esxVI_RemoteResponse_DeserializeFunc)esxVI_UpdateSet_Deserialize, - (void **)updateSet) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0 || + esxVI_UpdateSet_Deserialize(conn, remoteResponse->node, + updateSet) < 0) { goto failure; } @@ -870,13 +851,10 @@ esxVI_ValidateMigration(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("ValidateMigration"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObjectList - (conn, remoteResponse, - (esxVI_RemoteResponse_DeserializeListFunc) - esxVI_Event_DeserializeList, - (esxVI_List **)eventList) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_True) < 0 || + esxVI_Event_DeserializeList(conn, remoteResponse->node, + eventList) < 0) { goto failure; } @@ -954,10 +932,10 @@ esxVI_FindByIp(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("FindByIp"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObjectAsManagedObjectReference - (conn, remoteResponse, managedObjectReference, + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0 || + esxVI_ManagedObjectReference_Deserialize + (conn, remoteResponse->node, managedObjectReference, vmSearch == esxVI_Boolean_True ? "VirtualMachine" : "HostSystem") < 0) { goto failure; @@ -1040,10 +1018,10 @@ esxVI_FindByUuid(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("FindByUuid"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObjectAsManagedObjectReference - (conn, remoteResponse, managedObjectReference, + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_False) < 0 || + esxVI_ManagedObjectReference_Deserialize + (conn, remoteResponse->node, managedObjectReference, vmSearch == esxVI_Boolean_True ? "VirtualMachine" : "HostSystem") < 0) { goto failure; @@ -1126,13 +1104,10 @@ esxVI_QueryAvailablePerfMetric(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("QueryAvailablePerfMetric"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObjectList - (conn, remoteResponse, - (esxVI_RemoteResponse_DeserializeListFunc) - esxVI_PerfMetricId_DeserializeList, - (esxVI_List **)perfMetricIdList) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_True) < 0 || + esxVI_PerfMetricId_DeserializeList(conn, remoteResponse->node, + perfMetricIdList) < 0) { goto failure; } @@ -1204,13 +1179,10 @@ esxVI_QueryPerfCounter(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("QueryPerfCounter"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObjectList - (conn, remoteResponse, - (esxVI_RemoteResponse_DeserializeListFunc) - esxVI_PerfCounterInfo_DeserializeList, - (esxVI_List **)perfCounterInfoList) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_True) < 0 || + esxVI_PerfCounterInfo_DeserializeList(conn, remoteResponse->node, + perfCounterInfoList) < 0) { goto failure; } @@ -1282,13 +1254,10 @@ esxVI_QueryPerf(virConnectPtr conn, esxVI_Context *ctx, remoteRequest->request = virBufferContentAndReset(&buffer); remoteRequest->xpathExpression = ESX_VI__SOAP__RESPONSE_XPATH("QueryPerf"); - if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, - &remoteResponse) < 0 || - esxVI_RemoteResponse_DeserializeXPathObjectList - (conn, remoteResponse, - (esxVI_RemoteResponse_DeserializeListFunc) - esxVI_PerfEntityMetric_DeserializeList, - (esxVI_List **)perfEntityMetricList) < 0) { + if (esxVI_RemoteRequest_Execute(conn, ctx, remoteRequest, &remoteResponse, + esxVI_Boolean_True) < 0 || + esxVI_PerfEntityMetric_DeserializeList(conn, remoteResponse->node, + perfEntityMetricList) < 0) { goto failure; }