[libvirt] [libvirt-qpid PATCH 1/3] Convert to QMFv2 APIs

Zane Bitter zbitter at redhat.com
Tue Jul 12 16:28:46 UTC 2011


Note that this version removes GSS support. In the future, authentication
will be handled through matahari.
---
 AUTHORS             |    4 
 libvirt-qpid.spec   |    4 
 src/DomainWrap.cpp  |  444 +++++++++++++++++++++++------------------
 src/DomainWrap.h    |   49 ++---
 src/Error.h         |    8 +
 src/Exception.cpp   |   38 ++++
 src/Exception.h     |   30 +++
 src/Makefile.am     |   29 +--
 src/ManagedObject.h |   78 +++++++
 src/NodeWrap.cpp    |  552 ++++++++++++++++++++++++++++-----------------------
 src/NodeWrap.h      |   76 ++++---
 src/PoolWrap.cpp    |  365 +++++++++++++++++++---------------
 src/PoolWrap.h      |   60 ++----
 src/VolumeWrap.cpp  |  153 +++++++-------
 src/VolumeWrap.h    |   58 ++---
 15 files changed, 1100 insertions(+), 848 deletions(-)
 create mode 100644 src/Exception.cpp
 create mode 100644 src/Exception.h
 create mode 100644 src/ManagedObject.h

diff --git a/AUTHORS b/AUTHORS
index d042b71..367ea49 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -8,3 +8,7 @@ The libvirt-qpid project was initiated by:
 Patches have also been contributed by:
 
   Ted Ross              <tross at redhat.com>
+
+Conversion to QMFv2 API by:
+
+  Zane Bitter           <zbitter at redhat.com>
diff --git a/libvirt-qpid.spec b/libvirt-qpid.spec
index 5de1fd2..d64552d 100644
--- a/libvirt-qpid.spec
+++ b/libvirt-qpid.spec
@@ -8,12 +8,12 @@ License: LGPLv2+
 Group: Applications/System
 Requires: libxml2 >= 2.7.1
 Requires: qmf >= 0.5.790661
-Requires: qpid-cpp-client >= 0.5.790661
+Requires: qpid-cpp-client >= 0.10
 Requires: libvirt >= 0.4.4
 Requires(post):  /sbin/chkconfig
 Requires(preun): /sbin/chkconfig
 Requires(preun): initscripts
-BuildRequires: qpid-cpp-client-devel >= 0.5.790661
+BuildRequires: qpid-cpp-client-devel >= 0.10
 BuildRequires: libxml2-devel >= 2.7.1
 BuildRequires: libvirt-devel >= 0.5.0
 BuildRequires: qmf-devel >= 0.5.790661
diff --git a/src/DomainWrap.cpp b/src/DomainWrap.cpp
index 47876de..eab6bbc 100644
--- a/src/DomainWrap.cpp
+++ b/src/DomainWrap.cpp
@@ -2,266 +2,310 @@
 #include "NodeWrap.h"
 #include "DomainWrap.h"
 #include "Error.h"
+#include "Exception.h"
 
-#include "ArgsDomainMigrate.h"
-#include "ArgsDomainRestore.h"
-#include "ArgsDomainSave.h"
-#include "ArgsDomainGetXMLDesc.h"
+#include <cstdio>
 
-namespace _qmf = qmf::com::redhat::libvirt;
 
-DomainWrap::DomainWrap(ManagementAgent *agent, NodeWrap *parent,
-                       virDomainPtr _domain_ptr, virConnectPtr _conn) :
-                       domain_ptr(_domain_ptr), conn(_conn)
+DomainWrap::DomainWrap(
+        NodeWrap *parent,
+        virDomainPtr domain_ptr,
+        virConnectPtr conn):
+    PackageOwner<NodeWrap::PackageDefinition>(parent),
+    ManagedObject(package().data_Domain),
+    _domain_ptr(domain_ptr), _conn(conn)
 {
     char dom_uuid[VIR_UUID_STRING_BUFLEN];
 
-    domain = NULL;
-
-    if (virDomainGetUUIDString(domain_ptr, dom_uuid) < 0) {
-        REPORT_ERR(conn, "DomainWrap: Unable to get UUID string of domain.");
+    if (virDomainGetUUIDString(_domain_ptr, dom_uuid) < 0) {
+        REPORT_ERR(_conn, "DomainWrap: Unable to get UUID string of domain.");
         throw 1;
     }
 
-    domain_uuid = dom_uuid;
+    _domain_uuid = dom_uuid;
 
-    const char *dom_name = virDomainGetName(domain_ptr);
+    const char *dom_name = virDomainGetName(_domain_ptr);
     if (!dom_name) {
-        REPORT_ERR(conn, "Unable to get domain name!\n");
+        REPORT_ERR(_conn, "Unable to get domain name!\n");
         throw 1;
     }
 
-    domain_name = dom_name;
+    _domain_name = dom_name;
+
+    _data.setProperty("uuid", _domain_uuid);
+    _data.setProperty("name", _domain_name);
+    _data.setProperty("node", parent->objectID());
+
+    // Set defaults
+    _data.setProperty("state", "");
+    _data.setProperty("numVcpus", 0);
+    _data.setProperty("maximumMemory", 0);
+    _data.setProperty("memory", (uint64_t)0);
+    _data.setProperty("cpuTime", (uint64_t)0);
+
+    addData(_data);
 
-    domain = new _qmf::Domain(agent, this, parent, domain_uuid, domain_name);
-    printf("Creating new domain object for %s\n", domain_name.c_str());
-    agent->addObject(domain);
+    printf("Initialised new domain object for %s\n", _domain_name.c_str());
 }
 
 DomainWrap::~DomainWrap()
 {
-    if (domain) {
-        domain->resourceDestroy();
-    }
-    virDomainFree(domain_ptr);
+    virDomainFree(_domain_ptr);
+    delData(_data);
 }
 
-
 void
 DomainWrap::update()
 {
     virDomainInfo info;
     int ret;
 
-    ret = virDomainGetInfo(domain_ptr, &info);
+    ret = virDomainGetInfo(_domain_ptr, &info);
     if (ret < 0) {
-        REPORT_ERR(conn, "Domain get info failed.");
+        REPORT_ERR(_conn, "Domain get info failed.");
         /* Next domainSync() will take care of this in the node wrapper if the domain is
          * indeed dead. */
         return;
     } else {
+        const char *state = NULL;
         switch (info.state) {
-
             case VIR_DOMAIN_NOSTATE:
-                domain->set_state("nostate");
+                state = "nostate";
                 break;
             case VIR_DOMAIN_RUNNING:
-                domain->set_state("running");
+                state = "running";
                 break;
             case VIR_DOMAIN_BLOCKED:
-                domain->set_state("blocked");
+                state = "blocked";
                 break;
             case VIR_DOMAIN_PAUSED:
-                domain->set_state("paused");
+                state = "paused";
                 break;
             case VIR_DOMAIN_SHUTDOWN:
-                domain->set_state("shutdown");
+                state = "shutdown";
                 break;
             case VIR_DOMAIN_SHUTOFF:
-                domain->set_state("shutoff");
+                state = "shutoff";
                 break;
             case VIR_DOMAIN_CRASHED:
-                domain->set_state("crashed");
+                state = "crashed";
                 break;
         }
 
-        domain->set_numVcpus(info.nrVirtCpu);
-        domain->set_maximumMemory(info.maxMem);
-        domain->set_memory(info.memory);
-        domain->set_cpuTime(info.cpuTime);
+        if (state) {
+            _data.setProperty("state", state);
+        }
+        _data.setProperty("numVcpus", info.nrVirtCpu);
+        _data.setProperty("maximumMemory", info.maxMem);
+        _data.setProperty("memory", (uint64_t)info.memory);
+        _data.setProperty("cpuTime", (uint64_t)info.cpuTime);
     }
 
-    ret = virDomainGetID(domain_ptr);
+    int id = virDomainGetID(_domain_ptr);
     // Just set it directly, if there's an error, -1 will be right.
-    domain->set_id(ret);
+    _data.setProperty("id", id);
 
-    if (ret > 0) {
-        domain->set_active("true");
-    } else {
-        domain->set_active("false");
-    }
-    domain->set_id(ret);
+    _data.setProperty("active", (id > 0) ? "true" : "false");
 }
 
-Manageable::status_t
-DomainWrap::ManagementMethod(uint32_t methodId, Args& args, std::string &errstr)
+bool
+DomainWrap::handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event)
 {
     int ret;
 
-    switch (methodId) {
-        case _qmf::Domain::METHOD_CREATE:
-            ret = virDomainCreate(domain_ptr);
-            update();
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error creating new domain (virDomainCreate).", &ret);
-                return STATUS_USER + ret;
-            }
-            return STATUS_OK;
-
-        case _qmf::Domain::METHOD_DESTROY:
-            ret = virDomainDestroy(domain_ptr);
-            update();
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error destroying domain (virDomainDestroy).", &ret);
-                return STATUS_USER + ret;
-            }
-
-            return STATUS_OK;
-
-        case _qmf::Domain::METHOD_UNDEFINE:
-            ret = virDomainUndefine(domain_ptr);
-
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error undefining domain (virDomainUndefine).", &ret);
-                return STATUS_USER + ret;
-            }
-
-            /* We now wait for domainSync() to clean this up. */
-            return STATUS_OK;
-
-        case _qmf::Domain::METHOD_SUSPEND:
-            ret = virDomainSuspend(domain_ptr);
-            update();
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error suspending domain (virDomainSuspend).", &ret);
-                return STATUS_USER + ret;
-            }
-            return STATUS_OK;
-
-        case _qmf::Domain::METHOD_RESUME:
-            ret = virDomainResume(domain_ptr);
-            update();
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error resuming domain (virDomainResume).", &ret);
-                return STATUS_USER + ret;
-            }
-            return STATUS_OK;
-
-        case _qmf::Domain::METHOD_SAVE:
-            {
-                _qmf::ArgsDomainSave *io_args = (_qmf::ArgsDomainSave *) &args;
-
-                ret = virDomainSave(domain_ptr, io_args->i_filename.c_str());
-                if (ret < 0) {
-                    errstr = FORMAT_ERR(conn, "Error saving domain (virDomainSave).", &ret);
-                    return STATUS_USER + ret;
-                }
-                return STATUS_OK;
-            }
-
-        case _qmf::Domain::METHOD_RESTORE:
-            {
-                _qmf::ArgsDomainRestore *io_args = (_qmf::ArgsDomainRestore *) &args;
-
-                ret = virDomainRestore(conn, io_args->i_filename.c_str());
-                update();
-                if (ret < 0) {
-                    errstr = FORMAT_ERR(conn, "Error restoring domain (virDomainRestore).", &ret);
-                    return STATUS_USER + ret;
-                }
-                return STATUS_OK;
-            }
-
-        case _qmf::Domain::METHOD_SHUTDOWN:
-            ret = virDomainShutdown(domain_ptr);
-            update();
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error shutting down domain (virDomainShutdown).", &ret);
-                return STATUS_USER + ret;
-            }
-            return STATUS_OK;
-
-        case _qmf::Domain::METHOD_REBOOT:
-            ret = virDomainReboot(domain_ptr, 0);
-            update();
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error rebooting domain (virDomainReboot).", &ret);
-                return STATUS_USER + ret;
-            }
-            return STATUS_OK;
-
-        case _qmf::Domain::METHOD_GETXMLDESC:
-            {
-                _qmf::ArgsDomainGetXMLDesc *io_args = (_qmf::ArgsDomainGetXMLDesc *) &args;
-                char *desc;
-                desc = virDomainGetXMLDesc(domain_ptr, VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_INACTIVE);
-                if (desc) {
-                    io_args->o_description = desc;
-                } else {
-                    errstr = FORMAT_ERR(conn, "Error getting XML description of domain(virDomainGetXMLDesc).", &ret);
-                    return STATUS_USER + ret;
-                }
-                return STATUS_OK;
-            }
-
-        case _qmf::Domain::METHOD_MIGRATE:
-            {
-                virConnectPtr dest_conn;
-                virDomainPtr rem_dom;
-                _qmf::ArgsDomainMigrate *io_args = (_qmf::ArgsDomainMigrate *) &args;
-
-                // This is actually quite broken.  Most setups won't allow unauthorized connection
-                // from one node to another directly like this.
-                dest_conn = virConnectOpen(io_args->i_destinationUri.c_str());
-                if (!dest_conn) {
-                    errstr = FORMAT_ERR(dest_conn, "Unable to connect to remote system for migration: virConnectOpen", &ret);
-                    return STATUS_USER + ret;
-                }
-
-                const char *new_dom_name = NULL;
-                if (io_args->i_newDomainName.size() > 0) {
-                    new_dom_name = io_args->i_newDomainName.c_str();
-                }
-
-                const char *uri = NULL;
-                if (io_args->i_uri.size() > 0) {
-                    uri = io_args->i_uri.c_str();
-                }
-
-                printf ("calling migrate, new_dom_name: %s, uri: %s, flags: %d (live is %d)\n",
-                        new_dom_name ? new_dom_name : "NULL",
-                        uri ? uri : "NULL",
-                        io_args->i_flags,
-                        VIR_MIGRATE_LIVE);
-
-                rem_dom = virDomainMigrate(domain_ptr, dest_conn, io_args->i_flags,
-                                           new_dom_name,
-                                           uri,
-                                           io_args->i_bandwidth);
-
-                virConnectClose(dest_conn);
-
-                if (!rem_dom) {
-                    errstr = FORMAT_ERR(conn, "virDomainMigrate", &ret);
-                    return STATUS_USER + ret;
-                }
-                virDomainFree(rem_dom);
-
-                return STATUS_OK;
-            }
+    if (*this != event.getDataAddr()) {
+        return false;
+    }
+
+    const std::string& methodName(event.getMethodName());
+    qpid::types::Variant::Map args(event.getArguments());
+
+    if (methodName == "create") {
+        int ret = virDomainCreate(_domain_ptr);
+        update();
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error creating new domain (virDomainCreate).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    else if (methodName == "destroy") {
+        int ret = virDomainDestroy(_domain_ptr);
+        update();
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error destroying domain (virDomainDestroy).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    else if (methodName == "undefine") {
+        int ret = virDomainUndefine(_domain_ptr);
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error undefining domain (virDomainUndefine).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            session.methodSuccess(event);
+        }
+        /* We now wait for domainSync() to clean this up. */
+        return true;
     }
 
-    return STATUS_NOT_IMPLEMENTED;
+    else if (methodName == "suspend") {
+        int ret = virDomainSuspend(_domain_ptr);
+        update();
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error suspending domain (virDomainSuspend).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    else if (methodName == "resume") {
+        int ret = virDomainResume(_domain_ptr);
+        update();
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error resuming domain (virDomainResume).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    else if (methodName == "save") {
+        const std::string filename = args["filename"].asString();
+        int ret = virDomainSave(_domain_ptr, filename.c_str());
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error saving domain (virDomainSave).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    else if (methodName == "restore") {
+        const std::string filename = args["filename"].asString();
+        int ret = virDomainRestore(_conn, filename.c_str());
+        update();
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error saving domain (virDomainSave).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    else if (methodName == "shutdown") {
+        int ret = virDomainShutdown(_domain_ptr);
+        update();
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error shutting down domain (virDomainShutdown).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    else if (methodName == "reboot") {
+        int ret = virDomainReboot(_domain_ptr, 0);
+        update();
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error rebooting domain (virDomainReboot).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    else if (methodName == "getXMLDesc") {
+        const char *desc = virDomainGetXMLDesc(_domain_ptr,
+                VIR_DOMAIN_XML_SECURE | VIR_DOMAIN_XML_INACTIVE);
+        if (!desc) {
+            std::string err = FORMAT_ERR(_conn, "Error rebooting domain (virDomainReboot).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            event.addReturnArgument("description", desc);
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    else if (methodName == "migrate") {
+        if (migrate(session, event)) {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    raiseException(session, event,
+                   ERROR_UNKNOWN_METHOD, STATUS_UNKNOWN_METHOD);
+    return true;
 }
 
+bool
+DomainWrap::migrate(qmf::AgentSession& session, qmf::AgentEvent& event)
+{
+    virConnectPtr dest_conn;
+    virDomainPtr rem_dom;
+    qpid::types::Variant::Map args(event.getArguments());
+    int ret;
+
+    // This is actually quite broken. Most setups won't allow unauthorized
+    // connection from one node to another directly like this.
+    dest_conn = virConnectOpen(args["destinationUri"].asString().c_str());
+    if (!dest_conn) {
+        std::string err = FORMAT_ERR(dest_conn, "Unable to connect to remote system for migration: virConnectOpen", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
+
+    const std::string newDomainName_arg(args["newDomainName"]);
+    const char *new_dom_name = NULL;
+    if (newDomainName_arg.size() > 0) {
+        new_dom_name = newDomainName_arg.c_str();
+    }
+
+    const std::string uri_arg(args["uri"]);
+    const char *uri = NULL;
+    if (uri_arg.size() > 0) {
+        uri = uri_arg.c_str();
+    }
+
+    uint32_t flags(args["flags"]);
+    uint32_t bandwidth(args["bandwidth"]);
+
+    printf ("calling migrate, new_dom_name: %s, uri: %s, flags: %d (live is %d)\n",
+            new_dom_name ? new_dom_name : "NULL",
+            uri ? uri : "NULL",
+            flags,
+            VIR_MIGRATE_LIVE);
+
+    rem_dom = virDomainMigrate(_domain_ptr, dest_conn, flags,
+                               new_dom_name,
+                               uri,
+                               bandwidth);
+
+    virConnectClose(dest_conn);
+
+    if (!rem_dom) {
+        std::string err = FORMAT_ERR(_conn, "virDomainMigrate", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
+    virDomainFree(rem_dom);
+
+    return true;
+}
 
diff --git a/src/DomainWrap.h b/src/DomainWrap.h
index 27822bd..fc39a5f 100644
--- a/src/DomainWrap.h
+++ b/src/DomainWrap.h
@@ -1,10 +1,7 @@
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-#include <qpid/sys/Mutex.h>
+#ifndef DOMAIN_WRAP_H
+#define DOMAIN_WRAP_H
 
-#include "Package.h"
-#include "Domain.h"
+#include "NodeWrap.h"
 
 #include <unistd.h>
 #include <cstdlib>
@@ -15,38 +12,30 @@
 #include <libvirt/libvirt.h>
 #include <libvirt/virterror.h>
 
-using namespace qpid::management;
-using namespace qpid::sys;
-using namespace std;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::Mutex;
 
-class DomainWrap : public Manageable
+class DomainWrap:
+    PackageOwner<NodeWrap::PackageDefinition>,
+    public ManagedObject
 {
-    ManagementAgent *agent;
-    qmf::com::redhat::libvirt::Domain *domain;
+    virDomainPtr _domain_ptr;
+    virConnectPtr _conn;
 
-    virDomainPtr domain_ptr;
-    virConnectPtr conn;
+    std::string _domain_name;
+    std::string _domain_uuid;
 
 public:
-
-    std::string domain_name;
-    std::string domain_uuid;
-
-    DomainWrap(ManagementAgent *agent, NodeWrap *parent, virDomainPtr domain_ptr, 
-                virConnectPtr connect);
+    DomainWrap(NodeWrap *parent,
+               virDomainPtr domain_ptr, virConnectPtr conn);
     ~DomainWrap();
 
-    ManagementObject* GetManagementObject(void) const
-    { 
-        return domain; 
-    }
-
+    std::string& name(void) { return _domain_name; }
+    std::string& uuid(void) { return _domain_uuid; }
     void update();
 
-    status_t ManagementMethod (uint32_t methodId, Args& args, std::string &errstr);
+    bool handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event);
+
+private:
+    bool migrate(qmf::AgentSession& session, qmf::AgentEvent& event);
 };
 
+#endif
diff --git a/src/Error.h b/src/Error.h
index 388b41a..5bd7397 100644
--- a/src/Error.h
+++ b/src/Error.h
@@ -1,11 +1,19 @@
+#ifndef ERROR_H
+#define ERROR_H
+
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+
 
 #define REPORT_ERR(conn,msg) reportError(conn, msg, __func__, __LINE__, __FILE__)
 
 #define FORMAT_ERR(conn,msg,err_ret) formatError(conn, msg, err_ret, __func__, __LINE__, __FILE__)
 
+
 void
 reportError(virConnectPtr conn, const char *msg, const char *function, int line, const char *file);
 
 std::string
 formatError(virConnectPtr conn, const char *msg, int *err_ret, const char *function, int line, const char *file);
 
+#endif
diff --git a/src/Exception.cpp b/src/Exception.cpp
new file mode 100644
index 0000000..105df27
--- /dev/null
+++ b/src/Exception.cpp
@@ -0,0 +1,38 @@
+#include "Exception.h"
+#include "Error.h"
+#include <qmf/Schema.h>
+#include <qmf/SchemaProperty.h>
+#include <qmf/Data.h>
+
+
+#define ERROR_TEXT "error_text"
+#define ERROR_CODE "error_code"
+
+
+static qmf::Schema errorSchema(qmf::SCHEMA_TYPE_DATA,
+        "com.redhat.libvirt", "error");
+
+
+void
+initErrorSchema(qmf::AgentSession& session)
+{
+    qmf::SchemaProperty status_text(ERROR_TEXT, qmf::SCHEMA_DATA_STRING);
+    qmf::SchemaProperty status_code(ERROR_CODE, qmf::SCHEMA_DATA_INT);
+
+    errorSchema.addProperty(status_text);
+    errorSchema.addProperty(status_code);
+
+    session.registerSchema(errorSchema);
+}
+
+void
+raiseException(qmf::AgentSession& session,
+               qmf::AgentEvent& event,
+               const std::string& error_text,
+               unsigned int error_code)
+{
+    qmf::Data response(errorSchema);
+    response.setProperty(ERROR_TEXT, error_text);
+    response.setProperty(ERROR_CODE, error_code);
+    session.raiseException(event, response);
+}
diff --git a/src/Exception.h b/src/Exception.h
new file mode 100644
index 0000000..efbd327
--- /dev/null
+++ b/src/Exception.h
@@ -0,0 +1,30 @@
+#ifndef EXCEPTION_H
+#define EXCEPTION_H
+
+#include <qmf/AgentSession.h>
+#include <qmf/AgentEvent.h>
+#include <string>
+
+
+#define STATUS_OK               0
+#define STATUS_UNKNOWN_OBJECT   1
+#define STATUS_UNKNOWN_METHOD   2
+#define STATUS_NOT_IMPLEMENTED  3
+#define STATUS_EXCEPTION        7
+#define STATUS_USER             0x10000
+
+#define ERROR_UNKNOWN_OBJECT   "Unknown Object"
+#define ERROR_UNKNOWN_METHOD   "Unknown Method"
+#define ERROR_NOT_IMPLEMENTED  "Not implemented"
+
+
+void
+initErrorSchema(qmf::AgentSession& session);
+
+void
+raiseException(qmf::AgentSession& session,
+               qmf::AgentEvent& event,
+               const std::string& error_text,
+               unsigned int error_code);
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 1b4ef23..4bb27b2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,37 +5,22 @@ INCLUDES = -I$(top_srcdir)/src/qmf/com/redhat/libvirt $(XML_CFLAGS)
 sbin_PROGRAMS = libvirt-qpid
 
 generated_file_list = \
-	qmf/com/redhat/libvirt/Domain.cpp\
-	qmf/com/redhat/libvirt/Node.cpp\
-	qmf/com/redhat/libvirt/Package.cpp\
-	qmf/com/redhat/libvirt/Pool.cpp\
-	qmf/com/redhat/libvirt/Volume.cpp\
-	qmf/com/redhat/libvirt/ArgsDomainGetXMLDesc.h\
-	qmf/com/redhat/libvirt/ArgsDomainMigrate.h\
-	qmf/com/redhat/libvirt/ArgsDomainRestore.h\
-	qmf/com/redhat/libvirt/ArgsDomainSave.h\
-	qmf/com/redhat/libvirt/ArgsNodeDomainDefineXML.h\
-	qmf/com/redhat/libvirt/ArgsNodeStoragePoolCreateXML.h\
-	qmf/com/redhat/libvirt/ArgsNodeStoragePoolDefineXML.h\
-	qmf/com/redhat/libvirt/ArgsPoolCreateVolumeXML.h\
-	qmf/com/redhat/libvirt/ArgsPoolGetXMLDesc.h\
-	qmf/com/redhat/libvirt/ArgsVolumeGetXMLDesc.h\
-	qmf/com/redhat/libvirt/Domain.h\
-	qmf/com/redhat/libvirt/Node.h\
-	qmf/com/redhat/libvirt/Package.h\
-	qmf/com/redhat/libvirt/Pool.h\
-	qmf/com/redhat/libvirt/Volume.h
+	qmf/com/redhat/libvirt/QmfPackage.cpp\
+	qmf/com/redhat/libvirt/QmfPackage.h
 
 nodist_libvirt_qpid_SOURCES = $(generated_file_list)
 
 libvirt_qpid_SOURCES = \
 	DomainWrap.cpp \
 	Error.cpp \
+	Exception.cpp \
 	NodeWrap.cpp \
 	PoolWrap.cpp \
 	VolumeWrap.cpp \
+	ManagedObject.h \
 	DomainWrap.h \
 	Error.h \
+	Exception.h \
 	NodeWrap.h \
 	PoolWrap.h \
 	VolumeWrap.h
@@ -43,12 +28,12 @@ libvirt_qpid_SOURCES = \
 $(generated_file_list): .libvirt-schema.xml.tstamp
 
 .libvirt-schema.xml.tstamp: libvirt-schema.xml
-	qmf-gen -o ./qmf $< && touch $@ || rm -f $@
+	qmf-gen -2 -o ./qmf $< && touch $@ || rm -f $@
 
 BUILT_SOURCES = $(generated_file_list)
 CLEANFILES = $(generated_file_list) .libvirt-schema.xml.tstamp
 
-libvirt_qpid_LDADD = -lqmf -lqpidtypes -lqpidcommon -lqpidclient -lvirt $(XML_LIBS)
+libvirt_qpid_LDADD = -lqmf2 -lqpidtypes -lqpidcommon -lqpidmessaging -lvirt $(XML_LIBS)
 
 dist_pkgdata_DATA = libvirt-schema.xml
 
diff --git a/src/ManagedObject.h b/src/ManagedObject.h
new file mode 100644
index 0000000..b372f24
--- /dev/null
+++ b/src/ManagedObject.h
@@ -0,0 +1,78 @@
+#ifndef MANAGED_OBJECT_H
+#define MANAGED_OBJECT_H
+
+#include <qmf/AgentEvent.h>
+#include <qmf/AgentSession.h>
+#include <qmf/Data.h>
+#include <qmf/DataAddr.h>
+
+#include <assert.h>
+
+
+template <class T>
+class PackageOwner
+{
+    PackageOwner<T> *_parent;
+
+public:
+    typedef T PackageDefinition;
+
+protected:
+    PackageOwner<T>(void): _parent(NULL) { }
+    PackageOwner<T>(PackageOwner<T> *parent): _parent(parent) { }
+    virtual ~PackageOwner<T>() { }
+
+    virtual PackageDefinition& package(void) {
+        assert(_parent != NULL);
+        return _parent->package();
+    }
+
+    virtual void addData(qmf::Data& data) {
+        assert(_parent != NULL);
+        _parent->addData(data);
+    }
+
+    virtual void delData(qmf::Data& data) {
+        assert(_parent != NULL);
+        _parent->delData(data);
+    }
+};
+
+
+class ManagedObject
+{
+public:
+    qpid::types::Variant objectID(void) {
+        assert(_data.hasAddr());
+        return _data.getAddr().asMap();
+    }
+
+    virtual bool handleMethod(qmf::AgentSession& session,
+                              qmf::AgentEvent& event) = 0;
+
+protected:
+    ManagedObject(qmf::Schema& schema): _data(schema) { }
+    virtual ~ManagedObject() { }
+
+    bool operator==(const qmf::DataAddr& addr) {
+        if (!_data.hasAddr()) {
+            return false;
+        }
+
+        // Due to a bug (#QPID3344) in current versions of libqmf2, the first
+        // operand to qmf::DataAddr::operator==() must not be const, otherwise
+        // a bogus value is returned.
+        qmf::DataAddr& mutableAddr = const_cast<qmf::DataAddr&>(_data.getAddr());
+
+        return mutableAddr == addr;
+    }
+
+    bool operator!=(const qmf::DataAddr& addr) {
+        return !(*this == addr);
+    }
+
+    qmf::Data _data;
+};
+
+#endif
+
diff --git a/src/NodeWrap.cpp b/src/NodeWrap.cpp
index b663235..d65db11 100644
--- a/src/NodeWrap.cpp
+++ b/src/NodeWrap.cpp
@@ -6,20 +6,19 @@
 #include <getopt.h>
 #include <syslog.h>
 #include <signal.h>
+#include <cstdio>
 
 #include "NodeWrap.h"
 #include "DomainWrap.h"
 #include "PoolWrap.h"
 #include "Error.h"
+#include "Exception.h"
 
-#include "ArgsNodeDomainDefineXML.h"
-#include "ArgsNodeStoragePoolCreateXML.h"
-#include "ArgsNodeStoragePoolDefineXML.h"
-#include "ArgsNodeFindStoragePoolSources.h"
 
-namespace _qmf = qmf::com::redhat::libvirt;
-
-NodeWrap::NodeWrap(ManagementAgent* _agent, string _name) : name(_name), agent(_agent)
+NodeWrap::NodeWrap(qmf::AgentSession& agent_session, PackageDefinition& package):
+    ManagedObject(package.data_Node),
+    _session(agent_session),
+    _package(package)
 {
     virNodeInfo info;
     char *hostname;
@@ -36,33 +35,33 @@ NodeWrap::NodeWrap(ManagementAgent* _agent, string _name) : name(_name), agent(_
     unsigned int minor;
     unsigned int rel;
 
-    conn = virConnectOpen(NULL);
-    if (!conn) {
-        REPORT_ERR(conn, "virConnectOpen");
+    _conn = virConnectOpen(NULL);
+    if (!_conn) {
+        REPORT_ERR(_conn, "virConnectOpen");
         throw -1;
     }
 
-    hostname = virConnectGetHostname(conn);
+    hostname = virConnectGetHostname(_conn);
     if (hostname == NULL) {
-        REPORT_ERR(conn, "virConnectGetHostname");
+        REPORT_ERR(_conn, "virConnectGetHostname");
         throw -1;
     }
 
-    hv_type = virConnectGetType(conn);
+    hv_type = virConnectGetType(_conn);
     if (hv_type == NULL) {
-        REPORT_ERR(conn, "virConnectGetType");
+        REPORT_ERR(_conn, "virConnectGetType");
         throw -1;
     }
 
-    uri = virConnectGetURI(conn);
+    uri = virConnectGetURI(_conn);
     if (uri == NULL) {
-        REPORT_ERR(conn, "virConnectGetURI");
+        REPORT_ERR(_conn, "virConnectGetURI");
         throw -1;
     }
 
     ret = virGetVersion(&libvirt_v, hv_type, &api_v);
     if (ret < 0) {
-        REPORT_ERR(conn, "virGetVersion");
+        REPORT_ERR(_conn, "virGetVersion");
     } else {
         major = libvirt_v / 1000000;
         libvirt_v %= 1000000;
@@ -77,9 +76,9 @@ NodeWrap::NodeWrap(ManagementAgent* _agent, string _name) : name(_name), agent(_
         snprintf(api_version, sizeof(api_version), "%d.%d.%d", major, minor, rel);
     }
 
-    ret = virConnectGetVersion(conn, &hv_v);
+    ret = virConnectGetVersion(_conn, &hv_v);
     if (ret < 0) {
-        REPORT_ERR(conn, "virConnectGetVersion");
+        REPORT_ERR(_conn, "virConnectGetVersion");
     } else {
         major = hv_v / 1000000;
         hv_v %= 1000000;
@@ -88,48 +87,64 @@ NodeWrap::NodeWrap(ManagementAgent* _agent, string _name) : name(_name), agent(_
         snprintf(hv_version, sizeof(hv_version), "%d.%d.%d", major, minor, rel);
     }
 
-    ret = virNodeGetInfo(conn, &info);
+    ret = virNodeGetInfo(_conn, &info);
     if (ret < 0) {
-        REPORT_ERR(conn, "virNodeGetInfo");
+        REPORT_ERR(_conn, "virNodeGetInfo");
         memset((void *) &info, sizeof(info), 1);
     }
 
-    mgmtObject = new _qmf::Node(agent, this, hostname, uri, libvirt_version, api_version, hv_version, hv_type,
-                                info.model, info.memory, info.cpus, info.mhz, info.nodes, info.sockets,
-                                info.cores, info.threads);
-    agent->addObject(mgmtObject);
+
+    _data.setProperty("hostname", hostname);
+    _data.setProperty("uri", uri);
+    _data.setProperty("libvirtVersion", libvirt_version);
+    _data.setProperty("apiVersion", api_version);
+    _data.setProperty("hypervisorVersion", hv_version);
+    _data.setProperty("hypervisorType", hv_type);
+
+    _data.setProperty("model", info.model);
+    _data.setProperty("memory", info.memory);
+    _data.setProperty("cpus", info.cpus);
+    _data.setProperty("mhz", info.mhz);
+    _data.setProperty("nodes", info.nodes);
+    _data.setProperty("sockets", info.sockets);
+    _data.setProperty("cores", info.cores);
+    _data.setProperty("threads", info.threads);
+
+    addData(_data);
 }
 
 NodeWrap::~NodeWrap()
 {
     /* Go through our list of pools and destroy them all! MOOOHAHAHA */
-    for (std::vector<PoolWrap*>::iterator iter = pools.begin(); iter != pools.end();) {
-        delete(*iter);
-        iter = pools.erase(iter);
+    PoolList::iterator iter_p = _pools.begin();
+    while (iter_p != _pools.end()) {
+        delete(*iter_p);
+        iter_p = _pools.erase(iter_p);
     }
 
     /* Same for domains.. */
-    for (std::vector<DomainWrap*>::iterator iter = domains.begin(); iter != domains.end();) {
-        delete (*iter);
-        iter = domains.erase(iter);
+    DomainList::iterator iter_d = _domains.begin();
+    while (iter_d != _domains.end()) {
+        delete (*iter_d);
+        iter_d = _domains.erase(iter_d);
     }
 
-    mgmtObject->resourceDestroy();
+    delData(_data);
 }
 
-void NodeWrap::syncDomains()
+void NodeWrap::syncDomains(void)
 {
     /* Sync up with domains that are defined but not active. */
-    int maxname = virConnectNumOfDefinedDomains(conn);
+    int maxname = virConnectNumOfDefinedDomains(_conn);
     if (maxname < 0) {
-        REPORT_ERR(conn, "virConnectNumOfDefinedDomains");
+        REPORT_ERR(_conn, "virConnectNumOfDefinedDomains");
         return;
     } else {
         char **dnames;
         dnames = (char **) malloc(sizeof(char *) * maxname);
 
-        if ((maxname = virConnectListDefinedDomains(conn, dnames, maxname)) < 0) {
-            REPORT_ERR(conn, "virConnectListDefinedDomains");
+        if ((maxname = virConnectListDefinedDomains(_conn, dnames, maxname)) < 0) {
+            REPORT_ERR(_conn, "virConnectListDefinedDomains");
             free(dnames);
             return;
         }
@@ -139,9 +154,9 @@ void NodeWrap::syncDomains()
             virDomainPtr domain_ptr;
 
             bool found = false;
-            for (std::vector<DomainWrap*>::iterator iter = domains.begin();
-                    iter != domains.end(); iter++) {
-                if ((*iter)->domain_name == dnames[i]) {
+            for (DomainList::iterator iter = _domains.begin();
+                    iter != _domains.end(); iter++) {
+                if ((*iter)->name() == dnames[i]) {
                     found = true;
                     break;
                 }
@@ -151,18 +166,18 @@ void NodeWrap::syncDomains()
                 continue;
             }
 
-            domain_ptr = virDomainLookupByName(conn, dnames[i]);
+            domain_ptr = virDomainLookupByName(_conn, dnames[i]);
             if (!domain_ptr) {
-                REPORT_ERR(conn, "virDomainLookupByName");
+                REPORT_ERR(_conn, "virDomainLookupByName");
             } else {
                 DomainWrap *domain;
                 try {
-                    domain = new DomainWrap(agent, this, domain_ptr, conn);
+                    domain = new DomainWrap(this, domain_ptr, _conn);
                     printf("Created new domain: %s, ptr is %p\n", dnames[i], domain_ptr);
-                    domains.push_back(domain);
+                    _domains.push_back(domain);
                 } catch (int i) {
-                    printf ("Error constructing domain\n");
-                    REPORT_ERR(conn, "constructing domain.");
+                    printf("Error constructing domain\n");
+                    REPORT_ERR(_conn, "constructing domain.");
                     delete domain;
                 }
             }
@@ -175,15 +190,15 @@ void NodeWrap::syncDomains()
     }
 
     /* Go through all the active domains */
-    int maxids = virConnectNumOfDomains(conn);
+    int maxids = virConnectNumOfDomains(_conn);
     if (maxids < 0) {
-        REPORT_ERR(conn, "virConnectNumOfDomains");
+        REPORT_ERR(_conn, "virConnectNumOfDomains");
         return;
     } else {
         int *ids;
         ids = (int *) malloc(sizeof(int *) * maxids);
 
-        if ((maxids = virConnectListDomains(conn, ids, maxids)) < 0) {
+        if ((maxids = virConnectListDomains(_conn, ids, maxids)) < 0) {
             printf("Error getting list of defined domains\n");
             return;
         }
@@ -192,21 +207,21 @@ void NodeWrap::syncDomains()
             virDomainPtr domain_ptr;
             char dom_uuid[VIR_UUID_STRING_BUFLEN];
 
-            domain_ptr = virDomainLookupByID(conn, ids[i]);
+            domain_ptr = virDomainLookupByID(_conn, ids[i]);
             if (!domain_ptr) {
-                REPORT_ERR(conn, "virDomainLookupByID");
+                REPORT_ERR(_conn, "virDomainLookupByID");
                 continue;
             }
 
             if (virDomainGetUUIDString(domain_ptr, dom_uuid) < 0) {
-                REPORT_ERR(conn, "virDomainGetUUIDString");
+                REPORT_ERR(_conn, "virDomainGetUUIDString");
                 continue;
             }
 
             bool found = false;
-            for (std::vector<DomainWrap*>::iterator iter = domains.begin();
-                    iter != domains.end(); iter++) {
-                if (strcmp((*iter)->domain_uuid.c_str(), dom_uuid) == 0) {
+            for (DomainList::iterator iter = _domains.begin();
+                    iter != _domains.end(); iter++) {
+                if (strcmp((*iter)->uuid().c_str(), dom_uuid) == 0) {
                     found = true;
                     break;
                 }
@@ -219,12 +234,12 @@ void NodeWrap::syncDomains()
 
             DomainWrap *domain;
             try {
-                domain = new DomainWrap(agent, this, domain_ptr, conn);
+                domain = new DomainWrap(this, domain_ptr, _conn);
                 printf("Created new domain: %d, ptr is %p\n", ids[i], domain_ptr);
-                domains.push_back(domain);
+                _domains.push_back(domain);
             } catch (int i) {
-                printf ("Error constructing domain\n");
-                REPORT_ERR(conn, "constructing domain.");
+                printf("Error constructing domain\n");
+                REPORT_ERR(_conn, "constructing domain.");
                 delete domain;
             }
         }
@@ -233,14 +248,14 @@ void NodeWrap::syncDomains()
     }
 
     /* Go through our list of domains and ensure that they still exist. */
-    for (std::vector<DomainWrap*>::iterator iter = domains.begin(); iter != domains.end();) {
-
-        printf("verifying domain %s\n", (*iter)->domain_name.c_str());
-        virDomainPtr ptr = virDomainLookupByUUIDString(conn, (*iter)->domain_uuid.c_str());
+    DomainList::iterator iter = _domains.begin();
+    while (iter != _domains.end()) {
+        printf("verifying domain %s\n", (*iter)->name().c_str());
+        virDomainPtr ptr = virDomainLookupByUUIDString(_conn, (*iter)->uuid().c_str());
         if (ptr == NULL) {
-            REPORT_ERR(conn, "virDomainLookupByUUIDString");
+            REPORT_ERR(_conn, "virDomainLookupByUUIDString");
             delete (*iter);
-            iter = domains.erase(iter);
+            iter = _domains.erase(iter);
         } else {
             virDomainFree(ptr);
             iter++;
@@ -253,9 +268,9 @@ void NodeWrap::checkPool(char *pool_name)
     virStoragePoolPtr pool_ptr;
 
     bool found = false;
-    for (std::vector<PoolWrap*>::iterator iter = pools.begin();
-            iter != pools.end(); iter++) {
-        if ((*iter)->pool_name == pool_name) {
+    for (PoolList::iterator iter = _pools.begin();
+            iter != _pools.end(); iter++) {
+        if ((*iter)->name() == pool_name) {
             found = true;
             break;
         }
@@ -265,38 +280,37 @@ void NodeWrap::checkPool(char *pool_name)
         return;
     }
 
-    pool_ptr = virStoragePoolLookupByName(conn, pool_name);
+    pool_ptr = virStoragePoolLookupByName(_conn, pool_name);
     if (!pool_ptr) {
-        REPORT_ERR(conn, "virStoragePoolLookupByName");
+        REPORT_ERR(_conn, "virStoragePoolLookupByName");
     } else {
         printf("Creating new pool: %s, ptr is %p\n", pool_name, pool_ptr);
         PoolWrap *pool;
         try {
-            pool = new PoolWrap(agent, this, pool_ptr, conn);
+            pool = new PoolWrap(this, pool_ptr, _conn);
             printf("Created new pool: %s, ptr is %p\n", pool_name, pool_ptr);
-            pools.push_back(pool);
+            _pools.push_back(pool);
         } catch (int i) {
-            printf ("Error constructing pool\n");
-            REPORT_ERR(conn, "constructing pool.");
+            printf("Error constructing pool\n");
+            REPORT_ERR(_conn, "constructing pool.");
             delete pool;
         }
     }
 }
 
-void NodeWrap::syncPools()
+void NodeWrap::syncPools(void)
 {
     int maxname;
 
-    maxname = virConnectNumOfStoragePools(conn);
+    maxname = virConnectNumOfStoragePools(_conn);
     if (maxname < 0) {
-        REPORT_ERR(conn, "virConnectNumOfStroagePools");
+        REPORT_ERR(_conn, "virConnectNumOfStoragePools");
         return;
     } else {
-        char **names;
-        names = (char **) malloc(sizeof(char *) * maxname);
+        char *names[maxname];
 
-        if ((maxname = virConnectListStoragePools(conn, names, maxname)) < 0) {
-            REPORT_ERR(conn, "virConnectListStoragePools");
+        if ((maxname = virConnectListStoragePools(_conn, names, maxname)) < 0) {
+            REPORT_ERR(_conn, "virConnectListStoragePools");
             return;
         }
 
@@ -304,19 +318,17 @@ void NodeWrap::syncPools()
             checkPool(names[i]);
             free(names[i]);
         }
-        free(names);
     }
 
-    maxname = virConnectNumOfDefinedStoragePools(conn);
+    maxname = virConnectNumOfDefinedStoragePools(_conn);
     if (maxname < 0) {
-        REPORT_ERR(conn, "virConnectNumOfDefinedStoragePools");
+        REPORT_ERR(_conn, "virConnectNumOfDefinedStoragePools");
         return;
     } else {
-        char **names;
-        names = (char **) malloc(sizeof(char *) * maxname);
+        char *names[maxname];
 
-        if ((maxname = virConnectListDefinedStoragePools(conn, names, maxname)) < 0) {
-            REPORT_ERR(conn, "virConnectListDefinedStoragePools");
+        if ((maxname = virConnectListDefinedStoragePools(_conn, names, maxname)) < 0) {
+            REPORT_ERR(_conn, "virConnectListDefinedStoragePools");
             return;
         }
 
@@ -324,19 +336,17 @@ void NodeWrap::syncPools()
             checkPool(names[i]);
             free(names[i]);
         }
-
-        free(names);
     }
 
     /* Go through our list of pools and ensure that they still exist. */
-    for (std::vector<PoolWrap*>::iterator iter = pools.begin(); iter != pools.end();) {
-
-        printf ("Verifying pool %s\n", (*iter)->pool_name.c_str());
-        virStoragePoolPtr ptr = virStoragePoolLookupByUUIDString(conn, (*iter)->pool_uuid.c_str());
+    PoolList::iterator iter = _pools.begin();
+    while (iter != _pools.end()) {
+        printf("Verifying pool %s\n", (*iter)->name().c_str());
+        virStoragePoolPtr ptr = virStoragePoolLookupByUUIDString(_conn, (*iter)->uuid().c_str());
         if (ptr == NULL) {
-            printf("Destroying pool %s\n", (*iter)->pool_name.c_str());
+            printf("Destroying pool %s\n", (*iter)->name().c_str());
             delete(*iter);
-            iter = pools.erase(iter);
+            iter = _pools.erase(iter);
         } else {
             virStoragePoolFree(ptr);
             iter++;
@@ -344,7 +354,6 @@ void NodeWrap::syncPools()
     }
 }
 
-
 void NodeWrap::doLoop()
 {
     fd_set fds;
@@ -354,12 +363,10 @@ void NodeWrap::doLoop()
     /* Go through all domains and call update() for each, letting them update
      * information and statistics. */
     while (1) {
-        int read_fd = agent->getSignalFd();
-
         // We're using this to check to see if our connection is still good.
         // I don't see any reason this call should fail unless there is some
         // connection problem..
-        int maxname = virConnectNumOfDefinedDomains(conn);
+        int maxname = virConnectNumOfDefinedDomains(_conn);
         if (maxname < 0) {
             return;
         }
@@ -367,151 +374,200 @@ void NodeWrap::doLoop()
         syncDomains();
         syncPools();
 
-        for (std::vector<DomainWrap*>::iterator iter = domains.begin();
-                iter != domains.end(); iter++) {
+        for (DomainList::iterator iter = _domains.begin();
+                iter != _domains.end(); iter++) {
             (*iter)->update();
         }
-        for (std::vector<PoolWrap*>::iterator iter = pools.begin();
-                iter != pools.end(); iter++) {
+        for (PoolList::iterator iter = _pools.begin();
+                iter != _pools.end(); iter++) {
             (*iter)->update();
         }
 
-        /* Poll agent fd.  If any methods are being made this FD will be ready for reading.  */
-        FD_ZERO(&fds);
-        FD_SET(read_fd, &fds);
+        qmf::AgentEvent event;
+        if (_session.nextEvent(event, qpid::messaging::Duration(3000))) {
+            if (event.getType() == qmf::AGENT_METHOD) {
+                bool handled = handleMethod(_session, event);
+                if (!handled) {
+                    raiseException(_session, event,
+                                   ERROR_UNKNOWN_OBJECT, STATUS_UNKNOWN_OBJECT);
+                }
+            }
+        }
 
-        /* Wait up to three seconds. */
-        tv.tv_sec = 3;
-        tv.tv_usec = 0;
+    }
+}
 
-        retval = select(read_fd + 1, &fds, NULL, NULL, &tv);
-        if (retval < 0) {
-            fprintf(stderr, "Error in select loop: %s\n", strerror(errno));
-            continue;
-        }
+bool
+NodeWrap::domainDefineXML(qmf::AgentSession& session,
+                          qmf::AgentEvent& event)
+{
+    const std::string xmlDesc(event.getArguments()["xmlDesc"].asString());
+    int ret;
+
+    virDomainPtr domain_ptr = virDomainDefineXML(_conn, xmlDesc.c_str());
+    if (!domain_ptr) {
+        std::string err = FORMAT_ERR(_conn, "Error creating domain using xml description (virDomainDefineXML).", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
 
-        if (retval > 0) {
-            /* This implements any pending methods. */
-            agent->pollCallbacks();
+    // Now we have to check to see if this domain is actually new or not,
+    // because it's possible that one already exists with this name/description
+    // and we just replaced it... *ugh*
+    DomainList::iterator iter = _domains.begin();
+    while (iter != _domains.end()) {
+        if ((*iter)->name() == virDomainGetName(domain_ptr)) {
+            // We're just replacing an existing domain, however I'm pretty sure
+            // the old domain pointer becomes invalid at this point, so we
+            // should destroy the old domain reference. The other option would
+            // be to replace it and keep the object valid... not sure which is
+            // better.
+            printf("Old domain already exists, removing it in favor of new object.");
+            delete(*iter);
+            iter = _domains.erase(iter);
+        } else {
+            iter++;
         }
+    }
 
+    DomainWrap *domain;
+    try {
+        domain = new DomainWrap(this, domain_ptr, _conn);
+        _domains.push_back(domain);
+        event.addReturnArgument("domain", domain->objectID());
+    } catch (int i) {
+        delete domain;
+        std::string err = FORMAT_ERR(_conn, "Error constructing domain object in virDomainDefineXML.", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
     }
+
+    return true;
 }
 
-Manageable::status_t
-NodeWrap::ManagementMethod(uint32_t methodId, Args& args, std::string &errstr)
+bool
+NodeWrap::storagePoolDefineXML(qmf::AgentSession& session,
+                               qmf::AgentEvent& event)
 {
-    virDomainPtr domain_ptr;
-    cout << "Method Received: " << methodId << endl;
+    const std::string xmlDesc(event.getArguments()["xmlDesc"].asString());
+    virStoragePoolPtr pool_ptr;
     int ret;
 
-    switch (methodId) {
-        case _qmf::Node::METHOD_DOMAINDEFINEXML:
-        {
-            _qmf::ArgsNodeDomainDefineXML *io_args = (_qmf::ArgsNodeDomainDefineXML *) &args;
-            domain_ptr = virDomainDefineXML(conn, io_args->i_xmlDesc.c_str());
-            if (!domain_ptr) {
-                errstr = FORMAT_ERR(conn, "Error creating domain using xml description (virDomainDefineXML).", &ret);
-                return STATUS_USER + ret;
-            } else {
-                // Now we have to check to see if this domain is actually new or not, because it's possible that
-                // one already exists with this name/description and we just replaced it.. *ugh*
-                for (std::vector<DomainWrap*>::iterator iter = domains.begin(); iter != domains.end();) {
-                    if (strcmp((*iter)->domain_name.c_str(), virDomainGetName(domain_ptr)) == 0) {
-                        // We're just replacing an existing domain, however I'm pretty sure the
-                        // old domain pointer becomes invalid at this point, so we should destroy
-                        // the old domain reference.  The other option would be to replace it and
-                        // keep the object valid.. not sure which is better.
-                        printf("Old domain already exists, removing it in favor of new object.");
-                        delete(*iter);
-                        iter = domains.erase(iter);
-                    } else {
-                        iter++;
-                    }
-                }
+    pool_ptr = virStoragePoolDefineXML(_conn, xmlDesc.c_str(), 0);
+    if (pool_ptr == NULL) {
+        std::string err = FORMAT_ERR(_conn, "Error defining storage pool using xml description (virStoragePoolDefineXML).", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
 
-                DomainWrap *domain;
-                try {
-                    domain = new DomainWrap(agent, this, domain_ptr, conn);
-                    domains.push_back(domain);
-                    io_args->o_domain = domain->GetManagementObject()->getObjectId();
-                } catch (int i) {
-                    delete domain;
-                    errstr = FORMAT_ERR(conn, "Error constructing domain object in virDomainDefineXML.", &ret);
-                    return STATUS_USER + i;
-                }
+    PoolWrap *pool;
+    try {
+        pool = new PoolWrap(this, pool_ptr, _conn);
+        _pools.push_back(pool);
+        event.addReturnArgument("pool", pool->objectID());
+    } catch (int i) {
+        delete pool;
+        std::string err = FORMAT_ERR(_conn, "Error constructing pool object in virStoragePoolDefineXML.", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
 
-                return STATUS_OK;
-            }
-        }
+    return true;
+}
+
+bool
+NodeWrap::storagePoolCreateXML(qmf::AgentSession& session,
+                               qmf::AgentEvent& event)
+{
+    const std::string xmlDesc(event.getArguments()["xmlDesc"].asString());
+    virStoragePoolPtr pool_ptr;
+    int ret;
 
-        case _qmf::Node::METHOD_STORAGEPOOLDEFINEXML:
-        {
-            _qmf::ArgsNodeStoragePoolDefineXML *io_args = (_qmf::ArgsNodeStoragePoolDefineXML *) &args;
-            virStoragePoolPtr pool_ptr;
+    pool_ptr = virStoragePoolCreateXML (_conn, xmlDesc.c_str(), 0);
+    if (pool_ptr == NULL) {
+        std::string err = FORMAT_ERR(_conn, "Error creating storage pool using xml description (virStoragePoolCreateXML).", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
 
-            pool_ptr = virStoragePoolDefineXML (conn, io_args->i_xmlDesc.c_str(), 0);
-            if (pool_ptr == NULL) {
-                errstr = FORMAT_ERR(conn, "Error defining storage pool using xml description (virStoragePoolDefineXML).", &ret);
-                return STATUS_USER + ret;
-            }
+    PoolWrap *pool;
+    try {
+        pool = new PoolWrap(this, pool_ptr, _conn);
+        _pools.push_back(pool);
+        event.addReturnArgument("pool", pool->objectID());
+    } catch (int i) {
+        delete pool;
+        std::string err = FORMAT_ERR(_conn, "Error constructing pool object in virStoragePoolCreateXML.", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
 
-            PoolWrap *pool;
-            try {
-                pool = new PoolWrap(agent, this, pool_ptr, conn);
-                pools.push_back(pool);
-                io_args->o_pool = pool->GetManagementObject()->getObjectId();
-            } catch (int i) {
-                delete pool;
-                errstr = FORMAT_ERR(conn, "Error constructing pool object in virStoragePoolDefineXML.", &ret);
-                return STATUS_USER + i;
-            }
-            return STATUS_OK;
+    return true;
+}
 
-        }
-        case _qmf::Node::METHOD_STORAGEPOOLCREATEXML:
-        {
-            _qmf::ArgsNodeStoragePoolCreateXML *io_args = (_qmf::ArgsNodeStoragePoolCreateXML *) &args;
-            virStoragePoolPtr pool_ptr;
-
-            pool_ptr = virStoragePoolCreateXML (conn, io_args->i_xmlDesc.c_str(), 0);
-            if (pool_ptr == NULL) {
-                errstr = FORMAT_ERR(conn, "Error creating storage pool using xml description (virStoragePoolCreateXML).", &ret);
-                return STATUS_USER + ret;
-            }
+bool
+NodeWrap::findStoragePoolSources(qmf::AgentSession& session,
+                                 qmf::AgentEvent& event)
+{
+    qpid::types::Variant::Map args(event.getArguments());
+    const std::string type(args["type"].asString());
+    const std::string srcSpec(args["srcSpec"].asString());
+    char *xml_result;
+    int ret;
 
-            PoolWrap *pool;
-            try {
-                pool = new PoolWrap(agent, this, pool_ptr, conn);
-                pools.push_back(pool);
-                io_args->o_pool = pool->GetManagementObject()->getObjectId();
-            } catch (int i) {
-                delete pool;
-                errstr = FORMAT_ERR(conn, "Error constructing pool object in virStoragePoolCreateXML.", &ret);
-                return STATUS_USER + i;
-            }
+    xml_result = virConnectFindStoragePoolSources(_conn, type.c_str(), srcSpec.c_str(), 0);
+    if (xml_result == NULL) {
+        std::string err = FORMAT_ERR(_conn, "Error creating storage pool using xml description (virStoragePoolCreateXML).", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
 
-            return STATUS_OK;
+    event.addReturnArgument("xmlDesc", xml_result);
+    free(xml_result);
+
+    return true;
+}
+
+bool
+NodeWrap::handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event)
+{
+    if (!event.hasDataAddr() || *this == event.getDataAddr()) {
+        const std::string& methodName(event.getMethodName());
+        bool success;
+
+        if (methodName == "domainDefineXML") {
+            success = domainDefineXML(session, event);
+        } else if (methodName == "storagePoolDefineXML") {
+            success = storagePoolDefineXML(session, event);
+        } else if (methodName == "storagePoolCreateXML") {
+            success = storagePoolCreateXML(session, event);
+        } else if (methodName == "findStoragePoolSources") {
+            success = findStoragePoolSources(session, event);
+        } else {
+            raiseException(session, event,
+                           ERROR_UNKNOWN_METHOD, STATUS_UNKNOWN_METHOD);
+            return true;
         }
-        case _qmf::Node::METHOD_FINDSTORAGEPOOLSOURCES:
-        {
-            _qmf::ArgsNodeFindStoragePoolSources *io_args = (_qmf::ArgsNodeFindStoragePoolSources *) &args;
-            char *xml_result;
-
-            xml_result = virConnectFindStoragePoolSources(conn, io_args->i_type.c_str(), io_args->i_srcSpec.c_str(), 0);
-            if (xml_result == NULL) {
-                errstr = FORMAT_ERR(conn, "Error creating storage pool using xml description (virStoragePoolCreateXML).", &ret);
-                return STATUS_USER + ret;
-            }
 
-            io_args->o_xmlDesc = xml_result;
-            free(xml_result);
+        if (success) {
+            session.methodSuccess(event);
+        }
+        return true;
+    } else {
+        bool handled = false;
 
-            return STATUS_OK;
+        for (DomainList::iterator iter = _domains.begin();
+                !handled && iter != _domains.end(); iter++) {
+            handled = (*iter)->handleMethod(session, event);
+        }
+
+        for (PoolList::iterator iter = _pools.begin();
+                !handled && iter != _pools.end(); iter++) {
+            handled = (*iter)->handleMethod(session, event);
         }
-    }
 
-    return STATUS_NOT_IMPLEMENTED;
+        return handled;
+    }
 }
 
 static void
@@ -521,7 +577,6 @@ print_usage()
     printf("\t-d | --daemon     run as a daemon.\n");
     printf("\t-h | --help       print this help message.\n");
     printf("\t-b | --broker     specify broker host name..\n");
-    printf("\t-g | --gssapi     force GSSAPI authentication.\n");
     printf("\t-u | --username   username to use for authentication purproses.\n");
     printf("\t-s | --service    service name to use for authentication purproses.\n");
     printf("\t-p | --port       specify broker port.\n");
@@ -536,8 +591,7 @@ int main(int argc, char** argv) {
     int idx = 0;
     bool verbose = false;
     bool daemonize = false;
-    bool gssapi = false;
-    char *host = NULL;
+    const char *host = NULL;
     char *username = NULL;
     char *service = NULL;
     int port = 5672;
@@ -546,14 +600,13 @@ int main(int argc, char** argv) {
         {"help", 0, 0, 'h'},
         {"daemon", 0, 0, 'd'},
         {"broker", 1, 0, 'b'},
-        {"gssapi", 0, 0, 'g'},
         {"username", 1, 0, 'u'},
         {"service", 1, 0, 's'},
         {"port", 1, 0, 'p'},
         {0, 0, 0, 0}
     };
 
-    while ((arg = getopt_long(argc, argv, "hdb:gu:s:p:", opt, &idx)) != -1) {
+    while ((arg = getopt_long(argc, argv, "hdb:u:s:p:", opt, &idx)) != -1) {
         switch (arg) {
             case 'h':
             case '?':
@@ -582,9 +635,6 @@ int main(int argc, char** argv) {
                     exit(1);
                 }
                 break;
-            case 'g':
-                gssapi = true;
-                break;
             case 'p':
                 if (optarg) {
                     port = atoi(optarg);
@@ -620,44 +670,42 @@ int main(int argc, char** argv) {
     // This prevents us from dying if libvirt disconnects.
     signal(SIGPIPE, SIG_IGN);
 
-    // Create the management agent
-    ManagementAgent::Singleton singleton;
-    ManagementAgent* agent = singleton.getInstance();
-
-    // Register the schema with the agent
-    _qmf::Package packageInit(agent);
-
-    // Start the agent.  It will attempt to make a connection to the
-    // management broker.  The third argument is the interval for sending
-    // updates to stats/properties to the broker.  The last is set to 'true'
-    // to keep this all single threaded.  Otherwise a second thread would be
-    // used to implement methods.
-
-    qpid::management::ConnectionSettings settings;
-    settings.host = host ? host : "127.0.0.1";
-    settings.port = port;
+    qpid::types::Variant::Map options;
 
     if (username != NULL) {
-        settings.username = username;
+        options["username"] = username;
     }
     if (service != NULL) {
-        settings.service = service;
+        options["service"] = service;
     }
-    if (gssapi == true) {
-        settings.mechanism = "GSSAPI";
+
+    if (host == NULL) {
+        host = "127.0.0.1";
     }
 
-    agent->setName("Red Hat", "libvirt-qpid");
-    agent->init(settings, 3, true);
+    std::stringstream url;
+
+    url << "amqp:" << "tcp" << ":" << host << ":" << port;
+
+    qpid::messaging::Connection amqp_connection(url.str(), options);
+    amqp_connection.open();
+
+    qmf::AgentSession session(amqp_connection);
+    session.setVendor("redhat.com");
+    session.setProduct("libvirt-qpid");
+    session.setAttribute("hostname", host);
 
-    while(true) {
+    session.open();
+    NodeWrap::PackageDefinition package;
+    package.configure(session);
+
+    initErrorSchema(session);
+
+    while (true) {
         try {
-            NodeWrap node(agent, "Libvirt Node");
+            NodeWrap node(session, package);
             node.doLoop();
-        } catch (int err) {
-        }
+        } catch (int err) { }
         sleep(10);
     }
 }
-
-
diff --git a/src/NodeWrap.h b/src/NodeWrap.h
index 920608b..6f55061 100644
--- a/src/NodeWrap.h
+++ b/src/NodeWrap.h
@@ -1,60 +1,70 @@
+#ifndef NODE_WRAP_H
+#define NODE_WRAP_H
 
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-#include <qpid/client/ConnectionSettings.h>
-#include <qpid/sys/Mutex.h>
-
-#include "Package.h"
-#include "Node.h"
-#include "Domain.h"
-#include "Pool.h"
+#include "ManagedObject.h"
+#include "QmfPackage.h"
 
 #include <unistd.h>
 #include <cstdlib>
 #include <iostream>
+#include <vector>
 
 #include <sstream>
 
 #include <libvirt/libvirt.h>
 #include <libvirt/virterror.h>
 
-using namespace qpid::management;
-using namespace qpid::sys;
-using namespace std;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::Mutex;
 
-// Forward decl of DomainWrap to get around cyclic reference.
 class DomainWrap;
 class PoolWrap;
 
-class NodeWrap : public Manageable
+class NodeWrap:
+    public PackageOwner<qmf::com::redhat::libvirt::PackageDefinition>,
+    public ManagedObject
 {
-    string name;
-    ManagementAgent *agent;
-    qmf::com::redhat::libvirt::Node *mgmtObject;
-    std::vector<DomainWrap*> domains;
-    std::vector<PoolWrap*> pools;
+    typedef std::vector<DomainWrap*> DomainList;
+    typedef std::vector<PoolWrap*> PoolList;
 
-    virConnectPtr conn;
+    DomainList _domains;
+    PoolList _pools;
 
-public:
+    virConnectPtr _conn;
 
-    NodeWrap(ManagementAgent* agent, string _name);
-    ~NodeWrap();
+    qmf::AgentSession& _session;
+    PackageDefinition& _package;
 
-    ManagementObject* GetManagementObject(void) const
-    { return mgmtObject; }
+public:
+    NodeWrap(qmf::AgentSession& agent_session, PackageDefinition& package);
+    ~NodeWrap();
 
     void doLoop();
-    void syncDomains();
+
+    bool handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event);
+
+    virtual PackageDefinition& package(void) { return _package; }
+
+    virtual void addData(qmf::Data& data) {
+        _session.addData(data);
+    }
+
+    virtual void delData(qmf::Data& data) {
+        _session.delData(data.getAddr());
+    }
+
+protected:
+    void syncDomains(void);
+    void syncPools(void);
     void checkPool(char *pool_name);
-    void syncPools();
 
-    status_t ManagementMethod (uint32_t methodId, Args& args, std::string &errstr);
+    bool domainDefineXML(qmf::AgentSession& session,
+                         qmf::AgentEvent& event);
+    bool storagePoolDefineXML(qmf::AgentSession& session,
+                              qmf::AgentEvent& event);
+    bool storagePoolCreateXML(qmf::AgentSession& session,
+                              qmf::AgentEvent& event);
+    bool findStoragePoolSources(qmf::AgentSession& session,
+                                qmf::AgentEvent& event);
 };
 
+#endif
 
diff --git a/src/PoolWrap.cpp b/src/PoolWrap.cpp
index 0274e63..a5992f2 100644
--- a/src/PoolWrap.cpp
+++ b/src/PoolWrap.cpp
@@ -1,4 +1,3 @@
-
 #include <libxml/xmlmemory.h>
 #include <libxml/parser.h>
 #include <string.h>
@@ -7,42 +6,40 @@
 #include "PoolWrap.h"
 #include "VolumeWrap.h"
 #include "Error.h"
+#include "Exception.h"
 
-#include "ArgsPoolCreateVolumeXML.h"
-#include "ArgsPoolGetXMLDesc.h"
-
-namespace _qmf = qmf::com::redhat::libvirt;
 
-PoolWrap::PoolWrap(ManagementAgent *_agent, NodeWrap *parent,
-                   virStoragePoolPtr _pool_pointer, virConnectPtr _connect) :
-                   agent(_agent), pool_ptr(_pool_pointer), conn(_connect)
+PoolWrap::PoolWrap(NodeWrap *parent,
+                   virStoragePoolPtr pool_ptr,
+                   virConnectPtr connect):
+    PackageOwner<NodeWrap::PackageDefinition>(parent),
+    ManagedObject(package().data_Pool),
+    _pool_ptr(pool_ptr), _conn(connect)
 {
     int ret;
     char pool_uuid_str[VIR_UUID_STRING_BUFLEN];
     const char *pool_name_str;
     char *parent_volume = NULL;
 
-    pool = NULL;
-
-    ret = virStoragePoolGetUUIDString(pool_ptr, pool_uuid_str);
+    ret = virStoragePoolGetUUIDString(_pool_ptr, pool_uuid_str);
     if (ret < 0) {
-        REPORT_ERR(conn, "PoolWrap: Unable to get UUID\n");
+        REPORT_ERR(_conn, "PoolWrap: Unable to get UUID\n");
         throw 1;
     }
 
-    pool_name_str = virStoragePoolGetName(pool_ptr);
+    pool_name_str = virStoragePoolGetName(_pool_ptr);
     if (pool_name_str == NULL) {
-        REPORT_ERR(conn, "PoolWrap: error getting pool name\n");
+        REPORT_ERR(_conn, "PoolWrap: error getting pool name\n");
         throw 1;
     }
 
-    pool_sources_xml = virConnectFindStoragePoolSources(conn, "logical", NULL, 0);
+    _pool_sources_xml = virConnectFindStoragePoolSources(_conn, "logical", NULL, 0);
 
-    if (pool_sources_xml) {
+    if (_pool_sources_xml) {
         xmlDocPtr doc;
         xmlNodePtr cur;
 
-        doc = xmlParseMemory(pool_sources_xml, strlen(pool_sources_xml));
+        doc = xmlParseMemory(_pool_sources_xml, strlen(_pool_sources_xml));
 
         if (doc == NULL ) {
             goto done;
@@ -77,7 +74,7 @@ PoolWrap::PoolWrap(ManagementAgent *_agent, NodeWrap *parent,
                 if (name && path) {
                     if (strcmp(pool_name_str, (char *) name) == 0) {
                         virStorageVolPtr vol;
-                        vol = virStorageVolLookupByPath(conn, (char *) path);
+                        vol = virStorageVolLookupByPath(_conn, (char *) path);
                         if (vol != NULL) {
                             printf ("found storage volume associated with pool!\n");
                             parent_volume = virStorageVolGetPath(vol);
@@ -96,22 +93,28 @@ PoolWrap::PoolWrap(ManagementAgent *_agent, NodeWrap *parent,
     }
 
 done:
+    _pool_name = pool_name_str;
+    _pool_uuid = pool_uuid_str;
 
-    pool_name_str = virStoragePoolGetName(pool_ptr);
-
-    pool_name = pool_name_str;
-    pool_uuid = pool_uuid_str;
-
-    pool = new _qmf::Pool(agent, this, parent, pool_uuid, pool_name, parent_volume ? parent_volume : "");
-    agent->addObject(pool);
+    _data.setProperty("uuid", _pool_uuid);
+    _data.setProperty("name", _pool_name);
+    _data.setProperty("parentVolume", parent_volume ? parent_volume : "");
+    _data.setProperty("node", parent->objectID());
 
     // Call refresh storage volumes in case anything changed in libvirt.
     // I don't think we're too concerned if it fails?
-    virStoragePoolRefresh(pool_ptr, 0);
+    virStoragePoolRefresh(_pool_ptr, 0);
 
     // Set storage pool state to an inactive. Should the state be different, the
     // subsequent call to update will pick it up and fix it.
-    storagePoolState = VIR_STORAGE_POOL_INACTIVE;
+    _storagePoolState = VIR_STORAGE_POOL_INACTIVE;
+
+    // Set the state before adding the new Data object
+    updateProperties();
+
+    // This must be done before update(), which will check for and create any
+    // volumes. (VolumeWrap objects will need a valid parent DataAddr.)
+    addData(_data);
 
     // Call update() here so we set the state and see if there are any volumes
     // before returning the new object.
@@ -121,21 +124,21 @@ done:
 PoolWrap::~PoolWrap()
 {
     // Destroy volumes..
-    for (std::vector<VolumeWrap*>::iterator iter = volumes.begin(); iter != volumes.end();) {
+    VolumeList::iterator iter = _volumes.begin();
+    while (iter != _volumes.end()) {
         delete (*iter);
-        iter = volumes.erase(iter);
+        iter = _volumes.erase(iter);
     }
 
-    if (pool) {
-        pool->resourceDestroy();
-    }
-    virStoragePoolFree(pool_ptr);
+    virStoragePoolFree(_pool_ptr);
+
+    delData(_data);
 }
 
-char *
+const char *
 PoolWrap::getPoolSourcesXml()
 {
-    return pool_sources_xml;
+    return _pool_sources_xml;
 }
 
 void
@@ -146,30 +149,30 @@ PoolWrap::syncVolumes()
     int i;
     virStoragePoolInfo info;
 
-    cout << "Syncing volumes.\n";
+    std::cout << "Syncing volumes.\n";
 
-    ret = virStoragePoolGetInfo(pool_ptr, &info);
+    ret = virStoragePoolGetInfo(_pool_ptr, &info);
     if (ret < 0) {
-        REPORT_ERR(conn, "PoolWrap: Unable to get info of storage pool");
+        REPORT_ERR(_conn, "PoolWrap: Unable to get info of storage pool");
         return;
     }
 
     // Only try to list volumes if the storage pool is active.
     if (info.state != VIR_STORAGE_POOL_INACTIVE) {
 
-        maxactive = virStoragePoolNumOfVolumes(pool_ptr);
+        maxactive = virStoragePoolNumOfVolumes(_pool_ptr);
         if (maxactive < 0) {
             //vshError(ctl, FALSE, "%s", _("Failed to list active vols"));
-            REPORT_ERR(conn, "error getting number of volumes in pool\n");
+            REPORT_ERR(_conn, "error getting number of volumes in pool\n");
             return;
         }
 
         char **names;
         names = (char **) malloc(sizeof(char *) * maxactive);
 
-        ret = virStoragePoolListVolumes(pool_ptr, names, maxactive);
+        ret = virStoragePoolListVolumes(_pool_ptr, names, maxactive);
         if (ret < 0) {
-            REPORT_ERR(conn, "error getting list of volumes\n");
+            REPORT_ERR(_conn, "error getting list of volumes\n");
             return;
         }
 
@@ -178,28 +181,28 @@ PoolWrap::syncVolumes()
             bool found = false;
             char *volume_name = names[i];
 
-            for (std::vector<VolumeWrap*>::iterator iter = volumes.begin();
-                 iter != volumes.end(); iter++) {
-                if ((*iter)->volume_name == volume_name) {
+            for (VolumeList::iterator iter = _volumes.begin();
+                 iter != _volumes.end(); iter++) {
+                if (strcmp((*iter)->name(), volume_name) == 0) {
                     found = true;
                     break;
                 }
             }
 
             if (!found) {
-                vol_ptr = virStorageVolLookupByName(pool_ptr, volume_name);
+                vol_ptr = virStorageVolLookupByName(_pool_ptr, volume_name);
                 if (vol_ptr == NULL) {
-                    REPORT_ERR(conn, "error looking up storage volume by name\n");
+                    REPORT_ERR(_conn, "error looking up storage volume by name\n");
                     continue;
                 }
                 VolumeWrap *volume = NULL;
                 try {
-                    VolumeWrap *volume = new VolumeWrap(agent, this, vol_ptr, conn);
+                    VolumeWrap *volume = new VolumeWrap(this, vol_ptr, _conn);
                     printf("Created new volume: %s, ptr is %p\n", volume_name, vol_ptr);
-                    volumes.push_back(volume);
+                    _volumes.push_back(volume);
                 } catch (int i) {
                     printf ("Error constructing volume\n");
-                    REPORT_ERR(conn, "constructing volume.");
+                    REPORT_ERR(_conn, "constructing volume.");
                     if (volume) {
                         delete volume;
                     }
@@ -214,14 +217,14 @@ PoolWrap::syncVolumes()
     }
 
     /* Go through our list of volumes and ensure that they still exist. */
-    for (std::vector<VolumeWrap*>::iterator iter = volumes.begin(); iter != volumes.end();) {
-
-        printf ("Verifying volume %s\n", (*iter)->volume_name.c_str());
-        virStorageVolPtr ptr = virStorageVolLookupByName(pool_ptr, (*iter)->volume_name.c_str());
+    VolumeList::iterator iter = _volumes.begin();
+    while (iter != _volumes.end()) {
+        printf ("Verifying volume %s\n", (*iter)->name());
+        virStorageVolPtr ptr = virStorageVolLookupByName(_pool_ptr, (*iter)->name());
         if (ptr == NULL) {
-            printf("Destroying volume %s\n", (*iter)->volume_name.c_str());
+            printf("Destroying volume %s\n", (*iter)->name());
             delete(*iter);
-            iter = volumes.erase(iter);
+            iter = _volumes.erase(iter);
         } else {
             virStorageVolFree(ptr);
             iter++;
@@ -229,170 +232,206 @@ PoolWrap::syncVolumes()
     }
 
     /* And finally *phew*, call update() on all volumes. */
-    for (std::vector<VolumeWrap*>::iterator iter = volumes.begin(); iter != volumes.end(); iter++) {
+    for (iter = _volumes.begin(); iter != _volumes.end(); iter++) {
         (*iter)->update();
     }
 }
 
 void
-PoolWrap::update()
+PoolWrap::updateProperties(void)
 {
     virStoragePoolInfo info;
     int ret;
 
-    ret = virStoragePoolGetInfo(pool_ptr, &info);
+    ret = virStoragePoolGetInfo(_pool_ptr, &info);
     if (ret < 0) {
-        REPORT_ERR(conn, "PoolWrap: Unable to get info of storage pool");
+        REPORT_ERR(_conn, "PoolWrap: Unable to get info of storage pool");
         return;
     }
 
+    const char *state = NULL;
     switch (info.state) {
         case VIR_STORAGE_POOL_INACTIVE:
-            pool->set_state("inactive");
+            state = "inactive";
             break;
         case VIR_STORAGE_POOL_BUILDING:
-            pool->set_state("building");
+            state = "building";
             break;
         case VIR_STORAGE_POOL_RUNNING:
-            pool->set_state("running");
+            state = "running";
             break;
         case VIR_STORAGE_POOL_DEGRADED:
-            pool->set_state("degraded");
+            state = "degraded";
             break;
     }
+    _data.setProperty("state", state);
 
-    pool->set_capacity(info.capacity);
-    pool->set_allocation(info.allocation);
-    pool->set_available(info.available);
+    _data.setProperty("capacity", (uint64_t)info.capacity);
+    _data.setProperty("allocation", (uint64_t)info.allocation);
+    _data.setProperty("available", (uint64_t)info.available);
 
     // Check if state has changed compared to stored state. If so, rescan
     // storage pool sources (eg. logical pools on a lun might now be visible)
-    if (storagePoolState != info.state)
-        pool_sources_xml = virConnectFindStoragePoolSources(conn, "logical", NULL, 0);
+    if (_storagePoolState != info.state) {
+        _pool_sources_xml = virConnectFindStoragePoolSources(_conn, "logical", NULL, 0);
+    }
+
+    _storagePoolState = info.state;
+}
 
-    storagePoolState = info.state;
+void
+PoolWrap::update(void)
+{
+    updateProperties();
 
-    // Sync volumes after (potentially) rescanning for logical storage pool sources
-    // so we pick up any new pools if the state of this pool changed.
+    // Sync volumes after (potentially) rescanning for logical storage pool
+    // sources so we pick up any new pools if the state of this pool changed.
     syncVolumes();
 }
 
-Manageable::status_t
-PoolWrap::ManagementMethod(uint32_t methodId, Args& args, std::string &errstr)
+bool
+PoolWrap::handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event)
 {
-    cout << "Method Received: " << methodId << endl;
     int ret;
 
-    switch (methodId) {
-        case _qmf::Pool::METHOD_GETXMLDESC:
-        {
-            _qmf::ArgsPoolGetXMLDesc *ioArgs = (_qmf::ArgsPoolGetXMLDesc *) &args;
-            char *desc;
-
-            desc = virStoragePoolGetXMLDesc(pool_ptr, 0);
-            if (desc) {
-                ioArgs->o_description = desc;
-            } else {
-                errstr = FORMAT_ERR(conn, "Error getting XML description of storage pool (virStoragePoolGetXMLDesc).", &ret);
-                return STATUS_USER + ret;
-            }
-            return STATUS_OK;
+    if (*this != event.getDataAddr()) {
+        bool handled = false;
+        VolumeList::iterator iter = _volumes.begin();
+
+        while (!handled && iter != _volumes.end()) {
+            handled = (*iter)->handleMethod(session, event);
         }
+        return handled;
+    }
 
-        case _qmf::Pool::METHOD_CREATE:
-        {
-            ret = virStoragePoolCreate(pool_ptr, 0);
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error creating new storage pool (virStoragePoolCreate).", &ret);
-                return STATUS_USER + ret;
-            }
-            update();
-            return STATUS_OK;
+    const std::string& methodName(event.getMethodName());
+    qpid::types::Variant::Map args(event.getArguments());
+
+    if (methodName == "getXMLDesc") {
+        const char *desc = virStoragePoolGetXMLDesc(_pool_ptr, 0);
+        if (!desc) {
+            std::string err = FORMAT_ERR(_conn, "Error getting XML description of storage pool (virStoragePoolGetXMLDesc).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            event.addReturnArgument("description", desc);
+            session.methodSuccess(event);
         }
+        return true;
+    }
 
-        case _qmf::Pool::METHOD_BUILD:
-        {
-            ret = virStoragePoolBuild(pool_ptr, 0);
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error building storage pool (virStoragePoolBuild).", &ret);
-                return STATUS_USER + ret;
-            }
+    if (methodName == "create") {
+        ret = virStoragePoolCreate(_pool_ptr, 0);
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error creating new storage pool (virStoragePoolCreate).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
             update();
-            return STATUS_OK;
+            session.methodSuccess(event);
         }
+        return true;
+    }
 
-        case _qmf::Pool::METHOD_DESTROY:
-        {
-            ret = virStoragePoolDestroy(pool_ptr);
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error destroying storage pool (virStoragePoolDestroy).", &ret);
-                return STATUS_USER + ret;
-            }
+    if (methodName == "build") {
+        ret = virStoragePoolBuild(_pool_ptr, 0);
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error building storage pool (virStoragePoolBuild).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
             update();
-            return STATUS_OK;
+            session.methodSuccess(event);
         }
+        return true;
+    }
 
-        case _qmf::Pool::METHOD_DELETE:
-        {
-            ret = virStoragePoolDelete(pool_ptr, 0);
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error deleting storage pool (virStoragePoolDelete).", &ret);
-                return STATUS_USER + ret;
-            }
+    if (methodName == "destroy") {
+        ret = virStoragePoolDestroy(_pool_ptr);
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error destroying storage pool (virStoragePoolDestroy).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
             update();
-            return STATUS_OK;
+            session.methodSuccess(event);
         }
+        return true;
+    }
 
-        case _qmf::Pool::METHOD_UNDEFINE:
-        {
-            ret = virStoragePoolUndefine(pool_ptr);
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error undefining storage pool (virStoragePoolUndefine).", &ret);
-                return STATUS_USER + ret;
-            }
+    if (methodName == "delete") {
+        ret = virStoragePoolDelete(_pool_ptr, 0);
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error deleting storage pool (virStoragePoolDelete).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
             update();
-            return STATUS_OK;
+            session.methodSuccess(event);
         }
+        return true;
+    }
 
-        case _qmf::Pool::METHOD_CREATEVOLUMEXML:
-        {
-            _qmf::ArgsPoolCreateVolumeXML *io_args = (_qmf::ArgsPoolCreateVolumeXML *) &args;
-            virStorageVolPtr volume_ptr;
-
-            volume_ptr = virStorageVolCreateXML(pool_ptr, io_args->i_xmlDesc.c_str(), 0);
-            if (volume_ptr == NULL) {
-                errstr = FORMAT_ERR(conn, "Error creating new storage volume from XML description (virStorageVolCreateXML).", &ret);
-                return STATUS_USER + ret;
-            }
-
-            VolumeWrap *volume;
-            try {
-                volume = new VolumeWrap(agent, this, volume_ptr, conn);
-                volumes.push_back(volume);
-                io_args->o_volume = volume->GetManagementObject()->getObjectId();
-            } catch (int i) {
-                delete volume;
-                errstr = FORMAT_ERR(conn, "Error constructing pool object in virStorageVolCreateXML.", &ret);
-                return STATUS_USER + i;
-            }
-
+    if (methodName == "undefine") {
+        ret = virStoragePoolUndefine(_pool_ptr);
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error undefining storage pool (virStoragePoolUndefine).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
             update();
-            return STATUS_OK;
+            session.methodSuccess(event);
         }
-        
-        case _qmf::Pool::METHOD_REFRESH:
-        {
-            ret = virStoragePoolRefresh(pool_ptr, 0);
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error refreshing storage pool (virStoragePoolRefresh).", &ret);
-                return STATUS_USER + ret;
-            }
+        return true;
+    }
+
+    if (methodName == "createVolumeXML") {
+        if (createVolumeXML(session, event)) {
+            session.methodSuccess(event);
+        }
+        return true;
+    }
+
+    if (methodName == "refresh") {
+        ret = virStoragePoolRefresh(_pool_ptr, 0);
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error refreshing storage pool (virStoragePoolRefresh).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
             update();
-            return STATUS_OK;
+            session.methodSuccess(event);
         }
+        return true;
     }
 
-    return STATUS_NOT_IMPLEMENTED;
+    raiseException(session, event,
+                   ERROR_UNKNOWN_METHOD, STATUS_UNKNOWN_METHOD);
+    return true;
 }
 
+bool
+PoolWrap::createVolumeXML(qmf::AgentSession& session, qmf::AgentEvent& event)
+{
+    int ret;
+    virStorageVolPtr volume_ptr;
+
+    qpid::types::Variant::Map args(event.getArguments());
+
+    std::string xmlDesc(args["xmlDesc"]);
+    volume_ptr = virStorageVolCreateXML(_pool_ptr, xmlDesc.c_str(), 0);
+    if (volume_ptr == NULL) {
+        std::string err = FORMAT_ERR(_conn, "Error creating new storage volume from XML description (virStorageVolCreateXML).", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
+
+    VolumeWrap *volume;
+    try {
+        volume = new VolumeWrap(this, volume_ptr, _conn);
+        _volumes.push_back(volume);
+        event.addReturnArgument("volume", volume->objectID());
+    } catch (int i) {
+        delete volume;
+        std::string err = FORMAT_ERR(_conn, "Error constructing pool object in virStorageVolCreateXML.", &ret);
+        raiseException(session, event, err, STATUS_USER + ret);
+        return false;
+    }
+
+    update();
+    return true;
+}
 
diff --git a/src/PoolWrap.h b/src/PoolWrap.h
index 654ce44..1e6dfeb 100644
--- a/src/PoolWrap.h
+++ b/src/PoolWrap.h
@@ -1,10 +1,7 @@
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-#include <qpid/sys/Mutex.h>
+#ifndef POOL_WRAP_H
+#define POOL_WRAP_H
 
-#include "Package.h"
-#include "Pool.h"
+#include "NodeWrap.h"
 
 #include <unistd.h>
 #include <cstdlib>
@@ -15,49 +12,46 @@
 #include <libvirt/libvirt.h>
 #include <libvirt/virterror.h>
 
-using namespace qpid::management;
-using namespace qpid::sys;
-using namespace std;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::Mutex;
 
-// Forward decl.
 class VolumeWrap;
 
-class PoolWrap : public Manageable
+class PoolWrap:
+    public PackageOwner<NodeWrap::PackageDefinition>,
+    public ManagedObject
 {
-    ManagementAgent *agent;
-    qmf::com::redhat::libvirt::Pool *pool;
+    typedef std::vector<VolumeWrap*> VolumeList;
 
-    virStoragePoolPtr pool_ptr;
-    virConnectPtr conn;
+    virStoragePoolPtr _pool_ptr;
+    virConnectPtr _conn;
 
-    std::vector<VolumeWrap*> volumes;
+    VolumeList _volumes;
 
-    char *pool_sources_xml;
-    int storagePoolState;
+    char *_pool_sources_xml;
+    int _storagePoolState;
 
-public:
+    std::string _pool_name;
+    std::string _pool_uuid;
 
-    PoolWrap(ManagementAgent *agent, NodeWrap *parent, virStoragePoolPtr pool_ptr, virConnectPtr connect);
+public:
+    PoolWrap(NodeWrap *parent,
+             virStoragePoolPtr pool_ptr,
+             virConnectPtr connect);
     ~PoolWrap();
 
-    std::string pool_name;
-    std::string pool_uuid;
+    std::string name(void) { return _pool_name; }
+    std::string uuid(void) { return _pool_uuid; }
 
-    ManagementObject* GetManagementObject(void) const
-    {
-        return pool;
-    }
+    bool handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event);
 
-    char * getPoolSourcesXml();
+    const char *getPoolSourcesXml();
     void update();
     void syncVolumes();
 
-    status_t ManagementMethod (uint32_t methodId, Args& args, std::string &errstr);
-};
+private:
+    void updateProperties();
+    bool createVolumeXML(qmf::AgentSession& session, qmf::AgentEvent& event);
 
+};
 
+#endif
 
diff --git a/src/VolumeWrap.cpp b/src/VolumeWrap.cpp
index d4ce536..fcda96e 100644
--- a/src/VolumeWrap.cpp
+++ b/src/VolumeWrap.cpp
@@ -9,52 +9,54 @@
 #include "PoolWrap.h"
 #include "VolumeWrap.h"
 #include "Error.h"
+#include "Exception.h"
 
-#include "ArgsVolumeGetXMLDesc.h"
 
-namespace _qmf = qmf::com::redhat::libvirt;
-
-VolumeWrap::VolumeWrap(ManagementAgent *agent, PoolWrap *parent,
-                       virStorageVolPtr _volume_ptr, virConnectPtr _conn) :
-                       conn(_conn), volume_ptr(_volume_ptr)
+VolumeWrap::VolumeWrap(PoolWrap *parent,
+                       virStorageVolPtr volume_ptr,
+                       virConnectPtr connect):
+    PackageOwner<PoolWrap::PackageDefinition>(parent),
+    ManagedObject(package().data_Volume),
+    _volume_ptr(volume_ptr), _conn(connect),
+    _lvm_name(""), _has_lvm_child(false),
+    _wrap_parent(parent)
 {
-    const char *volume_key_s;
-    char *volume_path_s;
-    const char *volume_name_s;
-
-    volume = NULL;
+    const char *volume_key;
+    char *volume_path;
+    const char *volume_name;
 
-    wrap_parent = parent;
-
-    volume_key_s = virStorageVolGetKey(volume_ptr);
-    if (volume_key_s == NULL) {
-        REPORT_ERR(conn, "Error getting storage volume key\n");
+    volume_key = virStorageVolGetKey(_volume_ptr);
+    if (volume_key == NULL) {
+        REPORT_ERR(_conn, "Error getting storage volume key\n");
         throw 1;
     }
-    volume_key = volume_key_s;
+    _volume_key = volume_key;
 
-    volume_path_s = virStorageVolGetPath(volume_ptr);
-    if (volume_path_s == NULL) {
-        REPORT_ERR(conn, "Error getting volume path\n");
+    volume_path = virStorageVolGetPath(_volume_ptr);
+    if (volume_path == NULL) {
+        REPORT_ERR(_conn, "Error getting volume path\n");
         throw 1;
     }
-    volume_path = volume_path_s;
+    _volume_path = volume_path;
 
-    volume_name_s = virStorageVolGetName(volume_ptr);
-    if (volume_name_s == NULL) {
-        REPORT_ERR(conn, "Error getting volume name\n");
+    volume_name = virStorageVolGetName(_volume_ptr);
+    if (volume_name == NULL) {
+        REPORT_ERR(_conn, "Error getting volume name\n");
         throw 1;
     }
-    volume_name = volume_name_s;
+    _volume_name = volume_name;
 
-    lvm_name = "";
-    has_lvm_child = false;
+    _data.setProperty("key", _volume_key);
+    _data.setProperty("path", _volume_path);
+    _data.setProperty("name", _volume_name);
+    _data.setProperty("childLVMName", _lvm_name);
+    _data.setProperty("storagePool", parent->objectID());
 
-    checkForLVMPool();
+    // Set defaults
+    _data.setProperty("capacity", (uint64_t)0);
+    _data.setProperty("allocation", (uint64_t)0);
 
-    volume = new _qmf::Volume(agent, this, parent, volume_key, volume_path, volume_name, lvm_name);
-    printf("adding volume to agent - volume %p\n", volume);
-    agent->addObject(volume);
+    addData(_data);
 
     printf("done\n");
 }
@@ -63,9 +65,9 @@ void
 VolumeWrap::checkForLVMPool()
 {
     char *real_path = NULL;
-    char *pool_sources_xml;
+    const char *pool_sources_xml;
 
-    pool_sources_xml = wrap_parent->getPoolSourcesXml();
+    pool_sources_xml = _wrap_parent->getPoolSourcesXml();
 
     if (pool_sources_xml) {
         xmlDocPtr doc;
@@ -106,14 +108,14 @@ VolumeWrap::checkForLVMPool()
                 if (name && path) {
                     virStorageVolPtr vol;
 
-                    printf ("xml returned device name %s, path %s; volume path is %s\n", name, path, volume_path.c_str());
-                    vol = virStorageVolLookupByPath(conn, (char *) path);
+                    printf ("xml returned device name %s, path %s; volume path is %s\n", name, path, _volume_path.c_str());
+                    vol = virStorageVolLookupByPath(_conn, (char *) path);
                     if (vol != NULL) {
                         real_path = virStorageVolGetPath(vol);
-                        if (real_path && strcmp(real_path, volume_path.c_str()) == 0) {
+                        if (real_path && strcmp(real_path, _volume_path.c_str()) == 0) {
                             printf ("found matching storage volume associated with pool!\n");
-                            lvm_name.assign((char *) name);
-                            has_lvm_child = true;
+                            _lvm_name.assign((char *) name);
+                            _has_lvm_child = true;
                         }
                     }
                     xmlFree(path);
@@ -136,58 +138,59 @@ VolumeWrap::update()
 
     printf("Updating volume info\n");
 
-    ret = virStorageVolGetInfo(volume_ptr, &info);
+    ret = virStorageVolGetInfo(_volume_ptr, &info);
     if (ret < 0) {
-        REPORT_ERR(conn, "VolumeWrap: Unable to get info of storage volume info\n");
+        REPORT_ERR(_conn, "VolumeWrap: Unable to get info of storage volume info\n");
         return;
     }
-    volume->set_capacity(info.capacity);
-    volume->set_allocation(info.allocation);
+    _data.setProperty("capacity", (uint64_t)info.capacity);
+    _data.setProperty("allocation", (uint64_t)info.allocation);
 }
 
 VolumeWrap::~VolumeWrap()
 {
-    if (volume) {
-        volume->resourceDestroy();
-    }
-    virStorageVolFree(volume_ptr);
+    virStorageVolFree(_volume_ptr);
+
+    delData(_data);
 }
 
-Manageable::status_t
-VolumeWrap::ManagementMethod(uint32_t methodId, Args& args, std::string &errstr)
+bool
+VolumeWrap::handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event)
 {
-    cout << "Method Received: " << methodId << endl;
     int ret;
 
-    switch (methodId) {
-    case _qmf::Volume::METHOD_GETXMLDESC:
-        {
-            _qmf::ArgsVolumeGetXMLDesc *io_args = (_qmf::ArgsVolumeGetXMLDesc *) &args;
-            char *desc;
-
-            desc = virStorageVolGetXMLDesc(volume_ptr, 0);
-            if (desc) {
-                io_args->o_description = desc;
-            } else {
-                errstr = FORMAT_ERR(conn, "Error getting xml description for volume (virStorageVolGetXMLDesc).", &ret);
-                return STATUS_USER + ret;
-            }
-            return STATUS_OK;
+    if (*this != event.getDataAddr()) {
+        return false;
+    }
+
+    const std::string& methodName(event.getMethodName());
+    qpid::types::Variant::Map args(event.getArguments());
+
+    if (methodName == "getXMLDesc") {
+        const char *desc = virStorageVolGetXMLDesc(_volume_ptr, 0);
+        if (!desc) {
+            std::string err = FORMAT_ERR(_conn, "Error getting xml description for volume (virStorageVolGetXMLDesc).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
+            event.addReturnArgument("description", desc);
+            session.methodSuccess(event);
         }
-    case _qmf::Volume::METHOD_DELETE:
-        {
-            ret = virStorageVolDelete(volume_ptr, 0);
-            if (ret < 0) {
-                errstr = FORMAT_ERR(conn, "Error deleting storage volume (virStorageVolDelete).", &ret);
-                return STATUS_USER + ret;
-            }
+        return true;
+    }
+
+    if (methodName == "delete") {
+        ret = virStorageVolDelete(_volume_ptr, 0);
+        if (ret < 0) {
+            std::string err = FORMAT_ERR(_conn, "Error deleting storage volume (virStorageVolDelete).", &ret);
+            raiseException(session, event, err, STATUS_USER + ret);
+        } else {
             update();
-            return STATUS_OK;
+            session.methodSuccess(event);
         }
+        return true;
     }
 
-
-    return STATUS_NOT_IMPLEMENTED;
+    raiseException(session, event,
+                   ERROR_UNKNOWN_METHOD, STATUS_UNKNOWN_METHOD);
+    return true;
 }
-
-
diff --git a/src/VolumeWrap.h b/src/VolumeWrap.h
index 50d1347..7f3a63f 100644
--- a/src/VolumeWrap.h
+++ b/src/VolumeWrap.h
@@ -1,10 +1,7 @@
-#include <qpid/management/Manageable.h>
-#include <qpid/management/ManagementObject.h>
-#include <qpid/agent/ManagementAgent.h>
-#include <qpid/sys/Mutex.h>
+#ifndef VOLUME_WRAP_H
+#define VOLUME_WRAP_H
 
-#include "Package.h"
-#include "Volume.h"
+#include "PoolWrap.h"
 
 #include <unistd.h>
 #include <cstdlib>
@@ -15,51 +12,36 @@
 #include <libvirt/libvirt.h>
 #include <libvirt/virterror.h>
 
-using namespace qpid::management;
-using namespace qpid::sys;
-using namespace std;
-using qpid::management::ManagementObject;
-using qpid::management::Manageable;
-using qpid::management::Args;
-using qpid::sys::Mutex;
 
-// Forward decl.
-class PoolWrap;
-
-class VolumeWrap : public Manageable
+class VolumeWrap:
+    PackageOwner<PoolWrap::PackageDefinition>,
+    public ManagedObject
 {
-    ManagementAgent *agent;
-    qmf::com::redhat::libvirt::Volume *volume;
-
-    std::string volume_key;
-    std::string volume_path;
+    virStorageVolPtr _volume_ptr;
+    virConnectPtr _conn;
 
-    std::string lvm_name;
-    bool has_lvm_child;
+    std::string _volume_name;
+    std::string _volume_key;
+    std::string _volume_path;
 
-    virConnectPtr conn;
-    virStorageVolPtr volume_ptr;
+    std::string _lvm_name;
+    bool _has_lvm_child;
 
-    PoolWrap *wrap_parent;
+    PoolWrap *_wrap_parent;
 
     void checkForLVMPool();
 
 public:
-
-    std::string volume_name;
-
-    VolumeWrap(ManagementAgent *agent, PoolWrap *parent, virStorageVolPtr pool_ptr, virConnectPtr connect);
+    VolumeWrap(PoolWrap *parent,
+               virStorageVolPtr volume_ptr,
+               virConnectPtr connect);
     ~VolumeWrap();
 
-    ManagementObject* GetManagementObject(void) const
-    {
-        return volume;
-    }
+    const char *name(void) { return _volume_name.c_str(); }
 
     void update();
 
-    status_t ManagementMethod (uint32_t methodId, Args& args, std::string &errstr);
+    bool handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event);
 };
 
-
-
+#endif




More information about the libvir-list mailing list