private static function check_path($path, $op_user)
 {
     // 1. check length
     $snappath = SnapShotUtil::getSnapShotPath($path, $op_user);
     $snappath_length = strlen($snappath);
     if ($snappath_length >= InfoDescUtil::SNAPSHOT_PATH_MAX_LENGTH) {
         QconfMgrLog::err(__FILE__, __LINE__, "path of snapshot is too long, path_lengrh({$snappath_length})");
         return InfoDescUtil::ERR_SNAPSHOT_PATH_TO_LONG;
     }
     // 2. check character
     $path_reg = "/^[\\w\\d_\\-\\.:\\/]+\$/";
     $is_illegal = preg_match($path_reg, $path);
     if ($is_illegal === 0) {
         QconfMgrLog::err(__FILE__, __LINE__, "illegal path, path({$path})");
         return InfoDescUtil::ERR_SNAPSHOT_PATH_ILLEGAL;
     }
     return InfoDescUtil::QCONF_OK;
 }
 public function addServiceAction()
 {
     $node_id = $this->getRequest("node_id", "");
     $idc = $this->getRequest("idc", "");
     $service_name = $this->getRequest("service_name", "");
     $op_user = $this->userInfo["userName"];
     // 1. parameter is not right
     if ($node_id === "" || $idc === "" || $service_name === "") {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_BAD_ARGS);
         QconfMgrLog::err(__FILE__, __LINE__, "parameter 'node_id', 'idc', 'service_name', is null!");
         echo json_encode($res);
         return;
     }
     // 2. check node_id
     $node_row = NodeServ::getNode($node_id);
     if ($node_row === FALSE || count($node_row) === 0) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_NODE_NOT_EXIST);
         QconfMgrLog::err(__FILE__, __LINE__, "'node_id : {$node_id} not exist!'");
         echo json_encode($res);
         return;
     }
     $db_node_whole = $node_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;
     }
     // 3. check node type code
     $node_type_code = $node_row["node_type_code"];
     if ($node_type_code === InfoDescUtil::NODE_TYPE_NORMAL_FATHER) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_NODE_TYPE);
         QconfMgrLog::err(__FILE__, __LINE__, "node {$node_id} is not a normal father node!'");
         echo json_encode($res);
         return;
     } else {
         if ($node_type_code === InfoDescUtil::NODE_TYPE_NORMAL) {
             //[SNAPSHOT CHECK]
             $main_buss_id = $node_row["main_buss_id"];
             $snapshot_ret = SnapShotUtil::existSnapShotForNode($main_buss_id, $db_node_whole, $snapshot_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;
             }
         }
     }
     // 4. check idc exist
     $idc = trim($idc, ",");
     $idc_list = preg_split("/[,]+/", $idc);
     $failed_idcs = "";
     foreach ($idc_list as $idc_each) {
         $idc_host = ZkConf::getZkHost($idc_each);
         if ($idc_host === NULL) {
             //idc does not exist
             $failed_idcs .= ",{$idc_each}";
         }
     }
     if ($failed_idcs != "") {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IDC_NOT_EXIST);
         $res["data"] .= trim($failed_idcs, ",");
         echo json_encode($res);
         return;
     }
     // 5. add add in zookeeper
     $failed_idcs = self::retryOperation($node_id, $idc_list, $service_name, $op_user, InfoDescUtil::OP_TYPE_BATCH_ADD_SERV);
     // 6. send result
     if (count($failed_idcs) === 0) {
         //success return
         $res = array("errno" => "0", "errmsg" => "", "data" => "add service success!");
         $json = json_encode($res);
         echo $json;
         return;
     } else {
         //failed return
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_BATCH_FAIL_EXIST);
         foreach ($failed_idcs as $fail_idc) {
             if ($res["data"] != "") {
                 $res["data"] .= ",";
             }
             $res["data"] .= $fail_idc;
         }
         $json = json_encode($res);
         echo $json;
         return;
     }
 }
 public function uploadAndExamineAction()
 {
     $node_id = $this->getRequest("node_id", "");
     $idc = $this->getRequest("idc", "");
     $file_name = InfoDescUtil::IMPORT_FILE_CONTROL_NAME;
     $op_user = $this->userInfo["userName"];
     // 1. parameter is not right
     if ($node_id === "" || $idc === "") {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_BAD_ARGS);
         QconfMgrLog::err(__FILE__, __LINE__, "parameter 'node_id' or 'idc' is null!");
         echo json_encode($res);
         return;
     }
     // 2. get node from database
     $node = NodeServ::getNode($node_id);
     if ($node === FALSE) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_NODE_NOT_EXIST);
         QconfMgrLog::err(__FILE__, __LINE__, "node does not exist in database, node_id({$node_id})!");
         echo json_encode($res);
         return;
     }
     $main_buss_id = $node["main_buss_id"];
     $db_node_whole = $node["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);
     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 idc
     $idc_host = ZkConf::getZkHost($idc);
     if ($idc_host === NULL) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IDC_NOT_EXIST);
         QconfMgrLog::err(__FILE__, __LINE__, "Illegal idc : {$idc}!");
         $res["data"] .= $idc;
         echo json_encode($res);
         return;
     }
     $data_idcs = explode(',', $node["idc"]);
     $exist_idc = in_array($idc, $data_idcs);
     if ($exist_idc === FALSE) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IDC_NOT_IN_DATABASE);
         echo json_encode($res);
         return;
     }
     // 4. check parent node type
     $parent_type_code = $node["node_type_code"];
     $parent_node_whole = $node["node_whole"];
     if ($parent_type_code === InfoDescUtil::NODE_TYPE_SERV_FATHER) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_ADD_UNDER_SERV_FATHER);
         QconfMgrLog::err(__FILE__, __LINE__, "try to add node under service node : {$parent_node_whole}!");
         echo json_encode($res);
         return;
     }
     // 5. get upload file
     // 5.1 check upload success
     if ($_FILES[$file_name] === NULL) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_BAD_ARGS);
         QconfMgrLog::err(__FILE__, __LINE__, "file_name: {$file_name} may be error!");
         echo json_encode($res);
         return;
     }
     if ($_FILES[$file_name]['error'] > 0) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_UPLOAD_FAILED);
         QconfMgrLog::err(__FILE__, __LINE__, "failed to upload configure file, file_name : {$file_name}!");
         echo json_encode($res);
         return;
     }
     $file_size = $_FILES[$file_name]['size'];
     if ($file_size > InfoDescUtil::IMPORT_MAX_SIZE) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_TOO_LARGE);
         QconfMgrLog::err(__FILE__, __LINE__, "upload file too large, size : {$file_size}!");
         echo json_encode($res);
         return;
     }
     $file_type = end(explode(".", $_FILES[$file_name]['name']));
     if ($file_type != "ini" && $file_type != "php") {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_ILEGAL_FILE_TYPE);
         QconfMgrLog::err(__FILE__, __LINE__, "not support file type: {$file_type}, file_name({$file_name})!");
         echo json_encode($res);
         return;
     }
     // 5.2 get upload file
     $tmp_file_dir = $_SERVER['DOCUMENT_ROOT'] . "/" . InfoDescUtil::IMPORT_DIR;
     list($usec, $sec) = explode(" ", microtime());
     $usec_decimals = end(explode(".", $usec));
     $file_id = "{$sec}-{$usec_decimals}-{$op_user}";
     $tmp_file_name = "{$tmp_file_dir}/{$file_id}." . $file_type;
     $move_res = move_uploaded_file($_FILES[$file_name]['tmp_name'], $tmp_file_name);
     if ($move_res === FALSE) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_UPLOAD_FAILED);
         QconfMgrLog::err(__FILE__, __LINE__, "failed to move uploaded configure file, file_name({$file_name}), tmp_file_name({$tmp_file_name})!");
         echo json_encode($res);
         return;
     }
     QconfMgrLog::err(__FILE__, __LINE__, "user {$op_user} uploaded configure file, file_name : {$file_name} , file_id : {$file_id}!");
     // 6. syntax check
     if ($file_type == "php") {
         $output = shell_exec("/usr/local/php/bin/php -l " . $tmp_file_name . " 2>>/dev/null");
         if (strpos($output, "No syntax errors") === FALSE) {
             $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_FAILED_SYNTAX_CHECK);
             QconfMgrLog::err(__FILE__, __LINE__, "failed the syntax check! tmp_file_name({$tmp_file_name})!");
             echo json_encode($res);
             return;
         }
         $import_file = new ImportFilePHP();
     } else {
         if ($file_type == "ini") {
             $import_file = new ImportFileINI();
         } else {
             QconfMgrLog::err(__FILE__, __LINE__, "Should never be here! tmp_file_name({$tmp_file_name})!");
         }
     }
     // 7. previous validation
     $pre_ret = $import_file->preValidation($tmp_file_name);
     if ($pre_ret != 0) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_EXECUTABLE_ITEM);
         QconfMgrLog::err(__FILE__, __LINE__, "function reference exist in the configure file : {$file_name}!");
         echo json_encode($res);
         return FALSE;
     }
     $load_res = $import_file->load($tmp_file_name);
     if ($load_res === FALSE) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_LOAD_FAILED);
         QconfMgrLog::err(__FILE__, __LINE__, "failed load file! tmp_file_name({$tmp_file_name})!");
         echo json_encode($res);
         return;
     }
     $settings = $import_file->getAll();
     if (empty($settings)) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_EMPTY_ARRAY);
         QconfMgrLog::err(__FILE__, __LINE__, "empty config loaded! tmp_file_name({$tmp_file_name})!");
         echo json_encode($res);
         return;
     }
     // 7. semantic check
     $main_buss_id = $node["main_buss_id"];
     $check_res = ImportValidation::validation($settings, $parent_node_whole, $main_buss_id, $idc, $check_results);
     if ($check_res != InfoDescUtil::IMPORT_OK) {
         $res = InfoDescUtil::getErrorMsg($check_res);
         QconfMgrLog::err(__FILE__, __LINE__, "failed the semantic check! tmp_file_name({$tmp_file_name})!");
         echo json_encode($res);
         return;
     }
     // 8. generate inter file
     $inter_file_name = "{$tmp_file_dir}/{$file_id}." . InfoDescUtil::IMPORT_SUFFIX;
     $inter_file_content = array();
     $inter_file_content["settings"] = $check_results;
     $inter_file_content["idc"] = $idc;
     $write_res = file_put_contents($inter_file_name, json_encode($inter_file_content));
     if ($write_res === FALSE) {
         $res = InfoDescUtil::getErrorMsg(InfoDescUtil::ERR_IMPORT_FAILED_GENERATE_INTER);
         QconfMgrLog::err(__FILE__, __LINE__, "failed to generate inter file ! inter_file_name({$inter_file_name})!");
         echo json_encode($res);
         return;
     }
     $result = array();
     $has_repetition = "0";
     foreach ($check_results as $key => $value) {
         if ($value["status"] == "1") {
             $has_repetition = "1";
         }
         $result[] = array("key" => $key, "value" => $value["value"], "status" => $value["status"]);
     }
     // 9. return value
     $data = array("file_id" => $file_id, "has_repetition" => $has_repetition, "result" => $result);
     $res = array("errno" => "0", "errmsg" => "", "data" => $data);
     $json = json_encode($res);
     echo $json;
     return;
 }