inline void marshall_json(rapidjson::Writer<rapidjson::StringBuffer>& writer, const cluster_info& info)
 {
     writer.StartObject();
     writer.String("name"); marshall_json(writer, info.name);
     writer.String("type"); marshall_json(writer, info.type);
     writer.EndObject();
 };
        void deploy_svc_service_impl::on_get_cluster_list_cli(void *context, int argc, const char **argv, dsn_cli_reply *reply)
        {
            dassert(context == (void*)this, "context must be this");

            cluster_list clist;
            std::string format;
            if (argc > 0)
            {
                error_code err = unmarshall_json(argv[0], "format", format);
                if (err != ERR_OK)
                {
                    //TODO: need raise error here?
                    format = std::string("");
                }
            }

            on_get_cluster_list_internal(format, clist);

            std::string* resp_json = new std::string();
            *resp_json = marshall_json(clist);
            reply->context = resp_json;
            reply->message = (const char*)resp_json->c_str();
            reply->size = resp_json->size();
            return;
        }
        void deploy_svc_service_impl::on_get_service_list_cli(void *context, int argc, const char **argv, dsn_cli_reply *reply)
        {
            dassert(context == (void*)this, "context must be this");

            deploy_info_list dlist;
            std::string package_id;

            if (argc >=1)
            {
                error_code err = unmarshall_json(argv[0], "package_id", package_id);
                if (err != ERR_OK)
                {
                    //TODO: need raise error here?
                    package_id = std::string("");
                }
            }
            on_get_service_list_internal(package_id, dlist);

            std::string* resp_json = new std::string();
            *resp_json = marshall_json(dlist);
            reply->context = resp_json;
            reply->message = (const char*)resp_json->c_str();
            reply->size = resp_json->size();
            return;
        }
        /*
        * example format:
          {
            "cluster":"mycluster",
            "error":0,
            "name":"name",
            "package_id":"123",
            "service_url":"node1:8080",
            "status":0
          }
        */
        inline std::string marshall_json(const deploy_info& info)
        {
            rapidjson::StringBuffer sbuf;
            rapidjson::Writer<rapidjson::StringBuffer> writer(sbuf);

            marshall_json(writer, info);

            return sbuf.GetString();
        };
        /*
        * example format:
          {
            "error": "xx"
          }
        */
        inline std::string marshall_json(const error_code& err)
        {
            rapidjson::StringBuffer sbuf;
            rapidjson::Writer<rapidjson::StringBuffer> writer(sbuf);

            writer.StartObject();
            writer.String("error"); marshall_json(writer, err);
            writer.EndObject();

            return sbuf.GetString();
        };
 inline void marshall_json(rapidjson::Writer<rapidjson::StringBuffer>& writer, const deploy_info& info)
 {
     writer.StartObject();
     writer.String("cluster"); marshall_json(writer, info.cluster);
     writer.String("error"); marshall_json(writer, info.error);
     writer.String("name"); marshall_json(writer, info.name);
     writer.String("package_id"); marshall_json(writer, info.package_id);
     writer.String("service_url"); marshall_json(writer, info.service_url);
     writer.String("status"); marshall_json(writer, info.status);
     writer.EndObject();
 };
        /*
        * example format:
          {
            "clusters":
            [
              {
                "name":"cname",
                "type":"xx"
              },
              {
                "name":"cname2",
                "type":"yy"
              }
            ]
          }
        */
        inline std::string marshall_json(const cluster_list& clist)
        {
            rapidjson::StringBuffer sbuf;
            rapidjson::Writer<rapidjson::StringBuffer> writer(sbuf);

            writer.StartObject();
            writer.String("clusters");
            writer.StartArray();
            for (std::vector<cluster_info>::const_iterator i = clist.clusters.begin(); i != clist.clusters.end(); i++)
            {
                marshall_json(writer, *i);
            }
            writer.EndArray();
            writer.EndObject();

            return sbuf.GetString();
        };
        /*
        * example format:
          {
            "services":
            [
              {
                "cluster":"mycluster",
                "error":0,
                "name":"name",
                "package_id":"123",
                "service_url":"node1:8080",
                "status":0
              },
              {
                "cluster":"mycluster",
                "error":0,
                "name":"name2",
                "package_id":"123",
                "service_url":"node1:8080",
                "status":0
              }
            ]
          }
        */
        inline std::string marshall_json(const deploy_info_list& dlist)
        {
            rapidjson::StringBuffer sbuf;
            rapidjson::Writer<rapidjson::StringBuffer> writer(sbuf);

            writer.StartObject();
            writer.String("services");
            writer.StartArray();
            for (std::vector<deploy_info>::const_iterator i = dlist.services.begin(); i != dlist.services.end(); i++)
            {
                marshall_json(writer, *i);
            }
            writer.EndArray();
            writer.EndObject();

            return sbuf.GetString();
        };
        void deploy_svc_service_impl::on_get_service_info_cli(void *context, int argc, const char **argv, dsn_cli_reply *reply)
        {
            dassert(context == (void*)this, "context must be this");

            deploy_info di;
            std::string service_name;

            if (argc < 1 || ERR_OK != unmarshall_json(argv[0], "service_name", service_name))
            {
                di.error = ERR_INVALID_PARAMETERS;
            }
            else
            {
                on_get_service_info_internal(service_name, di);
            }

            std::string* resp_json = new std::string();
            *resp_json = marshall_json(di);
            reply->context = resp_json;
            reply->message = (const char*)resp_json->c_str();
            reply->size = resp_json->size();
            return;
        }