/** * Analyzes, if an object is obsolete by checking if a specified retention time is exceeded. * * This analyzer does that, by checking the objects (and possible children) changed date. If all changes are older then the minimum age an action will be executed. * * var analyzer = sol.create("sol.common_monitoring.as.analyzers.RetentionAnalyzer", { * retention: { value: 2, unit: "M" }, * action: { type: "WORKFLOW", templateId: "TestMonitoring", user: "Administrator" } * }); * * For possible retention configuration see {@link sol.common_monitoring.as.MonitorUtils#evalDateUnitConfig}. * * The action needs to be specified, because analysers are responsible for determining the actions. This special analyzer just returns exactely one ore no action. * * @eloas * * @requires sol.common.DateUtils * @requires sol.common.RepoUtils * @requires sol.common_monitoring.as.MonitorUtils */ sol.define("sol.common_monitoring.as.analyzers.RetentionAnalyzer", { requiredConfig: ["retention", "action"], /** * @cfg {Object} retention Configuration to determine, if an object is obsolete or not (see {@link sol.common_monitoring.as.MonitorUtils#evalDateUnitConfig}) * @cfg {String} retention.type (optional) * @cfg {String} retention.key (optional) * @cfg {Number} retention.value (optional) * @cfg {String|Object} retention.unit (optional) * @cfg {String} retention.unit.type (optional) * @cfg {String} retention.unit.key (optional) */ /** * @cfg {Object} action */ initialize: function (config) { var me = this; me.$super("sol.Base", "initialize", [config]); me._todayIso = sol.common.DateUtils.dateToIso(new Date()); }, /** * Analyzes if the object and all children are older than a specified retention time. * @param {de.elo.ix.client.Sord} sord * @return {Object[]} */ analyze: function (sord) { var me = this, results = [], latestChange, latestChildChangedDate, nextRun; me.logger.enter("analyze", { objId: sord.id, name: String(sord.name) }); latestChange = me.retrieveChangedDate(sord); latestChildChangedDate = me.retrieveOldestChildrenChangedDate(sord); if (latestChildChangedDate && (latestChange.getTime() < latestChildChangedDate.getTime())) { latestChange = latestChildChangedDate; } me.logger.debug(["last change: {0}", latestChange]); if (me.isObsolete(sord, latestChange)) { results.push({ action: me.action }); me.logger.info(["retention exceeded: objId={0}, latestChange={1}", sord.id, latestChange]); } else { nextRun = me.calculateNextCheck(sord, latestChange, true); results.push({ nextRun: nextRun }); me.logger.info(["retention not exceeded: objId={0}, nextPossibleRetention={1};", sord.id, nextRun]); } me.logger.exit("analyze", results); return results; }, /** * @private * Retrieves an objects last changed date. * @param {de.elo.ix.client.Sord} sord * @return {Date} */ retrieveChangedDate: function (sord) { return sol.common.DateUtils.isoToDate(sord.TStamp + ""); }, /** * @private * Retrieves the most current last changed date of all children. * @param {de.elo.ix.client.Sord} sord * @return {Date} */ retrieveOldestChildrenChangedDate: function (sord) { var me = this, findOptions = new FindOptions(), changedDate = null, children; findOptions.orderBy = "objtstamp DESC"; findOptions.totalCount = 1; children = sol.common.RepoUtils.findChildren(sord.id, { includeFolders: true, includeDocuments: true, sordZ: SordC.mbLean, recursive: true, level: -1, findOptions: findOptions }); if (children && (children.length === 1)) { changedDate = me.retrieveChangedDate(children[0]); me.logger.debug(["latest changed child: objId={0}; name={1}, changed={2}", children[0].id, children[0].name, changedDate]); } return changedDate; }, /** * @private * Calculates the date on which the next check should occur using {@link #retention} and `latestChange`. * @param {de.elo.ix.client.Sord} sord Used to determine the retention (if it depends on indexfields) * @param {Date} latestChange The most current change of the object (or any child) * @param {Boolean} [resultWithoutTime=false] (optional) Defines, if the resutling ISO string should contain tzhe time or not * @return {String} */ calculateNextCheck: function (sord, latestChange, resultWithoutTime) { var me = this, distance = sol.common_monitoring.as.MonitorUtils.evalDateUnitConfig(sord, me.retention), checkDate; checkDate = sol.common.DateUtils.shift(latestChange, distance.value, { unit: distance.unit }); return sol.common.DateUtils.dateToIso(checkDate, { withoutTime: resultWithoutTime }); }, /** * @private * Checks, if an date (`latestChange`) has exceeded the retention time. * @param {de.elo.ix.client.Sord} sord Used to determine the retention (if it depends on indexfields) * @param {Date} latestChange The most current change of the object (or any child) * @return {Boolean} */ isObsolete: function (sord, latestChange) { var me = this, nextCheck = me.calculateNextCheck(sord, latestChange); me.logger.debug(["check retention: object would expire at {0}", nextCheck]); return nextCheck < me._todayIso; } });