Skip to content

Commit 910b08f

Browse files
DaanHooglandyadvr
authored andcommitted
server: fix duplicate tag exception as CloudRuntimeException (apache#3348)
See apache#3339: a runtime exception is thrown but it should be converted to an error return. Wrapping it in a CloudRuntimeException should do the trick. Fixes apache#3339
1 parent 0929866 commit 910b08f

2 files changed

Lines changed: 86 additions & 1 deletion

File tree

server/src/com/cloud/tags/TaggedResourceManagerImpl.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585

8686
import javax.inject.Inject;
8787
import javax.naming.ConfigurationException;
88+
import javax.persistence.EntityExistsException;
8889
import java.util.ArrayList;
8990
import java.util.HashMap;
9091
import java.util.List;
@@ -310,7 +311,11 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
310311
}
311312

312313
ResourceTagVO resourceTag = new ResourceTagVO(key, value, accountDomainPair.first(), accountDomainPair.second(), id, resourceType, customer, resourceUuid);
313-
resourceTag = _resourceTagDao.persist(resourceTag);
314+
try {
315+
resourceTag = _resourceTagDao.persist(resourceTag);
316+
} catch (EntityExistsException e) {
317+
throw new CloudRuntimeException(String.format("tag %s already on %s with id %s", resourceTag.getKey(), resourceType.toString(), resourceId),e);
318+
}
314319
resourceTags.add(resourceTag);
315320
}
316321
}

test/integration/component/test_tags.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2974,3 +2974,83 @@ def test_32_user_a_doesnt_have_access_to_user_b_tags(self):
29742974
self.fail("User1 has access to create tags for User2.")
29752975

29762976
return
2977+
2978+
@attr(tags=["advanced", "basic"], required_hardware="false")
2979+
def test_33_duplicate_vm_tag(self):
2980+
"""
2981+
Test creation of a duplicate tag on UserVM and verify error return.
2982+
cleanup by deleting
2983+
"""
2984+
# Validate the following
2985+
# 1. Create a tag on VM using createTags API
2986+
# 2. Create the same tag on VM using createTags API
2987+
# 3. check the return for the right error message
2988+
2989+
tag_key = 'scope'
2990+
tag_value = 'test_33_duplicate_vm_tag'
2991+
2992+
self.debug("Creating a tag for user VM")
2993+
# use vm_2 as vm_1 is deleted in other tests :(
2994+
tag = Tag.create(
2995+
self.apiclient,
2996+
resourceIds=self.vm_2.id,
2997+
resourceType='userVM',
2998+
tags={tag_key: tag_value}
2999+
)
3000+
self.debug("Tag created: %s" % tag.__dict__)
3001+
3002+
self.debug("Trying second tag witgh the same key for user VM")
3003+
try:
3004+
erronousTag = Tag.create(
3005+
self.apiclient,
3006+
resourceIds=self.vm_2.id,
3007+
resourceType='userVM',
3008+
tags={tag_key: tag_value}
3009+
)
3010+
except Exception as e:
3011+
# verify e.message
3012+
assert "tag scope already on UserVm with id" in e.message, \
3013+
"neat error message missing from error result"
3014+
pass
3015+
3016+
3017+
# we should still find the tag
3018+
vms = VirtualMachine.list(
3019+
self.apiclient,
3020+
listall=True,
3021+
key=tag_key,
3022+
value=tag_value
3023+
)
3024+
3025+
self.assertEqual(
3026+
isinstance(vms, list),
3027+
True,
3028+
"Tag based VMs listing failed")
3029+
3030+
self.debug("Deleting the created tag..")
3031+
try:
3032+
Tag.delete(
3033+
self.apiclient,
3034+
resourceIds=self.vm_2.id,
3035+
resourceType='userVM',
3036+
tags={tag_key: tag_value}
3037+
)
3038+
except Exception as e:
3039+
self.fail("Failed to delete the tag - %s" % e)
3040+
3041+
self.debug("Verifying if tag is actually deleted!")
3042+
tags = Tag.list(
3043+
self.apiclient,
3044+
listall=True,
3045+
resourceType='userVM',
3046+
account=self.account.name,
3047+
domainid=self.account.domainid,
3048+
key=tag_key,
3049+
value=tag_value
3050+
)
3051+
self.assertEqual(
3052+
tags,
3053+
None,
3054+
"List tags should return empty response"
3055+
)
3056+
return

0 commit comments

Comments
 (0)