public function getDiffInfoAction()
 {
     $main_buss_id = $this->getRequest("main_buss_id", "");
     $path = trim($this->getRequest("path", ""), "/");
     $idc = $this->getRequest("idc", "");
     // 1. parameter null
     if ($path === "" || $main_buss_id === "" || $idc === "") {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_BAD_ARGS);
         QconfMgrLog::err(__FILE__, __LINE__, "parameter 'main_buss_id', 'path' or 'idc' is null!");
         echo json_encode($res);
         return;
     }
     // 2. check node exist
     $path = "/" . $path;
     $node = NodeServ::getNodeByNodeWhole($path, $main_buss_id);
     if ($node === FALSE) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_NODE_NOT_EXIST);
         QconfMgrLog::err(__FILE__, __LINE__, "node({$path}) with main_buss_id({$main_buss_id}) not exist!");
         echo json_encode($res);
         return;
     }
     $node_whole = $node["node_whole"];
     $main_buss_id = $node["main_buss_id"];
     // 3. idc validation
     $cur_idcs = $node["idc"];
     $check_res = self::idcValidation($idc, $cur_idcs);
     if ($check_res["errno"] != "0") {
         echo json_encode($check_res);
         return;
     }
     // 4. get snapshot content
     $snapshot_content = SnapShotUtil::getSnapShotContent($main_buss_id, $node_whole);
     if ($snapshot_content === FALSE) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_SNAPSHOT_MODULE_FAILED);
         QconfMgrLog::err(__FILE__, __LINE__, "failed to get snapshot by node_whole({$node_whole}), main_buss_id({$main_buss_id})");
         echo json_encode($res);
         return;
     }
     // 5.add current value into content
     if (!array_key_exists($idc, $snapshot_content)) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_SNAPSHOT_IDC_NOT_EXIST);
         QconfMgrLog::err(__FILE__, __LINE__, "snapshot of node_whole({$node_whole}), main_buss_id({$main_buss_id}) do not exist on idc({$idc}) ");
         echo json_encode($res);
         return;
     }
     $result_idc = $snapshot_content[$idc];
     if (!array_key_exists("conf", $result_idc) || !array_key_exists("serv", $result_idc)) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_SNAPSHOT_FILE_ERROR);
         QconfMgrLog::err(__FILE__, __LINE__, "snapshot error of node_whole({$node_whole}), main_buss_id({$main_buss_id})");
         echo json_encode($res);
         return;
     }
     $idc_host = ZkConf::getZkHost($idc);
     $zk_web = new QconfZkWebBase(Log::INFO);
     $zk_web->connect($idc_host);
     $result_conf = $result_idc["conf"];
     $final_conf = array();
     foreach ($result_conf as $key => $value) {
         $get_conf = NodeController::getConfWithLink($zk_web, $key, $idc, $cur_val);
         if ($get_conf != InfoDescUtil::QCONF_OK) {
             $res = InfoDescUtil::getErrorMsg($get_conf);
             $res["data"] .= $idc;
             echo json_encode($res);
             return;
         }
         if ($cur_val === $value) {
             continue;
         }
         $value_cmp["path"] = $key;
         $value_cmp["cur"] = $cur_val;
         $value_cmp["snp"] = $value;
         $final_conf[] = $value_cmp;
     }
     $result_serv = $result_idc["serv"];
     $final_serv = array();
     foreach ($result_serv as $key => $service) {
         $get_service = ServiceController::getServicesAndStatusWithLink($zk_web, $key, $idc, $cur_service);
         if ($get_service != InfoDescUtil::QCONF_OK) {
             $res = InfoDescUtil::getErrorMsg($get_service);
             $res["data"] .= $idc;
             echo json_encode($res);
             return;
         }
         if ($cur_service === $service) {
             continue;
         }
         $hosts_cmp["path"] = $key;
         $hosts_cmp["cur"] = $cur_service;
         $hosts_cmp["snp"] = $service;
         $final_serv[] = $hosts_cmp;
     }
     $final_idc["conf"] = $final_conf;
     $final_idc["serv"] = $final_serv;
     $final["info"] = $final_idc;
     $res = array("errno" => "0", "errmsg" => "", "data" => $final);
     $json = json_encode($res);
     echo $json;
     return;
 }
 private function upOrOfflineService($op_type)
 {
     // 1.argument receive and preprocess
     $res = "";
     $argus = self::commonArgusProcess($res);
     if ($argus === FALSE) {
         echo json_encode($res);
         return;
     }
     $user = $argus["user"];
     $path = $argus["path"];
     $idc = $argus["idc"];
     $main_buss_id = $argus["main_buss_id"];
     $sub_buss_id = $argus["sub_buss_id"];
     $service_name = $this->getRequest("service_name", "");
     if ($service_name === "") {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_BAD_ARGS);
         QconfMgrLog::err(__FILE__, __LINE__, "paramter: 'service_name({$service_name})'is required!");
         echo json_encode($res);
         return;
     }
     $service_list = preg_split("/[,]+/", trim($service_name, ","));
     //validate for ip_port
     if (ArgsUtil::ipPortsValidation($service_list) === FALSE) {
         //failed to add any new services
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_BAD_ARGS);
         QconfMgrLog::err(__FILE__, __LINE__, "ilegal services : {$service_name} under {$path}!");
         echo json_encode($res);
         return;
     }
     // 2. check node exist and is node father type
     $check_res = ServiceController::checkServFatherNode($path, $main_buss_id);
     if ($check_res != InfoDescUtil::QCONF_OK) {
         $res = InfoDescUtil::getErrorMsg($check_res);
         echo json_encode($res);
         return;
     }
     // 3. do up or offline
     $op_type_msg = $op_type === InfoDescUtil::OP_TYPE_OFFLINE ? "offline" : "up";
     $idc_list = preg_split("/[,]+/", $idc);
     // split by ,
     foreach ($idc_list as $idc_each) {
         $idc_host = ZkConf::getZkHost($idc_each);
         $zk_web = new QconfZkWebBase(Log::INFO);
         $zk_web->connect($idc_host);
         $get_ret = ServiceController::getServicesAndStatusWithLink($zk_web, $path, $idc_each, $exist_services);
         if ($get_ret != InfoDescUtil::QCONF_OK) {
             $res = InfoDescUtil::getErrorMsg($get_ret);
             echo json_encode($res);
             return;
         }
         foreach ($service_list as $service) {
             $show_ser_path = PathUtil::unionPath($path, $service);
             // check service exist
             if (!array_key_exists($service, $exist_services)) {
                 $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_SERVICE_NO_EXIST);
                 echo json_encode($res);
                 return;
             }
             if ($op_type === InfoDescUtil::OP_TYPE_OFFLINE) {
                 //check up service cout for offline operation
                 $is_last = TRUE;
                 foreach ($exist_services as $one_exist_service => $service_status) {
                     if ($service_status === InfoDescUtil::SERV_STATUS_UP && $one_exist_service != $service) {
                         $is_last = FALSE;
                         break;
                     }
                 }
                 if ($is_last) {
                     $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_OFFILE_SERVICE_ONLY);
                     QconfMgrLog::err(__FILE__, __LINE__, "{$service} is the last up service under {$path}");
                     echo json_encode($res);
                     return;
                 }
                 $ret = ServiceController::offlineServiceWithLink($zk_web, $path, $service, $idc_each);
                 $exist_services[$service] = InfoDescUtil::SERV_STATUS_DOWN;
             } else {
                 $ret = ServiceController::upServiceWithLink($zk_web, $path, $service, $idc_each);
             }
             if ($ret != InfoDescUtil::QCONF_OK) {
                 $res = InfoDescUtil::getErrorMsg($ret);
                 QconfMgrLog::err(__FILE__, __LINE__, "{$op_type_msg} service!");
                 OpServ::insert($op_type, $show_ser_path, $idc_each, InfoDescUtil::OP_STATUS_ZOO_FAILED, $main_buss_id, $sub_buss_id, $user, "");
                 echo json_encode($res);
                 return;
             }
             OpServ::insert($op_type, $show_ser_path, $idc_each, InfoDescUtil::OP_STATUS_SUCCESS, $main_buss_id, $sub_buss_id, $user, $op_type === InfoDescUtil::OP_TYPE_OFFLINE ? InfoDescUtil::SERV_STATUS_OFFLINE : InfoDescUtil::SERV_STATUS_UP);
         }
     }
     $res = array("errno" => "0", "errmsg" => "", "data" => "{$op_type_msg} service success");
     $json = json_encode($res);
     echo $json;
     return;
 }
 public function addIdcRecursiveAction()
 {
     $node_id = $this->getRequest("node_id", "");
     $idc = $this->getRequest("idc", "");
     $template_idc = $this->getRequest("template_idc", "");
     $is_copy_servs = $this->getRequest("is_copy_servs", "");
     $op_user = $this->userInfo["userName"];
     QconfMgrLog::err(__FILE__, __LINE__, "parameter 'node_id({$node_id})' 'idc({$idc})' 'template_idc({$template_idc})' or 'copy_services({$is_copy_servs})' is null!");
     // 1. parameter is not right
     if ($node_id === "" || $idc === "" || $template_idc === "" || $is_copy_servs === "") {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_BAD_ARGS);
         QconfMgrLog::err(__FILE__, __LINE__, "parameter 'node_id' 'idc' 'template_idc' or 'copy_services' is null!");
         echo json_encode($res);
         return;
     }
     $is_copy_services = $is_copy_servs === "1" ? TRUE : FALSE;
     // 2. get the node info from database
     $row = NodeServ::getNode($node_id);
     if ($row === FALSE) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_NODE_NOT_EXIST);
         echo json_encode($res);
         return;
     }
     $main_buss_id = $row["main_buss_id"];
     $db_node_whole = $row["node_whole"];
     //[USERPERM CHECK]
     $userperm_ret = UserPermServ::checkPerm($op_user, $db_node_whole);
     if ($userperm_ret === FALSE) {
         QconfMgrLog::err(__FILE__, __LINE__, "Insufficient permission of {$op_user} on node {$db_node_whole}");
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_USER_PERM_PERMISSION_DENIED);
         echo json_encode($res);
         return;
     }
     //[SNAPSHOT CHECK]
     $snapshot_ret = SnapShotUtil::existSnapShotForNode($main_buss_id, $db_node_whole, $snapshot_path, InfoDescUtil::SNAPSHOT_FULL_PATH);
     if ($snapshot_ret === FALSE) {
         QconfMgrLog::err(__FILE__, __LINE__, "snapshot operation failed");
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_SNAPSHOT_MODULE_FAILED);
         echo json_encode($res);
         return;
     }
     if ($snapshot_ret === InfoDescUtil::SNAPSHOT_FILE_EXIST) {
         QconfMgrLog::err(__FILE__, __LINE__, "snapshot existed on current node node_whole({$node_whole})");
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_SNAPSHOT_LOCKED_NODE);
         $res["errmsg"] .= ": {$snapshot_path}";
         echo json_encode($res);
         return;
     }
     // 3. check target idc exist
     $idc = trim($idc, ",");
     $idc_list = preg_split("/[,]+/", $idc);
     $idc_to = $idc_list[0];
     $idc_host = ZkConf::getZkHost($idc_to);
     if ($idc_host === NULL) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IDC_NOT_EXIST);
         $res["data"] .= $idc_to;
         echo json_encode($res);
         return;
     }
     $zk_web_target = new QconfZkWebBase(Log::INFO);
     $zk_web_target->connect($idc_host);
     // 4. check template idc exist
     $template_idc = trim($template_idc, ",");
     $template_list = preg_split("/[,]+/", $template_idc);
     $idc_from = $template_list[0];
     $template_host = ZkConf::getZkHost($idc_from);
     if ($template_host === NULL) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IDC_NOT_EXIST);
         $res["data"] .= $idc_from;
         echo json_encode($res);
         return;
     }
     $zk_web_template = new QconfZkWebBase(Log::INFO);
     $zk_web_template->connect($template_host);
     $descendant = NodeServ::getDescendant($row["node_whole"]);
     // add the current node itself
     $descendant[] = $row;
     mysql_query("BEGIN");
     foreach ($descendant as $one_descendant) {
         $node_cur_id = $one_descendant["node_id"];
         $node_type_code = $one_descendant["node_type_code"];
         $node_whole = $one_descendant["node_whole"];
         $main_buss_id = $one_descendant["main_buss_id"];
         $sub_buss_id = $one_descendant["sub_buss_id"];
         //idc maybe update during the previous loop
         $cur_descendant = NodeServ::getNode($node_cur_id);
         if ($cur_descendant === FALSE) {
             QconfMgrLog::err(__FILE__, __LINE__, "faied to retrive node_id : {$node_cur_id}");
             $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_MYSQL_FAIL);
             echo json_encode($res);
             mysql_query("ROLLBACK");
             return;
         }
         $descendant_idc = $cur_descendant["idc"];
         // 5. check wether descendant exist on template idc
         // 5.1 check exist
         $descendant_idcs_array = explode(',', $descendant_idc);
         $exist_on_template = in_array($idc_from, $descendant_idcs_array);
         if ($exist_on_template === FALSE) {
             QconfMgrLog::err(__FILE__, __LINE__, "expect {$node_whole} on " . $idc_from);
             continue;
         }
         // 5.2 get value
         $get_ret = self::getConfWithLink($zk_web_template, $node_whole, $idc_from, $node_val);
         if ($get_ret != InfoDescUtil::QCONF_OK) {
             $res = InfoDescUtil::getErrorMsg($get_ret);
             $res["data"] .= $idc_from;
             echo json_encode($res);
             mysql_query("ROLLBACK");
             return;
         }
         // 5.3 get services
         $node_services = NULL;
         if ($is_copy_services === TRUE && $node_type_code === InfoDescUtil::NODE_TYPE_SERV_FATHER) {
             $get_ret = ServiceController::getServicesAndStatusWithLink($zk_web_template, $node_whole, $idc_host, $node_services);
             if ($get_ret != InfoDescUtil::QCONF_OK) {
                 $res = InfoDescUtil::getErrorMsg($get_ret);
                 mysql_query("ROLLBACK");
                 echo json_encode($res);
                 return;
             }
         }
         // check wether descendant exist on target idc
         $exist_on_target = in_array($idc_to, $descendant_idcs_array);
         if ($exist_on_target === FALSE) {
             // 6. find all leaf descendants under given node and expand it to the new idc
             // 6.1 add in zookeeper
             $res_cur = self::addOneIdcWithLink($node_type_code, $node_whole, $idc_to, $node_val, $node_services, $zk_web_target);
             if ($res_cur === -1) {
                 OpServ::insert(InfoDescUtil::OP_TYPE_EXPANSION, $node_whole, $idc_to, InfoDescUtil::OP_STATUS_ZOO_FAILED, $main_buss_id, $sub_buss_id, $op_user, "");
                 $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_ZOOKEEPER_FAIL);
                 $res["data"] .= $idc_to;
                 echo json_encode($res);
                 mysql_query("ROLLBACK");
                 return;
             }
             // 6.2 update database
             $ret = NodeServ::modIdc($node_cur_id, $idc_to);
             if ($ret === FALSE) {
                 $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_MYSQL_FAIL);
                 OpServ::insert(InfoDescUtil::OP_TYPE_EXPANSION, $node_whole, $idc_to, InfoDescUtil::OP_STATUS_MYSQL_FAILED, $main_buss_id, $sub_buss_id, $op_user, "");
                 echo json_encode($res);
                 mysql_query("ROLLBACK");
                 return;
             }
             OpServ::insert(InfoDescUtil::OP_TYPE_EXPANSION, $node_whole, $idc_to, InfoDescUtil::OP_STATUS_SUCCESS, $main_buss_id, $sub_buss_id, $op_user, $node_val);
         } else {
             // 7. sync value and services between target idc and template idc
             // 7.1 sync value
             $sync_ret = InfoDescUtil::QCONF_OK;
             if ($node_val != "") {
                 $sync_ret = self::setConfWithLink($zk_web_target, $node_whole, $idc_to, $node_val);
                 // modify the zookeeper failed
             }
             // 7.2 sync services
             if ($sync_ret === InfoDescUtil::QCONF_OK && $node_services != NULL) {
                 foreach ($node_services as $ser => $status) {
                     $sync_ret = ServiceController::addServiceWithLink($zk_web_target, $node_whole, $ser, $idc_to, $status);
                     if ($sync_ret === -1) {
                         break;
                     }
                 }
             }
             if ($sync_ret != InfoDescUtil::QCONF_OK) {
                 OpServ::insert(InfoDescUtil::OP_TYPE_MOD, $node_whole, $idc_to, InfoDescUtil::OP_STATUS_ZOO_FAILED, $main_buss_id, $sub_buss_id, $op_user, "");
                 $res = InfoDescUtil::getErrorMsg($sync_ret);
                 $res["data"] .= $idc_to;
                 echo json_encode($res);
                 mysql_query("ROLLBACK");
                 return;
             }
             OpServ::insert(InfoDescUtil::OP_TYPE_MOD, $node_whole, $idc_to, InfoDescUtil::OP_STATUS_SUCCESS, $main_buss_id, $sub_buss_id, $op_user, $node_val);
         }
     }
     mysql_query("COMMIT");
     // 8. return the data
     $res = array("errno" => "0", "errmsg" => "", "data" => "add idc success!");
     $json = json_encode($res);
     echo $json;
     return;
 }