diff --git a/src/main/groovy/com/rundeck/plugins/ansible/plugin/AnsibleResourceModelSource.java b/src/main/groovy/com/rundeck/plugins/ansible/plugin/AnsibleResourceModelSource.java index c50253a..919f7c9 100644 --- a/src/main/groovy/com/rundeck/plugins/ansible/plugin/AnsibleResourceModelSource.java +++ b/src/main/groovy/com/rundeck/plugins/ansible/plugin/AnsibleResourceModelSource.java @@ -57,6 +57,7 @@ import java.util.Map.Entry; import java.util.Properties; import java.util.Set; +import java.util.stream.Collectors; import static com.rundeck.plugins.ansible.ansible.InventoryList.ALL; import static com.rundeck.plugins.ansible.ansible.InventoryList.CHILDREN; @@ -815,18 +816,34 @@ public void applyNodeTags(NodeEntryImpl node, Map nodeValues) th InventoryList.tagHandle(NodeTag.DESCRIPTION, node, nodeValues); } + /** + * Adds a node to the ansibleNodes map, merging tags if the node already exists. + * + * @param node The node to add. + * @param tags The tags to associate with the node. + */ public void addNode(NodeEntryImpl node, Set tags) { - if (ansibleNodes.containsKey(node.getNodename())) { - NodeEntryImpl oldNode = ansibleNodes.get(node.getNodename()); - Set currentTags = getStringTags(oldNode); - currentTags.addAll(tags); - oldNode.setTags(Set.copyOf(currentTags)); - } else { - node.setTags(Set.copyOf(tags)); - ansibleNodes.put(node.getNodename(), node); - } + ansibleNodes.compute(node.getNodename(), (key, existingNode) -> { + if (existingNode != null) { + // Node exists, merge tags efficiently + Set mergedTags = new HashSet<>(getStringTags(existingNode)); // Start with existing tags + mergedTags.addAll(tags); // Add the new tags + existingNode.setTags(Set.copyOf(mergedTags)); // Update the existing node + return existingNode; // Return the updated node + } else { + // Node doesn't exist, add it with the given tags + node.setTags(Set.copyOf(tags)); + return node; // Return the new node + } + }); } + /** + * Retrieves the tags from a node and converts them to strings. + * + * @param node The node whose tags are to be retrieved. + * @return A set of strings representing the node's tags. Returns an empty set if the node has no tags. + */ public Set getStringTags(NodeEntryImpl node) { Set tags = new HashSet<>(); for (Object tag : node.getTags()) {