requestTime = date('Ymd',time()); if (!isset($data)) { $this->userID = 'impex'; return array('success' => true); } if(is_object($data)){ $vars = get_object_vars($data); $this->isSoap = true; } else { $vars = $data; } if (isset($vars['userID'])){ $this->userID = $vars['userID']; IHMConfigClass::setUserName($this->userID); } else { $this->userID = 'impex'; } $this->sessionID = $this->userID; if (isset($vars['password'])) $this->userPWD = $vars['password']; else $this->userPWD = 'impexfp7'; return array('success' => true, 'vars' => $vars); } private function initUserMgr($setPathOnly = false) { $wsUserMgr = new WSUserMgr(); $wsUserMgr->init($this->userID, $this->userPWD, $this->sessionID, $setPathOnly, $this->isSoap); $this->IPclient = $wsUserMgr->getIPClient(); return array('success' => true); } private function throwError($errorType, $msg) { if ($this->isSoap) throw new SoapFault($errorType, $msg); else exit(json_encode(array("error" => $msg))); } private function isGetPlotRequest($name){ return (substr($name,0,7) == 'getplot'); } private function xsl2vot($inputName, $outputName) { // Load Time table $xml = new DomDocument("1.0"); if (!@$xml->load($inputName)) $this->throwError("wokrspaceError", "Cannot load time table $inputName for ".$this->userID); // Load XSL file $xsl = new DomDocument("1.0"); if (!@$xsl->load(WSConfigClass::getXslDir()."xml2vot.xsl")) $this->throwError("systemError", "Cannot load xsl file"); // Import XSL and write output file in vot format $xslt = new XSLTProcessor(); $xslt->importStylesheet($xsl); $vot = new DomDocument("1.0"); if (!@$vot->loadXML($xslt->transformToXML($xml))) $this->throwError("systemError", "Cannot convert time table to VOtable"); if (!$vot->save(WSConfigClass::getWsResultDir().$outputName)) $this->throwError("systemError", "Cannot save time table to result dir"); } private function getDatasetInfo($id) { $dataSetXml = WSConfigClass::getDataSetInfoDir().$id.".xml"; if (!file_exists($dataSetXml)) $this->throwError("systemError", "Cannot find info file for dataset ".$id); $dataSetDom = new DomDocument("1.0"); if (!@$dataSetDom->load($dataSetXml)) $this->throwError("systemError", "Cannot load info file for dataset ".$id); return $dataSetDom; } /* * get user TimeTables list; Shared for impex */ private function getTimeTablesCatalogsList($object) { $this->initUserMgr(); $dom = new DOMDocument("1.0"); if ($this->userID == 'impex') { $sharedObjMgr = new SharedObjectsMgr(); if (!@$dom->load($sharedObjMgr->getTreeFilePath())) $this->throwError("workspaceError", "Workspace Error : Cannot load Shared TimeTable list"); $tagName = $object == "timetables" ? "timeTableList" : "catalogList"; } else { if (!@$dom->load(USERWSDIR.'Tt.xml')) $this->throwError("workspaceError", "Workspace Error : Cannot load TimeTable list for ".$this->userID); $tagName = $object == "timetables" ? "timetabList" : "catalogList"; } $timetabNode = $dom->getElementsByTagName($tagName); if ($timetabNode->length < 1){ $this->throwError("workspaceWarning", "Workspace Warning : No $object"); } $outDOM = new DOMDocument("1.0"); $outDOM->formatOutput = TRUE; $outDOM->preserveWhiteSpace = FALSE; $newNode = $outDOM->importNode($timetabNode->item(0),TRUE); $outDOM->appendChild($newNode); $ttListResult = $object.'_'.$this->userID.'_'.$this->requestTime.'.xml'; if (!$outDOM->save(WSConfigClass::getWsResultDir().$ttListResult)) $this->throwError("workspaceError", "Workspace Error : problem while saving $object list file"); return WSConfigClass::getUrl().$ttListResult; } /* * Get corresponding orbit parameter ID */ private function getOrbitParameter($orbitRequest) { if (!file_exists(WSConfigClass::getOrbitsXml())) $this->throwError('systemError', "No AMDA system orbits file"); $orbitsXml = new DomDocument(); if (!@$orbitsXml->load(WSConfigClass::getOrbitsXml())) $this->throwError('systemError', "Cannot load AMDA system orbits file"); $spacecraft = strtolower($orbitRequest['spacecraft']); $spacecraft = str_replace('-', '', $spacecraft); $xpath = new DOMXpath($orbitsXml); $path = '//orbites[@mission="'.$spacecraft.'" and @coordinate_system="'.$orbitRequest['coordinateSystem'].'" and @units="'.$orbitRequest['units'].'" ] '; $orbits = $xpath->query($path); foreach ($orbits as $orbit) { $datasetID = strtr($orbit->getAttribute('dataset'),"_","-"); $dataSetDom = $this->getDatasetInfo($datasetID); $paramStart = strtotime($dataSetDom->getElementsByTagName('global_start')->item(0)->nodeValue); $paramStop = strtotime($dataSetDom->getElementsByTagName('global_stop')->item(0)->nodeValue); if(($paramStart <= strtotime($orbitRequest['startTime']) && (strtotime($orbitRequest['stopTime'])) <= $paramStop)) { return array('success' => true, 'parameterID' => $orbit->getAttribute('xml:id') ); } } $this->throwError('systemError', "Cannot find orbit data for ".$orbitRequest['spacecraft']." for ".$orbitRequest['startTime']."-".$orbitRequest['stopTime']." in ".$orbitRequest['units']." ".$orbitRequest['coordinateSystem']."($paramStart - $paramStop)"); } private function doDownloadRequest($interval, $paramList, $formatInfo) { if (!isset($this->paramLoader)) $this->paramLoader = new IHMUserParamLoaderClass(); //Build parameter list $params = array(); //TODO template arguments to implement ? foreach ($paramList['params'] as $paramId) { $param = new stdClass; if (preg_match("#^ws_#",$paramId)) { $res = $this->paramLoader->getDerivedParameterNameFromId($paramId); if (!$res["success"]) { $this->throwError("serverError", "Not available derived parameter $paramId"); } $param->paramid = "ws_".$res['name']; } else if (preg_match("#^wsd_#",$paramId)) { $res = $this->paramLoader->getUploadedParameterNameFromId($paramId); if (!$res["success"]){ $this->throwError("serverError", "Not available parameter $paramId"); } $param->paramid = "wsd_".$res['name']; } else { $param->paramid = $paramId; } $params[] = $param; } $obj = (object)array( "sampling" => $interval['sampling'], "startDate" => $interval['startTime'], "stopDate" => $interval['stopTime'], "list" => $params, "fileformat" => $formatInfo['format'], "timeformat" => $formatInfo['timeFormat'], "compression" => $formatInfo['gzip'] ); if (!isset($this->requestManager)) $this->requestManager = new RequestManagerClass(); try { $downloadResult = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::PARAMS, $this->service, $obj); } catch (Exception $e) { $this->throwError("executionError", "Exception detected : ".$e->getMessage()); } if (!$downloadResult['success']) { $this->throwError("serverError", $downloadResult['message']); } if($downloadResult['status'] == 'in_progress') { return ['success' => true, 'status' => 'in progress', 'id' => $downloadResult['id']]; } elseif ($downloadResult['status'] == 'done') { $this->deleteProcess($downloadResult['id']); return array('success' => true, 'status' => 'done', 'dataFileURLs' => WSConfigClass::getUrl().$downloadResult['result']); } else { return ['success' => false, 'message' => 'Unknown status ' . $downloadResult['status']]; } } /* * delete process after execution : * delete temporary files/folders ( JOBS/process_xxxx, RES/DDxxx ); * delete job node in processManager.xml */ private function deleteProcess($id) { $obj = (object)array('id' => $id); if (!isset($this->requestManager)) $this->requestManager = new RequestManagerClass(); try { $downloadResult = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::PROCESSDELETE, null, $obj); } catch (Exception $e) { $this->throwError("deleteProcessError", $e->getMessage()); } } /* * generate AUTH token for access to REST services */ public function getNewToken() { // generate token from timeStamp and some salt $newToken = md5(1321 * (int)( time() / WSConfigClass::$timeLimitQuery)); return array('success' => true, 'token' => $newToken); } private function excludePrivateNodes($locParamSrc, $locParamDst) { $locParamSrcDom = new DomDocument("1.0"); $locParamSrcDom->preserveWhiteSpace = FALSE; /// Important !!! otherwise removeChild() leaves empty text nodes if (!$locParamSrcDom->load($locParamSrc)) $this->throwError("getObsDataTree", "Cannot load Amda Local DataBase Parameters description file".$this->userID); $xp = new domxpath($locParamSrcDom); $restricted = $xp->query("//*[@group]"); foreach ($restricted as $node) { $parentNode = $node->parentNode; $parentNode->removeChild($node); if (!$parentNode->hasChildNodes()) { if ($parentNode->parentNode){ $parentParentNode = $parentNode->parentNode; $parentParentNode->removeChild($parentNode); } } } if (!$locParamSrcDom->save(WSConfigClass::getWsResultDir().$locParamDst)) $this->throwError('workspaceError', 'Cannot save Amda Local DataBase Parameters description file'.$this->userID); } /************************** WEB SERVICES **************************************/ /* * public data only : user impex */ public function getObsDataTree() { $res = $this->init(); $this->initUserMgr(); $locParamSrc = USERWSDIR.'LocalParams.xml'; $locParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_AmdaLocalDataBaseParameters.xml'; // if (!copy($locParamSrc,WSConfigClass::getWsResultDir().$locParamDst)) // $this->throwError('workspaceError', 'No Amda Local DataBase Parameters description file'); $this->excludePrivateNodes($locParamSrc,$locParamDst); return array('success' => true,'WorkSpace' => array("LocalDataBaseParameters" => WSConfigClass::getUrl().$locParamDst)); } /* * get Parameter List for given user */ public function getParameterList($data) { $res = $this->init($data); $this->initUserMgr(); $vars = $res['vars']; $locParamSrc = USERWSDIR.'LocalParams.xml'; $wsParamSrc = USERWSDIR.'WsParams.xml'; $locParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_AmdaLocalDataBaseParameters.xml'; $wsParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_UserDefinedParameters.xml'; // if (!copy($locParamSrc, WSConfigClass::getWsResultDir().$locParamDst)) // $this->throwError('workspaceError', 'No Amda Local DataBase Parameters description file for '.$this->userID); $this->excludePrivateNodes($locParamSrc,$locParamDst); if (!copy($wsParamSrc, WSConfigClass::getWsResultDir().$wsParamDst)) return array('success' => true,'ParameterList' => array("LocalDataBaseParameters" => WSConfigClass::getUrl().$locParamDst)); return array('success' => true,'ParameterList' => array("UserDefinedParameters" => WSConfigClass::getUrl().$wsParamDst, "LocalDataBaseParameters" => WSConfigClass::getUrl().$locParamDst)); } /* * getParameter */ public function getParameter($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $this->initUserMgr(); $vars = $res['vars']; if (strtotime($vars["stopTime"]) <= strtotime($vars["startTime"])){ $this->throwError("requestError", "Requested time interval should be greater than 0"); } $paramId = array(); array_push($paramId, $vars["parameterID"]); if (!$vars["timeFormat"]) $timeFormat = "ISO8601"; else $timeFormat = $vars["timeFormat"]; if (!$vars["gzip"]) $gzip = 0; else $gzip = $vars["gzip"]; if (!$vars["stream"]) $stream = 0; else $stream = $vars["stream"]; $this->service = strtolower(__FUNCTION__); $res = $this->doDownloadRequest( array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "sampling" => $vars["sampling"]), array("params" => $paramId), array("format" => $vars["outputFormat"], "timeFormat"=> $timeFormat, "gzip"=>$gzip, "stream"=>$stream)); if ($res['success']) return $res; $this->throwError("serverError", $res['message']); } /* * get user Catalogs list; Shared for impex */ public function getCatalogsList($data) { $this->init($data); return array('success' => true, 'CatalogsList' => $this->getTimeTablesCatalogsList('catalogs')); } /* * get user TimeTables list; Shared for impex */ public function getTimeTablesList($data) { $this->init($data); return array('success' => true, 'TimeTablesList' => $this->getTimeTablesCatalogsList('timetables')); } public function isAlive() { return true; } /* * get Dataset */ public function getDataset($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $this->initUserMgr(); $vars = $res['vars']; if (strtotime($vars["stopTime"]) <= strtotime($vars["startTime"])){ $this->throwError("requestError", "Requested time interval should be greater than 0"); } $dataSetDom = $this->getDatasetInfo($vars['datasetID']); $params = $dataSetDom->getElementsByTagName("parameter"); if ($params->length == 0) $this->throwError("systemError", "Cannot find parameter list for dataset ".$vars['datasetID']); $paramId = array(); foreach ($params as $p) $paramId[] = $p->nodeValue; if (!$vars["sampling"]) { $sampling = $dataSetDom->getElementsByTagName('min_sampling')->item(0)->nodeValue; $units = substr($sampling,-1); $sampling = substr($sampling,0,strlen($sampling)-1); switch ($units) { // case 'S': // $sampling = floatval($sampling); // break; case 'M': $sampling = floatval($sampling)*60; break; case 'H': $sampling = floatval($sampling)*60*60; break; default: } } else { $sampling = $vars["sampling"]; } if (!$vars["timeFormat"]) $timeFormat = "ISO8601"; else $timeFormat = $vars["timeFormat"]; if (!$vars["gzip"]) $gzip = 0; else $gzip = $vars["gzip"]; if (!$vars["stream"]) $stream = 0; else $stream = $vars["stream"]; $this->service = strtolower(__FUNCTION__); $res = $this->doDownloadRequest( array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "sampling" => $sampling), array("params" => $paramId), array("format" => $vars["outputFormat"], "timeFormat"=> $timeFormat, "gzip"=>$gzip, "stream"=>$stream)); if ($res['success']) return $res; $this->throwError("serverError", $res['message']); } /* * get status for jobs in batch */ public function getStatus($data) { $result = $this->init($data); $id = $result['vars']['id']; if (!isset($this->requestManager)) $this->requestManager = new RequestManagerClass(); try { $res = $this->requestManager->runWSRequest('nobody', 'nobody', FunctionTypeEnumClass::PROCESSGETINFO, null, $id); } catch (Exception $e) { // after first getStatus() call process is deleted $jobsManager = new WSJobsManagerClass(); try { $res = $jobsManager->getResultFromProcessId($id); if (!$res['success']) { $this->throwError("processError","Cannot retrieve process $id info"); } $resultTag = $this->isGetPlotRequest($res['result']) ? 'plotURL' : 'dataFileURLs'; return array('success' => true, 'status' => 'done', $resultTag => WSConfigClass::getUrl().$res['result']); } catch (Exception $e) { $this->throwError("getResultFromProcessIdError", "Exception detected : ".$e->getMessage()); } } if (!$res['success']) { $this->throwError("processError","Cannot retrieve process $id info"); } if ($res['status'] == 'in_progress') { return array('success' => true, 'status' => 'in progress'); } if ($res['error']) { $this->throwError("processError","Process $id error code"); } $this->deleteProcess($res['id']); $resultTag = $this->isGetPlotRequest($res['result']) ? 'plotURL' : 'dataFileURLs'; return array('success' => true, 'status' => $res['status'], $resultTag => WSConfigClass::getUrl().$res['result']); } /* * TODO Can be done by TTCONVERT function of AMDA_Kernel - more hard !!! * TODO Think about this if merge/union will be also done by AMDA_Kernel * * get Time Table : shared for impex ; user' for user */ public function getTimeTable($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $this->initUserMgr(); $ttID = $res['vars']['ttID']; if ($this->userID == 'impex') { $sharedObjMgr = new SharedObjectsMgr(); $ttSrc = $sharedObjMgr->getDataFilePath('timeTable', $ttID); } else $ttSrc = USERTTDIR.$ttID.'.xml'; if (!file_exists($ttSrc)) { $this->throwError("workspaceError", "No such table ".$ttID." for user ".$this->userID); } $ttDst = substr(strtolower(__FUNCTION__), 3)."_".$this->userID."_".$this->requestTime."_$ttID.xml"; //TODO can be done by // $res = $this->requestManager->runWSRequest($this->userID, $this->IPclient,FunctionTypeEnumClass::TTCONVERT, null, $ttID); $this->xsl2vot($ttSrc,$ttDst); return array('success' => true, 'ttFileURL' => WSConfigClass::getUrl().$ttDst); } /* * get Orbits */ public function getOrbites($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $this->initUserMgr(); $vars = $res['vars']; if (strtotime($vars["stopTime"]) <= strtotime($vars["startTime"])){ $this->throwError("requestError", "Requested time interval should be greater than 0"); } $spacecraft = $vars["spacecraft"]; $coordinateSystem = $vars["coordinateSystem"]; if (!$vars["units"]) $units = "km"; else $units = $vars["units"]; $orbitRequest = array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "spacecraft" => $spacecraft, "coordinateSystem" => $coordinateSystem, "units" => $units ); $orbitParam = $this->getOrbitParameter($orbitRequest); $paramId = array(); array_push($paramId, $orbitParam['parameterID']); if (!$vars["timeFormat"]) $timeFormat = "ISO8601"; else $timeFormat = $vars["timeFormat"]; if (!$vars["gzip"]) $gzip = 0; else $gzip = $vars["gzip"]; $this->service = strtolower(__FUNCTION__); $res = $this->doDownloadRequest( array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "sampling" => $vars["sampling"]), array("params" => $paramId), array("format" => $vars["outputFormat"], "timeFormat"=> $timeFormat, "gzip"=>$gzip, "stream"=>$stream)); if ($res['success']) return $res; $this->throwError("serverError",$res['message']); } /* * getPlot : predefined; by mission */ public function getPlot($data) { $res = $this->init($data); if (!$res['success']){ $this->throwError("requestError", "Cannot parse request"); } $this->initUserMgr(); $vars = $res['vars']; $mission = $vars["missionID"]; $resultFilePrefix = strtolower(__FUNCTION__)."_".$mission."_".date("YmdHms",strtotime($vars["startTime"]))."_".date("YmdHms",strtotime($vars["stopTime"])); if ($this->userID != "impex") $resultFilePrefix .= "_".$this->userID; $dom = new DomDocument("1.0"); if (!@$dom->load(WSConfigClass::getXslDir()."AmdaPlots.xml")) $this->throwError("systemError", "Cannot load predefined plot definition"); ; $missionTag = $dom->getElementById($mission); $params = $missionTag->getElementsByTagName('param'); $paramsList = array(); foreach ($params as $param) $paramsList[] = $param->getAttribute('name'); $requestObject = (Object) array( "nodeType" => "request", "file-format" => "PNG", "result-file" => $resultFilePrefix, "timesrc" => "Interval", "startDate" => $vars["startTime"], "stopDate" => $vars["stopTime"], "parameters" => array() ); foreach ($paramsList as $paramToPlot) { $paramObject = (Object) array( "paramid" => $paramToPlot ); $requestObject->{"parameters"}[] = $paramObject; } $this->service = strtolower(__FUNCTION__); if (!isset($this->requestManager)) $this->requestManager = new RequestManagerClass(); try { $plotResult = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::PARAMS, $this->service, $requestObject); } catch (Exception $e) { $this->throwError("plotError", "Exeption detected : ".$e->getMessage()); } if (!$plotResult['success']) { $this->throwError("serverError", $plotResult['message']); } if($plotResult['status'] == 'in_progress') { return ['success' => true, 'status' => 'in progress', 'id' => $plotResult['id']]; } elseif ($plotResult['status'] == 'done') { $this->deleteProcess($plotResult['id']); return array('success' => true, 'status' => 'done', 'plotFileURL' => WSConfigClass::getUrl().$plotResult['result']); } else { return ['success' => false, 'message' => 'Unknown status ' . $plotResult['status']]; } } } ?>