UNPKG

haufe-azure-arm-utils

Version:
266 lines (234 loc) 8.38 kB
'use strict'; const debug = require('debug')('haufe-azure-arm-utils:filter-utils'); const filterUtils = function () { }; // FIXME: this should not be decided in a filter-class, much less in a utils-package // and even lesser in a library-repository. const FILTER_OPTIONS = { keepWeekly: true, weeklyDay: 3, weeklyThreshold: 14, keepMonthly: true, monthlyThreshold: 60 }; filterUtils.filterByTags = (list, filterTags) => { debug('filterByTags: ' + filterTags); const filterList = []; for (let i = 0; i < list.length; ++i) { const tags = list[i].tags; if (tagsMatch(tags, filterTags)) { filterList.push(list[i]); } } debug('result: ' + JSON.stringify(filterList)); return filterList; }; filterUtils.getByName = (list, name) => { debug('getByName(): ' + name); const entry = list.find(e => e.name.toUpperCase() === name.toUpperCase()); if (entry) { debug('Result: ' + JSON.stringify(entry)); } else { debug('name not found, returning null'); } return entry; }; const sortDescending = (list) => { // Clone the list; sort changes the original; we don't want that const copyList = []; for (let i = 0; i < list.length; ++i) { copyList.push(list[i]); } return copyList.sort((a, b) => { const aDate = new Date(a.timeCreated); const bDate = new Date(b.timeCreated); return bDate.getTime() - aDate.getTime(); }); }; filterUtils.getNewest = (list, tags) => { let filteredList = list; if (tags) { filteredList = filterUtils.filterByTags(list, tags); } if (filteredList.length === 0) { return null; } if (filteredList.length === 1) { return filteredList[0]; } // Sort in descending order by timeCreated const sortedList = sortDescending(filteredList); return sortedList[0]; }; const isSameDay = (d1, d2) => { return (d1.getUTCFullYear() === d2.getUTCFullYear() && d1.getUTCMonth() === d2.getUTCMonth() && d1.getUTCDate() === d2.getUTCDate()); }; const filterForToday = (list, filterOptions) => { // filterOptions are not used here currently const today = new Date(); return list.filter(entry => { const d = new Date(entry.timeCreated); return isSameDay(today, d); }); }; const filterForYesterday = (list, filterOptions) => { // filterOptions are not used here currently const yesterday = new Date((new Date()).getTime() - (24 * 60 * 60 * 1000)); return list.filter(entry => { const d = new Date(entry.timeCreated); return isSameDay(yesterday, d); }); }; const filterForWeekDay = (list, filterOptions) => { // Do we want to keep weekly backups? if (!filterOptions.keepWeekly) { return []; } // Yes, check which ones we have and filter out too old ones const weeklyThresholdDate = (new Date()).getTime() - (filterOptions.weeklyThreshold * 24 * 60 * 60 * 1000); return list.filter(entry => { const d = new Date(entry.timeCreated); return (d.getUTCDay() === filterOptions.weeklyDay && d.getTime() > weeklyThresholdDate); // week day, and not older than threshold }); }; const filterForFirstDayInMonth = (list, filterOptions) => { // Do we want to keep monthly backups? if (!filterOptions.keepMonthly) { return []; } // Yes, check which ones we have and filter out too old ones const monthlyThresholdDate = (new Date()).getTime() - (filterOptions.monthlyThreshold * 24 * 60 * 60 * 1000); return list.filter(entry => { const d = new Date(entry.timeCreated); return (d.getUTCDate() === 1 && d.getTime() > monthlyThresholdDate); // 1st in each month, and not older than threshold }); }; const filterDayDuplicates = (list) => { debug('filterDayDuplicates()'); if (list.length === 0) { return []; } const sortedList = sortDescending(list); debug('sortedList'); debug(sortedList); const resultList = [sortedList[0]]; // we will definitely need the first entry let currentDate = new Date(sortedList[0].timeCreated); for (let i = 1; i < sortedList.length; ++i) { const nextEntryDate = new Date(sortedList[i].timeCreated); if (!isSameDay(currentDate, nextEntryDate)) { // Skip if it's the same date; we already have the newest resultList.push(sortedList[i]); currentDate = nextEntryDate; } else { debug('removing day duplicate for ' + currentDate.toUTCString()); } } debug('result filterDayDuplicates'); debug(resultList); return resultList; }; const mergeLists = (lists) => { debug('mergeLists()'); const resultList = []; for (let i = 0; i < lists.length; ++i) { for (let j = 0; j < lists[i].length; ++j) { const entry = lists[i][j]; if (!resultList.find(e => e.id === entry.id)) { debug('Seeing new ID ' + entry.id); resultList.push(entry); } else { debug('Filtering out duplicate ID ' + entry.id); } } } return filterDayDuplicates(resultList); }; const findEntriesNotInKeepList = (fullList, keepList) => { // Remove by IDs const resultList = []; for (let i = 0; i < fullList.length; ++i) { const entry = fullList[i]; const findEntry = keepList.find(e => e.id === entry.id); if (findEntry) { continue; } resultList.push(entry); } return resultList; }; filterUtils.getKeepList = (list, tags, options) => { debug('getKeepList()'); const filterOptions = FILTER_OPTIONS; if (options) { for (let key in filterOptions) { if (options[key]) { filterOptions[key] = options[key]; } } } const taggedList = filterUtils.filterByTags(list, tags); if (taggedList.length === 0) { return taggedList; } // We have at least one image; make sure we don't delete the newest image, // in case we only have one, and we have no current ones. const newestList = [filterUtils.getNewest(taggedList)]; debug('newestList:'); debug(newestList); // Which backups were created today? const todayList = filterForToday(taggedList, filterOptions); debug('todayList:'); debug(todayList); // Which backups were created yesterday? const yesterdayList = filterForYesterday(taggedList, filterOptions); debug('yesterdayList:'); debug(yesterdayList); // Which backups were created on a certain week day? const weekList = filterForWeekDay(taggedList, filterOptions); debug('weekList:'); debug(weekList); // Which backups were created on the first of a month? const monthList = filterForFirstDayInMonth(taggedList, filterOptions); debug('monthList:'); debug(monthList); // Merge the list; we know the newest backup is definitely part of this list. const mergedList = mergeLists([newestList, todayList, yesterdayList, weekList, monthList]); debug('mergedList:'); debug(mergedList); return mergedList; }; filterUtils.getDeleteList = (list, tags, options) => { debug('getDeleteList()'); const keepList = filterUtils.getKeepList(list, tags, options); const fullList = filterUtils.filterByTags(list, tags); // Remove the entries from the keepList from the fullList, these // are the disks we want to remove. const deleteList = findEntriesNotInKeepList(fullList, keepList); debug('deleteList:'); debug(deleteList); return deleteList; }; const tagsMatch = (tags, filterTags) => { debug('tagsMatch(): ' + tags + ', ' + filterTags); // Do we have tags to filter for? if (!filterTags || filterTags.length === 0) { return true; } // Does the item have tags, if not, it's not a match if (!tags || tags.length === 0) { return false; } for (let key in filterTags) { if (!tags[key]) { return false; } const filterValue = filterTags[key].toUpperCase(); const tagValue = tags[key].toUpperCase(); if (filterValue !== tagValue) { return false; } } return true; }; module.exports = filterUtils;