From 78bd5ea3156d6a63b6c8fcc0af55ee97f70205d6 Mon Sep 17 00:00:00 2001 From: Jan Kielmann Date: Thu, 20 May 2021 16:55:13 +0200 Subject: [PATCH] Implement statistics endpoint --- backend/src/contaxy/api/endpoints/system.py | 5 +- backend/src/contaxy/clients/system.py | 10 ++- backend/src/contaxy/managers/components.py | 3 + backend/src/contaxy/managers/system.py | 85 +++++++++++++++++++-- backend/src/contaxy/operations/system.py | 2 +- 5 files changed, 94 insertions(+), 11 deletions(-) diff --git a/backend/src/contaxy/api/endpoints/system.py b/backend/src/contaxy/api/endpoints/system.py index aa663004..63dea48b 100644 --- a/backend/src/contaxy/api/endpoints/system.py +++ b/backend/src/contaxy/api/endpoints/system.py @@ -69,12 +69,15 @@ def check_health( responses={**AUTH_ERROR_RESPONSES}, ) def get_system_statistics( + include_technical: bool = True, component_manager: ComponentManager = Depends(get_component_manager), token: str = Depends(get_api_token), ) -> Any: """Returns statistics about this instance.""" component_manager.verify_access(token, "system", AccessLevel.READ) - return component_manager.get_system_manager().get_system_statistics() + return component_manager.get_system_manager().get_system_statistics( + include_technical + ) @router.post( diff --git a/backend/src/contaxy/clients/system.py b/backend/src/contaxy/clients/system.py index a78124b9..70fa6037 100644 --- a/backend/src/contaxy/clients/system.py +++ b/backend/src/contaxy/clients/system.py @@ -22,8 +22,14 @@ def is_healthy(self, request_kwargs: Dict = {}) -> bool: handle_errors(response) return True - def get_system_statistics(self, request_kwargs: Dict = {}) -> SystemStatistics: - response = self._client.get("/system/statistics", **request_kwargs) + def get_system_statistics( + self, include_technical: bool = True, request_kwargs: Dict = {} + ) -> SystemStatistics: + response = self._client.get( + "/system/statistics", + params={"include_technical": include_technical}, + **request_kwargs, + ) handle_errors(response) return parse_raw_as(SystemStatistics, response.text) diff --git a/backend/src/contaxy/managers/components.py b/backend/src/contaxy/managers/components.py index be7effcd..fd07df4b 100644 --- a/backend/src/contaxy/managers/components.py +++ b/backend/src/contaxy/managers/components.py @@ -160,6 +160,9 @@ def get_system_manager(self) -> SystemManager: self.get_json_db_manager(), self.get_auth_manager(), self.get_project_manager(), + self.get_service_manager(), + self.get_job_manager(), + self.get_file_manager(), ) assert self._system_manager is not None diff --git a/backend/src/contaxy/managers/system.py b/backend/src/contaxy/managers/system.py index 83808aa9..1ae24549 100644 --- a/backend/src/contaxy/managers/system.py +++ b/backend/src/contaxy/managers/system.py @@ -1,13 +1,25 @@ -from typing import Optional +from typing import List, Optional from contaxy import __version__, config from contaxy.config import settings from contaxy.managers.auth import AuthManager -from contaxy.operations import SystemOperations +from contaxy.operations import ( + FileOperations, + JobOperations, + ServiceOperations, + SystemOperations, +) from contaxy.operations.json_db import JsonDocumentOperations from contaxy.operations.project import ProjectOperations -from contaxy.schema.auth import ADMIN_ROLE, USERS_KIND, AccessLevel, UserRegistration -from contaxy.schema.project import ProjectCreation +from contaxy.schema import File, Job, Service +from contaxy.schema.auth import ( + ADMIN_ROLE, + USERS_KIND, + AccessLevel, + User, + UserRegistration, +) +from contaxy.schema.project import Project, ProjectCreation from contaxy.schema.system import SystemInfo, SystemStatistics from contaxy.utils import auth_utils from contaxy.utils.state_utils import GlobalState, RequestState @@ -23,6 +35,9 @@ def __init__( json_db_manager: JsonDocumentOperations, auth_manager: AuthManager, project_manager: ProjectOperations, + service_manager: ServiceOperations, + job_manager: JobOperations, + file_manager: FileOperations, ): """Initializes the system manager. @@ -32,12 +47,18 @@ def __init__( json_db_manager: Json document manager instance. auth_manager: Auth manager instance. project_manager: Project manager instance. + service_manager: Service manager instance. + job_manager: Job manager instance. + file_manager: File manager instance. """ self._global_state = global_state self._request_state = request_state self._auth_manager = auth_manager self._project_manager = project_manager self._json_db_manager = json_db_manager + self._service_manager = service_manager + self._job_manager = job_manager + self._file_manager = file_manager def get_system_info(self) -> SystemInfo: return SystemInfo( @@ -49,10 +70,18 @@ def is_healthy(self) -> bool: # TODO: do real healthchecks return True - def get_system_statistics(self) -> SystemStatistics: - # TODO: Implement system statistics + def get_system_statistics(self, include_technical: bool) -> SystemStatistics: + projects = self._list_all_projects(include_technical) + users = self._list_all_users(include_technical) + jobs = self._list_all_jobs(projects) + services = self._list_all_services(projects) + files = self._list_all_files(projects) return SystemStatistics( - project_count=0, user_count=0, job_count=0, service_count=0, file_count=0 + project_count=len(jobs), + user_count=len(users), + job_count=len(jobs), + service_count=len(services), + file_count=len(files), ) def initialize_system( @@ -103,3 +132,45 @@ def initialize_system( ) auth_utils.create_user_project(admin_user, self._project_manager) + + def _list_all_projects(self, include_technical: bool) -> List[Project]: + # Temporarily set authorized_access to None so that list_projects returns all projects + # TODO: Find better solution to get all projects + temp = self._request_state.authorized_access + self._request_state.authorized_access = None + projects = self._project_manager.list_projects() + self._request_state.authorized_access = temp + + if not include_technical: + projects = [proj for proj in projects if not proj.technical_project] + return projects + + def _list_all_users(self, include_technical: bool) -> List[User]: + users = self._auth_manager.list_users() + if not include_technical: + users = [user for user in users if not user.technical_user] + return users + + def _list_all_jobs(self, projects: List[Project]) -> List[Job]: + return [ + job + for project in projects + if project.id + for job in self._job_manager.list_jobs(project.id) + ] + + def _list_all_services(self, projects: List[Project]) -> List[Service]: + return [ + service + for project in projects + if project.id + for service in self._service_manager.list_services(project.id) + ] + + def _list_all_files(self, projects: List[Project]) -> List[File]: + return [ + file + for project in projects + if project.id + for file in self._file_manager.list_files(project.id) + ] diff --git a/backend/src/contaxy/operations/system.py b/backend/src/contaxy/operations/system.py index 79e67475..dc860907 100644 --- a/backend/src/contaxy/operations/system.py +++ b/backend/src/contaxy/operations/system.py @@ -13,7 +13,7 @@ def is_healthy(self) -> bool: pass @abstractmethod - def get_system_statistics(self) -> SystemStatistics: + def get_system_statistics(self, include_technical: bool) -> SystemStatistics: pass @abstractmethod