Beispiel #1
0
 def __init__(self, tracer, create_session):
     super().__init__(name="template",
                      tracer=tracer,
                      create_session=create_session)
     self.template = VersionObject(name=self.name,
                                   primary_key="template_id",
                                   entity=Template,
                                   create_session=create_session)
Beispiel #2
0
    def __init__(self, tracer, create_session):

        super().__init__(name="task",
                         tracer=tracer,
                         create_session=create_session)
        self.task = VersionObject(name=self.name,
                                  primary_key="task_id",
                                  entity=Task,
                                  create_session=create_session)
Beispiel #3
0
    def __init__(self, tracer, create_session):

        super().__init__(name="complect",
                         tracer=tracer,
                         create_session=create_session)
        self.complect = VersionObject(name=self.name,
                                      primary_key="complect_id",
                                      entity=Complect,
                                      create_session=create_session)
    def __init__(self, tracer, create_session):

        super().__init__(name="access.user",
                         tracer=tracer,
                         create_session=create_session)
        self.access_profile_user = VersionObject(name=self.name,
                                                 primary_key=("user_id",
                                                              "profile_id"),
                                                 entity=AccessProfileUser,
                                                 create_session=create_session)
Beispiel #5
0
    def __init__(self, tracer, create_session) -> None:

        super().__init__(name="complect_revision",
                         tracer=tracer,
                         create_session=create_session)

        self.complect_revision = VersionObject(name=self.name,
                                               primary_key="revision_id",
                                               entity=ComplectRevision,
                                               create_session=create_session)
    def __init__(self, tracer, create_session) -> None:

        super().__init__(name="access.complect_account",
                         tracer=tracer,
                         create_session=create_session)
        self.access_complect_account = VersionObject(
            name=self.name,
            primary_key=("account_id", "complect_id"),
            entity=AccessComplectAccount,
            create_session=create_session)
Beispiel #7
0
    def __init__(self, tracer, create_session):

        super().__init__(name="access.account",
                         tracer=tracer,
                         create_session=create_session)
        self.access_account = VersionObject(name=self.name,
                                            primary_key=("account_id",
                                                         "profile_id"),
                                            entity=AccessProfileAccount,
                                            create_session=create_session)
Beispiel #8
0
    def __init__(self, tracer, create_session):

        super().__init__(name="dictionary",
                         tracer=tracer,
                         create_session=create_session)
        self.dictionary = VersionObject(
            name=self.name,
            primary_key="dictionary_id",
            entity=Dictionary,
            versions_entity=DictionaryVersion,
            create_session=create_session,
        )
class AccessProfileUserRpc(RpcGroup):
    def __init__(self, tracer, create_session):

        super().__init__(name="access.user",
                         tracer=tracer,
                         create_session=create_session)
        self.access_profile_user = VersionObject(name=self.name,
                                                 primary_key=("user_id",
                                                              "profile_id"),
                                                 entity=AccessProfileUser,
                                                 create_session=create_session)

    def create(self, **kwargs):

        with self.create_session() as session:
            kwargs['session'] = session
            result = self._store(**kwargs)
            session.commit()

            return result

    def update(self, **kwargs):

        with self.create_session() as session:
            kwargs['session'] = session
            kwargs['action'] = 'update'
            result = self._store(**kwargs)
            session.commit()

            return result

    def fetch(self, user_id, profile_ids):

        with self.create_session() as session:
            result = []
            for profile_id in profile_ids:

                permission_model = self.access_profile_user.get(
                    (user_id, profile_id), session=session)
                if not permission_model:
                    raise ApiError(
                        code="NOT_EXISTS",
                        message="Can't find permission with user_id={} "
                        "and profile_id={}".format(user_id, profile_id))
                result.append(permission_model.to_dict())

            return result

    def remove(self, user_id, profile_ids):

        try:
            ids = []
            for profile_id in profile_ids:
                ids.append((user_id, profile_id))

            return self.access_profile_user.remove(ids)

        except VersionNoObject as e:
            raise ApiError(code="NOT_EXISTS", message=e.args[0]) from e

    @staticmethod
    def _form_items(items):

        res = []
        for item in items:
            item_dict = item[0].to_dict()
            res.append(item_dict["profile_id"])
        return res

    def list(self, user_id, offset=None, limit=None, search=None, order=None):
        """
        Получение списка
        """
        items, total_items = self.access_profile_user.filter(
            filter_q=[AccessProfileUser.user_id == user_id],
            offset=offset,
            limit=limit,
            form_items=self._form_items,
            order=order)

        return {
            "items": items,
            "total": total_items,
        }

    @staticmethod
    def _form_permissions(permissions, new_permissions):

        for perm, value in new_permissions.items():
            permissions[perm] = value

        return permissions

    def _store(self,
               user_id=None,
               profile_ids=None,
               action=None,
               session=None):

        for item in profile_ids:
            if action == "update":
                permission_model = self.access_profile_user.get(
                    (user_id, item["profile_id"]), session=session)

                if not permission_model:
                    raise ApiError(
                        code="NOT_EXISTS",
                        message="Can't find permission with user_id={} "
                        "and profile_id={}".format(user_id,
                                                   item["profile_id"]))

                permission_model.permissions = self._form_permissions(
                    copy.deepcopy(permission_model.permissions),
                    item["permissions"])

            else:
                permission_model = self.access_profile_user.get(
                    (user_id, item["profile_id"]), session=session)

                if permission_model:
                    permission_model.permissions = item["permissions"]
                else:
                    permission_model = AccessProfileUser(
                        user_id=user_id,
                        profile_id=item["profile_id"],
                        permissions=item["permissions"])

            session.add(permission_model)

            return {
                "user_id": user_id,
                "profile_ids": profile_ids,
            }
Beispiel #10
0
class TaskRpc(RpcGroup):
    """Задача"""
    def __init__(self, tracer, create_session):

        super().__init__(name="task",
                         tracer=tracer,
                         create_session=create_session)
        self.task = VersionObject(name=self.name,
                                  primary_key="task_id",
                                  entity=Task,
                                  create_session=create_session)

    def create(self, script, type, args=None, meta=None, extra=None):
        """Создание"""

        return self._store(script=script,
                           type=type,
                           args=args,
                           meta=meta,
                           extra=extra)

    def info(self, task_id):
        """Получение задачи"""
        with self.create_session() as session:
            task_model = self.task.get(task_id, session=session)
            if not task_model:
                raise ApiError(code="NOT_EXISTS",
                               message="Can't find task_id with id=%r" %
                               task_id)

            return task_model.to_dict()

    @rpc_name("list")
    def list_(self, type, extra=None, offset=None, limit=None, order=None):
        """Получение списка"""
        def form_items(items):
            return [it[0].to_short_dict() for it in items]

        filter_q = [Task.type == type]

        if extra is not None and isinstance(extra, dict):
            for key, value in extra.items():
                if isinstance(value, int):
                    filter_q.append(
                        Task.extra[str(key)].astext.cast(Integer) == value)
                else:
                    filter_q.append(Task.extra[str(key)].astext == value)

        items, total_items = self.task.filter(filter_q=filter_q,
                                              offset=offset,
                                              limit=limit,
                                              form_items=form_items,
                                              order=order)

        return {
            "items": items,
            "total": total_items,
        }

    def _store(self, script, type, args=None, meta=None, extra=None):

        with self.create_session() as session:

            task_model = Task(
                script=script,
                type=type,
                args=args,
                meta=meta,
                extra=extra,
                created=datetime.now(),
            )

            session.add(task_model)
            session.commit()

            return task_model.to_dict()
Beispiel #11
0
class DictionaryRpc(RpcGroup, BatchUpdateMixin):
    def __init__(self, tracer, create_session):

        super().__init__(name="dictionary",
                         tracer=tracer,
                         create_session=create_session)
        self.dictionary = VersionObject(
            name=self.name,
            primary_key="dictionary_id",
            entity=Dictionary,
            versions_entity=DictionaryVersion,
            create_session=create_session,
        )

    def create(
        self,
        code=None,
        description=None,
        content=None,
        common=None,
        state=None,
        meta=None,
        profile_ids=None,
        is_enabled=None,
        hidden=None,
        kind=None,
        parts=None,
    ):

        with self.create_session() as session:
            result = self._store(
                id=None,
                code=code,
                description=description,
                content=content,
                common=common,
                state=state,
                meta=meta,
                profile_ids=profile_ids,
                is_enabled=is_enabled,
                hidden=hidden,
                session=session,
                kind=kind,
                parts=parts,
            )
            session.commit()
            return result

    def list(self,
             profile_id=None,
             offset=None,
             limit=None,
             search=None,
             common=None,
             order=None,
             code=None,
             id=None,
             kind=None,
             _with_content=None,
             _process=None):

        filter_q = []

        if id is not None:
            filter_q.append(Dictionary.dictionary_id.in_(id))

        if profile_id is not None and profile_id != "":
            if isinstance(profile_id, str):
                profile_id = [profile_id]
            filter_q.append(Dictionary.profile_ids.contains(profile_id))

        if code is not None:
            filter_q.append(Dictionary.code == code)

        if kind is not None:
            filter_q.append(Dictionary.kind == kind)

        if common is not None:
            filter_q.append(Dictionary.common == common)

        form_items = lambda items: [  # noqa
            item[0].to_dict() if _with_content else item[0].to_short_dict()
            for item in items
        ]

        items, total_items = self.dictionary.filter(filter_q=filter_q,
                                                    offset=offset,
                                                    limit=limit,
                                                    form_items=form_items,
                                                    order=order)

        if _process:
            items = [_process_dictionary_inplace(item) for item in items]

        return {
            "items": items,
            "total": total_items,
        }

    def list_versions(self, id, order=None, offset=None, limit=None):
        items, total_items = self.dictionary.versions(
            id,
            order=order,
            offset=offset,
            limit=limit,
        )

        return {
            "items": items,
            "total": total_items,
        }

    def fetch(self, id, _process=None):

        with self.create_session() as session:
            profile_model = self.dictionary.get(id, session=session)
            if not profile_model:
                raise ApiError(code="NOT_EXISTS",
                               message="Can't find profile with id=%r" % id)
            item = profile_model.to_dict()

            if _process:
                item = _process_dictionary_inplace(item)

            return item

    def remove(self, id):

        try:
            result = self.dictionary.remove(id)
            return result
        except VersionNoObject as e:
            raise ApiError(code="NOT_EXISTS", message=e.args[0]) from e

    def _store(self,
               id=None,
               code=None,
               description=None,
               content=None,
               common=None,
               state=None,
               meta=None,
               profile_ids=None,
               is_enabled=None,
               hidden=None,
               action=None,
               kind=None,
               parts=None,
               session=None):

        if action == 'update':
            dictionary_model = self.dictionary.get(id, session=session)
            if not dictionary_model:
                raise ApiError(code="NOT_EXISTS",
                               message="Can't find dictionary with id=%r" % id)
        else:
            dictionary_model = Dictionary(
                created=datetime.now(),
                version=0,
            )

        if code is not None:
            dictionary_model.code = code

        if description is not None:
            dictionary_model.description = description

        if content is not None:
            dictionary_model.content = content

        if common is not None:
            dictionary_model.common = common

        if kind is not None:
            dictionary_model.kind = kind

        if state is not None:
            dictionary_model.state = state

        if meta is not None:
            dictionary_model.meta = meta

        if profile_ids is not None:
            dictionary_model.profile_ids = profile_ids

        if is_enabled is not None:
            dictionary_model.is_enabled = is_enabled

        if hidden is not None:
            dictionary_model.hidden = hidden

        if parts is not None:
            dictionary_model.parts = parts

        dictionary_model.version += 1

        session.add(dictionary_model)
        session.flush()

        data = dictionary_model.to_dict()

        return data

    @staticmethod
    def import_file(profile_ids, file_name, data):
        """
        Импортирование словарей из файла
        """
        result = post_request(url=PROCESSOR_HOST,
                              headers=None,
                              request_data=get_create_request(
                                  method="task.create",
                                  script="scripts.dictionary.import_run",
                                  type=TYPE,
                                  args={
                                      "profile_ids": profile_ids,
                                      "file_name": file_name,
                                      "data": data,
                                  }))

        result = result["result"]
        if result["status"]:
            return result["response"]

        raise ApiError(code="UNHANDLED", message=result["errors"]["message"])

    def export(self, ids):
        """
        Экспортирование шаблонов
        """
        dictionaries = {}

        for dict_id in ids:
            dictionaries[dict_id] = {}

            suite = self.fetch(dict_id)

            dictionaries[dict_id][
                "name"] = suite["code"] or suite.dictionary_id  # noqa
            dictionaries[dict_id]["content"] = suite["content"]

        result = post_request(url=PROCESSOR_HOST,
                              headers=None,
                              request_data=get_create_request(
                                  method="task.create",
                                  script="scripts.dictionaries.export_run",
                                  type=TYPE,
                                  args={"dictionaries": dictionaries}))

        result = result["result"]
        if result["status"]:
            return result["response"]

        raise ApiError(code="UNHANDLED", message=result["errors"]["message"])
Beispiel #12
0
class SuiteRpc(RpcGroup, BatchUpdateMixin):
    def __init__(self, tracer, create_session):

        super().__init__(
            name="suite", tracer=tracer, create_session=create_session
        )
        self.suite = VersionObject(
            name=self.name, primary_key="suite_id", entity=Suite,
            create_session=create_session
        )

    def create(self, **kwargs):
        with self.create_session() as session:
            kwargs['session'] = session
            result = self._store(**kwargs)
            session.commit()

        return result

    def remove(self, id):

        try:
            with self.create_session() as session:
                query_result = session.query(Template).filter(
                    Template.suite_id.in_(
                        [id] if not isinstance(id, list) else id
                    )
                )

                query_result.delete(synchronize_session=False)
                session.commit()

                return self.suite.remove(id=id, session=session)

        except VersionNoObject as e:
            raise ApiError(code="NOT_EXISTS", message=e.args[0]) from e

    def list(self, profile_ids, offset=None, limit=None, search=None,
             order=None, is_enabled=None):

        if not isinstance(profile_ids, list):
            profile_ids = [profile_ids]

        filter_q = [
            Suite.profile_id.in_(profile_ids),
        ]
        return self._stat_filter(
            filter_q=filter_q, offset=offset, limit=limit,
            order=order, is_enabled=is_enabled
        )

    def _stat_filter(self, filter_q, offset, limit, order, is_enabled):

        with self.create_session() as session:
            fetch_args = [
                func.count(Template.template_id).label("templates")
            ]

            if is_enabled is not None:
                filter_q.append(Suite.is_enabled.is_(is_enabled))

            q = self.suite.prepare_filter_q(
                session=session,
                filter_q=filter_q,
                offset=offset,
                limit=limit,
                fetch_args=fetch_args,
                outerjoin=[Template],
                group_by=[Suite.suite_id],
                order=order,
            )

            items = q.all()
            total_items = 0
            if items:
                total_items = items[0][1]

            result_items = []
            for item, total_count, templates_count in items:
                res = item.to_dict()
                res["stat"] = {
                    "templates": templates_count,
                }
                result_items.append(res)

            return {
                "items": result_items,
                "total": total_items,
            }

    def store(self, **kwargs):

        with self.create_session() as session:
            kwargs['session'] = session
            result = self._store(**kwargs)
            session.commit()

            return result

    def _store(self, title=None, state=None, profile_id=None, id=None,
               meta=None, is_enabled=None, action=None, session=None):

        if action == "update":
            suite_model = self.suite.get(id, session=session)
            if not suite_model:
                raise ApiError(
                    code="NOT_EXISTS",
                    message="Can't find suite with id=%r" % id
                )
        else:
            if not profile_id:
                raise ApiError(
                    code="MISSING_PROFILE_ID",
                    message="profile_id must be given for creating suite"
                )

            suite_model = Suite(
                profile_id=profile_id,
                created=datetime.now(),
                version=0,
            )

        if title is not None:
            suite_model.title = title

        if state is not None:
            suite_model.state = state

        if meta is not None:
            suite_model.meta = meta

        if is_enabled is not None:
            suite_model.is_enabled = is_enabled

        suite_model.version += 1

        session.add(suite_model)
        session.flush()

        return suite_model.to_dict()

    def fetch(self, id):

        with self.create_session() as session:
            suite_model = self.suite.get(id, session=session)
            if not suite_model:
                raise ApiError(
                    code="NOT_EXISTS",
                    message="Can't find suite with id=%r" % id
                )
            return suite_model.to_dict()

    @staticmethod
    def import_file(profile_id, file_name, data):
        """
        Импортирование шаблонов из файла
        """
        result = post_request(
            url=PROCESSOR_HOST, headers=None,
            request_data=get_create_request(
                method="task.create",
                script="scripts.suite.import_run",
                type=TYPE,
                args={
                    "profile_id": profile_id, "file_name": file_name,
                    "data": data
                }
            )
        )

        result = result["result"]
        if result["status"]:
            return result["response"]

        raise ApiError(code="UNHANDLED", message=result["errors"]["message"])

    def export(self, ids):
        """
        Экспортирование шаблонов
        """
        suites = {}
        template_rpc = TemplateRpc(
            tracer=self.tracer, create_session=self.create_session
        )

        for suite_id in ids:
            suites[suite_id] = {}

            suite = self.fetch(suite_id)

            suites[suite_id]["name"] = suite["title"] or suite_id

            suites[suite_id]["templates"] = []
            templates = template_rpc.list(suite_id=suite_id)

            for template in templates["items"]:
                suites[suite_id]["templates"].append(template["content"])

        result = post_request(
            url=PROCESSOR_HOST, headers=None,
            request_data=get_create_request(
                method="task.create",
                script="scripts.suite.export_run",
                type=TYPE,
                args={"suites": suites}
            )
        )

        result = result["result"]
        if result["status"]:
            return result["response"]

        raise ApiError(code="UNHANDLED", message=result["errors"]["message"])
Beispiel #13
0
class TemplateRpc(RpcGroup):
    def __init__(self, tracer, create_session):
        super().__init__(name="template",
                         tracer=tracer,
                         create_session=create_session)
        self.template = VersionObject(name=self.name,
                                      primary_key="template_id",
                                      entity=Template,
                                      create_session=create_session)

    def create(self,
               suite_id,
               content=None,
               is_enabled=None,
               is_compilable=None,
               meta=None,
               position=None,
               position_before=None,
               position_after=None):

        return self._store(
            content=content,
            suite_id=suite_id,
            id=None,
            is_enabled=is_enabled,
            is_compilable=is_compilable,
            meta=meta,
            position=position,
            position_before=position_before,
            position_after=position_after,
        )

    def update(self, *args, **kwargs):

        if args:  # Получили список словарей
            result = []  # Возвращать, так же, будем список
            for item in args:
                item['action'] = 'update'
                result.append(self._store(**item))
            return result
        else:  # Получили словарь
            kwargs['action'] = 'update'
            return self._store(**kwargs)

    def list(self,
             offset=None,
             limit=None,
             profile_ids=None,
             suite_id=None,
             search=None,
             order=None,
             is_enabled=None,
             id=None,
             _process=None):

        filter_q = []

        if id is not None:
            filter_q.append(Template.template_id.in_(id))

        filter_by_q = {}
        if suite_id:
            filter_by_q["suite_id"] = suite_id

        join = []

        if profile_ids:
            join.append(Template.suite)
            filter_q.append(Suite.profile_id.in_(profile_ids))

        if is_enabled is not None:
            filter_q.append(Template.is_enabled.is_(is_enabled))

        items, total_items = self.template.filter(filter_q=filter_q,
                                                  filter_by_q=filter_by_q,
                                                  offset=offset,
                                                  limit=limit,
                                                  join=join,
                                                  order=order)

        if _process:
            items = [_process_template_inplace(item) for item in items]

        return {
            "items": items,
            "total": total_items,
        }

    def fetch(self, id, _process=None):

        with self.create_session() as session:
            template_model = self.template.get(id, session=session)
            if not template_model:
                raise ApiError(code="NOT_EXISTS",
                               message="Can't find template with id=%r" % id)

            item = template_model.to_dict()

            if _process:
                item = _process_template_inplace(item)

            return item

    def remove(self, id):

        try:
            with self.create_session() as session:
                if not isinstance(id, list):
                    id = [id]

                for iid in id:
                    template_model = self.template.get(iid, session=session)
                    self._update_parent(template_model, session=session)

                return self.template.remove(id, session)

        except VersionNoObject as e:
            raise ApiError(code="NOT_EXISTS", message=e.args[0]) from e

    def store(self,
              content=None,
              suite_id=None,
              id=None,
              is_enabled=None,
              is_compilable=None,
              meta=None,
              position=None):

        return self._store(
            content=content,
            suite_id=suite_id,
            id=id,
            is_enabled=is_enabled,
            is_compilable=is_compilable,
            meta=meta,
            position=position,
            position_before=None,
            position_after=None,
        )

    def _store(self,
               *,
               content=None,
               suite_id=None,
               id=None,
               is_enabled=None,
               is_compilable=None,
               meta=None,
               position=None,
               position_before=None,
               position_after=None,
               action=None):

        with self.create_session() as session:
            set_position = self._calculate_template_position(
                position=position,
                position_before=position_before,
                position_after=position_after,
                suite_id=suite_id,
                do_insert=not id,
                session=session)

            if action == "update":
                template_model = self.template.get(id, session=session)
                if not template_model:
                    raise ApiError(code="NOT_EXISTS",
                                   message="Can't find template with id=%r" %
                                   id)
            else:
                if suite_id is None:
                    raise ApiError(
                        code="MISSING_SUITE_ID",
                        message="suite_id must be given for creating template")

                if set_position is None:
                    # Если позиция не указана, ставим в конец.
                    max_position = session.query(func.max(
                        Template.position)).filter_by(
                            suite_id=suite_id).scalar()
                    set_position = (max_position or 0) + 1

                template_model = Template(
                    template_id=id,
                    suite_id=suite_id,
                    created=datetime.now(),
                    version=0,
                )

            if content is not None:
                template_model.content = content

            if is_enabled is not None:
                template_model.is_enabled = is_enabled

            if is_compilable is not None:
                template_model.is_compilable = is_compilable

            if meta is not None:
                template_model.meta = meta

            if set_position is not None:
                self._move_positions_slow_method(template_model,
                                                 set_position,
                                                 session=session)

            # template_model.updated = datetime.now()
            template_model.version += 1

            session.add(template_model)

            self._update_parent(template_model, session)

            template = template_model.to_dict()
            del template["stats"]

            session.commit()

            return template_model.to_dict()

    @staticmethod
    def _update_parent(template_model: Template, session):
        suite_model = session.query(Suite).get(template_model.suite_id)
        suite_model.updated = datetime.now()
        session.add(suite_model)

    def _calculate_template_position(self, *, position: int,
                                     position_before: str, position_after: str,
                                     suite_id: str, do_insert: bool, session):
        """
        Calculates position for template in insert or update operation.

        :param position: Set position
        :param position_before: Position before template uuid or "last"
        :param position_after: Position after template uuid or "first"
        :param suite_id: Suite id
        :param do_insert: Do insert or update
        :param session: Database session
        :return: new position or None if not changes
        """
        position_arguments_exist = sum(
            int(arg is not None)
            for arg in (position, position_before, position_after))
        if position_arguments_exist > 1:
            raise ApiError(code="INVALID_POSITION",
                           message="Only one of `position`, `position_before` "
                           "and `position_after` arguments must be given!")

        fetch_position = position_before or position_after or None

        if fetch_position not in ("first", "last", None):
            # fetch_position is Template uuid
            fetch_template = (session.query(Template).filter_by(
                template_id=fetch_position).scalar())

            set_position = fetch_template.position
            if position_after:
                set_position += 1

        elif fetch_position == "first":
            set_position = 1
        elif position is not None:
            set_position = position
        elif do_insert or fetch_position == "last":
            # Get max template position in suite
            max_position = (session.query(func.max(
                Template.position)).filter_by(suite_id=suite_id).scalar())
            set_position = (max_position or 0) + 1
        else:
            # Do nothing
            set_position = None

        return set_position

    def _move_positions_slow_method(self, template_model: Template,
                                    position: int, *, session):
        """
        FIXME: Need correct batch solution for updating with constraint
        There was constraint uniquenness problem in updating positions.
        And something goes wrong with other correct methods.
        Slow but working method

        :param template_model: Model which position updates
        :param position: Set position
        :param session:
        :return:
        """
        templates = (
            session.query(Template.template_id).filter(
                # Move all templates in suite
                Template.suite_id == template_model.suite_id,
                # Which positions next to set position
                Template.position >= position,
            ).order_by(desc(Template.position)).all())

        for move_template in templates:
            session.query(Template).filter(
                Template.template_id == move_template.template_id).update(
                    {Template.position: Template.position + 1},
                    synchronize_session=False,
                )

        template_model.position = position
Beispiel #14
0
class ComplectRevisionRpc(RpcGroup):
    def __init__(self, tracer, create_session) -> None:

        super().__init__(name="complect_revision",
                         tracer=tracer,
                         create_session=create_session)

        self.complect_revision = VersionObject(name=self.name,
                                               primary_key="revision_id",
                                               entity=ComplectRevision,
                                               create_session=create_session)

    @rpc_name("list")
    def list_of_complect_revisions(self,
                                   complect_id=None,
                                   offset=None,
                                   limit=None,
                                   order=None) -> dict:
        """
            Возвращает строки из таблицы "revisions" для комплекта
            с "complect_id" (в словаре).
        """

        # TODO: Надо вынести отсюда эту функцию (и желательно переименовать)
        def form_items(items):
            return [item[0].to_dict() for item in items]

        # Подготовим фильтр по complect_id для будущего запроса
        filter_q = []
        if complect_id is not None:
            filter_q.append(ComplectRevision.complect_id == complect_id)

        # Запрос
        items, total_items = self.complect_revision.filter(
            filter_q=filter_q,
            offset=offset,
            limit=limit,
            form_items=form_items,
            order=order,
        )

        return {"items": items, "total": total_items}

    def fetch(self, id):
        """ Returns complect revision model by id """
        with self.create_session() as session:
            complect_revision_model = self.complect_revision.get(
                id, session=session)
            if not complect_revision_model:
                raise ApiError(
                    code="NOT_EXISTS",
                    message="Can't find complect revision with id=%r" % id)
            return complect_revision_model.to_dict()

    def _get_complect_code(self, complect_id):

        return get_complect_code(complect_id)

    def _make_complect_revision_code(self, complect_code,
                                     revision_number) -> str:
        """
            Возвращает значение для поля "code" для новой строки в таблице
            "complects_revisions"
        """
        return str(complect_code) + '.' + str(revision_number)

    def _create(self, complect_id, source_archive_path, binary_path, meta) \
            -> dict:
        """
            Создает новую строку в таблице "complects_revisions" для комплекта
            с "complect_id".

            Возвращает созданную строку (в словаре).
        """
        with self.create_session() as session:

            revision_number = get_next_complect_revision_number(
                complect_id, session)

            self.complect_code = self._get_complect_code(complect_id)

            code = self._make_complect_revision_code(self.complect_code,
                                                     revision_number)

            complect_revision_model = ComplectRevision(
                complect_id=complect_id,
                revision_number=revision_number,
                code=code,
                source_archive_path=source_archive_path,
                binary_path=binary_path,
                meta=meta,
            )

            session.add(complect_revision_model)
            session.commit()

            return complect_revision_model.to_dict()
class AccessComplectAccountRpc(RpcGroup):
    def __init__(self, tracer, create_session) -> None:

        super().__init__(name="access.complect_account",
                         tracer=tracer,
                         create_session=create_session)
        self.access_complect_account = VersionObject(
            name=self.name,
            primary_key=("account_id", "complect_id"),
            entity=AccessComplectAccount,
            create_session=create_session)

    def create(self, account_id, complect_ids) -> dict:

        return self._store(account_id=account_id, complect_ids=complect_ids)

    def _store(self, account_id, complect_ids) -> dict:

        with self.create_session() as session:
            for complect_id in complect_ids:
                access_complect_account = self.access_complect_account.get(
                    (account_id, complect_id), session=session)
                if not access_complect_account:

                    access_complect_account = AccessComplectAccount(
                        account_id=account_id, complect_id=complect_id)

                    session.add(access_complect_account)

            session.commit()

            return {"account_id": account_id, "complect_ids": complect_ids}

    @staticmethod
    def _form_items(items) -> list:

        res = []
        for item in items:
            item_dict = item[0].to_dict()
            res.append(item_dict["complect_id"])

        return res

    @rpc_name("list")
    def list_(self,
              account_id,
              offset=None,
              limit=None,
              search=None,
              order=None) -> dict:
        """
        Получение списка
        """
        items, total_items = self.access_complect_account.filter(
            filter_q=[AccessComplectAccount.account_id == account_id],
            offset=offset,
            limit=limit,
            form_items=self._form_items,
            order=order)

        return {
            "items": items,
            "total": total_items,
        }

    def fetch(self, account_id, complect_id) -> dict:
        """
        Получение записи
        :param account_id: идентификатор аккаунта
        :param complect_id: идентификатор комплекта
        """
        with self.create_session() as session:
            access_complect_account = self.access_complect_account.get(
                (account_id, complect_id), session=session)
            if not access_complect_account:
                raise ApiError(
                    code="NOT_EXISTS",
                    message="Can't find access complect account with "
                    "account_id={} and complect_id={}".format(
                        account_id, complect_id))

            return access_complect_account.to_dict()

    def remove(self, account_id, complect_ids) -> bool:
        """
        Удаление
        :param account_id: идентификатор аккаунта
        :param complect_ids: список идентификаторов профиля
        """
        try:
            ids = []
            for complect_id in complect_ids:
                ids.append((account_id, complect_id))

            return self.access_complect_account.remove(ids)

        except VersionNoObject as e:
            raise ApiError(code="NOT_EXISTS", message=e.args[0]) from e
Beispiel #16
0
class AccessProfileAccountRpc(RpcGroup):
    def __init__(self, tracer, create_session):

        super().__init__(name="access.account",
                         tracer=tracer,
                         create_session=create_session)
        self.access_account = VersionObject(name=self.name,
                                            primary_key=("account_id",
                                                         "profile_id"),
                                            entity=AccessProfileAccount,
                                            create_session=create_session)

    def create(self, account_id, profile_ids):
        """
        Создание записи
        """
        return self._store(account_id=account_id, profile_ids=profile_ids)

    @staticmethod
    def _form_items(items):

        res = []
        for item in items:
            item_dict = item[0].to_dict()
            res.append(item_dict["profile_id"])

        return res

    def list(self,
             account_id,
             offset=None,
             limit=None,
             search=None,
             order=None):
        """
        Получение списка
        """
        items, total_items = self.access_account.filter(
            filter_q=[AccessProfileAccount.account_id == account_id],
            offset=offset,
            limit=limit,
            form_items=self._form_items,
            order=order)

        return {
            "items": items,
            "total": total_items,
        }

    def fetch(self, account_id, profile_id):
        """
        Получение записи
        :param account_id: идентификатор аккаунта
        :param profile_id: идентификатор профиля
        """
        with self.create_session() as session:
            access_profile_account_model = self.access_account.get(
                (account_id, profile_id), session=session)
            if not access_profile_account_model:
                raise ApiError(
                    code="NOT_EXISTS",
                    message="Can't find access profile account with "
                    "account_id={} and profile_id={}".format(
                        account_id, profile_id))

            return access_profile_account_model.to_dict()

    def remove(self, account_id, profile_ids):
        """
        Удаление
        :param account_id: идентификатор аккаунта
        :param profile_ids: список идентификаторов профиля
        """
        try:
            ids = []
            for profile_id in profile_ids:
                ids.append((account_id, profile_id))

            return self.access_account.remove(ids)

        except VersionNoObject as e:
            raise ApiError(code="NOT_EXISTS", message=e.args[0]) from e

    def _store(self, account_id, profile_ids):

        with self.create_session() as session:
            for profile_id in profile_ids:
                access_profile_account_model = self.access_account.get(
                    (account_id, profile_id), session=session)
                if access_profile_account_model:
                    continue

                access_profile_account_model = AccessProfileAccount(
                    account_id=account_id, profile_id=profile_id)

                session.add(access_profile_account_model)

            session.commit()

            return {"account_id": account_id, "profile_ids": profile_ids}
Beispiel #17
0
class ComplectRpc(RpcGroup, BatchUpdateMixin):
    def __init__(self, tracer, create_session):

        super().__init__(name="complect",
                         tracer=tracer,
                         create_session=create_session)
        self.complect = VersionObject(name=self.name,
                                      primary_key="complect_id",
                                      entity=Complect,
                                      create_session=create_session)

    def create(self, **kwargs):
        with self.create_session() as session:
            kwargs['session'] = session
            result = self._store(**kwargs)
            session.commit()

        return result

    @rpc_name("list")
    def list_(self,
              user=None,
              account_id=None,
              offset=None,
              limit=None,
              search=None,
              order=None):

        filter_q = {}
        join = None

        items, total_items = self.complect.filter(filter_q=filter_q,
                                                  join=join,
                                                  offset=offset,
                                                  limit=limit,
                                                  order=order)

        return {
            "items": items,
            "total": total_items,
        }

    def fetch(self, id):

        with self.create_session() as session:
            complect_model = self.complect.get(id, session=session)
            if not complect_model:
                raise ApiError(code="NOT_EXISTS",
                               message="Can't find complect with id=%r" % id)

            return complect_model.to_dict()

    def change(self, id, action, profile_id):

        if action not in ("add", "remove"):
            raise ValueError("Invalid action: %s" % action)

        with self.create_session() as session:
            complect_model = self.complect.get(id, session=session)
            if not complect_model:
                raise ApiError(code="NOT_EXISTS",
                               message="Can't find complect with id=%r" % id)

            save = False

            in_ = profile_id in complect_model.profile_ids
            if action == "add":
                if not in_:
                    profile_ids = copy.deepcopy(complect_model.profile_ids)
                    profile_ids.append(profile_id)
                    complect_model.profile_ids = profile_ids
                    save = True
            else:
                if in_:
                    profile_ids = copy.deepcopy(complect_model.profile_ids)
                    profile_ids.remove(profile_id)
                    complect_model.profile_ids = profile_ids
                    save = True

            if save:
                session.add(complect_model)
                session.commit()

            return complect_model.to_dict()

    def remove(self, id):

        try:
            return self.complect.remove(id)
        except VersionNoObject as e:
            raise ApiError(code="NOT_EXISTS", message=e.args[0]) from e

    def _store(self,
               id=None,
               name=None,
               state=None,
               profile_ids=None,
               meta=None,
               is_enabled=None,
               code=None,
               action=None,
               compiler_target=None,
               debug_target=None,
               deploy_target=None,
               session=None):

        if action == 'update':
            complect_model = self.complect.get(id, session=session)
            if not complect_model:
                raise ApiError(code="NOT_EXISTS",
                               message="Can't find complect with id=%r" % id)
        else:
            complect_model = Complect(
                created=datetime.now(),
                version=0,
            )

        if name is not None:
            complect_model.name = name

        if state is not None:
            complect_model.state = state

        if profile_ids is not None:
            complect_model.profile_ids = profile_ids

        if meta is not None:
            complect_model.meta = meta

        if is_enabled is not None:
            complect_model.is_enabled = is_enabled

        if code is not None:
            complect_model.code = code

        if compiler_target is not None:
            complect_model.compiler_target = compiler_target

        if debug_target is not None:
            complect_model.debug_target = debug_target

        if deploy_target is not None:
            complect_model.deploy_target = deploy_target

        complect_model.version += 1

        session.add(complect_model)
        session.flush()

        return complect_model.to_dict()
Beispiel #18
0
class TestcaseRpc(RpcGroup, BatchUpdateMixin):
    __test__ = False

    """Тесткейс"""

    def __init__(self, tracer, create_session):

        super().__init__(
            name="testcase", tracer=tracer, create_session=create_session
        )
        self.testcase = VersionObject(
            name=self.name, primary_key="testcase_id", entity=Testcase,
            create_session=create_session
        )

    def create(self, **kwargs):
        with self.create_session() as session:
            kwargs['session'] = session
            result = self._store(**kwargs)
            session.commit()

        return result

    def _fetch(self, id):
        """Получение"""
        with self.create_session() as session:
            testcase_model = self.testcase.get(id, session=session)
            if not testcase_model:
                raise ApiError(
                    code="NOT_EXISTS",
                    message="Can't find testcase with id=%r" % id
                )
            return testcase_model.to_dict()

    def list(self, offset=None, limit=None, profile_ids=None, is_common=None,
             order=None):
        """Получение списка"""
        filter_q = []

        if profile_ids:
            if isinstance(profile_ids, str):
                profile_ids = [profile_ids]
            filter_q.append(Testcase.profile_id.in_(profile_ids))

        if is_common:
            filter_q.append(Testcase.is_common == is_common)

        items, total_items = self.testcase.filter(
            filter_q=filter_q, offset=offset, limit=limit, order=order
        )

        return {"items": items, "total": total_items, }

    def remove(self, id):
        """Удаление"""
        try:
            return self.testcase.remove(id)
        except VersionNoObject as e:
            raise ApiError(code="NOT_EXISTS", message=e.args[0]) from e

    @staticmethod
    def result_list(offset=None, limit=None):
        """
        Получение списка задача/статус
        """
        result = post_request(
            url=PROCESSOR_HOST, headers=None,
            request_data=get_info_request(
                method="task.list", type=TYPE, offset=offset, limit=limit
            )
        )

        result = result["result"]
        if result["status"]:
            return result["response"]

        raise ApiError(code="NOT_EXISTS", message=result["errors"]["message"])

    @staticmethod
    def result(task_id):
        """
        Получение результата по задаче
        """
        result = post_request(
            url=PROCESSOR_HOST, headers=None,
            request_data=get_info_request(method="task.info", task_id=task_id)
        )

        result = result["result"]
        if result["status"]:
            return result["response"]

        raise ApiError(
            code="PROCESSOR_SERVICE", message=result["errors"]["message"]
        )

    def run(self, profile_id, ids):
        """
        Запуск
        """
        if len(ids) > MAX_COUNT_TESTCASE_TO_RUN:
            raise ApiError(
                code="COUNT_TESTCASES",
                message="Количество тесткейсов превышает допустимое количество"
                        " {} для одного запуска".format(
                            MAX_COUNT_TESTCASE_TO_RUN
                        )
            )

        def form_items(items):
            res = []
            for item, _ in items:
                res.append(item.to_short_dict())

            return res

        filter_q = [
            Testcase.profile_id == profile_id, Testcase.testcase_id.in_(ids)
        ]
        testcases, _ = self.testcase.filter(
            filter_q=filter_q, limit=len(ids),
            form_items=form_items  # TODO: ? Так оно точно работает?
        )

        profile = ProfileRpc(
            tracer=self.tracer, create_session=self.create_session
        )
        profile_info = profile.fetch(profile_id)

        result = post_request(
            url=PROCESSOR_HOST, headers=None,
            request_data=get_create_request(
                method="task.create", script="scripts.testcase.run",
                type=TYPE, args={
                    "ids": ids, "testcases": testcases,
                    "profile_info": profile_info
                }
            )
        )

        return result["result"]["response"]

    def _store(self, id=None, profile_id=False, title=None, description=None,
               replicas=None, is_common=None, author=None,
               action=None, session=None):

        if action == "update":
            testcase_model = self.testcase.get(id, session=session)
            if not testcase_model:
                raise ApiError(
                    code="NOT_EXISTS",
                    message="Can't find testcase with id=%r" % id
                )
        else:
            testcase_model = Testcase(created=datetime.now(), )

        if profile_id is not False:
            # False, потому что клиент может отправлять None
            # для очистки profile_id
            testcase_model.profile_id = profile_id

        if title is not None:
            testcase_model.title = title

        if description is not None:
            testcase_model.description = description

        if replicas is not None:
            testcase_model.replicas = replicas

        if is_common is not None:
            testcase_model.is_common = is_common

        if author is not None:
            testcase_model.author = author

        session.add(testcase_model)
        session.flush()

        return testcase_model.to_dict()