-
Notifications
You must be signed in to change notification settings - Fork 77
keep date consistency when generate enclosure #455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,90 +68,41 @@ function generateEnclosureJobFactory( | |
| var self = this; | ||
| var enclNode; | ||
|
|
||
| Promise.all([ | ||
| Promise.any([ | ||
| self._findSerialNumber(self.enclConst.snPath[0]), | ||
| self._findSerialNumber(self.enclConst.snPath[1]) | ||
| ]), | ||
| waterline.nodes.find({ type: self.enclConst.type }) | ||
| Promise.any([ | ||
| self._findSerialNumber(self.enclConst.snPath[0]), | ||
| self._findSerialNumber(self.enclConst.snPath[1]) | ||
| ]) | ||
| .spread(self._matchEnclosure.bind(self)) | ||
| .then(function (matchInfo) { | ||
| // Create an enclosure node if there isn't matched one | ||
| enclNode = matchInfo.encl; | ||
|
|
||
| if (_.isEmpty(enclNode)) { | ||
|
|
||
| var enclData = { | ||
| name: self.enclConst.namePrefix + matchInfo.sn, | ||
| type: self.enclConst.type, | ||
| relations: [] | ||
| }; | ||
|
|
||
| return waterline.nodes.create(enclData) | ||
| .then(function(node) { | ||
| if (!node) { | ||
| return Promise.reject('Could not create enclosure node'); | ||
| } | ||
| enclNode = node; | ||
| logger.debug('No matched enclosure, create a new one', { | ||
| id: self.nodeId, | ||
| enclosure: enclNode.id | ||
| }); | ||
| }); | ||
| } | ||
| else { | ||
| logger.debug(enclNode.name + ' matched', { | ||
| id: self.nodeId, | ||
| enclosure: enclNode.id | ||
| }); | ||
| .then(function(nodeSn){ | ||
| var enclName = self.enclConst.namePrefix + nodeSn; | ||
| var enclData = { | ||
| name: enclName, | ||
| type: self.enclConst.type, | ||
| relations: [] | ||
| }; | ||
| return waterline.nodes.findOrCreate({ type: self.enclConst.type, name: enclName}, enclData); | ||
| }) | ||
| .then(function(node) { | ||
| if (!node) { | ||
| return Promise.reject('Could not create enclosure node'); | ||
| } | ||
| enclNode = node; | ||
| logger.debug('findOrCreate enclosure', { | ||
| id: self.nodeId, | ||
| enclosure: enclNode.id | ||
| }); | ||
| }) | ||
| .then(function () { | ||
| // Add compute node info into enclosure node | ||
|
|
||
| var enclosedNodes = self._popEnclTarget(enclNode); | ||
|
|
||
| if (enclosedNodes.indexOf(self.nodeId) === -1) { | ||
| // If current compute node id isn't in enclosure node, update the latter | ||
|
|
||
| enclosedNodes.push(self.nodeId); | ||
|
|
||
| enclNode.relations.push({ | ||
| relationType: self.enclConst.relationEncl, | ||
| targets: enclosedNodes | ||
| }); | ||
|
|
||
| return waterline.nodes.updateByIdentifier( | ||
| enclNode.id, | ||
| {relations: enclNode.relations}); | ||
| } | ||
| // Add compute relations into enclosure node | ||
| return self.addRelation(enclNode, self.enclConst.relationEncl, self.nodeId); | ||
| }) | ||
| .then(function () { | ||
| // Add enclosure node info into compute node | ||
|
|
||
| return waterline.nodes.findByIdentifier(self.nodeId) | ||
| .then(function (node) { | ||
| if (!node) { | ||
| return Promise.reject('Could not find node with identifier ' + self.nodeId); | ||
| } | ||
|
|
||
| var enclTarget = self._popEnclTarget(node); | ||
|
|
||
| if (enclTarget.length !== 1 || | ||
| enclTarget.indexOf(enclNode.id) === -1) { | ||
| // If enclosedBy relation of the compute node is not this enclosure, | ||
| // update it to this enclosure node | ||
|
|
||
| node.relations.push({ | ||
| relationType: self.enclConst.relationEnclBy, | ||
| targets: [enclNode.id] | ||
| }); | ||
|
|
||
| return waterline.nodes.updateByIdentifier( | ||
| self.nodeId, | ||
| {relations: node.relations}); | ||
| } | ||
| return self.addRelation(node, self.enclConst.relationEnclBy, enclNode); | ||
| }); | ||
| }) | ||
| .then(function () { | ||
|
|
@@ -191,62 +142,74 @@ function generateEnclosureJobFactory( | |
| }; | ||
|
|
||
| /** | ||
| * Find enclosure node that matches given catalog info | ||
| * | ||
| * @param {object} nodeSn node's serial number | ||
| * @param {object} encls enclosure nodes | ||
| * @return {object} matched serial number and enclosure node | ||
| * This function is duplicated with on-http/lib/service/node-api-service.js/addRelation | ||
| * Add the given target nodes to the given relationType on the given node. Fail | ||
| * silently with missing arguments. If a relation does not already exist on the node | ||
| * create it, otherwise append to the existing one. | ||
| * @param {Object} node - node whose relation needs to be updated | ||
| * @param {String} type - relation type that needs to be updated | ||
| * @param {String[] | Object[]} targets - nodes or ids in relation type that to be added | ||
| * @return {Object} the updated node | ||
| */ | ||
| GenerateEnclosureJob.prototype._matchEnclosure = function (nodeSn, encls) { | ||
| var self = this; | ||
|
|
||
| return _.transform(encls, function (result, encl) { | ||
| var enclSn = encl.name.slice(self.enclConst.namePrefix.length, encl.name.length); | ||
|
|
||
| if (enclSn === '') { | ||
| // No serial number in enclosure name, jump to the next entry | ||
| return true; | ||
| GenerateEnclosureJob.prototype.addRelation = function addRelation(node, type, targets) { | ||
| if (!(node && type && targets)) { | ||
| return; | ||
| } | ||
| return waterline.nodes.addFieldIfNotExistByIdentifier(node.id, "relations", []) | ||
| .then(function(){ | ||
| var relationsItemToBeAdded = { | ||
| relations: [{relationType: type, targets: []}] | ||
| }; | ||
| var existSign = [{relationType: type}]; | ||
| return waterline.nodes.addListItemsIfNotExistByIdentifier( | ||
| node.id, | ||
| relationsItemToBeAdded, | ||
| existSign | ||
| ); | ||
| }) | ||
| .then(function(modifiedNode){ | ||
| if (!modifiedNode){ | ||
| return node; | ||
| } | ||
|
|
||
| if (enclSn === nodeSn) { | ||
| result.encl = encl; | ||
| // Find the match and exit the loop | ||
| return false; | ||
| return modifiedNode; | ||
| }) | ||
| .then(function(modifiedNode){ | ||
| var targetsItems = _.map([].concat(targets), function(targetNode) { | ||
| targetNode = targetNode.id || targetNode; | ||
| if(targetNode === node.id ) { | ||
| return Promise.reject(new Error('Node cannot have relationship '+type+' with itself')); | ||
| } | ||
| return targetNode; | ||
| }); | ||
| var index = _.findIndex(modifiedNode.relations, { relationType: type }); | ||
| var field = ["relations.", String(index),".targets"].join(""); | ||
| var targetsToBeAdded = {}; | ||
| targetsToBeAdded[field] = _.uniq(targetsItems); | ||
|
|
||
| // Can not make sure prevent every exception in high concurrency. | ||
| if (type === 'containedBy' && | ||
| modifiedNode.relations[index].targets.length + targets.length > 1) { | ||
| return Promise.reject(new Error("Node "+node.id+" can only be contained by one node")); | ||
| } | ||
| }, { | ||
| sn: nodeSn, | ||
| encl: {} | ||
| }); | ||
| }; | ||
|
|
||
| /** | ||
| * Get target nodes of the encloses or enclosedBy relation, and | ||
| * remove this relation type from node's relations | ||
| * | ||
| * @param {object} node | ||
| * @return {array} target nodes | ||
| */ | ||
| GenerateEnclosureJob.prototype._popEnclTarget = function (node) { | ||
| var self = this; | ||
| var enclRelation = _.find(node.relations, function(entry) { | ||
| return entry.relationType === self.enclConst.relationEncl || | ||
| entry.relationType === self.enclConst.relationEnclBy; | ||
| }); | ||
|
|
||
| var targetNodes = []; | ||
|
|
||
| if (enclRelation) { | ||
| if (enclRelation.hasOwnProperty('targets')) { | ||
| // Store existing target node id | ||
| targetNodes = enclRelation.targets; | ||
| // Compute node can only have one enclosure target. | ||
| if (type === "enclosedBy") { | ||
| var targetsToBeRemoveded = {}; | ||
| targetsToBeRemoveded[field] = [modifiedNode.relations[index].targets[0]]; | ||
| return waterline.nodes.removeListItemsByIdentifier( | ||
| node.id, targetsToBeRemoveded | ||
| ) | ||
| .then(function(){ | ||
| return targetsToBeAdded; | ||
| }); | ||
| } | ||
|
|
||
| // Remove encloses relation | ||
| node.relations.pop(enclRelation); | ||
| } | ||
|
|
||
| return targetNodes; | ||
| return targetsToBeAdded; | ||
| }) | ||
| .then(function(targetsToBeAdded){ | ||
| return waterline.nodes.addListItemsIfNotExistByIdentifier( | ||
| node.id, targetsToBeAdded | ||
| ); | ||
| }); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Expected ')' and instead saw ';'. |
||
| }; | ||
|
|
||
| return GenerateEnclosureJob; | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without signs, is there any possibility that enclosure node will "encloses" one compute node more than once, if running this job multiple times?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mongo list update operator won't add two same items of value type to one list.