Services/Events.js

/**Copyright (c) 2009-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.**/
"use strict";const deepcopy=require("deepcopy"),Database=require("../Utils/Database"),filterTemplate=require("../queryTemplates/filter.json"),Elasticsearch=require("../Utils/Elasticsearch"),Validator=require("../Utils/Validator"),InternalServerError=require("../Errors/InternalServerError"),InvalidInputError=require("../Errors/InvalidInputError"),BadRequestError=require("../Errors/BadRequestError");
/** 
 * Class which defines Events
 * @memberof mdxWebApiCore.Services
 * */
class Events{static#e=25;static#t=100;#r({sensorId:e,place:t,tripwireId:r,fromTimestamp:i,toTimestamp:s,objectType:a}){let n=deepcopy(filterTemplate);return null!=e?(n.query.bool.must.push({term:{"sensor.id.keyword":e}}),null!=r&&n.query.bool.must.push({term:{"event.id.keyword":r}})):n.query.bool.must.push({term:{"place.name.keyword":t}}),n.query.bool.must.push({range:{timestamp:{lte:s}}}),n.query.bool.must.push({range:{end:{gte:i}}}),n.query.bool.must.push({term:{"object.type.keyword":a}}),n}async#i(e,t){let r={index:`${e.getConfigs().get("indexPrefix")}${Elasticsearch.getIndex("tripwire")}`,body:this.#r(t),sort:"end:desc",size:t.maxResultSize,_sourceIncludes:["Id","id","timestamp","end","timeInterval","locations","smoothLocations","length","speedOverTime","sensor","event.id","event.type","place.name","analyticsModule","object","direction","speed","distance","bearing","videoPath"]},i=new Array,s=await Elasticsearch.getSearchResults(e.getClient(),r,!1);return s.indexAbsent||(i=Elasticsearch.searchResultFormatter(s.body)),i}async#s(e,t){let r={index:`${e.getConfigs().get("indexPrefix")}${Elasticsearch.getIndex("tripwire")}`,body:this.#r(t),sort:"end:desc",_sourceIncludes:["Id","id","timestamp","end","timeInterval","locations","smoothLocations","length","speedOverTime","sensor","event.id","event.type","place.name","analyticsModule","object","direction","speed","distance","bearing","videoPath"]},i=new Set,s=new Array,a=!1;const n=e.getClient().helpers.scrollSearch(r);for await(const e of n){let r=e.documents;for(let e of r)if(!i.has(e.id)&&(s.push(e),i.add(e.id),i.size===t.maxResultSize)){a=!0;break}if(a){await e.clear();break}}return s}
/** 
     * returns an object containing an array of tripwire events.
     * @public
     * @async
     * @param {Database} documentDb - Database Object
     * @param {Object} input - Input object.
     * @param {string} [input.sensorId] - Either sensorId or place should be present.
     * @param {string} [input.place] - Either sensorId or place should be present.
     * @param {?string} [input.tripwireId=null] - tripwireId can be present only if sensorId is present in the input.
     * @param {string} input.fromTimestamp
     * @param {string} input.toTimestamp
     * @param {number} [input.maxResultSize=25] - maxResultSize must be an integer.
     * @param {string} [input.objectType="Person"]
     * @param {boolean} [input.effective=true] - If effective is true, then the result returned will contain only the latest tripwire events of each object.
     * @returns {Promise<Object>} An object containing an array of tripwire events is returned
     * @example
     * const mdx = require("@nvidia-mdx/web-api-core");
     * const elastic = new mdx.Utils.Elasticsearch({node: "elasticsearch-url"},databaseConfigMap);
     * let input = {sensorId: "abc", fromTimestamp: "2023-01-12T11:20:10.000Z", toTimestamp: "2023-01-12T14:20:10.000Z"};
     * let tripwireMetadata = new mdx.Services.Events();
     * let tripwireEvents = await tripwireMetadata.getTripwireEvents(elastic,input);
     */async getTripwireEvents(e,t){const r={type:"object",additionalProperties:{not:!0,errorMessage:"Invalid additional Input ${0#}."},properties:{sensorId:{type:["string","null"],default:null,minLength:1,errorMessage:{minLength:"sensorId should have atleast 1 character."}},place:{type:["string","null"],default:null,minLength:1,errorMessage:{minLength:"place should have atleast 1 character."}},tripwireId:{type:["string","null"],default:null,minLength:1,errorMessage:{minLength:"tripwireId should have atleast 1 character."}},fromTimestamp:{type:"string"},toTimestamp:{type:"string"},maxResultSize:{type:"integer",minimum:1,maximum:Events.#t,default:Events.#e,errorMessage:{type:"maxResultSize is not an integer.",minimum:"maxResultSize can have a minimum value of 1.",maximum:`maxResultSize can have a maximum value of ${Events.#t}.`}},objectType:{type:"string",minLength:1,default:"Person",errorMessage:{minLength:"objectType should have atleast 1 character."}},effective:{type:"boolean",default:!0,errorMessage:{type:"effective doesn't have a boolean value."}}},required:["fromTimestamp","toTimestamp"],oneOf:[{required:["sensorId"]},{required:["place"]}],dependentRequired:{tripwireId:["sensorId"]},errorMessage:{required:"Input should have required properties 'fromTimestamp' and 'toTimestamp'.",dependentRequired:"If input has 'tripwireId' then it should have 'sensorId'.",oneOf:"Input should have either 'sensorId' or 'place'."}};let i=Validator.validateJsonSchema(t,r);if(!i.valid)throw new BadRequestError(i.reason);let s=Validator.isValidTimeRange(t.fromTimestamp,t.toTimestamp);if(!s.valid)throw new InvalidInputError(s.reason);if("maxResultSize"in t&&!Number.isFinite(t.maxResultSize))throw new InvalidInputError("maxResultSize is not a finite integer.");let a=new Array;if("Elasticsearch"===e.getName())return a=t.effective?await this.#s(e,t):await this.#i(e,t),{tripwireEvents:a};throw new InternalServerError(`Invalid database: ${e.getName()}.`)}}module.exports=Events;