534 lines
21 KiB
PHP
534 lines
21 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Copyright (c) 2017 Open Assessment Technologies, S.A.
|
|
*
|
|
* @author A.Zagovorichev, <zagovorichev@1pt.com>
|
|
*/
|
|
|
|
namespace oat\taoDeliveryRdf\scripts\tools;
|
|
|
|
use oat\oatbox\extension\AbstractAction;
|
|
use oat\generis\model\OntologyAwareTrait;
|
|
use oat\taoDelivery\model\execution\OntologyDeliveryExecution;
|
|
use oat\taoDelivery\model\execution\ServiceProxy;
|
|
use oat\taoDeliveryRdf\model\DeliveryAssemblyService;
|
|
use oat\taoDelivery\model\execution\implementation\KeyValueService;
|
|
use oat\taoResultServer\models\classes\implementation\ResultServerService;
|
|
|
|
/**
|
|
* Start your way from this
|
|
* php index.php "oat\taoDeliveryRdf\scripts\tools\jMeterCleaner" it will provide you your path
|
|
*
|
|
* But be careful not all ways are safe, make sure that you have dump of the DB before use this
|
|
*
|
|
* Class jMeterCleaner
|
|
* @package oat\taoAct\scripts\tools
|
|
*/
|
|
class jMeterCleaner extends AbstractAction
|
|
{
|
|
use OntologyAwareTrait;
|
|
|
|
/**
|
|
* @var \common_report_Report
|
|
*/
|
|
private $report;
|
|
|
|
/**
|
|
* If one of the sections has been already done
|
|
* @var bool
|
|
*/
|
|
private $done = false;
|
|
|
|
/**
|
|
* All passed params
|
|
* @var array
|
|
*/
|
|
private $params = [];
|
|
|
|
private $testTakerClass;
|
|
private $deliveryClass;
|
|
|
|
public function __invoke($params)
|
|
{
|
|
// Load needed constants
|
|
\common_ext_ExtensionsManager::singleton()->getExtensionById('taoDelivery');
|
|
$extensionManager = $this->getServiceManager()->get(\common_ext_ExtensionsManager::SERVICE_ID);
|
|
$extensionManager->getExtensionById('taoDeliveryRdf');
|
|
$extensionManager->getExtensionById('taoDeliveryRdf');
|
|
|
|
$this->params = $params;
|
|
|
|
// since lti uses #user then we can't use #subject (but subject is the subclass of user then it will work)
|
|
$this->testTakerClass = $this->getClass('http://www.tao.lu/Ontologies/generis.rdf#User');
|
|
|
|
$deliveryService = DeliveryAssemblyService::singleton();
|
|
$this->deliveryClass = $deliveryService->getRootClass();
|
|
|
|
$this->report = \common_report_Report::createInfo('Report');
|
|
$this->usage();
|
|
$this->run();
|
|
return $this->report;
|
|
}
|
|
|
|
// how it works
|
|
private function usage()
|
|
{
|
|
if (empty($this->params)) {
|
|
$usageHelper = \common_report_Report::createInfo('USAGE: What you could do here:');
|
|
$usageHelper->add(\common_report_Report::createSuccess('Please, Note that sections must not intersect otherwise it will work according to priority'));
|
|
|
|
$countDeliveriesForUsers = \common_report_Report::createInfo('1. Count how many deliveries has each of the user');
|
|
$countDeliveriesForUsers->add(\common_report_Report::createInfo('--count-deliveries-by-user'));
|
|
$countDeliveriesForUsers->add(\common_report_Report::createInfo('--open-out `show all deliveries and executions id`'));
|
|
$usageHelper->add($countDeliveriesForUsers);
|
|
|
|
$openDeliveriesForUser = \common_report_Report::createInfo('2. Detailed report about deliveries for user');
|
|
$openDeliveriesForUser->add(\common_report_Report::createInfo('--detailed-report'));
|
|
$openDeliveriesForUser->add(\common_report_Report::createInfo('--detailed-user=[userId]'));
|
|
$openDeliveriesForUser->add(\common_report_Report::createInfo('--open-out `show all deliveries and executions id`'));
|
|
$usageHelper->add($openDeliveriesForUser);
|
|
|
|
$cleaner = \common_report_Report::createInfo('2. Clean test data that you want (The greater the force, the greater the responsibility)');
|
|
$cleaner->add(\common_report_Report::createFailure('Note: everything will be deleted even user'));
|
|
$cleaner->add(\common_report_Report::createInfo('--run-cleaner'));
|
|
$cleaner->add(\common_report_Report::createInfo('--clean-user=[userId] `will be deleted user, executions and states`'));
|
|
$cleaner->add(\common_report_Report::createInfo('--clean-user-with-his-deliveries `will be deleted user, executions, states, DELIVERIES and RESULTS`'));
|
|
$cleaner->add(\common_report_Report::createInfo('--clean-delivery=[deliveryId] `not required. If provided, then will be deleted only that delivery and results`'));
|
|
$usageHelper->add($cleaner);
|
|
|
|
$executionsCleaner = \common_report_Report::createInfo('3. Delete only executions and test results (The greater the force, the greater the responsibility)');
|
|
$executionsCleaner->add(\common_report_Report::createFailure('Note: will be deleted results, executions and services states'));
|
|
$executionsCleaner->add(\common_report_Report::createInfo('--run-executions-cleaner'));
|
|
$executionsCleaner->add(\common_report_Report::createInfo('--clean-user=[userId] `will be deleted executions, results and states`'));
|
|
$executionsCleaner->add(\common_report_Report::createInfo('--clean-users-whose-label-begin-with=[string] `min length 3 symbols. Will be deleted executions, results and states only for the users whose labels begin with specified string.`'));
|
|
$usageHelper->add($executionsCleaner);
|
|
|
|
$this->report->add($usageHelper);
|
|
}
|
|
}
|
|
|
|
// entry for the actions
|
|
private function run()
|
|
{
|
|
$this->counter();
|
|
$this->detailed();
|
|
$this->cleaner();
|
|
$this->executionsCleaner();
|
|
}
|
|
|
|
/**
|
|
* First section with general information about users
|
|
*/
|
|
private function counter()
|
|
{
|
|
if (!$this->done && in_array('--count-deliveries-by-user', $this->params)) {
|
|
$this->done = true;
|
|
|
|
$counterReport = \common_report_Report::createInfo('List of Users:');
|
|
|
|
$helper = new ConsoleTableHelper();
|
|
$helper->addHeader(['TestTaker', 'Deliveries', 'Executions']);
|
|
$helper->addRows($this->getCountersByUsers(!in_array('--open-out', $this->params)));
|
|
$counterReport->add($helper->generateReport());
|
|
|
|
$this->report->add($counterReport);
|
|
}
|
|
}
|
|
|
|
private function getCountersByUsers($counted = true)
|
|
{
|
|
$deliveries = $this->deliveryClass->getInstances(true);
|
|
$testTakers = $this->testTakerClass->getInstances(true);
|
|
$src = [];
|
|
|
|
foreach ($deliveries as $delivery) {
|
|
foreach ($testTakers as $testTaker) {
|
|
$this->getUserDeliveryData($testTaker, $delivery, $counted, $src);
|
|
}
|
|
}
|
|
|
|
return $this->convertSrcToData($src, $counted);
|
|
}
|
|
|
|
private function convertSrcToData($src, $counted)
|
|
{
|
|
if ($counted) {
|
|
$data = [];
|
|
foreach ($src as $ttLabel => $ttData) {
|
|
$row = [];
|
|
$row[] = $ttLabel;
|
|
$row[] = count($ttData); // count of the deliveries
|
|
$row[] = array_sum($ttData); // count of the executions
|
|
$data[] = $row;
|
|
}
|
|
} else {
|
|
$data = $src;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
private function getUserDeliveryData($testTaker, $delivery, $counted, &$src)
|
|
{
|
|
$executions = ServiceProxy::singleton()->getUserExecutions($delivery, $testTaker->getUri());
|
|
foreach ($executions as $execution) {
|
|
/*
|
|
* Uncounted source
|
|
*/
|
|
if (!$counted) {
|
|
$row = [];
|
|
$row[] = $testTaker->getUri() . ' (' . $testTaker->getLabel() . ')';
|
|
$row[] = $delivery->getUri();
|
|
$row[] = $execution->getIdentifier();
|
|
$src[] = $row;
|
|
} else {
|
|
$ttLabel = $testTaker->getUri() . ' (' . $testTaker->getLabel() . ')';
|
|
if (isset($src[$ttLabel])) {
|
|
if (isset($src[$ttLabel][$delivery->getUri()])) {
|
|
$src[$ttLabel][$delivery->getUri()]++;
|
|
} else {
|
|
$src[$ttLabel][$delivery->getUri()] = 1;
|
|
}
|
|
} else {
|
|
$src[$ttLabel] = [ $delivery->getUri() => 1];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Second section with detailed information about the specified user
|
|
*/
|
|
private function detailed()
|
|
{
|
|
if (!$this->done && in_array('--detailed-report', $this->params)) {
|
|
$this->done = true;
|
|
$details = $this->getDetailsForUser(!in_array('--open-out', $this->params));
|
|
if ($details !== false) {
|
|
$counterReport = \common_report_Report::createInfo('Detailed report for the user');
|
|
$helper = new ConsoleTableHelper();
|
|
$helper->addHeader(['TestTaker', 'Deliveries', 'Executions']);
|
|
$helper->addRows($details);
|
|
$counterReport->add($helper->generateReport());
|
|
$this->report->add($counterReport);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get parameter from the list of parameters as Resource
|
|
* @param string $prefix
|
|
* @return bool|\core_kernel_classes_Resource
|
|
*/
|
|
private function getResourceFromParameter($prefix = '--unique-prefix')
|
|
{
|
|
$resource = null;
|
|
$hasParameter = false;
|
|
|
|
$val = $this->getParameterValue($prefix);
|
|
if ($val) {
|
|
$hasParameter = true;
|
|
$resource = $this->getResource($val);
|
|
if (!$resource->exists()) {
|
|
$resource = null;
|
|
}
|
|
}
|
|
|
|
return $hasParameter ? $resource : false;
|
|
}
|
|
|
|
private function getParameterValue($prefix = '--unique-prefix')
|
|
{
|
|
$value = false;
|
|
foreach ($this->params as $param) {
|
|
if (mb_strpos($param, $prefix) !== false) {
|
|
$value = str_replace($prefix, '', $param);
|
|
$value = trim($value, '[]');
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
private function getDetailsForUser($counted = true)
|
|
{
|
|
$testTaker = $this->getResourceFromParameter('--detailed-user=');
|
|
|
|
if (!$testTaker) {
|
|
$this->report->add(\common_report_Report::createFailure('--detailed-user=[userId] is required and need to be a Resource'));
|
|
return false;
|
|
}
|
|
|
|
return $this->getDataByTestTaker($testTaker, $counted);
|
|
}
|
|
|
|
private function getDataByTestTaker($testTaker, $counted)
|
|
{
|
|
$deliveries = $this->deliveryClass->getInstances(true);
|
|
$src = [];
|
|
foreach ($deliveries as $delivery) {
|
|
$this->getUserDeliveryData($testTaker, $delivery, $counted, $src);
|
|
}
|
|
|
|
return $this->convertSrcToData($src, $counted);
|
|
}
|
|
|
|
/**
|
|
* The most dangerous of the sections which will affect on the stored data
|
|
*/
|
|
private function cleaner()
|
|
{
|
|
if (!$this->done && in_array('--run-cleaner', $this->params)) {
|
|
$this->done = true;
|
|
|
|
$testTaker = $this->getResourceFromParameter('--clean-user=');
|
|
if (!$testTaker) {
|
|
$this->report->add(\common_report_Report::createFailure('--clean-user=[userId] is required and need to be a Resource'));
|
|
return false;
|
|
}
|
|
|
|
$delivery = $this->getResourceFromParameter('--clean-delivery=');
|
|
if ($delivery) {
|
|
$this->report->add(\common_report_Report::createInfo('Deleting of the delivery data [' . $delivery->getUri() . ']'));
|
|
} elseif ($delivery === null) {
|
|
$this->report->add(\common_report_Report::createFailure('Delivery does not found'));
|
|
return false;
|
|
} else {
|
|
$this->report->add(\common_report_Report::createInfo('Deleting of the TestTaker data [' . $testTaker->getUri() . ']'));
|
|
}
|
|
|
|
$ttData = $this->getDataByTestTaker($testTaker, false);
|
|
if (!count($ttData)) {
|
|
$this->report->add(\common_report_Report::createFailure('TestTaker with id [' . $testTaker->getUri() . '] has not been found'));
|
|
return false;
|
|
} elseif ($delivery) {
|
|
$hasDelivery = false;
|
|
foreach ($ttData as $row) {
|
|
if ($row[1] == $delivery->getUri()) {
|
|
$hasDelivery = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$hasDelivery) {
|
|
$this->report->add(\common_report_Report::createFailure('Delivery with id [' . $testTaker->getUri() . '] has not been found'));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ($delivery) {
|
|
$this->deleteDelivery($delivery);
|
|
} else {
|
|
$this->deleteTestTaker($testTaker, $ttData);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private function executionsCleaner()
|
|
{
|
|
if (!$this->done && in_array('--run-executions-cleaner', $this->params)) {
|
|
$this->done = true;
|
|
|
|
$testTaker = $this->getResourceFromParameter('--clean-user=');
|
|
$labelBeginWith = $this->getParameterValue('--clean-users-whose-label-begin-with=');
|
|
|
|
if (!$testTaker && !$labelBeginWith) {
|
|
$this->report->add(\common_report_Report::createFailure('You should use one of the --clean-user or --clean-users-whose-label-begin-with, not together'));
|
|
return false;
|
|
}
|
|
|
|
if ($testTaker && $labelBeginWith) {
|
|
$this->report->add(\common_report_Report::createFailure('You can use --clean-user or --clean-users-whose-label-begin-with, not together'));
|
|
return false;
|
|
}
|
|
|
|
if (mb_strlen($labelBeginWith) < 3) {
|
|
$this->report->add(\common_report_Report::createFailure('Value of the --clean-users-whose-label-begin-with can not be less then 3 symbols'));
|
|
return false;
|
|
}
|
|
|
|
if ($testTaker) {
|
|
// clean his data
|
|
$this->cleanTestTakersExecutions($testTaker);
|
|
}
|
|
|
|
if ($labelBeginWith) {
|
|
// clean all test takers according to this mask
|
|
$this->cleanExecutionsByMask($labelBeginWith);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private function cleanTestTakersExecutions($testTaker)
|
|
{
|
|
$ttData = $this->getDataByTestTaker($testTaker, false);
|
|
if (!count($ttData)) {
|
|
$this->report->add(\common_report_Report::createFailure('TestTaker with id [' . $testTaker->getUri() . '] has not been found'));
|
|
return false;
|
|
}
|
|
|
|
// delete deliveries results
|
|
$deliveries = [];
|
|
foreach ($ttData as $row) {
|
|
if (isset($row[1])) {
|
|
$deliveries[] = $row[1];
|
|
}
|
|
}
|
|
|
|
$removeResultsReport = $this->removeResults($deliveries);
|
|
$this->report->add($removeResultsReport);
|
|
|
|
// delete executions
|
|
$executionRemovedReport = $this->removeDeliveryExecutions($testTaker->getUri());
|
|
$this->report->add($executionRemovedReport);
|
|
|
|
// delete states
|
|
$statesRemovedReport = $this->removeServiceState($testTaker->getUri());
|
|
$this->report->add($statesRemovedReport);
|
|
|
|
$this->report->add(\common_report_Report::createSuccess('TestTakers data about results and executions were cleaned'));
|
|
}
|
|
|
|
private function cleanExecutionsByMask($labelBeginWith = '')
|
|
{
|
|
$data = $this->getCountersByUsers();
|
|
foreach ($data as $row) {
|
|
if ($pos = mb_strpos($row[0], '(' . $labelBeginWith)) {
|
|
$uri = trim(mb_substr($row[0], 0, $pos));
|
|
$testTaker = $this->getResource($uri);
|
|
$this->cleanTestTakersExecutions($testTaker);
|
|
}
|
|
}
|
|
}
|
|
|
|
private function deleteDelivery($delivery)
|
|
{
|
|
if (!$delivery->exists()) {
|
|
return false;
|
|
}
|
|
$resultRemoveReport = $this->removeResults((array)$delivery->getUri());
|
|
$this->report->add($resultRemoveReport);
|
|
$delivery->delete(true);
|
|
$this->report->add(\common_report_Report::createSuccess('Delivery deleted'));
|
|
}
|
|
|
|
private function deleteTestTaker($testTaker, $ttData)
|
|
{
|
|
if (in_array('--clean-user-with-his-deliveries', $this->params)) {
|
|
foreach ($ttData as $executionRow) {
|
|
if (isset($executionRow[1])) {
|
|
$this->deleteDelivery($this->getResource($executionRow[1]));
|
|
}
|
|
}
|
|
}
|
|
|
|
$executionRemovedReport = $this->removeDeliveryExecutions($testTaker->getUri());
|
|
$this->report->add($executionRemovedReport);
|
|
|
|
$statesRemovedReport = $this->removeServiceState($testTaker->getUri());
|
|
$this->report->add($statesRemovedReport);
|
|
|
|
$testTaker->delete(true);
|
|
$this->report->add(\common_report_Report::createSuccess('TestTaker deleted'));
|
|
}
|
|
|
|
private function removeResults(array $deliveries)
|
|
{
|
|
$report = new \common_report_Report(\common_report_Report::TYPE_SUCCESS);
|
|
try {
|
|
/** @var ResultServerService $resultService */
|
|
$resultService = $this->getServiceLocator()->get(ResultServerService::SERVICE_ID);
|
|
$count = 0;
|
|
foreach ($deliveries as $delivery) {
|
|
$implementation = $resultService->getResultStorage($delivery);
|
|
foreach ($implementation->getResultByDelivery([$delivery]) as $result) {
|
|
if ($implementation->deleteResult($result['deliveryResultIdentifier'])) {
|
|
$count++;
|
|
} else {
|
|
$report->setType(\common_report_Report::TYPE_ERROR);
|
|
$report->setMessage('Cannot cleanup results for ' . $result['deliveryResultIdentifier']);
|
|
}
|
|
}
|
|
}
|
|
|
|
$report->setMessage('Removed ' . $count . ' on ' . count($deliveries) . ' RDS results');
|
|
} catch (\common_Exception $e) {
|
|
$report->setType(\common_report_Report::TYPE_ERROR);
|
|
$report->setMessage('Cannot cleanup Results: ' . $e->getMessage());
|
|
}
|
|
|
|
return $report;
|
|
}
|
|
|
|
private function removeDeliveryExecutions($userUri)
|
|
{
|
|
$report = new \common_report_Report(\common_report_Report::TYPE_SUCCESS);
|
|
|
|
// deliveryExecutions
|
|
$extension = \common_ext_ExtensionsManager::singleton()->getExtensionById('taoDelivery');
|
|
$deliveryService = $extension->getConfig('execution_service');
|
|
if ($deliveryService instanceof KeyValueService) {
|
|
$persistenceOption = $deliveryService->getOption(KeyValueService::OPTION_PERSISTENCE);
|
|
$persistence = \common_persistence_KeyValuePersistence::getPersistence($persistenceOption);
|
|
$count = 0;
|
|
foreach ($persistence->keys('kve_*' . $userUri . '*') as $key) {
|
|
if (substr($key, 0, 4) == 'kve_') {
|
|
$persistence->del($key);
|
|
$count++;
|
|
}
|
|
}
|
|
$report->setMessage('Removed ' . $count . ' key-value delivery executions of ' . $userUri);
|
|
} elseif ($deliveryService instanceof OntologyDeliveryExecution) {
|
|
$count = 0;
|
|
$deliveryExecutionClass = new \core_kernel_classes_Class(OntologyDeliveryExecution::CLASS_URI);
|
|
$deliveryExecutions = $deliveryExecutionClass->searchInstances([OntologyDeliveryExecution::PROPERTY_SUBJECT => $userUri]);
|
|
/** @var \core_kernel_classes_Class $deliveryExecution */
|
|
foreach ($deliveryExecutions as $deliveryExecution) {
|
|
$deliveryExecution->delete(true);
|
|
$count++;
|
|
}
|
|
$report->setMessage('Removed ' . $count . ' ontology delivery executions of ' . $userUri);
|
|
} else {
|
|
$report->setType(\common_report_Report::TYPE_ERROR);
|
|
$report->setMessage('Cannot cleanup delivery executions from ' . get_class($deliveryService));
|
|
}
|
|
|
|
return $report;
|
|
}
|
|
|
|
private function removeServiceState($userUri)
|
|
{
|
|
$report = new \common_report_Report(\common_report_Report::TYPE_SUCCESS);
|
|
// service states
|
|
$persistence = \common_persistence_KeyValuePersistence::getPersistence(\tao_models_classes_service_StateStorage::PERSISTENCE_ID);
|
|
if ($persistence instanceof \common_persistence_AdvKeyValuePersistence) {
|
|
$count = 0;
|
|
foreach ($persistence->keys('tao:state:' . $userUri . '*') as $key) {
|
|
if (substr($key, 0, 10) == 'tao:state:') {
|
|
$persistence->del($key);
|
|
$count++;
|
|
}
|
|
}
|
|
$report->setMessage('Removed ' . $count . ' states ' . $userUri);
|
|
} elseif ($persistence instanceof \common_persistence_KeyValuePersistence) {
|
|
try {
|
|
if ($persistence->purge()) {
|
|
$report->setMessage('States correctly removed');
|
|
}
|
|
} catch (\common_exception_NotImplemented $e) {
|
|
$report->setType(\common_report_Report::TYPE_ERROR);
|
|
$report->setMessage($e->getMessage());
|
|
}
|
|
} else {
|
|
$report->setType(\common_report_Report::TYPE_ERROR);
|
|
$report->setMessage('Cannot cleanup states from ' . get_class($persistence));
|
|
}
|
|
|
|
return $report;
|
|
}
|
|
}
|