diff --git a/config/autoload/cli.global.php b/config/autoload/cli.global.php index f39d722..8472c8b 100644 --- a/config/autoload/cli.global.php +++ b/config/autoload/cli.global.php @@ -5,11 +5,13 @@ return [ 'invokables' => [], 'factories' => [ App\Command\UpdateLabInfoCommand::class => App\Command\UpdateLabInfoFactory::class, + App\Command\UpdatePageCachesCommand::class => App\Command\UpdatePageCachesFactory::class, ], ], 'console' => [ 'commands' => [ App\Command\UpdateLabInfoCommand::class, + App\Command\UpdatePageCachesCommand::class, ], ], ]; diff --git a/src/App/Action/TspInfoAction.php b/src/App/Action/TspInfoAction.php index 3d38b4b..70b110e 100644 --- a/src/App/Action/TspInfoAction.php +++ b/src/App/Action/TspInfoAction.php @@ -7,6 +7,7 @@ use App\Service\JcatInfoCollectorService; use App\Service\JiraCollectorService; use App\Service\LabInfoCollectorService; use App\Service\TrInfoCollectorService; +use App\Service\TspInfoService; use App\Service\VacationInfoCollectorService; use Interop\Http\ServerMiddleware\DelegateInterface; use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface; @@ -16,48 +17,13 @@ use Zend\Config\Config; class TspInfoAction implements ServerMiddlewareInterface { /** - * @var Config + * @var TspInfoService */ - private $config; + private $tspInfoService; - /** - * @var VacationInfoCollectorService - */ - private $vacationInfoCollectorService; - - /** - * @var TrInfoCollectorService - */ - private $trInfoCollectorService; - - /** - * @var JcatInfoCollectorService - */ - private $jcatInfoCollectorService; - - /** - * @var LabInfoCollectorService - */ - private $labInfoCollectorService; - - /** - * @var JiraCollectorService - */ - private $jiraCollectorService; - - public function __construct(Config $config, - VacationInfoCollectorService $vacationInfoCollectorService, - TrInfoCollectorService $trInfoCollectorService, - JcatInfoCollectorService $jcatInfoCollectorService, - LabInfoCollectorService $labInfoCollectorService, - JiraCollectorService $jiraCollectorService) + public function __construct(TspInfoService $tspInfoService) { - $this->config = $config; - $this->vacationInfoCollectorService = $vacationInfoCollectorService; - $this->trInfoCollectorService = $trInfoCollectorService; - $this->jcatInfoCollectorService = $jcatInfoCollectorService; - $this->labInfoCollectorService = $labInfoCollectorService; - $this->jiraCollectorService = $jiraCollectorService; + $this->tspInfoService = $tspInfoService; } /** @@ -67,15 +33,6 @@ class TspInfoAction implements ServerMiddlewareInterface */ public function process(ServerRequestInterface $request, DelegateInterface $delegate) { - return new JsonCorsResponse([ - 'cameraUrls' => $this->config->get('url.eurestCameras')->toArray(), - 'animGifs' => [], - 'praGoals' => $this->trInfoCollectorService->getPraGoals(), - 'trProgressInfo' => $this->trInfoCollectorService->getProgressInfo(), - 'trFlowErrors' => $this->jcatInfoCollectorService->getTrFlowErrors(), - 'expedites' => $this->jiraCollectorService->getExpedites(), - 'isVacationSoon' => $this->vacationInfoCollectorService->isVacationSoon(), - 'labTemperature' => $this->labInfoCollectorService->getLabTemperatureData(), - ]); + return new JsonCorsResponse($this->tspInfoService->getTspInfo()); } } diff --git a/src/App/Action/TspInfoFactory.php b/src/App/Action/TspInfoFactory.php index 7bb6587..6bd5128 100644 --- a/src/App/Action/TspInfoFactory.php +++ b/src/App/Action/TspInfoFactory.php @@ -6,6 +6,7 @@ use App\Service\JcatInfoCollectorService; use App\Service\JiraCollectorService; use App\Service\LabInfoCollectorService; use App\Service\TrInfoCollectorService; +use App\Service\TspInfoService; use App\Service\VacationInfoCollectorService; use Interop\Container\ContainerInterface; use Zend\Config\Config; @@ -14,20 +15,7 @@ class TspInfoFactory { public function __invoke(ContainerInterface $container) { - $appConfig = $container->get('config')['app.config']; - $dataCollectorService = $container->get(VacationInfoCollectorService::class); - $trInfoCollectorService = $container->get(TrInfoCollectorService::class); - $jcatInfoCollectorService = $container->get(JcatInfoCollectorService::class); - $labInfoCollectorService = $container->get(LabInfoCollectorService::class); - $jiraInfoCollectorService = $container->get(JiraCollectorService::class); - - return new TspInfoAction( - new Config($appConfig), - $dataCollectorService, - $trInfoCollectorService, - $jcatInfoCollectorService, - $labInfoCollectorService, - $jiraInfoCollectorService - ); + $tspInfoService = $container->get(TspInfoService::class); + return new TspInfoAction($tspInfoService); } } diff --git a/src/App/Command/UpdatePageCachesCommand.php b/src/App/Command/UpdatePageCachesCommand.php new file mode 100644 index 0000000..8ba366d --- /dev/null +++ b/src/App/Command/UpdatePageCachesCommand.php @@ -0,0 +1,42 @@ +tspInfoService = $tspInfoService; + $this->jiraCollectorService = $jiraCollectorService; + parent::__construct(); + } + + protected function configure() + { + $this->setName('cache:update') + ->setDescription('Updates page-cache data for tspInfo and kanban pages'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->tspInfoService->getTspInfo(true); + $this->jiraCollectorService->getKanbanBoard(true); + } +} diff --git a/src/App/Command/UpdatePageCachesFactory.php b/src/App/Command/UpdatePageCachesFactory.php new file mode 100644 index 0000000..b6a26aa --- /dev/null +++ b/src/App/Command/UpdatePageCachesFactory.php @@ -0,0 +1,34 @@ +get(RouterInterface::class); + $router->addRoute($avatarRoute); + + $tspInfoService = $container->get(TspInfoService::class); + $jiraCollectorService = $container->get(JiraCollectorService::class); + return new UpdatePageCachesCommand($tspInfoService, $jiraCollectorService); + } +} diff --git a/src/App/ConfigProvider.php b/src/App/ConfigProvider.php index d3aa3a3..1634693 100644 --- a/src/App/ConfigProvider.php +++ b/src/App/ConfigProvider.php @@ -54,8 +54,9 @@ class ConfigProvider Service\VacationInfoCollectorService::class => Service\VacationInfoCollectorServiceFactory::class, Service\TrInfoCollectorService::class => Service\TrInfoCollectorServiceFactory::class, Service\JcatInfoCollectorService::class => Service\JcatInfoCollectorServiceFactory::class, + Service\TspInfoService::class => Service\TspInfoServiceFactory::class, - 'service.avatarCache' => function(ContainerInterface $container): StorageInterface { + 'service.cache' => function(ContainerInterface $container): StorageInterface { $cache = new FilesytemCache(); $cache->getOptions() ->setFromArray([ diff --git a/src/App/Service/AvatarService.php b/src/App/Service/AvatarService.php index 836846d..f971d46 100644 --- a/src/App/Service/AvatarService.php +++ b/src/App/Service/AvatarService.php @@ -36,6 +36,7 @@ class AvatarService * @param Client $client * @param Config $config * @param RouterInterface $router + * @param StorageInterface $cache */ public function __construct(Client $client, Config $config, RouterInterface $router, StorageInterface $cache) { diff --git a/src/App/Service/AvatarServiceFactory.php b/src/App/Service/AvatarServiceFactory.php index 26501ce..c207b42 100644 --- a/src/App/Service/AvatarServiceFactory.php +++ b/src/App/Service/AvatarServiceFactory.php @@ -13,7 +13,7 @@ class AvatarServiceFactory { $router = $container->get(RouterInterface::class); $httpClient = $container->get(Client::class); - $cache = $container->get('service.avatarCache'); + $cache = $container->get('service.cache'); $configArray = $container->get('config'); $config = new Config($configArray['app.config']); return new AvatarService($httpClient, $config, $router, $cache); diff --git a/src/App/Service/JiraCollectorService.php b/src/App/Service/JiraCollectorService.php index 1bb9925..af945d5 100644 --- a/src/App/Service/JiraCollectorService.php +++ b/src/App/Service/JiraCollectorService.php @@ -7,6 +7,7 @@ use App\Entity\JiraIssueType; use App\Entity\JiraStatus; use App\Entity\KanbanBoard; use App\Entity\KanbanEntry; +use Zend\Cache\Storage\StorageInterface; use Zend\Config\Config; use Zend\Http\Client; use Zend\Json\Decoder; @@ -14,6 +15,13 @@ use Zend\Json\Json; class JiraCollectorService { + + const CACHE_KEY_KANBANBOARD = 'kanbanBoard'; + + /** + * @var StorageInterface + */ + private $cache; /** * @var Config */ @@ -31,11 +39,14 @@ class JiraCollectorService /** * JiraClientService constructor. + * @param StorageInterface $cache * @param Client $client * @param Config $config + * @param AvatarService $avatarService */ - public function __construct(Client $client, Config $config, AvatarService $avatarService) + public function __construct(StorageInterface $cache, Client $client, Config $config, AvatarService $avatarService) { + $this->cache = $cache; $this->avatarService = $avatarService; $this->httpClient = $client; $this->config = $config; @@ -46,7 +57,7 @@ class JiraCollectorService */ public function getExpedites(): array { - $user = $this->config->get('jira.user'); + $user = $this->config->get('jira.user'); $password = $this->config->get('jira.password'); /** @var Config $expediteUriParams */ $expediteUriParams = $this->config->get('url.jiraTspExpedites'); @@ -64,7 +75,7 @@ class JiraCollectorService ->setAuth($user, $password) ->send(); - if(!$response->isSuccess()) { + if (!$response->isSuccess()) { throw new \UnexpectedValueException( sprintf("Bad JIRA result when trying to load: %s\n%s", $jiraResultUri, @@ -81,32 +92,42 @@ class JiraCollectorService } /** + * @param bool $forceReload * @return KanbanBoard */ - public function getKanbanBoard(): KanbanBoard + public function getKanbanBoard(bool $forceReload = false): KanbanBoard { - $user = $this->config->get('jira.user'); - $password = $this->config->get('jira.password'); - /** @var Config $kanbanBoardUriParams */ - $kanbanBoardUriParams = $this->config->get('url.jiraKanbanBoard'); + $kanbanBoard = $this->cache->getItem('kanbanBoard'); + if ($forceReload || null === $kanbanBoard) { + $user = $this->config->get('jira.user'); + $password = $this->config->get('jira.password'); + /** @var Config $kanbanBoardUriParams */ + $kanbanBoardUriParams = $this->config->get('url.jiraKanbanBoard'); - $kanbanBoardUri = sprintf( - $kanbanBoardUriParams['baseUrl'], - $kanbanBoardUriParams['filterId'], - implode(",", $kanbanBoardUriParams['fields']->toArray()) - ); + $kanbanBoardUri = sprintf( + $kanbanBoardUriParams['baseUrl'], + $kanbanBoardUriParams['filterId'], + implode(",", $kanbanBoardUriParams['fields']->toArray()) + ); - $response = $this->httpClient - ->setUri($kanbanBoardUri) - ->setAuth($user, $password) - ->send(); + $response = $this->httpClient + ->setUri($kanbanBoardUri) + ->setAuth($user, $password) + ->send(); - if(!$response->isSuccess()) { - throw new \UnexpectedValueException("Bad JIRA result", $response->getStatusCode()); + if (!$response->isSuccess()) { + throw new \UnexpectedValueException("Bad JIRA result", $response->getStatusCode()); + } + + $parsedJsonData = Decoder::decode($response->getBody(), Json::TYPE_ARRAY); + + $kanbanBoard = $this->hydrateKanbanBoard($parsedJsonData); + $this->cache->setItem(self::CACHE_KEY_KANBANBOARD, serialize($kanbanBoard)); + } else { + $kanbanBoard = unserialize($kanbanBoard); } - $parsedJsonData = Decoder::decode($response->getBody(), Json::TYPE_ARRAY); - return $this->hydrateKanbanBoard($parsedJsonData); + return $kanbanBoard; } /** @@ -118,7 +139,7 @@ class JiraCollectorService { $kanbanBoard = new KanbanBoard(); - foreach($parsedJsonData['issues'] as $jsonIssue) { + foreach ($parsedJsonData['issues'] as $jsonIssue) { $kanbanEntry = new KanbanEntry(); $kanbanEntry->setId(intval($jsonIssue['id'])) ->setKey($jsonIssue['key']) @@ -128,61 +149,60 @@ class JiraCollectorService ->setAnswerCode($jsonIssue['fields']['customfield_11692']) ->setIssuePriority($jsonIssue['fields']['priority']['name']) ->setIssuePriorityIcon($jsonIssue['fields']['priority']['iconUrl']) - ->setLabels($jsonIssue['fields']['labels']) - ; + ->setLabels($jsonIssue['fields']['labels']); $spikeTimeSpent = 0; - array_map(function($worklog) use (&$spikeTimeSpent){ + array_map(function ($worklog) use (&$spikeTimeSpent) { $spikeTimeSpent += strtoupper($worklog['comment']) == 'BLOCKED' ? 0 : $worklog['timeSpentSeconds']; }, $jsonIssue['fields']['worklog']['worklogs']); - $kanbanEntry->setWorklog(ceil($spikeTimeSpent/3600)); + $kanbanEntry->setWorklog(ceil($spikeTimeSpent / 3600)); $secondsBlocked = 0; - array_map(function($worklog) use (&$secondsBlocked){ + array_map(function ($worklog) use (&$secondsBlocked) { $secondsBlocked += strtoupper($worklog['comment']) == 'BLOCKED' ? $worklog['timeSpentSeconds'] : 0; }, $jsonIssue['fields']['worklog']['worklogs']); - $kanbanEntry->setDaysBlocked(ceil($secondsBlocked/28800)); + $kanbanEntry->setDaysBlocked(ceil($secondsBlocked / 28800)); // externalId : customfield_10010 - if(isset($jsonIssue['fields']['customfield_10010'])) { + if (isset($jsonIssue['fields']['customfield_10010'])) { $kanbanEntry->setPrio(intval($jsonIssue['fields']['customfield_10010'])); } // prio : customfield_10840 - if(isset($jsonIssue['fields']['customfield_11226'])) { + if (isset($jsonIssue['fields']['customfield_11226'])) { $kanbanEntry->setPrio($jsonIssue['fields']['customfield_11226']); } // functional area : customfield_11225 - if(isset($jsonIssue['fields']['customfield_11225'])) { + if (isset($jsonIssue['fields']['customfield_11225'])) { foreach ($jsonIssue['fields']['customfield_11225'] as $functionalArea) { $kanbanEntry->addFunctionalArea($functionalArea['value']); } } // project : customfield_10840 - if(isset($jsonIssue['fields']['customfield_10840'])) { + if (isset($jsonIssue['fields']['customfield_10840'])) { $kanbanEntry->setProject($jsonIssue['fields']['customfield_10840']['value']); } // mhweb hot : customfield_10847 - if(isset($jsonIssue['fields']['customfield_10847'])) { + if (isset($jsonIssue['fields']['customfield_10847'])) { $boolVal = $jsonIssue['fields']['customfield_10847'][0]['value'] == 'yes'; $kanbanEntry->setMhwebHot($boolVal); } // mhweb external : customfield_10849 - if(isset($jsonIssue['fields']['customfield_10849'])) { + if (isset($jsonIssue['fields']['customfield_10849'])) { $boolVal = $jsonIssue['fields']['customfield_10849'][0]['value'] == 'yes'; $kanbanEntry->setMhwebExternal($boolVal); } // team : customfield_10904 - if(isset($jsonIssue['fields']['customfield_10904'])) { + if (isset($jsonIssue['fields']['customfield_10904'])) { $kanbanEntry->setTeam($jsonIssue['fields']['customfield_10904']['value']); } @@ -193,7 +213,7 @@ class JiraCollectorService $kanbanEntry->setStatus($jiraStatus); // assignee - if($jsonIssue['fields']['assignee']) { + if ($jsonIssue['fields']['assignee']) { $avatarUrl = $this->avatarService->getJiraAvatarUrl( $jsonIssue['fields']['assignee']['avatarUrls']['48x48'], $jsonIssue['fields']['assignee']['key'] @@ -211,7 +231,7 @@ class JiraCollectorService } // issue type - if($jsonIssue['fields']['issuetype']) { + if ($jsonIssue['fields']['issuetype']) { $jiraIssueType = new JiraIssueType(); $jiraIssueType->setName($jsonIssue['fields']['issuetype']['name']) ->setDescription($jsonIssue['fields']['issuetype']['description']) @@ -223,7 +243,7 @@ class JiraCollectorService $kanbanEntry->setUpdatedAt(new \DateTime($jsonIssue['fields']['updated'])); - switch($jiraStatus->getName()) { + switch ($jiraStatus->getName()) { case "Backlog": $kanbanBoard->addInbox($kanbanEntry); break; diff --git a/src/App/Service/JiraCollectorServiceFactory.php b/src/App/Service/JiraCollectorServiceFactory.php index 1318ede..9dc3211 100644 --- a/src/App/Service/JiraCollectorServiceFactory.php +++ b/src/App/Service/JiraCollectorServiceFactory.php @@ -10,10 +10,11 @@ class JiraCollectorServiceFactory { public function __invoke(ContainerInterface $container) { + $cache = $container->get('service.cache'); $configArray = $container->get('config'); $httpClient = $container->get(Client::class); $config = new Config($configArray['app.config']); $avatarService = $container->get(AvatarService::class); - return new JiraCollectorService($httpClient, $config, $avatarService); + return new JiraCollectorService($cache,$httpClient, $config, $avatarService); } } diff --git a/src/App/Service/TspInfoService.php b/src/App/Service/TspInfoService.php new file mode 100644 index 0000000..0004557 --- /dev/null +++ b/src/App/Service/TspInfoService.php @@ -0,0 +1,95 @@ +cache = $cache; + $this->config = $config; + $this->vacationInfoCollectorService = $vacationInfoCollectorService; + $this->trInfoCollectorService = $trInfoCollectorService; + $this->jcatInfoCollectorService = $jcatInfoCollectorService; + $this->labInfoCollectorService = $labInfoCollectorService; + $this->jiraCollectorService = $jiraCollectorService; + } + + /** + * @param bool $forceReload + * @return array + */ + public function getTspInfo(bool $forceReload = false): array + { + $tspInfo = $this->cache->getItem(self::CACHE_KEY); + if($forceReload || null == $tspInfo) { + $tspInfo = [ + 'cameraUrls' => $this->config->get('url.eurestCameras')->toArray(), + 'animGifs' => [], + 'praGoals' => $this->trInfoCollectorService->getPraGoals(), + 'trProgressInfo' => $this->trInfoCollectorService->getProgressInfo(), + 'trFlowErrors' => $this->jcatInfoCollectorService->getTrFlowErrors(), + 'expedites' => $this->jiraCollectorService->getExpedites(), +// 'isVacationSoon' => $this->vacationInfoCollectorService->isVacationSoon(), +// 'labTemperature' => $this->labInfoCollectorService->getLabTemperatureData(), + ]; + $this->cache->setItem(self::CACHE_KEY, serialize($tspInfo)); + } else { + $tspInfo = unserialize($tspInfo); + } + return $tspInfo; + } +} diff --git a/src/App/Service/TspInfoServiceFactory.php b/src/App/Service/TspInfoServiceFactory.php new file mode 100644 index 0000000..2e15fab --- /dev/null +++ b/src/App/Service/TspInfoServiceFactory.php @@ -0,0 +1,30 @@ +get('config')['app.config']; + $cache = $container->get('service.cache'); + $dataCollectorService = $container->get(VacationInfoCollectorService::class); + $trInfoCollectorService = $container->get(TrInfoCollectorService::class); + $jcatInfoCollectorService = $container->get(JcatInfoCollectorService::class); + $labInfoCollectorService = $container->get(LabInfoCollectorService::class); + $jiraInfoCollectorService = $container->get(JiraCollectorService::class); + return new TspInfoService( + $cache, + new Config($appConfig), + $dataCollectorService, + $trInfoCollectorService, + $jcatInfoCollectorService, + $labInfoCollectorService, + $jiraInfoCollectorService + ); + } +}