def update_device(req, device_id): """ Updated the information about a particular device :param req: The received HTTP request, as created by Flask. :param device_id: The device to be updated. :return The updated device. :rtype JSON :raises HTTPRequestError: If no authorization token was provided (no tenant was informed) :raises HTTPRequestError: If this device could not be found in database. """ device_data, json_payload = parse_payload(req, device_schema) tenant = init_tenant_context(req, db) old_orm_device = assert_device_exists(device_id) db.session.delete(old_orm_device) db.session.flush() # handled separately by parse_template_list device_data.pop('templates') updated_orm_device = Device(**device_data) parse_template_list(json_payload.get('templates', []), updated_orm_device) auto_create_template(json_payload, updated_orm_device) updated_orm_device.id = device_id updated_orm_device.updated = datetime.now() updated_orm_device.created = old_orm_device.created db.session.add(updated_orm_device) full_device = serialize_full_device(updated_orm_device, tenant) if CONFIG.orion: # Create subscription pointing to history service # (STH, logstash based persister) subs_handler = PersistenceHandler(service=tenant) subs_handler.remove(old_orm_device.persistence) # Generating 'device type' field for subscription request type_descr = "template" for dev_type in full_device['attrs'].keys(): type_descr += "_" + str(dev_type) updated_orm_device.persistence = subs_handler.create( device_id, type_descr) ctx_broker_handler = OrionHandler(service=tenant) ctx_broker_handler.update( serialize_full_device(old_orm_device, tenant), type_descr) kafka_handler = KafkaHandler() kafka_handler.update(full_device, meta={"service": tenant}) try: db.session.commit() except IntegrityError as error: handle_consistency_exception(error) result = { 'message': 'device updated', 'device': serialize_full_device(updated_orm_device, tenant) } return result
def create_device(req): """ Creates and configures the given device. :param req: The received HTTP request, as created by Flask. :return The created device or a list of device summary. This depends on which value the verbose (/?verbose=true) has - if true, only one device can be created ("count" argument can't be used or - at least - it must be exactly "1") and the full device is returned. If false, "count" can be used with higher values and only the devices summary (a structure containing all device IDs and their labels) is returned. :raises HTTPRequestError: If no authorization token was provided (no tenant was informed) :raises HTTPRequestError: If verbose is used with multiple device creation request. :raises HTTPRequestError: If count argument ("?count=X") is provided and it is not an integer. """ tenant = init_tenant_context(req, db) try: count = int(req.args.get('count', '1')) except ValueError as e: LOGGER.error(e) raise HTTPRequestError(400, "If provided, count must be integer") c_length = len(str(count)) verbose = req.args.get('verbose', 'false') in ['true', '1', 'True'] if verbose and count != 1: raise HTTPRequestError( 400, "Verbose can only be used for single device creation") devices = [] # Handlers kafka_handler = KafkaHandler() if CONFIG.orion: ctx_broker_handler = OrionHandler(service=tenant) subs_handler = PersistenceHandler(service=tenant) else: ctx_broker_handler = None subs_handler = None full_device = None for i in range(0, count): device_data, json_payload = parse_payload(req, device_schema) device_data['id'] = DeviceHandler.generate_device_id() device_data['label'] = DeviceHandler.indexed_label( count, c_length, device_data['label'], i) # handled separately by parse_template_list device_data.pop('templates', None) orm_device = Device(**device_data) parse_template_list(json_payload.get('templates', []), orm_device) auto_create_template(json_payload, orm_device) db.session.add(orm_device) devices.append({ 'id': device_data['id'], 'label': device_data['label'] }) full_device = serialize_full_device(orm_device, tenant) # Updating handlers kafka_handler.create(full_device, meta={"service": tenant}) if CONFIG.orion: # Generating 'device type' field for history type_descr = "template" for dev_type in full_device['attrs'].keys(): type_descr += "_" + str(dev_type) # TODO remove this in favor of kafka as data broker.... ctx_broker_handler.create(full_device, type_descr) sub_id = subs_handler.create(full_device['id'], type_descr) orm_device.persistence = sub_id try: db.session.commit() except IntegrityError as error: handle_consistency_exception(error) if verbose: result = {'message': 'device created', 'device': full_device} else: result = {'message': 'devices created', 'devices': devices} return result