def __init__(self):
     self.conf = InventoryConfiguration()
     self.db_conn = self.conf.get_backend_db(CONFIG_FILE)
class ResourceOperationalAPI:
    def __init__(self):
        self.conf = InventoryConfiguration()
        self.db_conn = self.conf.get_backend_db(CONFIG_FILE)

    def createResource(self, resource_type, resource_name, status, description=None,
                       external_system=None, location=None, department=None, owner=None, **add_params):
        """
        Create resource object and save it into database
        @return created resource object
        """
        resource = Resource(specification_name=resource_type, resource_name=resource_name, resource_status=status,
                            description=description, external_system=external_system, location=location,
                            department=department, owner=owner, additional_parameters=add_params)
        resource.validate()

        self.db_conn.connect()
        res_id = self.db_conn.save_entity(CommonDatabaseAPI.ET_RESOURCE, resource.to_dict())
        self.db_conn.close()

        resource.set__id(res_id)

        return resource

    def updateResource(self, resource_id, resource_name=None, status=None, description=None, external_system=None,
                       location=None, department=None, owner=None, **add_params):
        """
        Update resource information
        Find resource in database by ID and update all non-None passed attributes
        """
        self.db_conn.connect()
        raw_resource = self.db_conn.get_entity(CommonDatabaseAPI.ET_RESOURCE, resource_id)
        resource = Resource(raw_resource)

        if resource_name is not None:
            resource.set_resource_name(resource_name)
        if status is not None:
            resource.set_resource_status(status)
        if description is not None:
            resource.set_description(description)
        if external_system is not None:
            resource.set_external_system(external_system)
        if location is not None:
            resource.set_location(location)
        if department is not None:
            resource.set_department(department)
        if owner is not None:
            resource.set_owner(owner)

        for param_name, param_value in add_params.iteritems():
            resource.set_attribute(param_name, param_value)

        resource.validate()
        self.db_conn.save_entity(CommonDatabaseAPI.ET_RESOURCE, resource.to_dict())
        self.db_conn.close()

        return resource

    def getResourceInfo(self, resource_id):
        """
        Find resource in database by ID and return Resource object
        """
        self.db_conn.connect()
        raw_resource = self.db_conn.get_entity(CommonDatabaseAPI.ET_RESOURCE, resource_id)
        self.db_conn.close()

        resource = Resource(raw_resource)

        return resource

    def findResources(self, resource_filter):
        """
        Find resources by filter and return found Resource objects
        Filter should be dictionary where key = resource attribute with
        optional qualificator suffix (__in, __gt, __ge, __lw, __le)
        """
        self.db_conn.connect()
        raw_resources = self.db_conn.find_entities(CommonDatabaseAPI.ET_RESOURCE, resource_filter)
        self.db_conn.close()
        ret_list = []
        for res in raw_resources:
            ret_list.append(Resource(res))

        return ret_list

    def removeResource(self, resource_id):
        """Remove resource from database"""
        self.db_conn.connect()
        self.db_conn.remove_entity(CommonDatabaseAPI.ET_RESOURCE, resource_id)
        self.db_conn.close()
 def __init__(self):
     self.conf = InventoryConfiguration()
     self.db_conn = self.conf.get_backend_db(CONFIG_FILE)
     self.CONNECTION = CommonDatabaseAPI.ET_CONNECTION
     self.RESOURCE = CommonDatabaseAPI.ET_RESOURCE
class ConnectionOperationalAPI():
    """ Implemented API for connection """
    def __init__(self):
        self.conf = InventoryConfiguration()
        self.db_conn = self.conf.get_backend_db(CONFIG_FILE)
        self.CONNECTION = CommonDatabaseAPI.ET_CONNECTION
        self.RESOURCE = CommonDatabaseAPI.ET_RESOURCE

    def updateConnection(self, conn_id, conn_type=None, connecting_res_id=None, connected_res_id=None, **add_params):
        """ Update connection information.
        Find connection in database by ID and update all non-None passed attributes.
        """
        self.db_conn.connect()
        raw_connection = self.db_conn.get_entity(self.CONNECTION, conn_id)
        connection = Connection(raw_connection)

        #if description:
        #    connection.set_description(description)
        if connecting_res_id:
            connection.set_connecting_resource(connecting_res_id)
        if connected_res_id:
            connection.set_connected_resource(connected_res_id)

        for param_name, param_value in add_params.items():
            for key, value in param_value.iteritems():
                connection.set_attribute(key, value)

        self.db_conn.save_entity(self.CONNECTION, connection.to_dict())
        self.db_conn.close()

        return connection

    def getConnectionInfo(self, connection_id):
        """ Find connection in database by ID and return Connection object """
        self.db_conn.connect()
        raw_connection = self.db_conn.get_entity(self.CONNECTION, connection_id)
        self.db_conn.close()
        #connection = Connection(raw_connection)

        return Connection(raw_connection)

    def findConnection(self, connection_filter):
        """
        Find connection by filter and return found Connection objects.
        Filter should be dictionary where key = resource attribute with
        optional qualificator suffix (__in, __gt, __ge, __lw, __le, __all).
        """
        self.db_conn.connect()
        raw_connection = self.db_conn.find_entities(self.CONNECTION, connection_filter)
        self.db_conn.close()

        ret_list = []
        for conn in raw_connection:
            ret_list.append(Connection(conn))

        return ret_list

    def deleteConnection(self, coll_id):
        """ Delete connection by ID """
        self.db_conn.connect()
        self.db_conn.remove_entity(self.CONNECTION, coll_id)
        self.db_conn.close()

    def connectResources(self, conn_type, connecting_res_id, connected_res_id, conn_desc=None, **add_params):
        """ Connecting resource by connect type """
        filter_conn = {'specification_name': conn_type,
                       'connecting_resource': connecting_res_id,
                       'connected_resource': connected_res_id}

        if connecting_res_id == connected_res_id:
            raise BIException('Connection between similar resources is not allowed!')
        elif self.findConnection(filter_conn):
            raise BIException('Connection between resources already exist!')

        connection = Connection(specification_name=conn_type, connecting_resource=connecting_res_id,
                                connected_resource=connected_res_id, description=conn_desc,
                                additional_parameters=add_params)

        res = ResourceOperationalAPI()
        connecting_res = res.getResourceInfo(connecting_res_id)
        connected_res = res.getResourceInfo(connected_res_id)

        if connecting_res.to_dict() and connected_res.to_dict():
            spec = ManagementAPI()

            connecting_res_d = connecting_res.to_dict()
            connected_res_d = connected_res.to_dict()
            connecting_res_spec = spec.findSpecification(self.RESOURCE,
                                                         {'type_name': connecting_res_d['specification_name'],
                                                          'spec_type': self.RESOURCE})[0]
            connected_res_spec = spec.findSpecification(self.RESOURCE, {'type_name': connected_res_d['specification_name'],
                                                                          'spec_type': self.RESOURCE})[0]
            Resource.setup_specification([ResourceSpecification(connecting_res_spec.to_dict())])
            Resource.setup_specification([ResourceSpecification(connected_res_spec.to_dict())])

            connection.connect(connecting_res, connected_res)

            self.db_conn.connect()
            self.db_conn.save_entity(self.CONNECTION, connection.to_dict())
            self.db_conn.close()

    def disconnectResourcesById(self, connection_id):
        """Disconnect resource by connection ID """

        self.db_conn.connect()
        self.db_conn.remove_entity(self.CONNECTION, connection_id)
        self.db_conn.close()

    def disconnectResources(self, conn_type, connecting_res_id, connected_res_id):
        """Disconnect resource"""

        filter_conn = {'specification_name': conn_type,
                       'connecting_resource': connecting_res_id,
                       'connected_resource': connected_res_id}

        conn = self.findConnection(filter_conn)
        conn_id = ''
        for item in conn:
            conn_id = item.get__id()

        try:
            if conn_id:
                self.db_conn.connect()
                self.db_conn.remove_entity(self.CONNECTION, conn_id)
                self.db_conn.close()
        except Exception:
            raise BIException('Connection is not found! specification_name "%s",'
                              ' connecting_resource "%s", connected_resource "%s"' %
                              (conn_type, connecting_res_id, connected_res_id))

    def getLinkedResources(self, resource_id, conn_type=None, conn_direction=BOTH, **res_filter):
        """Get linked resource by direction"""

        if conn_direction in [BOTH, CONNECTING, CONNECTED]:
            if not isinstance(conn_direction, list):
                conn_direction = [conn_direction]
            result = []
            for direction in conn_direction:
                res_filter.update({'specification_name': conn_type, direction: resource_id})
                result.extend(self.findConnection(res_filter))
                del res_filter[direction]
            return result
        else:
            raise BIException('Connection directions "%s" is not correct!' % conn_direction)
class CollectionOperationalAPI():
    def __init__(self):
        self.conf = InventoryConfiguration()
        self.db_conn = self.conf.get_backend_db(CONFIG_FILE)

    def createCollection(self, coll_type, description, **add_params):
        """
        Create collection and save it into DB
        @return created collection object
        """

        collection = Collection(specification_name=coll_type, description=description,
                                additional_parameters=add_params.itervalues().next())
        collection.validate()

        self.db_conn.connect()
        coll_id = self.db_conn.save_entity(CommonDatabaseAPI.ET_COLLECTION, collection.to_dict())
        self.db_conn.close()
        collection.set__id(coll_id)

        return collection

    def getCollectionInfo(self, collection_id):
        """
        Find collection in database by ID and return Collection object
        """

        self.db_conn.connect()
        raw_collection = self.db_conn.get_entity(CommonDatabaseAPI.ET_COLLECTION, collection_id)
        self.db_conn.close()

        collection = Collection(raw_collection)

        return collection

    def findCollections(self, coll_filter):
        """
        Find collection by filter and return found Collection objects
        Filter should be dictionary where key = resource attribute with
        optional qualificator suffix (__in, __gt, __ge, __lw, __le)
        """

        self.db_conn.connect()
        raw_collection = self.db_conn.find_entities(CommonDatabaseAPI.ET_COLLECTION, coll_filter)
        self.db_conn.close()

        ret_list = []
        for res in raw_collection:
            ret_list.append(Collection(res))

        return ret_list

    def deleteCollection(self, coll_id):
        """Delete collection by ID"""

        self.db_conn.connect()
        self.db_conn.remove_entity(CommonDatabaseAPI.ET_COLLECTION, coll_id)
        self.db_conn.close()

    def updateCollectionInfo(self, coll_id, description=None, **add_params):
        """Update additional_parameters in collection"""

        self.db_conn.connect()
        raw_collection = self.db_conn.get_entity(CommonDatabaseAPI.ET_COLLECTION, coll_id)

        collection = Collection(raw_collection)
        if description:
            collection.set_description(description)

        for param_name, param_value in add_params.items():
            for key, value in param_value.iteritems():
                collection.set_attribute(key, value)

        self.db_conn.save_entity(CommonDatabaseAPI.ET_COLLECTION, collection.to_dict())
        self.db_conn.close()

        return collection

    def appendResourceToCollection(self, coll_id, res_id):
        """Add resource to collection"""

        self.db_conn.connect()
        raw_collection = self.db_conn.get_entity(CommonDatabaseAPI.ET_COLLECTION, coll_id)
        collection = Collection(raw_collection)

        resource = ResourceOperationalAPI()
        res = resource.getResourceInfo(res_id)

        collection.append_resource(res)
        self.db_conn.save_entity(CommonDatabaseAPI.ET_COLLECTION, collection.to_dict())
        self.db_conn.close()

    def removeResourceFromCollection(self, coll_id, res_id):
        """Delete resource from collection"""

        self.db_conn.connect()
        raw_collection = self.db_conn.get_entity(CommonDatabaseAPI.ET_COLLECTION, coll_id)
        collection = Collection(raw_collection)

        resource = ResourceOperationalAPI()
        res = resource.getResourceInfo(res_id)

        collection.remove_resource(res)
        self.db_conn.save_entity(CommonDatabaseAPI.ET_COLLECTION, collection.to_dict())
        self.db_conn.close()
class ManagementAPI:
    def __init__(self):
        self.conf = InventoryConfiguration()
        self.db_conn = self.conf.get_backend_db(CONFIG_FILE)

    def createSpecification(self, spec_name, parent_spec_name, spec_type, description, **parameters):
        """
        Create specification of some entity in Inventory and save it into database
        @return created specification object
        """
        spec_class = SPEC_CLASSES.get(spec_type, None)

        if spec_class is None:
            raise BIException('Specification type <%s> is not supported!' % spec_type)

        if spec_type == 'resource':
            spec = {'type_name': spec_name,
                    'parent_type_name': parent_spec_name,
                    'spec_type': spec_type,
                    'description': description,
                    'params_spec': parameters['params_spec']}
        elif spec_type == 'connection':
            spec = {'type_name': spec_name,
                    'parent_type_name': parent_spec_name,
                    'spec_type': spec_type,
                    'description': description,
                    'connecting_type': parameters['connecting_type'],
                    'connected_type': parameters['connected_type'],
                    'params_spec': parameters['params_spec']}

        else:
            spec = {'type_name': spec_name,
                    'parent_type_name': parent_spec_name,
                    'spec_type': spec_type,
                    'description': description,
                    'allowed_types': parameters['allowed_types'],
                    'params_spec': parameters['params_spec']}

        spec_obj = spec_class(spec)
        spec_obj.validate()

        self.db_conn.connect()
        res_id = self.db_conn.save_entity(CommonDatabaseAPI.ET_SPECIFICATION, spec_obj.to_dict())
        self.db_conn.close()

        return spec_obj

    def updateSpecification(self, spec_id, spec_name, parent_spec_name, spec_type, description, **parameters):
        """
        Update specification of some entity in Inventory and save it into database
        @return created specification object
        """
        spec_class = SPEC_CLASSES.get(spec_type, None)

        if spec_class is None:
            raise BIException('Specification type <%s> is not supported!' % spec_type)

        self.db_conn.connect()
        raw_spec = self.db_conn.get_entity(CommonDatabaseAPI.ET_SPECIFICATION, spec_id)

        raw_spec['params_spec'] = parameters['params_spec']

        if spec_type == 'resource':
            spec = {'_id': spec_id,
                    'type_name': spec_name,
                    'parent_type_name': parent_spec_name,
                    'spec_type': spec_type,
                    'description': description,
                    'params_spec': raw_spec['params_spec']}
        elif spec_type == 'connection':
            spec = {'_id': spec_id,
                    'type_name': spec_name,
                    'parent_type_name': parent_spec_name,
                    'spec_type': spec_type,
                    'description': description,
                    'connecting_type': parameters['connecting_type'],
                    'connected_type': parameters['connected_type'],                    
                    'params_spec': raw_spec['params_spec']}
        else:
            spec = {'_id': spec_id,
                    'type_name': spec_name,
                    'parent_type_name': parent_spec_name,
                    'spec_type': spec_type,
                    'description': description,
                    'allowed_types': parameters['allowed_types'],                   
                    'params_spec': raw_spec['params_spec']}                    

        spec_obj = spec_class(spec)
        spec_obj.validate()

        self.db_conn.save_entity(CommonDatabaseAPI.ET_SPECIFICATION, spec_obj.to_dict())
        self.db_conn.close()

        return spec_obj

    def getSpecification(self, spec_id):
        """
        Get specification of some entity in Inventory from database
        @return found specification object
        """
        self.db_conn.connect()
        raw_spec = self.db_conn.get_entity(CommonDatabaseAPI.ET_SPECIFICATION, spec_id)
        self.db_conn.close()

        spec_class = SPEC_CLASSES.get(raw_spec['spec_type'], None)

        if spec_class is None:
            raise BIException('Specification type <%s> is not supported!' % raw_spec['spec_type'])

        spec_obj = spec_class(raw_spec)
        #spec_obj.validate()

        return spec_obj

    def findSpecification(self, spec_type, spec_filter):
        """
        Find specification by filter and return found Specification objects
        Filter should be dictionary where key = resource attribute with
        optional qualificator suffix (__in, __gt, __ge, __lw, __le)
        """
        spec_class = SPEC_CLASSES.get(spec_type, None)

        if spec_class is None:
            raise BIException('Specification type <%s> is not supported!' % spec_type)

        self.db_conn.connect()
        raw_specs = self.db_conn.find_entities(CommonDatabaseAPI.ET_SPECIFICATION, spec_filter)
        self.db_conn.close()

        ret_list = []
        for res in raw_specs:
            ret_list.append(spec_class(res))

        return ret_list

    def deleteSpecification(self, spec_id):
        """
        Delete specification of some entity in Inventory from database
        """
        self.db_conn.connect()
        self.db_conn.remove_entity(CommonDatabaseAPI.ET_SPECIFICATION, spec_id)
        self.db_conn.close()