public async create()

in source/packages/services/assetlibrary/src/devices/devices.full.service.ts [265:352]


    public async create(model: DeviceItem, applyProfile?:string) : Promise<string> {
        logger.debug(`device.full.service create: in: model: ${JSON.stringify(model)}, applyProfile:${applyProfile}`);

        ow(model, ow.object.nonEmpty);
        ow(model.templateId, ow.string.nonEmpty);
        ow(model.deviceId, ow.string.nonEmpty);

        // if a profile to apply has been provided, apply it first
        if (applyProfile!==undefined) {
            model = await this.applyProfile(model, applyProfile);
        }

        // remove any non printable characters from the id
        model.deviceId = model.deviceId.replace(/[^\x20-\x7E]+/g, '');

        // any ids need to be lowercase
        this.setIdsToLowercase(model);

        // default initial association if none provided
        if ( (model.groups===undefined || (model.groups.in===undefined && model.groups.out===undefined)) &&
             (model.devices===undefined || (model.devices.in===undefined && model.devices.out===undefined)) &&
             this.defaultDeviceParentRelation!=='' && this.defaultDeviceParentGroup!=='') {
            model.groups= {
                out: {}
            };
            model.groups.out[this.defaultDeviceParentRelation] = [this.defaultDeviceParentGroup];
        }

        // we cant check authz til here, as we need to understand any related devices and groups first
        await this.authServiceFull.authorizationCheck(model.listRelatedDeviceIds(), model.listRelatedGroupPaths(), ClaimAccess.C);

        // default initial state if none provided
        if (model.state===undefined && this.defaultDeviceState!==undefined) {
            model.state = <DeviceState> this.defaultDeviceState;
        }

        // perform validation of the device...
        const validateSubTypeFuture = this.typesService.validateSubType(model.templateId, TypeCategory.Device, model, Operation.CREATE);
        const validateGroupRelationshipsFuture = this.typesService.validateRelationshipsByPath(model.templateId, model.groups);
        const validateDeviceRelationshipsFuture = this.typesService.validateRelationshipsByType(model.templateId, model.devices);
        const results = await Promise.all([validateSubTypeFuture, validateGroupRelationshipsFuture, validateDeviceRelationshipsFuture]);

        // schema validation results
        const subTypeValidation = results[0];
        if (!subTypeValidation.isValid) {
            throw new Error('FAILED_VALIDATION');
        }

        // validate the path associations
        const groupRelationshipsValidation=results[1];
        if (!groupRelationshipsValidation)  {
            throw new Error('INVALID_RELATION');
        }

        // validate the device associations
        const deviceRelationshipsValidation=results[2];
        if (!deviceRelationshipsValidation)  {
            throw new Error('INVALID_RELATION');
        }

        // Assemble devicemodel into node
        model.category = TypeCategory.Device;
        const node = this.devicesAssembler.toNode(model);

        // Assemble the devices components
        const components: Node[]=[];
        if (model.components!==undefined) {
            model.components.forEach(c=> {
                c.category = TypeCategory.Component;
                components.push(this.devicesAssembler.toNode(c));
            });
        }

        // Save to datastore
        const id = await this.devicesDao.create(node, model.groups, model.devices, components);

        // fire event
        await this.eventEmitter.fire({
            objectId: model.deviceId,
            type: Type.device,
            event: Event.create,
            payload: JSON.stringify(model)
        });

        logger.debug(`device.full.service create: exit: id: ${id}`);
        return id;

    }