async def update_connected_space_name_by_id( connect_id: Optional[ConnectedSpaceId], name: Optional[str], principal_service: PrincipalService = Depends(get_console_principal) ) -> None: """ rename connected space will not increase the optimistic lock version """ if is_blank(connect_id): raise_400('Connected space id is required.') connected_space_service = get_connected_space_service(principal_service) # noinspection DuplicatedCode def action() -> None: existing_one = connected_space_service.find_tenant_and_user(connect_id) if existing_one is None: raise_404() existing_tenant_id, existing_user_id = existing_one if existing_tenant_id != principal_service.get_tenant_id(): raise_403() elif existing_user_id != principal_service.get_user_id(): raise_403() # noinspection PyTypeChecker connected_space_service.update_name(connect_id, name, principal_service.get_user_id(), principal_service.get_tenant_id()) trans(connected_space_service, action)
async def init_tenant( tenant_id: Optional[TenantId], principal_service: PrincipalService = Depends(get_any_admin_principal) ) -> None: if is_blank(tenant_id): if principal_service.is_super_admin(): raise_400('Tenant id is required.') elif principal_service.is_tenant_admin(): tenant_id = principal_service.get_tenant_id() else: if principal_service.get_tenant_id( ) != tenant_id and principal_service.is_tenant_admin(): raise_400(f'Tenant[{tenant_id}] does not match principal.') elif principal_service.is_super_admin(): tenant: Optional[Tenant] = get_tenant_service( principal_service).find_by_id(tenant_id) if tenant is None: raise_404(f'Tenant[id={tenant_id}] not found.') meta_tenant_service = get_meta_tenant_service(principal_service) def action() -> None: topics = ask_pipeline_monitor_topics() create_topics_and_pipelines( topics, lambda source_topics: ask_pipeline_monitor_pipelines( source_topics), tenant_id, meta_tenant_service, principal_service) topics = ask_dqc_topics() create_topics_and_pipelines( topics, lambda source_topics: ask_dqc_pipelines(source_topics), tenant_id, meta_tenant_service, principal_service) trans(meta_tenant_service, action)
async def delete_connected_space_by_id( connect_id: Optional[ConnectedSpaceId], principal_service: PrincipalService = Depends(get_console_principal) ) -> None: if is_blank(connect_id): raise_400('Connected space id is required.') connected_space_service = get_connected_space_service(principal_service) # noinspection DuplicatedCode def action() -> None: # noinspection PyTypeChecker existing_connected_space: Optional[ ConnectedSpace] = connected_space_service.find_by_id(connect_id) if existing_connected_space is None: raise_404() if existing_connected_space.tenantId != principal_service.get_tenant_id( ): raise_403() if not principal_service.is_tenant_admin( ) and existing_connected_space.userId != principal_service.get_user_id( ): raise_403() connected_space_service.delete(connect_id) subject_service: SubjectService = get_subject_service( connected_space_service) subject_service.delete_by_connect_id(connect_id) report_service: ReportService = get_report_service( connected_space_service) report_service.delete_by_connect_id(connect_id) trans(connected_space_service, action)
async def update_dashboard_name_by_id( dashboard_id: Optional[DashboardId], name: Optional[str], principal_service: PrincipalService = Depends(get_console_principal) ) -> None: """ rename dashboard will not increase the optimistic lock version """ if is_blank(dashboard_id): raise_400('Dashboard id is required.') dashboard_service = get_dashboard_service(principal_service) # noinspection DuplicatedCode def action() -> None: existing_one = dashboard_service.find_tenant_and_user(dashboard_id) if existing_one is None: raise_404() existing_tenant_id, existing_user_id = existing_one if existing_tenant_id != principal_service.get_tenant_id(): raise_403() elif existing_user_id != principal_service.get_user_id(): raise_403() # noinspection PyTypeChecker dashboard_service.update_name( dashboard_id, name, principal_service.get_user_id(), principal_service.get_tenant_id()) trans(dashboard_service, action)
async def delete_subject_by_id( subject_id: Optional[SubjectId], principal_service: PrincipalService = Depends(get_console_principal) ) -> None: if is_blank(subject_id): raise_400('Subject id is required.') subject_service = get_subject_service(principal_service) # noinspection DuplicatedCode def action() -> None: # noinspection PyTypeChecker existing_subject: Optional[Subject] = subject_service.find_by_id( subject_id) if existing_subject is None: raise_404() if existing_subject.tenantId != principal_service.get_tenant_id(): raise_403() if not principal_service.is_tenant_admin( ) and existing_subject.userId != principal_service.get_user_id(): raise_403() subject_service.delete(subject_id) report_service: ReportService = get_report_service(subject_service) report_service.delete_by_subject_id(subject_id) trans(subject_service, action)
async def update_pipeline_enabled_by_id( pipeline_id: Optional[PipelineId], enabled: Optional[bool], principal_service: PrincipalService = Depends(get_admin_principal) ) -> None: """ enable/disable pipeline will not increase the optimistic lock version """ if is_blank(pipeline_id): raise_400('Pipeline id is required.') if enabled is None: raise_400('Enabled is required.') pipeline_service = get_pipeline_service(principal_service) def action() -> None: existing_tenant_id: Optional[ TenantId] = pipeline_service.find_tenant_id(pipeline_id) if existing_tenant_id is None: raise_404() elif existing_tenant_id != principal_service.get_tenant_id(): raise_403() # noinspection PyTypeChecker pipeline: Pipeline = pipeline_service.update_enablement( pipeline_id, enabled, principal_service.get_tenant_id()) post_update_pipeline_enablement(pipeline, pipeline_service) trans(pipeline_service, action)
async def save_tenant( tenant: Tenant, principal_service: PrincipalService = Depends(get_super_admin_principal) ) -> Tenant: tenant_service = get_tenant_service(principal_service) def action(a_tenant: Tenant) -> Tenant: if tenant_service.is_storable_id_faked(a_tenant.tenantId): tenant_service.redress_storable_id(a_tenant) # noinspection PyTypeChecker a_tenant: Tenant = tenant_service.create(a_tenant) if ask_create_pipeline_monitor_topics_on_tenant_create(): topics = ask_pipeline_monitor_topics() create_topics_and_pipelines( topics, lambda source_topics: ask_pipeline_monitor_pipelines(source_topics), a_tenant.tenantId, tenant_service, principal_service) if ask_create_dqc_topics_on_tenant_create(): topics = ask_dqc_topics() create_topics_and_pipelines( topics, lambda source_topics: ask_dqc_pipelines(source_topics), a_tenant.tenantId, tenant_service, principal_service) else: # noinspection PyTypeChecker a_tenant: Tenant = tenant_service.update(a_tenant) CacheService.tenant().put(a_tenant) return a_tenant return trans(tenant_service, lambda: action(tenant))
async def import_user_groups( user_groups: List[UserGroup], principal_service: PrincipalService = Depends(get_any_admin_principal)) -> None: if user_groups is None: return if len(user_groups) == 0: return user_group_service = get_user_group_service(principal_service) def action() -> None: validate_tenant_based_tuples(user_groups, get_user_service(user_group_service), principal_service) save = ask_save_user_group_action(user_group_service, principal_service) # noinspection PyTypeChecker ArrayHelper(user_groups).each(lambda x: save(x)) trans(user_group_service, action)
async def delete_enum_by_id_by_super_admin( enum_id: Optional[EnumId] = None, principal_service: PrincipalService = Depends(get_super_admin_principal) ) -> Enum: if not ask_tuple_delete_enabled(): raise_404('Not Found') if is_blank(enum_id): raise_400('Enumeration id is required.') enum_service = get_enum_service(principal_service) def action() -> Enum: # noinspection PyTypeChecker an_enum: Enum = enum_service.delete(enum_id) if an_enum is None: raise_404() enum_item_service = get_enum_item_service(enum_service) enum_items = enum_item_service.find_by_enum_id(an_enum.enumId) if enum_items is None: an_enum.items = [] else: an_enum.items = enum_items enum_item_service.delete_by_enum_id(an_enum.enumId) return an_enum return trans(enum_service, action)
async def import_dashboards( dashboards: List[Dashboard], principal_service: PrincipalService = Depends(get_any_admin_principal)) -> None: if dashboards is None: return if len(dashboards) == 0: return dashboard_service = get_dashboard_service(principal_service) def action() -> None: validate_user_based_tuples(dashboards, get_user_service(dashboard_service), principal_service) save = ask_save_dashboard_action(dashboard_service, principal_service) # noinspection PyTypeChecker ArrayHelper(dashboards).each(lambda x: save(x)) trans(dashboard_service, action)
async def delete_user_by_id_by_super_admin( user_id: Optional[UserId] = None, principal_service: PrincipalService = Depends(get_super_admin_principal) ) -> User: if not ask_tuple_delete_enabled(): raise_404('Not Found') if is_blank(user_id): raise_400('User id is required.') user_service = get_user_service(principal_service) def action() -> User: # noinspection PyTypeChecker user: User = user_service.delete(user_id) if user is None: raise_404() user_group_ids = user.groupIds if user_group_ids is not None and len(user_group_ids) != 0: user_group_ids = ArrayHelper(user_group_ids).filter( lambda x: is_not_blank(x)).to_list() remove_user_from_groups(user_service, user.userId, user_group_ids, user.tenantId) return user return trans(user_service, action)
async def import_pipelines( pipelines: List[Pipeline], principal_service: PrincipalService = Depends(get_any_admin_principal) ) -> List[Pipeline]: if pipelines is None: return [] if len(pipelines) == 0: return [] pipeline_service = get_pipeline_service(principal_service) def action() -> List[Pipeline]: validate_tenant_based_tuples(pipelines, get_user_service(pipeline_service), principal_service) for pipeline in pipelines: for stage in ArrayHelper(pipeline.stages).to_list(): for unit in ArrayHelper(stage.units).to_list(): for an_action in ArrayHelper(unit.action).to_list(): if an_action.type == PipelineActionType.WRITE_TO_EXTERNAL: if isinstance(an_action, WriteToExternalAction): an_action.externalWriterId = None save = ask_save_pipeline_action(pipeline_service, principal_service) # noinspection PyTypeChecker return ArrayHelper(pipelines).map(lambda x: save(x)).to_list() return trans(pipeline_service, action)
async def save_console_space_graphic( connected_space_graphic: ConnectedSpaceGraphic, principal_service: PrincipalService = Depends(get_console_principal) ) -> ConnectedSpaceGraphic: """ create or update my connected space graphic """ connected_space_graphic_service = get_connected_space_graphic_service( principal_service) def action(graphic: ConnectedSpaceGraphic) -> ConnectedSpaceGraphic: graphic.userId = principal_service.get_user_id() graphic.tenantId = principal_service.get_tenant_id() # noinspection PyTypeChecker existing_graphic: Optional[ConnectedSpaceGraphic] = \ connected_space_graphic_service.find_by_id(graphic.connectId) if existing_graphic is not None: # connected space graphic exists if existing_graphic.tenantId != graphic.tenantId: raise_403() if existing_graphic.userId != graphic.userId: raise_403() # noinspection PyTypeChecker graphic: ConnectedSpaceGraphic = connected_space_graphic_service.update( graphic) else: # connected space graphic does not exist # noinspection PyTypeChecker graphic: ConnectedSpaceGraphic = connected_space_graphic_service.create( graphic) return graphic return trans(connected_space_graphic_service, lambda: action(connected_space_graphic))
async def save_subject( subject: Subject, principal_service: PrincipalService = Depends(get_console_principal) ) -> Subject: subject_service = get_subject_service(principal_service) action = ask_save_subject_action(subject_service, principal_service) return trans(subject_service, lambda: action(subject))
async def save_pipeline( pipeline: Pipeline, principal_service: PrincipalService = Depends(get_admin_principal) ) -> Pipeline: validate_tenant_id(pipeline, principal_service) pipeline_service = get_pipeline_service(principal_service) action = ask_save_pipeline_action(pipeline_service, principal_service) return trans(pipeline_service, lambda: action(pipeline))
async def save_user_group( user_group: UserGroup, principal_service: PrincipalService = Depends(get_admin_principal) ) -> UserGroup: validate_tenant_id(user_group, principal_service) user_group_service = get_user_group_service(principal_service) action = ask_save_user_group_action(user_group_service, principal_service) return trans(user_group_service, lambda: action(user_group))
async def save_user( user: User, principal_service: PrincipalService = Depends(get_any_admin_principal) ) -> User: validate_tenant_id(user, principal_service) user_service = get_user_service(principal_service) action = ask_save_user_action(user_service, principal_service) return trans(user_service, lambda: action(user))
async def import_subjects( subjects: List[Subject], principal_service: PrincipalService = Depends(get_any_admin_principal) ) -> None: if subjects is None: return if len(subjects) == 0: return subject_service = get_subject_service(principal_service) def action() -> None: validate_user_based_tuples(subjects, get_user_service(subject_service), principal_service) save = ask_save_subject_action(subject_service, principal_service) # noinspection PyTypeChecker ArrayHelper(subjects).each(lambda x: save(x)) trans(subject_service, action)
async def delete_dashboard_by_id( dashboard_id: Optional[DashboardId], principal_service: PrincipalService = Depends(get_console_principal) ) -> None: if is_blank(dashboard_id): raise_400('Dashboard id is required.') dashboard_service = get_dashboard_service(principal_service) # noinspection DuplicatedCode def action() -> None: # noinspection PyTypeChecker existing_dashboard: Optional[Dashboard] = dashboard_service.find_by_id(dashboard_id) if existing_dashboard is None: raise_404() if existing_dashboard.tenantId != principal_service.get_tenant_id(): raise_403() if not principal_service.is_tenant_admin() and existing_dashboard.userId != principal_service.get_user_id(): raise_403() dashboard_service.delete(dashboard_id) trans(dashboard_service, action)
async def find_my_pats(principal_service: PrincipalService = Depends( get_any_principal)) -> List[ClientPat]: pat_service = get_pat_service(principal_service) def action() -> List[ClientPat]: pats = pat_service.find_by_user_id(principal_service.get_user_id(), principal_service.get_tenant_id()) return ArrayHelper(pats) \ .map(lambda pat: ClientPat(patId=pat.patId, token=pat.token, note=pat.note)) \ .to_list() return trans(pat_service, action)
async def import_connected_spaces( connected_spaces: List[ConnectedSpace], principal_service: PrincipalService = Depends(get_any_admin_principal) ) -> None: if connected_spaces is None: return if len(connected_spaces) == 0: return connected_space_service = get_connected_space_service(principal_service) def action() -> None: validate_user_based_tuples(connected_spaces, get_user_service(connected_space_service), principal_service) save = ask_save_connected_space_action(connected_space_service, principal_service) # noinspection PyTypeChecker ArrayHelper(connected_spaces).each(lambda x: save(x)) trans(connected_space_service, action)
async def items_import( import_items_list: List[ImportEnumItems], principal_service: PrincipalService = Depends(get_admin_principal) ) -> None: if import_items_list is None or len(import_items_list) == 0: return enum_service = get_enum_service(principal_service) enum_item_service = get_enum_item_service(enum_service) def find_enum( import_items: ImportEnumItems) -> Tuple[Enum, List[EnumItem]]: enum_id = import_items.enumId name = import_items.name if is_blank(enum_id) and is_blank(name): raise_400( 'At least one of enumeration id and name must be provided.') enumeration = None if is_not_blank(enum_id): # both provided, find by id enumeration = enum_service.find_by_id(enum_id) elif is_not_blank(name): enumeration = enum_service.find_by_name( name, principal_service.get_tenant_id()) if enumeration is not None: # found if enumeration.tenantId != principal_service.get_tenant_id(): raise_404(f'Enumeration[id={enum_id}, name={name}] not found.') elif is_not_blank(name): # not found, but name is given, create one enumeration = Enum(enumId=enum_id, name=name, tenantId=principal_service.get_tenant_id(), items=[]) enum_service.create(enumeration) else: raise_404(f'Enumeration[id={enum_id}, name={name}] not found.') return enumeration, import_items.items def save_items(enumeration: Enum, items: List[EnumItem]) -> None: enum_item_service.delete_by_enum_id(enumeration.enumId) ArrayHelper(items).each( lambda x: create_enum_item(enum_item_service, x, enumeration)) def action() -> None: ArrayHelper(import_items_list).map(lambda x: find_enum(x)).each( lambda x: save_items(x[0], x[1])) return trans(enum_service, action)
async def delete_scheduler( scheduler_id: Optional[TopicSnapshotSchedulerId], principal_service: PrincipalService = Depends(get_admin_principal) ) -> None: if not ask_tuple_delete_enabled(): raise_404('Not Found') if is_blank(scheduler_id): raise_400('Scheduler id is required.') scheduler_service = get_topic_snapshot_scheduler_service(principal_service) # noinspection DuplicatedCode def action() -> None: # noinspection PyTypeChecker existing_scheduler: Optional[ TopicSnapshotScheduler] = scheduler_service.find_by_id( scheduler_id) if existing_scheduler is None: raise_404() scheduler_service.delete(scheduler_id) trans(scheduler_service, action)
async def mix_import( request: MixImportDataRequest, principal_service: PrincipalService = Depends(get_any_admin_principal) ) -> MixImportDataResponse: user_service = get_user_service(principal_service) if request.importType == MixedImportType.NON_REDUNDANT: action = import_on_non_redundant elif request.importType == MixedImportType.REPLACE: action = import_on_replace elif request.importType == MixedImportType.FORCE_NEW: action = import_on_force_new else: raise_400(f'Incorrect import type[{request.importType}].') return trans(user_service, lambda: action(request, user_service, principal_service))
async def delete_pat( pat_id: Optional[PatId] = None, principal_service: PrincipalService = Depends(get_any_principal) ) -> None: if is_blank(pat_id): raise_400('Pat id is required.') pat_service = get_pat_service(principal_service) def action() -> None: pat = pat_service.find_by_id(pat_id, principal_service.get_user_id(), principal_service.get_tenant_id()) if pat is not None: pat_service.delete_by_id(pat_id) return trans(pat_service, action)
async def create_pat(params: PatCreationParams = Body(...), principal_service: PrincipalService = Depends( get_any_principal)) -> ClientPat: pat_service = get_pat_service(principal_service) def action() -> ClientPat: pat = PersonalAccessToken(token=token_urlsafe(16), userId=principal_service.get_user_id(), username=principal_service.get_user_name(), tenantId=principal_service.get_tenant_id(), note=params.note, expired=params.expired, permissions=[], createdAt=get_current_time_in_seconds()) pat_service.create(pat) return ClientPat(patId=pat.patId, token=pat.token, note=pat.note) return trans(pat_service, action)
async def save_external_writer( external_writer: ExternalWriter, principal_service: PrincipalService = Depends(get_super_admin_principal) ) -> ExternalWriter: external_writer_service = get_external_writer_service(principal_service) # noinspection DuplicatedCode def action(writer: ExternalWriter) -> ExternalWriter: if external_writer_service.is_storable_id_faked(writer.writerId): external_writer_service.redress_storable_id(writer) # noinspection PyTypeChecker writer: ExternalWriter = external_writer_service.create(writer) else: # noinspection PyTypeChecker writer: ExternalWriter = external_writer_service.update(writer) return writer return trans(external_writer_service, lambda: action(external_writer))
async def connect_as_connected_space( space_id: Optional[SpaceId], name: Optional[str], template_ids: Optional[str], principal_service: PrincipalService = Depends(get_console_principal) ) -> ConnectedSpaceWithSubjects: if is_blank(space_id): raise_400('Space id is required.') connected_space_service = get_connected_space_service(principal_service) def action() -> ConnectedSpaceWithSubjects: space_service = get_space_service(connected_space_service) space: Optional[Space] = space_service.find_by_id(space_id) if space is None: raise_400('Incorrect space id.') if space.tenantId != principal_service.get_tenant_id(): raise_403() template_connected_spaces = find_template_connected_spaces_by_ids( connected_space_service, template_ids, space_id, space.tenantId) connected_space = ConnectedSpace(spaceId=space_id, name=name, isTemplate=False) connected_space_service.redress_storable_id(connected_space) connected_space.userId = principal_service.get_user_id() connected_space.tenantId = principal_service.get_tenant_id() connected_space.lastVisitTime = get_current_time_in_seconds() # noinspection PyTypeChecker connected_space: ConnectedSpace = connected_space_service.create( connected_space) subjects_with_reports = ArrayHelper(template_connected_spaces) \ .map(lambda x: copy_to_connected_space(x, connected_space, connected_space_service)) \ .flatten().to_list() connected_space_with_subjects = ConnectedSpaceWithSubjects( **connected_space.dict()) connected_space_with_subjects.subjects = subjects_with_reports return connected_space_with_subjects return trans(connected_space_service, action)
async def delete_report_by_id_by_super_admin( report_id: Optional[ReportId] = None, principal_service: PrincipalService = Depends(get_super_admin_principal) ) -> Report: if not ask_tuple_delete_enabled(): raise_404('Not Found') if is_blank(report_id): raise_400('Report id is required.') report_service = get_report_service(principal_service) def action() -> Report: # noinspection PyTypeChecker report: Report = report_service.delete(report_id) if report is None: raise_404() return report return trans(report_service, action)
async def delete_dashboard_by_id_by_super_admin( dashboard_id: Optional[DashboardId] = None, principal_service: PrincipalService = Depends(get_super_admin_principal) ) -> Dashboard: if not ask_tuple_delete_enabled(): raise_404('Not Found') if is_blank(dashboard_id): raise_400('Report id is required.') dashboard_service = get_dashboard_service(principal_service) def action() -> Dashboard: # noinspection PyTypeChecker dashboard: Dashboard = dashboard_service.delete(dashboard_id) if dashboard is None: raise_404() return dashboard return trans(dashboard_service, action)