blob: 1598ebaafdac99e13843c19c873fccc5675aa679 [file] [log] [blame]
<?php
use Airavata\API\Error\AiravataClientException;
use Airavata\API\Error\AiravataSystemException;
use Airavata\API\Error\ExperimentNotFoundException;
use Airavata\API\Error\InvalidRequestException;
use Airavata\Facades\Airavata;
use Airavata\Model\Application\Io\DataType;
use Airavata\Model\AppCatalog\AppInterface\ApplicationInterfaceDescription;
use Airavata\Model\Application\Io\InputDataObjectType;
use Airavata\Model\Scheduling\ComputationalResourceSchedulingModel;
use Airavata\Model\Experiment\ExperimentModel;
use Airavata\Model\Status\ExperimentState;
use Airavata\Model\Status\ProcessState;
use Airavata\Model\Status\JobState;
use Airavata\Model\Status\TaskState;
use Airavata\Model\Task\TaskTypes;
use Airavata\Model\Experiment\UserConfigurationDataModel;
class ExperimentUtilities
{
private static $experimentPath;
private static $relativeExperimentDataDir;
/**
* Launch the experiment with the given ID
* @param $expId
*/
public static function launch_experiment($expId)
{
try {
$gatewayId = Config::get('pga_config.airavata')['gateway-id'];
Airavata::launchExperiment(Session::get('authz-token'), $expId, $gatewayId);
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('<p>There was a problem launching the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>InvalidRequestException: ' . $ire->getMessage() . '</p>');
} catch (ExperimentNotFoundException $enf) {
CommonUtilities::print_error_message('<p>There was a problem launching the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>ExperimentNotFoundException: ' . $enf->getMessage() . '</p>');
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('<p>There was a problem launching the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataClientException: ' . $ace->getMessage() . '</p>');
} catch (AiravataSystemException $ase) {
CommonUtilities::print_error_message('<p>There was a problem launching the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataSystemException: ' . $ase->getMessage() . '</p>');
} catch (Exception $e) {
CommonUtilities::print_error_message('<p>There was a problem launching the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>Exception: ' . $e->getMessage() . '</p>');
}
}
/**
* List the experiment's input files
* @param $experiment
*/
public static function list_input_files($experimentInputs)
{
//$experimentInputs = $experiment->experimentInputs;
//showing experiment inputs in the order defined by the admins.
$order = array();
foreach ($experimentInputs as $index => $input) {
$order[$index] = $input->inputOrder;
}
array_multisort($order, SORT_ASC, $experimentInputs);
foreach ($experimentInputs as $input) {
$matchingAppInput = null;
if ($input->type == DataType::URI && empty($input->metaData)) {
$inputArray = explode('/', $input->value);
echo '<p><a target="_blank"
href="' . URL::to("/") . '/download/' . $inputArray[ count($inputArray)-2] . '/' .
$inputArray[ count($inputArray)-1] . '">' .
$inputArray[ count($inputArray)-1] . '
<span class="glyphicon glyphicon-new-window"></span></a></p>';
}elseif($input->type == DataType::URI && !empty($input->metaData)
&& json_decode($input->metaData)->location=="remote"){
echo '<p>' . $input->name . ': ' . $input->value . '</p>';
}elseif ($input->type == DataType::STRING || $input->type == DataType::INTEGER
|| $input->type == DataType::FLOAT) {
echo '<p>' . $input->name . ': ' . $input->value . '</p>';
}
}
}
/**
* Get the experiment with the given ID
* @param $expId
* @return null
*/
public static function get_experiment($expId)
{
try {
return Airavata::getExperiment(Session::get('authz-token'), $expId);
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>InvalidRequestException: ' . $ire->getMessage() . '</p>');
} catch (ExperimentNotFoundException $enf) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>ExperimentNotFoundException: ' . $enf->getMessage() . '</p>');
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataClientException: ' . $ace->getMessage() . '</p>');
} catch (AiravataSystemException $ase) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataSystemException: ' . $ase->getMessage() . '</p>');
} catch (TTransportException $tte) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>TTransportException: ' . $tte->getMessage() . '</p>');
} catch (Exception $e) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>Exception: ' . $e->getMessage() . '</p>');
}
}
/**
* Get the detailed tree of an experiment with the given ID
* @param $expId
* @return null
*/
public static function get_detailed_experiment($expId)
{
try {
return Airavata::getDetailedExperimentTree(Session::get('authz-token'), $expId);
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>InvalidRequestException: ' . $ire->getMessage() . '</p>');
} catch (ExperimentNotFoundException $enf) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>ExperimentNotFoundException: ' . $enf->getMessage() . '</p>');
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataClientException: ' . $ace->getMessage() . '</p>');
} catch (AiravataSystemException $ase) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataSystemException: ' . $ase->getMessage() . '</p>');
} catch (TTransportException $tte) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>TTransportException: ' . $tte->getMessage() . '</p>');
} catch (Exception $e) {
CommonUtilities::print_error_message('<p>There was a problem getting the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>Exception: ' . $e->getMessage() . '</p>');
}
}
/**
* Create and configure a new Experiment
* @return Experiment
*/
public static function assemble_experiment()
{
$experimentInputs = array();
$scheduling = new ComputationalResourceSchedulingModel();
$scheduling->totalCPUCount = $_POST['cpu-count'];
$scheduling->nodeCount = $_POST['node-count'];
$scheduling->queueName = $_POST['queue-name'];
$scheduling->wallTimeLimit = $_POST['wall-time'];
$scheduling->totalPhysicalMemory = $_POST['total-physical-memory'];
$scheduling->resourceHostId = $_POST['compute-resource'];
$scheduling->staticWorkingDir = $_POST['static-working-dir'];
$userConfigData = new UserConfigurationDataModel();
$userConfigData->computationalResourceScheduling = $scheduling;
$userConfigData->storageId = Config::get('pga_config.airavata')['gateway-data-store-resource-id'];
$userConfigData->airavataAutoSchedule = isset($_POST['enable-auto-scheduling']) ? true : false;
if (isset($_POST["userDN"])) {
$userConfigData->generateCert = 1;
$userConfigData->userDN = $_POST["userDN"];
}
$applicationInputs = AppUtilities::get_application_inputs($_POST['application']);
$experimentInputs = ExperimentUtilities::process_inputs($applicationInputs, $experimentInputs);
if (ExperimentUtilities::$experimentPath == null) {
ExperimentUtilities::create_experiment_folder_path();
}
$userConfigData->experimentDataDir = ExperimentUtilities::$relativeExperimentDataDir;
$experiment = new ExperimentModel();
// required
$experiment->projectId = $_POST['project'];
$experiment->userName = Session::get('username');
$experiment->name = $_POST['experiment-name'];
$experiment->gatewayId = Config::get('pga_config.airavata')['gateway-id'];
$experiment->experimentName = $_POST['experiment-name'];
// optional
$experiment->description = $_POST['experiment-description'];
$experiment->executionId = $_POST['application'];
$experiment->userConfigurationData = $userConfigData;
$experiment->experimentInputs = $experimentInputs;
if (isset($_POST["enableEmailNotification"])) {
$experiment->enableEmailNotification = intval($_POST["enableEmailNotification"]);
$experiment->emailAddresses = array_unique(array_filter($_POST["emailAddresses"], "trim"));
}
// adding default experiment outputs for now till prepoulated experiment template is not implemented.
$experiment->experimentOutputs = AppUtilities::get_application_outputs($_POST["application"]);
if ($experimentInputs) {
return $experiment;
}
}
/**
* @param $applicationInputs
* @param $experimentInputs
* @internal param $environmentPath
* @return array
*/
public static function process_inputs($applicationInputs, $experimentInputs)
{
$experimentAssemblySuccessful = true;
$newExperimentInputs = array();
//var_dump($_FILES);
if (sizeof($_FILES) > 0) {
if (ExperimentUtilities::file_upload_successful()) {
// construct unique path
ExperimentUtilities::create_experiment_folder_path();
} else {
$experimentAssemblySuccessful = false;
}
}
//sending application inputs in the order defined by the admins.
$order = array();
foreach ($applicationInputs as $index => $input) {
$order[$index] = $input->inputOrder;
}
array_multisort($order, SORT_ASC, $applicationInputs);
foreach ($applicationInputs as $applicationInput) {
$experimentInput = new InputDataObjectType();
$experimentInput = $applicationInput;
//$experimentInput->name = $applicationInput->name;
//$experimentInput->metaData = $applicationInput->metaData;
//$experimentInput->type = $applicationInput->type;
//$experimentInput->type = DataType::STRING;
if (($applicationInput->type == DataType::STRING) ||
($applicationInput->type == DataType::INTEGER) ||
($applicationInput->type == DataType::FLOAT) ||
($applicationInput->type == DataType::URI && !empty($applicationInput->metaData)
&& json_decode($applicationInput->metaData)->location=="remote")
) {
if (isset($_POST[$applicationInput->name]) && (trim($_POST[$applicationInput->name]) != '')) {
$experimentInput->value = $_POST[$applicationInput->name];
$experimentInput->type = $applicationInput->type;
} else // use previous value
{
$index = -1;
for ($i = 0; $i < sizeof($experimentInputs); $i++) {
if ($experimentInputs[$i]->name == $applicationInput->name) {
$index = $i;
}
}
if ($index >= 0) {
$experimentInput->value = $experimentInputs[$index]->value;
$experimentInput->type = $applicationInput->type;
}
}
} elseif ($applicationInput->type == DataType::URI) {
//var_dump($_FILES[$applicationInput->name]->name);
if ($_FILES[$applicationInput->name]['name']) {
$file = $_FILES[$applicationInput->name];
//
// move file to experiment data directory
//
if(!empty($applicationInput->value)){
$filePath = ExperimentUtilities::$experimentPath . $applicationInput->value;
}else{
$filePath = ExperimentUtilities::$experimentPath . $file['name'];
}
// check if file already exists
if (is_file($filePath)) {
unlink($filePath);
CommonUtilities::print_warning_message('Uploaded file already exists! Overwriting...');
}
$moveFile = move_uploaded_file($file['tmp_name'], $filePath);
if ($moveFile) {
CommonUtilities::print_success_message('Upload: ' . $file['name'] . '<br>' .
'Type: ' . $file['type'] . '<br>' .
'Size: ' . ($file['size'] / 1024) . ' kB');
//<br>' .
//'Stored in: ' . $experimentPath . $file['name']);
} else {
CommonUtilities::print_error_message('<p>Error moving uploaded file ' . $file['name'] . '!
Please try again later or report a bug using the link in the Help menu.</p>');
$experimentAssemblySuccessful = false;
}
$hostName = $_SERVER['SERVER_NAME'];
$experimentInput->value = 'file://' . Config::get('pga_config.airavata')['ssh-user'] . '@' . $hostName . ':' . $filePath;
$experimentInput->type = $applicationInput->type;
} else {
$index = -1;
for ($i = 0; $i < sizeof($experimentInputs); $i++) {
if ($experimentInputs[$i]->name == $applicationInput->name) {
$index = $i;
}
}
if ($index >= 0) {
$experimentInput->value = $experimentInputs[$index]->value;
$experimentInput->type = $applicationInput->type;
}
}
} else {
CommonUtilities::print_error_message('I cannot accept this input type yet!');
}
$newExperimentInputs[] = $experimentInput;
}
if ($experimentAssemblySuccessful) {
return $newExperimentInputs;
} else {
return false;
}
}
public static function create_experiment_folder_path()
{
do {
ExperimentUtilities::$relativeExperimentDataDir = "/" . Session::get('username') . "/" . md5(rand() * time()) . '/';
ExperimentUtilities::$experimentPath = Config::get('pga_config.airavata')['experiment-data-absolute-path'] .
ExperimentUtilities::$relativeExperimentDataDir;
} while (is_dir(ExperimentUtilities::$experimentPath)); // if dir already exists, try again
// create upload directory
if (!mkdir(ExperimentUtilities::$experimentPath, 0777, true)) {
CommonUtilities::print_error_message('<p>Error creating upload directory!
Please try again later or report a bug using the link in the Help menu.</p>');
$experimentAssemblySuccessful = false;
}
}
/**
* Check the uploaded files for errors
*/
public static function file_upload_successful()
{
$uploadSuccessful = true;
foreach ($_FILES as $file) {
//var_dump($file);
if ($file['name']) {
if ($file['error'] > 0) {
$uploadSuccessful = false;
CommonUtilities::print_error_message('<p>Error uploading file ' . $file['name'] . ' !
Please try again later or report a bug using the link in the Help menu.');
}
}
}
return $uploadSuccessful;
}
/**
* Update the experiment with the given ID
* @param $expId
* @param $updatedExperiment
*/
public static function update_experiment($expId, $updatedExperiment)
{
try {
Airavata::updateExperiment(Session::get('authz-token'), $expId, $updatedExperiment);
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('<p>There was a problem updating the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>InvalidRequestException: ' . $ire->getMessage() . '</p>');
} catch (ExperimentNotFoundException $enf) {
CommonUtilities::print_error_message('<p>There was a problem updating the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>ExperimentNotFoundException: ' . $enf->getMessage() . '</p>');
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('<p>There was a problem updating the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataClientException: ' . $ace->getMessage() . '</p>');
} catch (AiravataSystemException $ase) {
CommonUtilities::print_error_message('<p>There was a problem updating the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataSystemException: ' . $ase->getMessage() . '</p>');
}
}
/**
* Clone the experiment with the given ID
* @param $expId
*/
public static function clone_experiment($expId)
{
try {
//create new experiment to receive the clone
$experiment = Airavata::getExperiment(Session::get('authz-token'), $expId);
$cloneId = Airavata::cloneExperiment(Session::get('authz-token'), $expId, 'Clone of ' . $experiment->experimentName);
//updating the experiment inputs and output path
$experiment = Airavata::getExperiment(Session::get('authz-token'), $cloneId);
$experimentInputs = $experiment->experimentInputs;
ExperimentUtilities::create_experiment_folder_path();
$hostName = $_SERVER['SERVER_NAME'];
foreach ($experimentInputs as $experimentInput) {
if ($experimentInput->type == DataType::URI) {
$currentInputPath = $experimentInput->value;
$hostPathConstant = 'file://' . Config::get('pga_config.airavata')['ssh-user'] . '@' . $hostName . ':';
$currentInputPath = str_replace($hostPathConstant, '', $currentInputPath);
$parts = explode('/', rtrim($currentInputPath, '/'));
$fileName = array_pop($parts);
$newInputPath = ExperimentUtilities::$experimentPath . $fileName;
copy($currentInputPath, $newInputPath);
$experimentInput->value = $hostPathConstant . $newInputPath;
}
}
$experiment->userConfigurationData->experimentDataDir = ExperimentUtilities::$relativeExperimentDataDir;
Airavata::updateExperiment(Session::get('authz-token'), $cloneId, $experiment);
return $cloneId;
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('<p>There was a problem cloning the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>InvalidRequestException: ' . $ire->getMessage() . '</p>');
} catch (ExperimentNotFoundException $enf) {
CommonUtilities::print_error_message('<p>There was a problem cloning the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>ExperimentNotFoundException: ' . $enf->getMessage() . '</p>');
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('<p>There was a problem cloning the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataClientException: ' . $ace->getMessage() . '</p>');
} catch (AiravataSystemException $ase) {
CommonUtilities::print_error_message('<p>There was a problem cloning the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataSystemException: ' . $ase->getMessage() . '</p>');
} catch (TTransportException $tte) {
CommonUtilities::print_error_message('<p>There was a problem cloning the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>TTransportException: ' . $tte->getMessage() . '</p>');
}
}
/**
* Cancel the experiment with the given ID
* @param $expId
*/
public static function cancel_experiment($expId)
{
try {
Airavata::terminateExperiment(Session::get('authz-token'), $expId, Config::get('pga_config.airavata')["gateway-id"]);
CommonUtilities::print_success_message("Experiment canceled!");
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('<p>There was a problem canceling the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>InvalidRequestException: ' . $ire->getMessage() . '</p>');
} catch (ExperimentNotFoundException $enf) {
CommonUtilities::print_error_message('<p>There was a problem canceling the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>ExperimentNotFoundException: ' . $enf->getMessage() . '</p>');
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('<p>There was a problem canceling the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataClientException: ' . $ace->getMessage() . '</p>');
} catch (AiravataSystemException $ase) {
CommonUtilities::print_error_message('<p>There was a problem canceling the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>AiravataSystemException: ' . $ase->getMessage() . '</p>');
} catch (TTransportException $tte) {
CommonUtilities::print_error_message('<p>There was a problem canceling the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>TTransportException: ' . $tte->getMessage() . '</p>');
} catch (Exception $e) {
CommonUtilities::print_error_message('<p>There was a problem canceling the experiment.
Please try again later or submit a bug report using the link in the Help menu.</p>' .
'<p>Exception: ' . $e->getMessage() . '</p>');
}
}
/**
* Create form inputs to accept the inputs to the given application
* @param $id
* @param $isRequired
* @internal param $required
*/
public static function create_inputs($id, $isRequired)
{
$inputs = AppUtilities::get_application_inputs($id);
$required = $isRequired ? ' required' : '';
//var_dump( $inputs); echo "<br/>after sort<br/>";
//arranging inputs in ascending order.
foreach ($inputs as $index => $input) {
$order[$index] = $input->inputOrder;
}
if($inputs != null){
array_multisort($order, SORT_ASC, $inputs);
}
//var_dump( $inputs); exit;
foreach ($inputs as $input) {
switch ($input->type) {
case DataType::STRING:
echo '<div class="form-group">
<label for="experiment-input">' . $input->name . '</label>
<input value="' . $input->value . '" type="text" class="form-control" name="' . $input->name .
'" id="' . $input->name .
'" placeholder="' . $input->userFriendlyDescription . '"' . $required . '>
</div>';
break;
case DataType::INTEGER:
echo '<div class="form-group">
<label for="experiment-input">' . $input->name . '</label>
<input value="' . $input->value . '" type="number" class="form-control" name="' . $input->name .
'" id="' . $input->name .
'" placeholder="' . $input->userFriendlyDescription . '"' . $required . '>
</div>';
break;
case DataType::FLOAT:
echo '<div class="form-group">
<label for="experiment-input">' . $input->name . '</label>
<input value="' . $input->value . '" type="number" step="0.01" class="form-control" name="' . $input->name .
'" id="' . $input->name .
'" placeholder="' . $input->userFriendlyDescription . '"' . $required . '>
</div>';
break;
case DataType::URI:
if(!empty($input->metaData) && json_decode($input->metaData)->location == "remote"){
echo '<div class="form-group">
<label for="experiment-input">' . $input->name . '</label>
<input class="form-control" type="text" name="' . $input->name .
'" id="' . $input->name . '" ' . $required . '>
<p class="help-block">' . $input->userFriendlyDescription . '</p>
</div>';
break;
}else{
echo '<div class="form-group">
<label for="experiment-input">' . $input->name . '</label>
<div data-file-id="' . $input->name . '" class="readBytesButtons btn btn-default btn-xs"
data-toggle="modal" style="float: right">view file</div>
<input class="file-input" type="file" name="' . $input->name .
'" id="' . $input->name . '" ' . $required . '>
<p class="help-block">' . $input->userFriendlyDescription . '</p>
</div>';
break;
}
default:
CommonUtilities::print_error_message('Input data type not supported!
Please file a bug report using the link in the Help menu.');
break;
}
}
}
/**
* Create a new experiment from the values submitted in the form
* @return null
*/
public static function create_experiment()
{
$experiment = ExperimentUtilities::assemble_experiment();
$expId = null;
try {
if ($experiment) {
$expId = Airavata::createExperiment(Session::get('authz-token'), Session::get("gateway_id"), $experiment);
}
if ($expId) {
/*
CommonUtilities::print_success_message("Experiment {$_POST['experiment-name']} created!" .
' <a href="experiment_summary.php?expId=' . $expId . '">Go to experiment summary page</a>');
*/
} else {
CommonUtilities::print_error_message("Error creating experiment {$_POST['experiment-name']}!");
}
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('InvalidRequestException!<br><br>' . $ire->getMessage());
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('AiravataClientException!<br><br>' . $ace->getMessage());
} catch (AiravataSystemException $ase) {
CommonUtilities::print_error_message('AiravataSystemException!<br><br>' . $ase->getMessage());
}
return $expId;
}
/*
* Required in Experiment Sumamry page.
*
*/
public static function list_output_files($outputs, $status, $process)
{
if( $process)
{
$processStatusVal = array_search($status, ProcessState::$__names);
if ($status != ProcessState::COMPLETED)
echo "Process hasn't completed. Process Status is : " . ProcessState::$__names[ $status] . '<br/>';
}
else
{
$expStatusVal = array_search($status, ExperimentState::$__names);
if ( $status != ExperimentState::COMPLETED)
echo "Experiment hasn't completed. Experiment Status is : " . ExperimentState::$__names[ $status] . '<br/>';
}
//$outputs = $experiment->experimentOutputs;
//print_r( $outputs); exit;
foreach ((array)$outputs as $output) {
if ($output->type == DataType::URI || $output->type == DataType::STDOUT || $output->type == DataType::STDERR) {
if(file_exists(str_replace('//','/',$output->value))){
$outputPathArray = explode("/", $output->value);
echo '<p>' . $output->name . ' : ' . '<a target="_blank"
href="' . URL::to("/") . '/download/' . $outputPathArray[ count($outputPathArray)-3] . "/" . $outputPathArray[ count($outputPathArray)-2] . '/' .
$outputPathArray[ count($outputPathArray)-1] . '">' .
$outputPathArray[sizeof($outputPathArray) - 1] . ' <span class="glyphicon glyphicon-new-window"></span></a></p>';
}
// else
// echo 'Output paths are not correctly defined for : <br/>' . $output->name . '<br/><br/> Please report this issue to the admin<br/><br/>';
}
elseif ($output->type == DataType::STRING) {
echo '<p>' . $output->value . '</p>';
}
else
echo 'output : '. $output;
//echo 'output-type : ' . $output->type;
}
}
public static function get_experiment_summary_values($experimentSummary, $forSearch = false)
{
// var_dump( $experimentSummary); exit;
$expVal = array();
$expVal["experimentStatusString"] = "";
$expVal["experimentTimeOfStateChange"] = "";
$expVal["experimentCreationTime"] = "";
$expVal["experimentStatusString"] = $experimentSummary->experimentStatus;
$expVal["experimentTimeOfStateChange"] = $experimentSummary->statusUpdateTime / 1000; // divide by 1000 since timeOfStateChange is in ms
$expVal["experimentCreationTime"] = $experimentSummary->creationTime / 1000; // divide by 1000 since creationTime is in ms
if (!$forSearch) {
$userConfigData = $experimentSummary->userConfigurationData;
$scheduling = $userConfigData->computationalResourceScheduling;
$expVal['scheduling'] = $scheduling;
try {
$expVal["computeResource"] = CRUtilities::get_compute_resource($scheduling->resourceHostId);
} catch (Exception $ex) {
//Error while retrieving CR
$expVal["computeResource"] = "";
}
}
try{
$expVal["applicationInterface"] = AppUtilities::get_application_interface($experimentSummary->executionId);
}catch (Exception $ex){
//Failed retrieving Application Interface (May be it's deleted) Fix for Airavata-1801
$expVal["applicationInterface"] = new ApplicationInterfaceDescription();
$expVal["applicationInterface"]->applicationName = substr($experimentSummary->executionId, -8);
}
switch ($experimentSummary->experimentStatus) {
case 'CREATED':
case 'VALIDATED':
case 'SCHEDULED':
case 'FAILED':
$expVal["editable"] = true;
break;
default:
$expVal["editable"] = false;
break;
}
switch ($experimentSummary->experimentStatus) {
case 'CREATED':
case 'VALIDATED':
case 'SCHEDULED':
case 'LAUNCHED':
case 'EXECUTING':
$expVal["cancelable"] = true;
break;
default:
$expVal["cancelable"] = false;
break;
}
return $expVal;
}
public static function get_experiment_values($experiment, $project, $forSearch = false)
{
$expVal = array();
//$expVal["experimentStatusString"] = "";
$expVal["experimentTimeOfStateChange"] = "";
$expVal["experimentCreationTime"] = "";
$expVal["experimentStates"] = ExperimentState::$__names;
$expVal["processStates"] = ProcessState::$__names;
$expVal["jobStates"] = JobState::$__names;
$expVal["taskStates"] = TaskState::$__names;
$expVal["taskTypes"] = TaskTypes::$__names;
$experimentStatusString = $expVal["experimentStates"][$experiment->experimentStatus->state];
$expVal["experimentStatusString"] = $experimentStatusString;
if ( $experimentStatusString == ExperimentState::FAILED)
$expVal["editable"] = false;
$expVal["cancelable"] = false;
if ( $experimentStatusString == ExperimentState::LAUNCHED
|| $experimentStatusString == ExperimentState::EXECUTING)
$expVal["cancelable"] = true;
if ($experiment->experimentStatus != null) {
$experimentStatus = $experiment->experimentStatus;
/*
$experimentState = $experimentStatus->state;
$experimentStatusString = ExperimentState::$__names[$experimentState];
$expVal["experimentStatusString"] = $experimentStatusString;
*/
$expVal["experimentTimeOfStateChange"] = $experimentStatus->timeOfStateChange / 1000; // divide by 1000 since timeOfStateChange is in ms
$expVal["experimentCreationTime"] = $experiment->creationTime / 1000; // divide by 1000 since creationTime is in ms
}
if (!$forSearch) {
$userConfigData = $experiment->userConfigurationData;
$scheduling = $userConfigData->computationalResourceScheduling;
$expVal['scheduling'] = $scheduling;
try {
$expVal["computeResource"] = CRUtilities::get_compute_resource($scheduling->resourceHostId);
} catch (Exception $ex) {
//Error while retrieving CR
$expVal["computeResource"] = "";
}
}
try{
$expVal["applicationInterface"] = AppUtilities::get_application_interface($experiment->executionId);
}catch (Exception $ex){
//Failed retrieving Application Interface (May be it's deleted) Fix for Airavata-1801
$expVal["applicationInterface"] = new ApplicationInterfaceDescription();
$expVal["applicationInterface"]->applicationName = substr($experiment->executionId, -8);
}
switch (ExperimentState::$__names[$experiment->experimentStatus->state]) {
case 'CREATED':
case 'VALIDATED':
case 'SCHEDULED':
case 'FAILED':
$expVal["editable"] = true;
break;
default:
$expVal["editable"] = false;
break;
}
switch (ExperimentState::$__names[$experiment->experimentStatus->state]) {
case 'VALIDATED':
case 'SCHEDULED':
case 'LAUNCHED':
case 'EXECUTING':
$expVal["cancelable"] = true;
break;
default:
$expVal["cancelable"] = false;
break;
}
return $expVal;
}
/**
* Method to get the job status of an experiment
* @param $experiment
* @return null
*/
public static function get_job_status(ExperimentModel $experiment)
{
$jobStatus = Airavata::getJobStatuses(Session::get('authz-token'), $experiment->experimentId);
//TODO - implement following logic with new data model.
/* if(!empty($experiment->workflowNodeDetailsList)){
if(!empty($experiment->workflowNodeDetailsList[0]->taskDetailsList)){
if(!empty($experiment->workflowNodeDetailsList[0]->taskDetailsList[0]->jobDetailsList)){
$jobStatus = $experiment->workflowNodeDetailsList[0]->taskDetailsList[0]->jobDetailsList[0]->jobStatus;
}
}
}*/
if (isset($jobStatus) && count($jobStatus) > 0) {
$jobState = JobState::$__names[array_values($jobStatus)[0]->jobState];
} else {
$jobState = null;
}
return $jobState;
}
/**
* Create options for the search key select input
* @param $values
* @param $labels
* @param $disabled
*/
public static function create_options($values, $labels, $disabled)
{
for ($i = 0; $i < sizeof($values); $i++) {
$selected = '';
// if option was previously selected, mark it as selected
if (isset($_POST['search-key'])) {
if ($values[$i] == $_POST['search-key']) {
$selected = 'selected';
}
}
echo '<option value="' . $values[$i] . '" ' . $disabled[$i] . ' ' . $selected . '>' . $labels[$i] . '</option>';
}
}
/**
* Get results of the user's search of experiments with pagination
* @return array|null
*/
public static function get_expsearch_results_with_pagination($inputs, $limit, $offset)
{
$experiments = array();
try {
$filters = array();
if(!empty($inputs["status-type"])){
if ($inputs["status-type"] != "ALL") {
$filters[\Airavata\Model\Experiment\ExperimentSearchFields::STATUS] = $inputs["status-type"];
}
}
if(!empty($inputs["search-key"])){
switch ($inputs["search-key"]) {
case 'experiment-name':
$filters[\Airavata\Model\Experiment\ExperimentSearchFields::EXPERIMENT_NAME] = $inputs["search-value"];
break;
case 'experiment-description':
$filters[\Airavata\Model\Experiment\ExperimentSearchFields::EXPERIMENT_DESC] = $inputs["search-value"];
break;
case 'application':
$filters[\Airavata\Model\Experiment\ExperimentSearchFields::APPLICATION_ID] = $inputs["search-value"];
break;
case 'creation-time':
$filters[\Airavata\Model\Experiment\ExperimentSearchFields::FROM_DATE] = strtotime($inputs["from-date"]) * 1000;
$filters[\Airavata\Model\Experiment\ExperimentSearchFields::TO_DATE] = strtotime($inputs["to-date"]) * 1000;
break;
case '':
}
}
$experiments = Airavata::searchExperiments(Session::get('authz-token'),
Session::get('gateway_id'), Session::get('username'), $filters, $limit, $offset);
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('InvalidRequestException!<br><br>' . $ire->getMessage());
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('AiravataClientException!<br><br>' . $ace->getMessage());
} catch (AiravataSystemException $ase) {
if ($ase->airavataErrorType == 2) // 2 = INTERNAL_ERROR
{
CommonUtilities::print_info_message('<p>You have not created any experiments yet, so no results will be returned!</p>
<p>Click <a href="create_experiment.php">here</a> to create an experiment, or
<a href="create_project.php">here</a> to create a new project.</p>');
} else {
CommonUtilities::print_error_message('There was a problem with Airavata. Please try again later or report a bug using the link in the Help menu.');
//print_error_message('AiravataSystemException!<br><br>' . $ase->airavataErrorType . ': ' . $ase->getMessage());
}
} catch (TTransportException $tte) {
CommonUtilities::print_error_message('TTransportException!<br><br>' . $tte->getMessage());
}
//get values of all experiments
$expContainer = array();
$expNum = 0;
foreach ($experiments as $experiment) {
$expValue = ExperimentUtilities::get_experiment_summary_values($experiment, true);
$expContainer[$expNum]['experiment'] = $experiment;
if ($expValue["experimentStatusString"] == "FAILED")
$expValue["editable"] = false;
$expContainer[$expNum]['expValue'] = $expValue;
$expNum++;
}
return $expContainer;
}
/**
* Get results of the user's search of experiments
* @return array|null
*/
public static function get_expsearch_results($inputs)
{
$experiments = array();
try {
switch ($inputs["search-key"]) {
case 'experiment-name':
$experiments = Airavata::searchExperimentsByName(Session::get('authz-token'), Session::get('gateway_id'), Session::get('username'), $inputs["search-value"]);
break;
case 'experiment-description':
$experiments = Airavata::searchExperimentsByDesc(Session::get('authz-token'), Session::get('gateway_id'), Session::get('username'), $inputs["search-value"]);
break;
case 'application':
$experiments = Airavata::searchExperimentsByApplication(Session::get('authz-token'), Session::get('gateway_id'), Session::get('username'), $inputs["search-value"]);
break;
case 'creation-time':
$experiments = Airavata::searchExperimentsByCreationTime(Session::get('authz-token'), Session::get('gateway_id'), Session::get('username'), strtotime($inputs["from-date"]) * 1000, strtotime($inputs["to-date"]) * 1000);
break;
case '':
}
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('InvalidRequestException!<br><br>' . $ire->getMessage());
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('AiravataClientException!<br><br>' . $ace->getMessage());
} catch (AiravataSystemException $ase) {
if ($ase->airavataErrorType == 2) // 2 = INTERNAL_ERROR
{
CommonUtilities::print_info_message('<p>You have not created any experiments yet, so no results will be returned!</p>
<p>Click <a href="create_experiment.php">here</a> to create an experiment, or
<a href="create_project.php">here</a> to create a new project.</p>');
} else {
CommonUtilities::print_error_message('There was a problem with Airavata. Please try again later or report a bug using the link in the Help menu.');
//print_error_message('AiravataSystemException!<br><br>' . $ase->airavataErrorType . ': ' . $ase->getMessage());
}
} catch (TTransportException $tte) {
CommonUtilities::print_error_message('TTransportException!<br><br>' . $tte->getMessage());
}
//get values of all experiments
$expContainer = array();
$expNum = 0;
foreach ($experiments as $experiment) {
$expValue = ExperimentUtilities::get_experiment_search_values($experiment, ProjectUtilities::get_project($experiment->projectId), true);
$expContainer[$expNum]['experiment'] = $experiment;
if ($expValue["experimentStatusString"] == "FAILED")
$expValue["editable"] = false;
$expContainer[$expNum]['expValue'] = $expValue;
$expNum++;
}
return $expContainer;
}
/**
* Get results of the user's all experiments with pagination.
* Results are ordered creation time DESC
* @return array|null
*/
public static function get_all_user_experiments_with_pagination($limit, $offset)
{
$experiments = array();
try {
$experiments = Airavata::getUserExperiments(Session::get('authz-token'),
Session::get('gateway_id'), Session::get('username'), $limit, $offset
);
} catch (InvalidRequestException $ire) {
CommonUtilities::print_error_message('InvalidRequestException!<br><br>' . $ire->getMessage());
} catch (AiravataClientException $ace) {
CommonUtilities::print_error_message('AiravataClientException!<br><br>' . $ace->getMessage());
} catch (AiravataSystemException $ase) {
if ($ase->airavataErrorType == 2) // 2 = INTERNAL_ERROR
{
CommonUtilities::print_info_message('<p>You have not created any experiments yet, so no results will be returned!</p>
<p>Click <a href="create_experiment.php">here</a> to create an experiment, or
<a href="create_project.php">here</a> to create a new project.</p>');
} else {
CommonUtilities::print_error_message('There was a problem with Airavata. Please try again later or report a bug using the link in the Help menu.');
//print_error_message('AiravataSystemException!<br><br>' . $ase->airavataErrorType . ': ' . $ase->getMessage());
}
} catch (TTransportException $tte) {
CommonUtilities::print_error_message('TTransportException!<br><br>' . $tte->getMessage());
}
//get values of all experiments
$expContainer = array();
$expNum = 0;
foreach ($experiments as $experiment) {
$expValue = ExperimentUtilities::get_experiment_summary_values($experiment, true);
$expContainer[$expNum]['experiment'] = $experiment;
if ($expValue["experimentStatusString"] == "FAILED")
$expValue["editable"] = false;
$expContainer[$expNum]['expValue'] = $expValue;
$expNum++;
}
return $expContainer;
}
public static function getExpStates()
{
$states = ExperimentState::$__names;
//removing UNKNOWN and SUSPENDED states. (AIRAVATA-1756)
$index = array_search('UNKNOWN',$states);
if($index !== FALSE){
unset($states[$index]);
}
$index = array_search('SUSPENDED',$states);
if($index !== FALSE){
unset($states[$index]);
}
return $states;
}
public static function apply_changes_to_experiment($experiment, $input)
{
$experiment->experimentName = $input['experiment-name'];
$experiment->description = rtrim($input['experiment-description']);
$experiment->projectId = $input['project'];
// $experiment->applicationId = $_POST['application'];
// $experiment->executionId = $_POST['application'];
$userConfigDataUpdated = $experiment->userConfigurationData;
$schedulingUpdated = $userConfigDataUpdated->computationalResourceScheduling;
$schedulingUpdated->resourceHostId = $input['compute-resource'];
$schedulingUpdated->nodeCount = $input['node-count'];
$schedulingUpdated->queueName = $_POST['queue-name'];
$schedulingUpdated->totalCPUCount = $input['cpu-count'];
//$schedulingUpdated->numberOfThreads = $input['threads'];
$schedulingUpdated->wallTimeLimit = $input['wall-time'];
//$schedulingUpdated->totalPhysicalMemory = $input['memory'];
/*
switch ($_POST['compute-resource'])
{
case 'trestles.sdsc.edu':
$schedulingUpdated->ComputationalProjectAccount = 'sds128';
break;
case 'stampede.tacc.xsede.org':
case 'lonestar.tacc.utexas.edu':
$schedulingUpdated->ComputationalProjectAccount = 'TG-STA110014S';
break;
default:
$schedulingUpdated->ComputationalProjectAccount = 'admin';
}
*/
$userConfigDataUpdated->computationalResourceScheduling = $schedulingUpdated;
$userConfigDataUpdated->airavataAutoSchedule = isset($_POST['enable-auto-scheduling']) ? true : false;
if (isset($input["userDN"])) {
$userConfigDataUpdated->generateCert = 1;
$userConfigDataUpdated->userDN = $input["userDN"];
}
$experiment->userConfigurationData = $userConfigDataUpdated;
$applicationInputs = AppUtilities::get_application_inputs($experiment->executionId);
$experimentInputs = $experiment->experimentInputs; // get current inputs
$experimentInputs = ExperimentUtilities::process_inputs($applicationInputs, $experimentInputs); // get new inputs
if ($experimentInputs) {
$experiment->experimentInputs = $experimentInputs;
//var_dump($experiment);
return $experiment;
}
}
public static function get_job_details($experimentId)
{
return Airavata::getJobDetails(Session::get('authz-token'), $experimentId);
}
public static function get_transfer_details($experimentId)
{
return Airavata::getDataTransferDetails(Session::get('authz-token'), $experimentId);
}
public static function getQueueDatafromResourceId($crId)
{
$resourceObject = Airavata::getComputeResource(Session::get('authz-token'), $crId);
return $resourceObject->batchQueues;
}
/**
* Create a select input and populate it with applications options
* @param null $id
* @param bool $editable
*/
public static function create_application_select($id = null, $editable = true)
{
$disabled = $editable ? '' : 'disabled';
$applicationIds = AppUtilities::get_all_applications();
uksort($applicationIds, 'strcasecmp');
echo '<select class="form-control" name="application" id="application" required ' . $disabled . '>';
if (count($applicationIds)) {
foreach ((array)$applicationIds as $applicationId => $applicationName) {
$selected = ($applicationId == $id) ? 'selected' : '';
echo '<option value="' . $applicationId . '" ' . $selected . '>' . $applicationName . '</option>';
}
}
echo '</select>';
}
}