tapis_job-1.4.1-alpha1/src/Controller/TapisJobIntegrationTestsController.php
src/Controller/TapisJobIntegrationTestsController.php
<?php
namespace Drupal\tapis_job\Controller;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\node\Entity\Node;
use Drupal\tapis_app\DrupalIds as AppDrupalIds;
use Drupal\tapis_job\TapisJobInterface;
use Drupal\tapis_job\TapisProvider\TapisJobProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class TapisJobIntegrationTestsController.
*
* This class is used to create a controller that interfaces
* with the Tapis integration tests.
*
* @package Drupal\tapis_job\Controller
*/
class TapisJobIntegrationTestsController extends ControllerBase {
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface|\Drupal\Core\Config\ImmutableConfig
*/
protected ConfigFactoryInterface|ImmutableConfig $config;
/**
* The Tapis job provider.
*
* @var \Drupal\tapis_job\TapisProvider\TapisJobProviderInterface
*/
protected TapisJobProviderInterface $tapisJobProvider;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a new TapisJobIntegrationTestsController object.
*
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* The current user.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory.
* @param \Drupal\tapis_job\TapisProvider\TapisJobProviderInterface $tapisJobProvider
* The Tapis job provider.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
*/
public function __construct(AccountProxyInterface $current_user,
ConfigFactoryInterface $config_factory,
TapisJobProviderInterface $tapisJobProvider,
EntityTypeManagerInterface $entityTypeManager) {
$this->currentUser = $current_user;
$this->config = $config_factory->get('tapis_auth.config');
$this->tapisJobProvider = $tapisJobProvider;
$this->entityTypeManager = $entityTypeManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('current_user'),
$container->get('config.factory'),
$container->get('tapis_job.tapis_job_provider'),
$container->get('entity_type.manager')
);
}
/**
* Launch an app for integration testing.
*
* @param \Drupal\node\Entity\Node $node
* Node entity.
* @param \Symfony\Component\HttpFoundation\Request $request
* The HTTP request.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* Return job access link
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\Core\Entity\EntityStorageException
* @throws \Drupal\Core\TypedData\Exception\MissingDataException
*/
public function launchApp(Node $node, Request $request) {
// Validate this request.
$this->validateRequest($request);
$params = Json::decode($request->getContent());
// For apps with input type flexible parameters,
// allow the user to specify an appArgs string.
$appInputType = $node->get(AppDrupalIds::APP_INPUT_TYPE)->getValue()[0]['value'];
if ($appInputType === "flexible_parameters") {
// Ensure that an appArgsString is provided.
$appArgsString = $params['appArgs'];
if (!$appArgsString) {
// Throw a 404.
throw new NotFoundHttpException();
}
}
else {
$appArgsString = "";
}
$tenantId = $node->get(AppDrupalIds::APP_TENANT)->first()->getValue()['target_id'];
$useBatchScheduler = boolval($node->get(AppDrupalIds::APP_USE_BATCH_SCHEDULER)->getValue()[0]['value']);
$jobName = "Integration_Testing_" . $node->getTitle();
$appType = $node->get(AppDrupalIds::APP_TYPE)->getValue()[0]['value'];
$system_id = $params['system_id'] ?? $node->get(AppDrupalIds::APP_DEFAULT_SYSTEM)->getValue()[0]['target_id'];
$batch_logical_queue_id = $request->get('batch_logical_queue_id');
$batch_allocation_id = $request->get('batch_allocation_id');
// $uid = $params['uid'] ?? \Drupal::currentUser()->id();
$uid = $params['uid'] ?? $this->currentUser->id();
/** @var \Drupal\tapis_job\Entity\TapisJob $job */
// $job = \Drupal::entityTypeManager()->getStorage('tapis_job')->create([
$job = $this->entityTypeManager->getStorage('tapis_job')->create([
'tenant' => ['target_id' => $tenantId],
'app' => ['target_id' => $node->id()],
'system' => ['target_id' => $system_id],
'label' => $jobName,
'uid' => ['target_id' => $uid],
]);
if ($useBatchScheduler && $batch_logical_queue_id) {
$job->setCustomProperties([
'execSystemLogicalQueue' => $batch_logical_queue_id,
]);
}
if ($useBatchScheduler && $batch_allocation_id) {
$job->setAllocationId($batch_allocation_id);
}
// /** @var \Drupal\tapis_job\TapisProvider\TapisJobProviderInterface */
// $tapisJobProvider =
// \Drupal::service("tapis_job.tapis_job_provider");
// Proxy id refers to the very first satellite token we create for this job.
if ($appType === "web" || $appType === "vnc") {
$proxyId = $this->tapisJobProvider->createNewSatelliteToken($tenantId);
$job->setProxyId($proxyId);
}
else {
$proxyId = NULL;
}
// Custom job resources.
$customJobResources = [];
// . TODO: Allow accepting custom job resources from the request
$job->setCustomJobResources($customJobResources);
$tapisJobDefinition = $job->toJSON($appArgsString);
$job->setTapisDefinition($tapisJobDefinition);
$job->save();
$tapis_job_uuid = $job->getTapisUUID();
// /** @var Drupal\tapis_job\TapisProvider\TapisJobProviderInterface */
// $tapisJobProvider = \Drupal::service("tapis_job.tapis_job_provider");
$jobAccessLinks = $this->tapisJobProvider->getJobAccessLinksForJob($job);
$jobAccessLinkProxyURLs = [];
foreach ($jobAccessLinks as $jobAccessLink) {
$jobAccessLinkProxyURLs[] = $jobAccessLink->getProxyURL();
}
return new JsonResponse([
'job_id' => $job->id(),
'tapis_job_uuid' => $tapis_job_uuid,
'proxy_id' => $proxyId,
'job_access_link_proxy_urls' => $jobAccessLinkProxyURLs,
]);
}
/**
* Validate this request.
*
* To ensure that it is a valid request for integration testing.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The HTTP request.
*/
private function validateRequest(Request $request) {
// $config = \Drupal::config('tapis_auth.config');
if (!$this->config->get("enable_integration_tests")) {
// Throw a 404 error.
throw new NotFoundHttpException();
}
// Get the value of the 'X-Integration-Tests-Secret' header.
$integration_tests_secret = $request->headers->get('X-Integration-Tests-Secret');
// Get the key value for the key with
// id = integration_tests_secret_key_id from the config.
$integration_tests_secret_key_id = $this->config->get('integration_tests_secret_key_id');
// Load the key entity.
// $key_entity = \Drupal::entityTypeManager()->getStorage('key')->load($integration_tests_secret_key_id);
/** @var \Drupal\key\Entity\Key $key_entity */
$key_entity = $this->entityTypeManager->getStorage('key')->load($integration_tests_secret_key_id);
// Get the key value.
$key_value = $key_entity->getKeyValue();
// If the header is not equal to the value of
// the integration_tests_secret_key_id key,
// or there is no integration tests secret key defined, return an error.
if (!$key_value || $integration_tests_secret !== $key_value) {
// Throw a 404 error.
throw new NotFoundHttpException();
}
}
/**
* Get a job.
*
* @param \Drupal\tapis_job\TapisJobInterface $tapis_job
* The Tapis Job interface.
* @param \Symfony\Component\HttpFoundation\Request $request
* The HTTP request.
*/
public function getJob(TapisJobInterface $tapis_job, Request $request): JsonResponse {
// Validate this request.
$this->validateRequest($request);
// $tapisJobProvider = \Drupal::service("tapis_job.tapis_job_provider");
$jobOwnerId = $tapis_job->getOwnerId();
$tenantId = $tapis_job->getTenantId();
$tapisJobUUID = $tapis_job->getTapisUUID();
$job = $this->tapisJobProvider->getJob($tenantId, $tapisJobUUID, $jobOwnerId);
return new JsonResponse($job);
}
/**
* Cancel a job.
*
* @param \Drupal\tapis_job\TapisJobInterface $tapis_job
* The Tapis Job interface.
* @param \Symfony\Component\HttpFoundation\Request $request
* The HTTP request.
*/
public function cancelJob(TapisJobInterface $tapis_job, Request $request): JsonResponse {
// Validate this request.
$this->validateRequest($request);
$tenantId = $tapis_job->getTenantId();
$jobOwnerId = $tapis_job->getOwnerId();
// /** @var Drupal\tapis_job\TapisProvider\TapisJobProviderInterface */
// $tapisJobProvider = \Drupal::service("tapis_job.tapis_job_provider");
$this->tapisJobProvider->cancelJob($tenantId, $tapis_job->getTapisUUID(), $jobOwnerId);
$app = $tapis_job->getApp();
$appType = $app->get(AppDrupalIds::APP_TYPE)->getValue()[0]['value'];
if ($appType === "web" || $appType === "vnc") {
$this->tapisJobProvider->deleteAllAccessLinksForJob($tapis_job->id());
}
return new JsonResponse(['success' => TRUE]);
}
}
