From 06fd4bdf18a33383425c7ea9a5f580c419d20de9 Mon Sep 17 00:00:00 2001
From: Javi Fontan <jfontan@gmail.com>
Date: Wed, 3 Jun 2009 17:47:45 +0200
Subject: [PATCH 2/2] New C xmlrpc client code to connect to OpenNebula

---
 configure.in                |    8 +-
 src/Makefile.am             |    4 +-
 src/opennebula/one_client.c |  250 +++++++++++++++++++++++++++++++++++++++++++
 src/opennebula/one_client.h |   66 +++++++++++
 src/opennebula/one_conf.h   |    1 +
 src/opennebula/one_driver.h |    2 +-
 6 files changed, 326 insertions(+), 5 deletions(-)
 create mode 100644 src/opennebula/one_client.c
 create mode 100644 src/opennebula/one_client.h

diff --git a/configure.in b/configure.in
index 5c0575c..2036fb5 100644
--- a/configure.in
+++ b/configure.in
@@ -421,9 +421,11 @@ dnl OpenNebula driver Compilation setting
 dnl
 
 if test "$with_one" = "yes" ; then
- CFLAGS="$CFLAGS -I$ONE_LOCATION/include"
- ONE_LIBS="-L/usr/local/lib -lxmlrpc_client++ -lxmlrpc -lxmlrpc_util -lxmlrpc_xmlparse -lxmlrpc_xmltok -lxmlrpc++ -lxmlrpc_client -L$ONE_LOCATION/lib -loneapi"
- AC_SUBST([ONE_LIBS])
+    XMLRPC_CFLAGS=`xmlrpc-c-config client --cflags`
+    XMLRPC_LDFLAGS=`xmlrpc-c-config client --libs`
+    CFLAGS="$CFLAGS $XMLRPC_CFLAGS"
+    ONE_LIBS="$XMLRPC_LDFLAGS"
+    AC_SUBST([ONE_LIBS])
 fi
 
 dnl Need to test if pkg-config exists
diff --git a/src/Makefile.am b/src/Makefile.am
index 03d4cf5..880fadc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -149,7 +149,9 @@ ONE_DRIVER_SOURCES =					\
 		./opennebula/one_conf.c			\
 		./opennebula/one_conf.h			\
 		./opennebula/one_driver.c		\
-		./opennebula/one_driver.h
+		./opennebula/one_driver.h		\
+		./opennebula/one_client.c		\
+		./opennebula/one_client.h
 
 NETWORK_DRIVER_SOURCES =					\
 		network_driver.h network_driver.c
diff --git a/src/opennebula/one_client.c b/src/opennebula/one_client.c
new file mode 100644
index 0000000..6582e2e
--- /dev/null
+++ b/src/opennebula/one_client.c
@@ -0,0 +1,250 @@
+/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
+ * Complutense de Madrid (dsa-research.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "one_client.h"
+
+oneClient one_client;
+
+void c_oneStart()
+{
+    xmlrpc_env_init(&one_client.env);
+    xmlrpc_client_init2(&one_client.env, XMLRPC_CLIENT_NO_FLAGS,
+        "OpenNebula API Client", "1.2", NULL, 0);
+    
+    one_client.error=0;
+    
+#ifdef ONED_PORT
+    one_client.url=(char *)malloc(64);
+    snprintf(one_client.url, 63, "http://localhost:%d/RPC2", ONED_PORT);
+#else
+    one_client.url=(char *)"http://localhost:2633/RPC2";
+#endif
+
+    one_client.session=(char *)"one-session";
+};
+
+
+int c_oneReturnCode(xmlrpc_value *resultP);
+
+int c_oneReturnCode(xmlrpc_value *resultP)
+{
+    int return_code;
+    char *return_string;
+
+    xmlrpc_decompose_value(&one_client.env, resultP, "(bs)",
+        &return_code, &return_string);
+    
+    if( return_code )
+    {
+        xmlrpc_DECREF(resultP);
+        if(return_string)
+            free(return_string);
+        return 0;
+    }
+    else
+    {
+        if(one_client.error)
+            free(one_client.error);
+        
+        one_client.error=return_string;
+        return -1;
+    }
+}
+
+int c_oneDeploy(int vmid, int hid)
+{
+    xmlrpc_value *resultP;
+    
+    resultP = xmlrpc_client_call(&one_client.env, one_client.url,
+        "one.vmdeploy", "(sii)", one_client.session, (xmlrpc_int32)vmid,
+        (xmlrpc_int32)hid);
+    
+    return c_oneReturnCode(resultP);
+}
+
+int c_oneMigrate(int vmid, int hid, int flag)
+{
+    xmlrpc_value *resultP;
+    
+    resultP = xmlrpc_client_call(&one_client.env, one_client.url,
+        "one.vmmigrate", "(siib)", one_client.session, (xmlrpc_int32)vmid,
+        (xmlrpc_int32)hid,
+        (xmlrpc_bool)flag);
+    
+    return c_oneReturnCode(resultP);
+}
+
+int c_oneAllocate(char* template_file)
+{
+    int file;
+    int size;
+    int bytes_read;
+    char *file_text;
+    int return_code;
+    
+    file=open(template_file, O_RDONLY);
+    size=lseek(file, 0, SEEK_END);
+    lseek(file, 0, SEEK_SET);
+    
+    file_text=(char *)malloc(size+1);
+    bytes_read=read(file, file_text, size);
+    close(file);
+    
+    if(bytes_read==size) {
+        file_text[size]=0;
+        
+        return_code=c_oneAllocateTemplate(file_text);
+        free(file_text);
+        
+        return return_code;
+    } else {
+        free(file_text);
+        return -1;
+    }
+}
+
+int c_oneAllocateTemplate(char* vm_template)
+{
+    xmlrpc_value *resultP;
+    xmlrpc_value *valueP;
+    int return_code;
+    char *return_string;
+    int vmid;
+    
+    
+    resultP = xmlrpc_client_call(&one_client.env, one_client.url,
+        "one.vmallocate", "(ss)", one_client.session, vm_template);
+
+    xmlrpc_array_read_item(&one_client.env, resultP, 0, &valueP);
+    xmlrpc_read_bool(&one_client.env, valueP, &return_code);
+    
+    if( return_code )
+    {
+        xmlrpc_DECREF(valueP);
+        xmlrpc_array_read_item(&one_client.env, resultP, 1, &valueP);
+        xmlrpc_read_int(&one_client.env, valueP, &vmid);
+        
+        xmlrpc_DECREF(valueP);
+        xmlrpc_DECREF(resultP);
+            
+        return vmid;
+    }
+    else
+    {
+        xmlrpc_DECREF(valueP);
+        xmlrpc_array_read_item(&one_client.env, resultP, 1, &valueP);
+        xmlrpc_read_string(&one_client.env, valueP,
+            (const char **)&return_string);
+        
+        xmlrpc_DECREF(valueP);
+        xmlrpc_DECREF(resultP);
+        
+        if(one_client.error)
+            free(one_client.error);
+        
+        one_client.error=return_string;
+        return -1;
+    }
+}
+
+int c_oneAction(int vmid, char* action)
+{
+    xmlrpc_value *resultP;
+    
+    resultP = xmlrpc_client_call(&one_client.env, one_client.url,
+        "one.vmaction", "(ssi)", one_client.session, action,
+        (xmlrpc_int32)vmid);
+    
+    return c_oneReturnCode(resultP);
+}
+
+int c_oneShutdown(int vmid)
+{
+    return c_oneAction(vmid, (char *)"shutdown");
+}
+
+int c_oneSuspend(int vmid)
+{
+    return c_oneAction(vmid, (char *)"suspend");
+}
+
+int c_oneStop(int vmid)
+{
+    return c_oneAction(vmid, (char *)"stop");
+}
+
+int c_oneResume(int vmid)
+{
+    return c_oneAction(vmid, (char *)"resume");
+}
+
+int c_oneCancel(int vmid)
+{
+    return c_oneAction(vmid, (char *)"cancel");
+}
+
+int c_oneFinalize(int vmid)
+{
+    return c_oneAction(vmid, (char *)"finalize");
+}
+
+int c_oneVmInfo(int vmid, char* ret_info,int length)
+{
+    xmlrpc_value *resultP;
+    int return_code;
+    char *return_string;
+    
+    resultP = xmlrpc_client_call(&one_client.env, one_client.url,
+        "one.vmget_info", "(si)", one_client.session, vmid);
+
+    xmlrpc_decompose_value(&one_client.env, resultP, "(bs)",
+        &return_code, &return_string);
+
+    if( return_code )
+    {
+        strncpy(ret_info, return_string, length-1);
+            
+        xmlrpc_DECREF(resultP);
+        free(return_string);
+
+        return 0;
+    }
+    else
+    {
+        xmlrpc_DECREF(resultP);
+        free(return_string);
+
+        return -1;
+    }
+}
+
+void c_oneFree()
+{
+    xmlrpc_env_clean(&one_client.env);
+    xmlrpc_client_cleanup();
+#ifdef ONE_PORT
+    free(one_client.url);
+#endif
+}
+
+
diff --git a/src/opennebula/one_client.h b/src/opennebula/one_client.h
new file mode 100644
index 0000000..238d1a6
--- /dev/null
+++ b/src/opennebula/one_client.h
@@ -0,0 +1,66 @@
+/* Copyright 2002-2009, Distributed Systems Architecture Group, Universidad
+ * Complutense de Madrid (dsa-research.org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ */
+
+#ifndef ONE_CLIENT_H_
+#define ONE_CLIENT_H_
+
+#include <xmlrpc-c/base.h>
+#include <xmlrpc-c/client.h>
+
+struct _oneClient {
+    xmlrpc_env env;
+    char *url;
+    char *session;
+    char *error;
+};
+
+typedef struct _oneClient oneClient;
+typedef oneClient *oneClientPtr;
+
+void c_oneStart(void);
+
+int c_oneDeploy(int vmid, int hid);
+
+int c_oneMigrate(int vmid, int hid, int flag);
+
+int c_oneAllocate(char* template_file);
+
+int c_oneAllocateTemplate(char* vm_template);
+
+int c_oneAction(int vmid,char* action);
+
+int c_oneShutdown(int vmid);
+
+int c_oneSuspend(int vmid);
+
+int c_oneStop(int vmid);
+
+int c_oneResume(int vmid);
+
+int c_oneCancel(int vmid);
+
+int c_oneFinalize(int vmid);
+
+int c_oneVmInfo(int vmid, char* ret_info,int leng);
+
+void c_oneFree(void);
+
+
+#endif /* ONE_CLIENT_H_ */
+
+
diff --git a/src/opennebula/one_conf.h b/src/opennebula/one_conf.h
index b809220..06917f4 100644
--- a/src/opennebula/one_conf.h
+++ b/src/opennebula/one_conf.h
@@ -27,6 +27,7 @@
 #include "domain_conf.h"
 #include "capabilities.h"
 #include "threads.h"
+#include "one_client.h"
 
 struct one_driver{
     virMutex lock;
diff --git a/src/opennebula/one_driver.h b/src/opennebula/one_driver.h
index 393edc6..e30a59f 100644
--- a/src/opennebula/one_driver.h
+++ b/src/opennebula/one_driver.h
@@ -23,7 +23,7 @@
 #define ONE_DRIVER_H
 
 #include <config.h>
-#include <OneClient.h>
+#include "one_client.h"
 
 int oneRegister(void);
 
-- 
1.6.1.2

