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) num_all_products = prods.count() # prods get filtered later. if num_all_products < self.__server.num_products: # It can happen that a product gets removed from the # configuration database from a different server that uses the # same configuration database. In this case, the product is # no longer valid, yet the current server keeps a connection # object up. LOG.info( "%d products were removed but server is still " "connected to them. Disconnecting these...", self.__server.num_products - num_all_products) all_products = session.query(Product).all() self.__server.remove_products_except( [prod.endpoint for prod in all_products]) if product_endpoint_filter: prods = prods.filter( Product.endpoint.ilike(conv( util.escape_like(product_endpoint_filter, '\\')), escape='\\')) if product_name_filter: prods = prods.filter( Product.display_name.ilike(conv( util.escape_like(product_name_filter, '\\')), escape='\\')) prods = prods.all() for prod in prods: _, ret = self.__get_product(session, prod) result.append(ret) 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()
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()