Exemple #1
0
    def remove_template(template_id, token):
        """
        Deletes a single template.

        :param template_id: The template to be removed.
        :param token: The authorization token (JWT).
        :return The removed template.
        :rtype JSON
        :raises HTTPRequestError: If no authorization token was provided (no
        tenant was informed)
        :raises HTTPRequestError: If this template could not be found in
        database.
        :raises HTTPRequestError: If the template is being currently used by
        a device.
        """
        init_tenant_context(token, db)
        tpl = assert_template_exists(template_id)

        json_template = template_schema.dump(tpl)
        try:
            db.session.delete(tpl)
            db.session.commit()
        except IntegrityError:
            raise HTTPRequestError(400, "Templates cannot be removed as they are being used by devices")

        results = {
            'result': 'ok',
            'removed': json_template
        }

        return results
Exemple #2
0
    def add_template_to_device(req, device_id, template_id):
        """
        Associates given template with device

        :param req: The received HTTP request, as created by Flask.
        :param device_id: The device which should be updated
        :param template_id: The template to be added to this device.
        :raises HTTPRequestError: If no authorization token was provided (no
        tenant was informed)
        :raises HTTPRequestError: If this device or template could not be found
        in database.
        :return A status on whether the device was updated, and the new
        structure for that device.
        :rtype JSON
        """
        tenant = init_tenant_context(req, db)
        orm_device = assert_device_exists(device_id)
        orm_template = assert_template_exists(template_id)

        orm_device.templates.append(orm_template)

        try:
            db.session.commit()
        except IntegrityError as error:
            handle_consistency_exception(error)

        result = {
            'message': 'device updated',
            'device': serialize_full_device(orm_device, tenant)
        }

        return result
Exemple #3
0
    def update_template(req, template_id):
        """
        Updates a single template.

        :param req: The received HTTP request, as created by Flask.
        :param template_id: The template to be updated.
        :return The old version of this template (previous to the update).
        :rtype JSON
        :raises HTTPRequestError: If no authorization token was provided (no
        tenant was informed)
        :raises HTTPRequestError: If this template could not be found in
        database.
        """
        service = init_tenant_context(req, db)

        # find old version of the template, if any
        old = assert_template_exists(template_id)
        # parse updated version from payload
        updated, json_payload = parse_payload(req, template_schema)
        old.label = updated['label']

        for attr in old.attrs:
            db.session.delete(attr)
        for attr in json_payload['attrs']:
            mapped = DeviceAttr(template=old, **attr)
            db.session.add(mapped)

        try:
            db.session.commit()
        except IntegrityError as error:
            handle_consistency_exception(error)

        # notify interested parties that a set of devices might have been implicitly updated
        affected = db.session.query(DeviceTemplateMap) \
                             .filter(DeviceTemplateMap.template_id==template_id) \
                             .all()

        affected_devices = []
        for device in affected:
            affected_devices.append(device.device_id)

        event = {
            "event": DeviceEvent.TEMPLATE,
            "affected": affected_devices,
            "template": template_schema.dump(old).data,
            "meta": {
                "service": service
            }
        }
        send_raw(event, service)

        results = {'updated': template_schema.dump(old).data, 'result': 'ok'}
        return results
 def get_template(req, template_id):
     """
     Fetches a single template.
     :param req: The received HTTP request, as created by Flask.
     :param template_id: The requested template ID.
     :return A Template
     :rtype Template, as described in DatabaseModels package
     :raises HTTPRequestError: If no authorization token was provided (no
     tenant was informed)
     :raises HTTPRequestError: If this template could not be found in
     database.
     """
     init_tenant_context(req, db)
     tpl = assert_template_exists(template_id)
     json_template = template_schema.dump(tpl)
     attr_format(req, json_template)
     return json_template
Exemple #5
0
def parse_template_list(template_list, new_device):
    new_device.templates = []
    for template_id in template_list:
        new_device.templates.append(
            assert_template_exists(template_id, db.session))
Exemple #6
0
    def update_template(cls, params, template_id, token):
        """
        Updates a single template.

        :param params: Parameters received from request (content_type, data)
        as created by Flask
        :param template_id: The template to be updated.
        :param token: The authorization token (JWT).
        :return The old version of this template (previous to the update).
        :rtype JSON
        :raises HTTPRequestError: If no authorization token was provided (no
        tenant was informed)
        :raises HTTPRequestError: If this template could not be found in
        database.
        """
        service = init_tenant_context(token, db)

        content_type = params.get('content_type')
        data_request = params.get('data')

        # find old version of the template, if any
        old = assert_template_exists(template_id)
        # parse updated version from payload
        updated, json_payload = parse_payload(content_type, data_request, template_schema)
        
        LOGGER.debug(f" Current json payload: {json_payload}")

        old.label = updated['label']

        new = json_payload['attrs']
        LOGGER.debug(f" Checking old template attributes")
        def attrs_match(attr_from_db, attr_from_request):
            return ((attr_from_db.label == attr_from_request["label"]) and
              (attr_from_db.type == attr_from_request["type"]))

        def update_attr(attrs_from_db, attrs_from_request):
            attrs_from_db.value_type = attrs_from_request.get('value_type', None)
            attrs_from_db.static_value = attrs_from_request.get('static_value', None)

        def validate_attr(attr_from_request, is_meta):
            if is_meta is False:
                attr_schema.load(attr_from_request)
            else:
                metaattr_schema.load(attr_from_request)

        def analyze_attrs(attrs_from_db, attrs_from_request, parentAttr=None):
            for attr_from_db in attrs_from_db:
                found = False
                for idx, attr_from_request in enumerate(attrs_from_request):
                    validate_attr(attr_from_request, parentAttr is not None)
                    if attrs_match(attr_from_db, attr_from_request):
                        update_attr(attr_from_db, attr_from_request)
                        if "metadata" in attr_from_request:
                            analyze_attrs(attr_from_db.children, attr_from_request["metadata"], attr_from_db)
                        attrs_from_request.pop(idx)
                        found = True
                        break
                if not found:
                    LOGGER.debug(f" Removing attribute {attr_from_db.label}")
                    db.session.delete(attr_from_db)
            if parentAttr and attrs_from_request is not None:
                for attr_from_request in attrs_from_request:
                    orm_child = DeviceAttr(parent=parentAttr, **attr_from_request)
                    db.session.add(orm_child)
            return attrs_from_request

        to_be_added = analyze_attrs(old.attrs, new)
        for attr in to_be_added:
            LOGGER.debug(f" Adding new attribute {attr}")
            if "id" in attr:
                del attr["id"]
            child = DeviceAttr(template=old, **attr)
            db.session.add(child)
            if "metadata" in attr and attr["metadata"] is not None:
                for metadata in attr["metadata"]:
                    LOGGER.debug(f" Adding new metadata {metadata}")
                    orm_child = DeviceAttr(parent=child, **metadata)
                    db.session.add(orm_child)
        try:
            LOGGER.debug(f" Commiting new data...")
            refresh_template_update_column(db, old)
            db.session.commit()
            LOGGER.debug("... data committed.")
        except IntegrityError as error:
            LOGGER.debug(f"  ConsistencyException was thrown.")
            handle_consistency_exception(error)

        # notify interested parties that a set of devices might have been implicitly updated
        affected = db.session.query(DeviceTemplateMap) \
                             .filter(DeviceTemplateMap.template_id==template_id) \
                             .all()

        affected_devices = []
        
        kafka_handler_instance = cls.kafka.getInstance(cls.kafka.kafkaNotifier)
        for device in affected:
            orm_device = assert_device_exists(device.device_id)
            kafka_handler_instance.update(serialize_full_device(orm_device, service), meta={"service": service})
            affected_devices.append(device.device_id)

        event = {
            "event": DeviceEvent.TEMPLATE,
            "data": {
                "affected": affected_devices,
                "template": template_schema.dump(old)
            },
            "meta": {"service": service}
        }
        kafka_handler_instance.kafkaNotifier.send_raw(event, service)

        results = {
            'updated': template_schema.dump(old),
            'result': 'ok'
        }
        return results
def parse_template_list(template_list, new_device):
    new_device.templates = []
    LOGGER.debug(f" Adding new template list for device {new_device}")
    for template_id in template_list:
        new_device.templates.append(assert_template_exists(template_id, db.session))
Exemple #8
0
    def update_template(req, template_id):
        """
        Updates a single template.

        :param req: The received HTTP request, as created by Flask.
        :param template_id: The template to be updated.
        :return The old version of this template (previous to the update).
        :rtype JSON
        :raises HTTPRequestError: If no authorization token was provided (no
        tenant was informed)
        :raises HTTPRequestError: If this template could not be found in
        database.
        """
        service = init_tenant_context(req, db)

        # find old version of the template, if any
        old = assert_template_exists(template_id)
        # parse updated version from payload
        updated, json_payload = parse_payload(req, template_schema)

        LOGGER.debug(f" Current json payload: {json_payload}")

        old.label = updated['label']

        new = json_payload['attrs']
        LOGGER.debug(f" Checking old template attributes")
        for a in old.attrs:
            LOGGER.debug(f" Checking attribute {a}...")
            found = False
            for idx, b in enumerate(new):
                LOGGER.debug(f" Comparing against new attribute {b}")
                if (a.label == b['label']) and (a.type == b['type']):
                    found = True
                    a.value_type = b.get('value_type', None)
                    a.static_value = b.get('static_value', None)
                    new.pop(idx)
                    LOGGER.debug(f" They match. Attribute data will be updated.")
                    break
            if not found:
                LOGGER.debug(f" No match for this attribute. It will be removed.")
                db.session.delete(a)

        for a in new:
            LOGGER.debug(f" Adding new attribute {a}")
            if "id" in a:
                del a["id"]
            db.session.add(DeviceAttr(template=old, **a))

        try:
            LOGGER.debug(f" Commiting new data...")
            db.session.commit()
            LOGGER.debug("... data committed.")
        except IntegrityError as error:
            LOGGER.debug(f"  ConsistencyException was thrown.")
            handle_consistency_exception(error)

        # notify interested parties that a set of devices might have been implicitly updated
        affected = db.session.query(DeviceTemplateMap) \
                             .filter(DeviceTemplateMap.template_id==template_id) \
                             .all()

        affected_devices = []
        for device in affected:
            affected_devices.append(device.device_id)

        event = {
            "event": DeviceEvent.TEMPLATE,
            "data": {
                "affected": affected_devices,
                "template": template_schema.dump(old)
            },
            "meta": {"service": service}
        }
        send_raw(event, service)

        results = {
            'updated': template_schema.dump(old),
            'result': 'ok'
        }
        return results