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)
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()
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])
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)
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()