IGNITE-5466 Web Console: Fixed migration.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/7192c658 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/7192c658 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/7192c658 Branch: refs/heads/ignite-6467-1 Commit: 7192c6584a4657d09e5543cf08a3faf2182bacec Parents: c2ebb83 Author: Alexey Kuznetsov <akuznet...@apache.org> Authored: Tue Jul 24 15:05:06 2018 +0700 Committer: Alexey Kuznetsov <akuznet...@apache.org> Committed: Tue Jul 24 15:05:06 2018 +0700 ---------------------------------------------------------------------- .../migrations/1516948939797-migrate-configs.js | 121 +++++++++++++------ .../backend/migrations/migration-utils.js | 38 +----- 2 files changed, 93 insertions(+), 66 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/7192c658/modules/web-console/backend/migrations/1516948939797-migrate-configs.js ---------------------------------------------------------------------- diff --git a/modules/web-console/backend/migrations/1516948939797-migrate-configs.js b/modules/web-console/backend/migrations/1516948939797-migrate-configs.js index cfaf0f2..adeccf0 100644 --- a/modules/web-console/backend/migrations/1516948939797-migrate-configs.js +++ b/modules/web-console/backend/migrations/1516948939797-migrate-configs.js @@ -26,6 +26,12 @@ const getCacheForMigration = require('./migration-utils').getCacheForMigration; const _debug = false; const DUPLICATE_KEY_ERROR = 11000; +let dup = 1; + +function makeDup(name) { + return name + `_dup_${dup++}`; +} + function linkCacheToCluster(clustersModel, cluster, cachesModel, cache, domainsModel) { return clustersModel.update({_id: cluster._id}, {$addToSet: {caches: cache._id}}).exec() .then(() => cachesModel.update({_id: cache._id}, {clusters: [cluster._id]}).exec()) @@ -55,15 +61,20 @@ function cloneCache(clustersModel, cachesModel, domainsModel, cache) { delete cache._id; const newCache = _.clone(cache); + const domainIds = newCache.domains; newCache.clusters = [cluster]; + newCache.domains = []; return clustersModel.update({_id: {$in: newCache.clusters}}, {$pull: {caches: cacheId}}, {multi: true}).exec() .then(() => cachesModel.create(newCache)) .catch((err) => { if (err.code === DUPLICATE_KEY_ERROR) { - log(`Failed to clone cache, will change cache name and retry [cache=${newCache.name}]`); - newCache.name += '_dup'; + const retryWith = makeDup(newCache.name); + + error(`Failed to clone cache, will change cache name and retry [cache=${newCache.name}, retryWith=${retryWith}]`); + + newCache.name = retryWith; return cachesModel.create(newCache); } @@ -73,8 +84,6 @@ function cloneCache(clustersModel, cachesModel, domainsModel, cache) { .then((clone) => clustersModel.update({_id: {$in: newCache.clusters}}, {$addToSet: {caches: clone._id}}, {multi: true}).exec() .then(() => clone)) .then((clone) => { - const domainIds = newCache.domains; - if (_.isEmpty(domainIds)) return Promise.resolve(); @@ -91,14 +100,20 @@ function cloneCache(clustersModel, cachesModel, domainsModel, cache) { return domainsModel.create(newDomain) .catch((err) => { if (err.code === DUPLICATE_KEY_ERROR) { - log(`Failed to clone domain, will change type name and retry [cache=${newCache.name}, valueType=${newDomain.valueType}]`); - newDomain.valueType += '_dup'; + const retryWith = makeDup(newDomain.valueType); + + error(`Failed to clone domain, will change type name and retry [cache=${newCache.name}, valueType=${newDomain.valueType}, retryWith=${retryWith}]`); + + newDomain.valueType = retryWith; return domainsModel.create(newDomain); } }) - .then((createdDomain) => clustersModel.update({_id: cluster}, {$addToSet: {models: createdDomain._id}}).exec()) - .catch((err) => error('Failed to clone domain', err)); + .then((createdDomain) => { + return clustersModel.update({_id: cluster}, {$addToSet: {models: createdDomain._id}}).exec() + .then(() => cachesModel.update({_id: clone.id}, {$addToSet: {domains: createdDomain._id}})); + }) + .catch((err) => error('Failed to clone domain during cache clone', err)); }) .catch((err) => error(`Failed to duplicate domain model[domain=${domainId}], cache=${clone.name}]`, err)); }), Promise.resolve()); @@ -112,9 +127,9 @@ function cloneCache(clustersModel, cachesModel, domainsModel, cache) { } function migrateCache(clustersModel, cachesModel, domainsModel, cache) { - const len = _.size(cache.clusters); + const clustersCnt = _.size(cache.clusters); - if (len < 1) { + if (clustersCnt < 1) { if (_debug) log(`Found cache not linked to cluster [cache=${cache.name}]`); @@ -122,9 +137,9 @@ function migrateCache(clustersModel, cachesModel, domainsModel, cache) { .then((clusterLostFound) => linkCacheToCluster(clustersModel, clusterLostFound, cachesModel, cache, domainsModel)); } - if (len > 1) { + if (clustersCnt > 1) { if (_debug) - log(`Found cache linked to many clusters [cache=${cache.name}, cnt=${len}]`); + log(`Found cache linked to many clusters [cache=${cache.name}, clustersCnt=${clustersCnt}]`); return cloneCache(clustersModel, cachesModel, domainsModel, cache); } @@ -136,10 +151,10 @@ function migrateCache(clustersModel, cachesModel, domainsModel, cache) { function migrateCaches(clustersModel, cachesModel, domainsModel) { return cachesModel.find({}).lean().exec() .then((caches) => { - const sz = _.size(caches); + const cachesCnt = _.size(caches); - if (sz > 0) { - log(`Caches to migrate: ${sz}`); + if (cachesCnt > 0) { + log(`Caches to migrate: ${cachesCnt}`); return _.reduce(caches, (start, cache) => start.then(() => migrateCache(clustersModel, cachesModel, domainsModel, cache)), Promise.resolve()) .then(() => log('Caches migration finished.')); @@ -181,9 +196,9 @@ function cloneIgfs(clustersModel, igfsModel, igfs) { } function migrateIgfs(clustersModel, igfsModel, igfs) { - const len = _.size(igfs.clusters); + const clustersCnt = _.size(igfs.clusters); - if (len < 1) { + if (clustersCnt < 1) { if (_debug) log(`Found IGFS not linked to cluster [IGFS=${igfs.name}]`); @@ -191,9 +206,9 @@ function migrateIgfs(clustersModel, igfsModel, igfs) { .then((clusterLostFound) => linkIgfsToCluster(clustersModel, clusterLostFound, igfsModel, igfs)); } - if (len > 1) { + if (clustersCnt > 1) { if (_debug) - log(`Found IGFS linked to many clusters [IGFS=${igfs.name}, cnt=${len}]`); + log(`Found IGFS linked to many clusters [IGFS=${igfs.name}, clustersCnt=${clustersCnt}]`); return cloneIgfs(clustersModel, igfsModel, igfs); } @@ -205,10 +220,10 @@ function migrateIgfs(clustersModel, igfsModel, igfs) { function migrateIgfss(clustersModel, igfsModel) { return igfsModel.find({}).lean().exec() .then((igfss) => { - const sz = _.size(igfss); + const igfsCnt = _.size(igfss); - if (sz > 0) { - log(`IGFS to migrate: ${sz}`); + if (igfsCnt > 0) { + log(`IGFS to migrate: ${igfsCnt}`); return _.reduce(igfss, (start, igfs) => start.then(() => migrateIgfs(clustersModel, igfsModel, igfs)), Promise.resolve()) .then(() => log('IGFS migration finished.')); @@ -228,11 +243,13 @@ function linkDomainToCluster(clustersModel, cluster, domainsModel, domain) { function linkDomainToCache(cachesModel, cache, domainsModel, domain) { return cachesModel.update({_id: cache._id}, {$addToSet: {domains: domain._id}}).exec() .then(() => domainsModel.update({_id: domain._id}, {caches: [cache._id]}).exec()) - .catch((err) => error(`Failed link domain model to cache[cache=${cache.name}, domain=${domain._id}]`, err)); + .catch((err) => error(`Failed link domain model to cache [cache=${cache.name}, domain=${domain._id}]`, err)); } function migrateDomain(clustersModel, cachesModel, domainsModel, domain) { - if (_.isEmpty(domain.caches)) { + const cachesCnt = _.size(domain.caches); + + if (cachesCnt < 1) { if (_debug) log(`Found domain model not linked to cache [domain=${domain._id}]`); @@ -244,16 +261,51 @@ function migrateDomain(clustersModel, cachesModel, domainsModel, domain) { } if (_.isEmpty(domain.clusters)) { - return cachesModel.findOne({_id: {$in: domain.caches}}).lean().exec() - .then((cache) => { - if (cache) { - const clusterId = cache.clusters[0]; + const cachesCnt = _.size(domain.caches); - return domainsModel.update({_id: domain._id}, {clusters: [clusterId]}).exec() - .then(() => clustersModel.update({_id: clusterId}, {$addToSet: {models: domain._id}}).exec()); + if (_debug) + log(`Found domain model without cluster: [domain=${domain._id}, cachesCnt=${cachesCnt}]`); + + const grpByClusters = {}; + + return cachesModel.find({_id: {$in: domain.caches}}).lean().exec() + .then((caches) => { + if (caches) { + _.forEach(caches, (cache) => { + const c = _.get(grpByClusters, cache.clusters[0]); + + if (c) + c.push(cache._id); + else + grpByClusters[cache.clusters[0]] = [cache._id]; + }); + + return _.reduce(_.keys(grpByClusters), (start, cluster, idx) => start.then(() => { + const domainId = domain._id; + + const clusterCaches = grpByClusters[cluster]; + + if (idx > 0) { + delete domain._id; + domain.caches = clusterCaches; + + return domainsModel.create(domain) + .then((clonedDomain) => { + return cachesModel.update({_id: {$in: clusterCaches}}, {$addToSet: {domains: clonedDomain._id}}).exec() + .then(() => clonedDomain); + }) + .then((clonedDomain) => linkDomainToCluster(clustersModel, {_id: cluster, name: `stub${idx}`}, domainsModel, clonedDomain)) + .then(() => { + return cachesModel.update({_id: {$in: clusterCaches}}, {$pull: {domains: domainId}}, {multi: true}).exec(); + }); + } + + return domainsModel.update(domainsModel.update({_id: domainId}, {caches: clusterCaches}).exec()) + .then(() => linkDomainToCluster(clustersModel, {_id: cluster, name: `stub${idx}`}, domainsModel, domain)); + }), Promise.resolve()); } - log(`Found broken domain: [domain=${domain._id}, caches=${domain.caches}]`); + error(`Found domain with orphaned caches: [domain=${domain._id}, caches=${domain.caches}]`); return Promise.resolve(); }) @@ -267,10 +319,10 @@ function migrateDomain(clustersModel, cachesModel, domainsModel, domain) { function migrateDomains(clustersModel, cachesModel, domainsModel) { return domainsModel.find({}).lean().exec() .then((domains) => { - const sz = _.size(domains); + const domainsCnt = _.size(domains); - if (sz > 0) { - log(`Domain models to migrate: ${sz}`); + if (domainsCnt > 0) { + log(`Domain models to migrate: ${domainsCnt}`); return _.reduce(domains, (start, domain) => start.then(() => migrateDomain(clustersModel, cachesModel, domainsModel, domain)), Promise.resolve()) .then(() => log('Domain models migration finished.')); @@ -335,6 +387,7 @@ exports.up = function up(done) { .then(() => migrateCaches(clustersModel, cachesModel, domainsModel)) .then(() => migrateIgfss(clustersModel, igfsModel)) .then(() => migrateDomains(clustersModel, cachesModel, domainsModel)) + .then(() => log(`Duplicates counter: ${dup}`)) .then(() => done()) .catch(done); }; http://git-wip-us.apache.org/repos/asf/ignite/blob/7192c658/modules/web-console/backend/migrations/migration-utils.js ---------------------------------------------------------------------- diff --git a/modules/web-console/backend/migrations/migration-utils.js b/modules/web-console/backend/migrations/migration-utils.js index 0397247..8b7dd47 100644 --- a/modules/web-console/backend/migrations/migration-utils.js +++ b/modules/web-console/backend/migrations/migration-utils.js @@ -20,7 +20,7 @@ function log(msg) { } function error(msg, err) { - console.log(`[${new Date().toISOString()}] [ERROR] ${msg}. Error: ${err}`); + console.log(`[${new Date().toISOString()}] [ERROR] ${msg}.` + (err ? ` Error: ${err}` : '')); } function recreateIndex0(done, model, oldIdxName, oldIdx, newIdx) { @@ -52,19 +52,11 @@ function recreateIndex(done, model, oldIdxName, oldIdx, newIdx) { const LOST_AND_FOUND = 'LOST_AND_FOUND'; -let _clusterLostAndFound = null; - function getClusterForMigration(clustersModel, space) { - if (_clusterLostAndFound) - return Promise.resolve(_clusterLostAndFound); - - return clustersModel.findOne({name: LOST_AND_FOUND}).lean().exec() + return clustersModel.findOne({space, name: LOST_AND_FOUND}).lean().exec() .then((cluster) => { - if (cluster) { - _clusterLostAndFound = cluster; - + if (cluster) return cluster; - } return clustersModel.create({ space, @@ -82,28 +74,15 @@ function getClusterForMigration(clustersModel, space) { Multicast: {addresses: ['127.0.0.1:47500..47510']}, Vm: {addresses: ['127.0.0.1:47500..47510']} } - }) - .then((cluster) => { - _clusterLostAndFound = cluster; - - return cluster; - }); + }); }); } -let _cacheLostAndFound = null; - function getCacheForMigration(clustersModel, cachesModel, space) { - if (_cacheLostAndFound) - return Promise.resolve(_cacheLostAndFound); - - return cachesModel.findOne({name: LOST_AND_FOUND}) + return cachesModel.findOne({space, name: LOST_AND_FOUND}) .then((cache) => { - if (cache) { - _cacheLostAndFound = cache; - + if (cache) return cache; - } return getClusterForMigration(clustersModel, space) .then((cluster) => { @@ -131,11 +110,6 @@ function getCacheForMigration(clustersModel, cachesModel, space) { .then((cache) => { return clustersModel.update({_id: cache.clusters[0]}, {$addToSet: {caches: cache._id}}).exec() .then(() => cache); - }) - .then((cache) => { - _cacheLostAndFound = cache; - - return cache; }); }); }