Example #1
0
    def __get_product(self, session, product):
        """
        Retrieve the product connection object and create a Thrift Product
        object for the given product record in the database.
        """

        server_product = self.__server.get_product(product.endpoint)
        if not server_product:
            LOG.info("Product '{0}' was found in the configuration "
                     "database but no database connection was "
                     "present. Mounting analysis run database...".format(
                         product.endpoint))
            self.__server.add_product(product)
            server_product = self.__server.get_product(product.endpoint)

        name = base64.b64encode(product.display_name.encode('utf-8'))
        descr = base64.b64encode(product.description.encode('utf-8')) \
            if product.description else None

        args = {'config_db_session': session, 'productID': product.id}
        product_access = permissions.require_permission(
            permissions.PRODUCT_ACCESS, args, self.__auth_session)
        product_admin = permissions.require_permission(
            permissions.PRODUCT_ADMIN, args, self.__auth_session)

        return server_product, ttypes.Product(
            id=product.id,
            endpoint=product.endpoint,
            displayedName_b64=name,
            description_b64=descr,
            connected=server_product.db_status == shared.ttypes.DBStatus.OK,
            accessible=product_access,
            administrating=product_admin,
            databaseStatus=server_product.db_status)
Example #2
0
    def getCurrentProduct(self):
        """
        Return information about the current product.

        The request MUST be routed as /product-name/ProductService!
        """

        if not self.__product:
            msg = "Requested current product from ProductService but the " \
                  "request came through the main endpoint."
            LOG.error(msg)
            raise shared.ttypes.RequestFailed(shared.ttypes.ErrorCode.IOERROR,
                                              msg)

        try:
            session = self.__session()
            prod = session.query(Product).get(self.__product.id)

            server_product = self.__server.get_product(prod.endpoint)
            if not server_product:
                # TODO: Like above, better support this.
                LOG.error("Product '{0}' was found in the configuration "
                          "database, but no database connection is "
                          "present. Was the configuration database "
                          "connected to multiple servers?"
                          .format(prod.endpoint))
                LOG.info("Please restart the server to make this "
                         "product available.")
                raise shared.ttypes.RequestFailed(
                    shared.ttypes.ErrorCode.DATABASE,
                    "Product exists, but was not connected to this server.")

            name = base64.b64encode(prod.display_name.encode('utf-8'))
            descr = base64.b64encode(prod.description.encode('utf-8')) \
                if prod.description else None

            args = {'config_db_session': session,
                    'productID': prod.id}
            product_access = permissions.require_permission(
                permissions.PRODUCT_ACCESS, args, self.__auth_session)
            product_admin = permissions.require_permission(
                permissions.PRODUCT_ADMIN, args, self.__auth_session)

            return ttypes.Product(
                id=prod.id,
                endpoint=prod.endpoint,
                displayedName_b64=name,
                description_b64=descr,
                connected=server_product.connected,
                accessible=product_access,
                administrating=product_admin)

        except sqlalchemy.exc.SQLAlchemyError as alchemy_ex:
            msg = str(alchemy_ex)
            LOG.error(msg)
            raise shared.ttypes.RequestFailed(shared.ttypes.ErrorCode.DATABASE,
                                              msg)
        finally:
            session.close()
Example #3
0
    def __get_product(self, session, product):
        """
        Retrieve the product connection object and create a Thrift Product
        object for the given product record in the database.
        """

        server_product = self.__server.get_product(product.endpoint)
        if not server_product:
            LOG.info("Product '{0}' was found in the configuration "
                     "database but no database connection was "
                     "present. Mounting analysis run database..."
                     .format(product.endpoint))
            self.__server.add_product(product)
            server_product = self.__server.get_product(product.endpoint)

        server_product.connect()
        num_of_runs = 0
        latest_store_to_product = ""
        if server_product.db_status == shared.ttypes.DBStatus.OK:
            run_db_session = server_product.session_factory()
            num_of_runs = run_db_session.query(Run).count()
            if num_of_runs:
                last_updated_run = run_db_session.query(Run) \
                    .order_by(Run.date.desc()) \
                    .limit(1) \
                    .one_or_none()

                latest_store_to_product = last_updated_run.date

        name = base64.b64encode(product.display_name.encode('utf-8'))
        descr = base64.b64encode(product.description.encode('utf-8')) \
            if product.description else None

        args = {'config_db_session': session,
                'productID': product.id}
        product_access = permissions.require_permission(
            permissions.PRODUCT_ACCESS, args, self.__auth_session)
        product_admin = permissions.require_permission(
            permissions.PRODUCT_ADMIN, args, self.__auth_session)

        admin_perm_name = permissions.PRODUCT_ADMIN.name
        admins = session.query(ProductPermission). \
            filter(and_(ProductPermission.permission == admin_perm_name,
                        ProductPermission.product_id == product.id)) \
            .all()

        return server_product, ttypes.Product(
            id=product.id,
            endpoint=product.endpoint,
            displayedName_b64=name,
            description_b64=descr,
            runCount=num_of_runs,
            latestStoreToProduct=str(latest_store_to_product),
            connected=server_product.db_status == shared.ttypes.DBStatus.OK,
            accessible=product_access,
            administrating=product_admin,
            databaseStatus=server_product.db_status,
            admins=[admin.name for admin in admins])
Example #4
0
    def __get_product(self, session, product):
        """
        Retrieve the product connection object and create a Thrift Product
        object for the given product record in the database.
        """

        server_product = self.__server.get_product(product.endpoint)
        if not server_product:
            LOG.info(
                "Product '%s' was found in the configuration "
                "database but no database connection was "
                "present. Mounting analysis run database...", product.endpoint)
            self.__server.add_product(product)
            server_product = self.__server.get_product(product.endpoint)

        num_of_runs = 0
        runs_in_progress = set()
        latest_store_to_product = ""

        # Try to get product details. It may throw different error messages
        # depending on the used SQL driver adapter in case of connection error,
        # so we should try to connect to the database and get the results
        # again on failure.
        try:
            num_of_runs, runs_in_progress, latest_store_to_product = \
                server_product.get_details()
        except Exception:
            # Try to connect to the product and try to get details again.
            server_product.connect()

            if server_product.db_status ==\
                    codechecker_api_shared.ttypes.DBStatus.OK:
                num_of_runs, runs_in_progress, latest_store_to_product = \
                    server_product.get_details()

        name = base64.b64encode(product.display_name.encode('utf-8'))
        descr = base64.b64encode(product.description.encode('utf-8')) \
            if product.description else None

        args = {'config_db_session': session, 'productID': product.id}
        product_access = permissions.require_permission(
            permissions.PRODUCT_ACCESS, args, self.__auth_session)
        product_admin = permissions.require_permission(
            permissions.PRODUCT_ADMIN, args, self.__auth_session)

        admin_perm_name = permissions.PRODUCT_ADMIN.name
        admins = session.query(ProductPermission). \
            filter(and_(ProductPermission.permission == admin_perm_name,
                        ProductPermission.product_id == product.id)) \
            .all()

        connected = server_product.db_status ==\
            codechecker_api_shared.ttypes.DBStatus.OK

        return server_product, ttypes.Product(
            id=product.id,
            endpoint=product.endpoint,
            displayedName_b64=name,
            description_b64=descr,
            runCount=num_of_runs,
            latestStoreToProduct=str(latest_store_to_product),
            connected=connected,
            accessible=product_access,
            administrating=product_admin,
            databaseStatus=server_product.db_status,
            admins=[admin.name for admin in admins],
            runStoreInProgress=runs_in_progress)
Example #5
0
    def getProducts(self, product_endpoint_filter, product_name_filter):
        """
        Get the list of products configured on the server.
        """

        result = []

        try:
            session = self.__session()
            prods = session.query(Product)

            if product_endpoint_filter:
                prods = prods.filter(Product.endpoint.ilike('%{0}%'.format(
                    util.escape_like(product_endpoint_filter)), escape='*'))

            if product_name_filter:
                prods = prods.filter(Product.display_name.ilike('%{0}%'.format(
                    util.escape_like(product_name_filter)), escape='*'))

            prods = prods.all()

            for prod in prods:
                server_product = self.__server.get_product(prod.endpoint)

                if not server_product:
                    # TODO: Better support this, if the configuration database
                    # is mounted to multiple servers?
                    LOG.error("Product '{0}' was found in the configuration "
                              "database, but no database connection is "
                              "present. Was the configuration database "
                              "connected to multiple servers?"
                              .format(prod.endpoint))
                    LOG.info("Please restart the server to make this "
                             "product available.")
                    continue

                # Clients are expected to use this method to query if
                # the product exists and usable. Usability sometimes requires
                # "updating" the "is connected" status of the database.
                if not server_product.connected:
                    server_product.connect()

                name = base64.b64encode(prod.display_name.encode('utf-8'))
                descr = base64.b64encode(prod.description.encode('utf-8')) \
                    if prod.description else None

                args = {'config_db_session': session,
                        'productID': prod.id}
                product_access = permissions.require_permission(
                    permissions.PRODUCT_ACCESS, args, self.__auth_session)
                product_admin = permissions.require_permission(
                    permissions.PRODUCT_ADMIN, args, self.__auth_session)

                result.append(ttypes.Product(
                    id=prod.id,
                    endpoint=prod.endpoint,
                    displayedName_b64=name,
                    description_b64=descr,
                    connected=server_product.connected,
                    accessible=product_access,
                    administrating=product_admin))

            return result

        except sqlalchemy.exc.SQLAlchemyError as alchemy_ex:
            msg = str(alchemy_ex)
            LOG.error(msg)
            raise shared.ttypes.RequestFailed(shared.ttypes.ErrorCode.DATABASE,
                                              msg)
        finally:
            session.close()