Skip to content

Commit 1136924

Browse files
META-2694 Use UUID in qualifiedName instead of name (#13)
* META-2694 Use UUID in qualifiedName instead of name (cherry picked from commit d2be391) * META-2694 Remove redundant code Co-authored-by: Anshul Mehta <[email protected]>
1 parent 18a6548 commit 1136924

File tree

7 files changed

+277
-36
lines changed

7 files changed

+277
-36
lines changed

3party-licenses/jnanoid-LICENSE

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
MIT License
2+
3+
Copyright (c) 2017 The JNanoID Authors
4+
Copyright (c) 2017 Aventrix LLC
5+
Copyright (c) 2017 Andrey Sitnik
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.

intg/src/main/java/org/apache/atlas/AtlasErrorCode.java

+1
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ public enum AtlasErrorCode {
208208
GLOSSARY_ALREADY_EXISTS(409, "ATLAS-409-00-007", "Glossary with name {0} already exists"),
209209
GLOSSARY_TERM_ALREADY_EXISTS(409, "ATLAS-409-00-009", "Glossary term with qualifiedName {0} already exists"),
210210
GLOSSARY_CATEGORY_ALREADY_EXISTS(409, "ATLAS-409-00-00A", "Glossary category with qualifiedName {0} already exists"),
211+
ACHOR_UPDATION_NOT_SUPPORTED(409, "ATLAS-400-00-0010", "Anchor(glossary) change not supported"),
211212
GLOSSARY_IMPORT_FAILED(409, "ATLAS-409-00-011", "Glossary import failed"),
212213

213214
// All internal errors go here

repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java

+70-7
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ private void processParentCategory(AtlasGlossaryCategory storeObject, AtlasGloss
167167
} else {
168168
// Delete link to existing parent and link to new parent
169169
relationshipStore.deleteById(parentRelationship.getGuid(), true);
170+
updateQualifiedName(storeObject, newParent.getCategoryGuid());
170171
createRelationship(defineCategoryHierarchyLink(newParent, storeObject.getGuid()));
171172
}
172173
}
@@ -187,8 +188,7 @@ private void processNewParent(AtlasGlossaryCategory storeObject, AtlasRelatedCat
187188

188189
// New parent added, qualifiedName needs recomputation
189190
// Derive the qualifiedName of the Glossary
190-
AtlasGlossaryCategory parentCategory = dataAccess.load(getAtlasGlossaryCategorySkeleton(newParent.getCategoryGuid()));
191-
storeObject.setQualifiedName(storeObject.getName() + "." + parentCategory.getQualifiedName());
191+
updateQualifiedName(storeObject, newParent.getCategoryGuid());
192192

193193
if (LOG.isDebugEnabled()) {
194194
LOG.debug("Derived qualifiedName = {}", storeObject.getQualifiedName());
@@ -197,6 +197,14 @@ private void processNewParent(AtlasGlossaryCategory storeObject, AtlasRelatedCat
197197
updateChildCategories(storeObject, storeObject.getChildrenCategories(), impactedCategories, false);
198198
}
199199

200+
private void updateQualifiedName(AtlasGlossaryCategory storeObject, String guid) throws AtlasBaseException {
201+
AtlasRelatedCategoryHeader parentCat = new AtlasRelatedCategoryHeader();
202+
parentCat.setCategoryGuid(guid);
203+
AtlasGlossaryCategory glossaryCategory = new AtlasGlossaryCategory(storeObject);
204+
glossaryCategory.setParentCategory(parentCat);
205+
storeObject.setQualifiedName(createQualifiedName(glossaryCategory));
206+
}
207+
200208
private void processParentRemoval(AtlasGlossaryCategory storeObject, AtlasGlossaryCategory updatedCategory, AtlasRelatedCategoryHeader existingParent, Map<String, AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
201209
if (DEBUG_ENABLED) {
202210
LOG.debug("Removing category parent, category = {}, parent = {}", storeObject.getGuid(), existingParent.getDisplayText());
@@ -207,8 +215,9 @@ private void processParentRemoval(AtlasGlossaryCategory storeObject, AtlasGlossa
207215

208216
// Derive the qualifiedName of the Glossary
209217
String anchorGlossaryGuid = updatedCategory.getAnchor().getGlossaryGuid();
210-
AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
211-
storeObject.setQualifiedName(storeObject.getName() + "@" + glossary.getQualifiedName());
218+
AtlasGlossaryCategory glossaryCategory = new AtlasGlossaryCategory(storeObject);
219+
glossaryCategory.setAnchor(new AtlasGlossaryHeader(anchorGlossaryGuid));
220+
storeObject.setQualifiedName(createQualifiedName(glossaryCategory, true));
212221

213222
if (LOG.isDebugEnabled()) {
214223
LOG.debug("Derived qualifiedName = {}", storeObject.getQualifiedName());
@@ -393,6 +402,7 @@ private void processCategoryChildren(AtlasGlossaryCategory storeObject, AtlasGlo
393402
.stream()
394403
.filter(c -> updatedExistingCategoryRelation(existingChildren, c))
395404
.collect(Collectors.toSet());
405+
updateChildCategories(storeObject, toUpdate, impactedCategories, false);
396406
updateCategoryRelationships(storeObject, toUpdate);
397407

398408
Set<AtlasRelatedCategoryHeader> toDelete = existingChildren
@@ -535,20 +545,25 @@ private void updateChildCategories(AtlasGlossaryCategory parentCategory, Collect
535545

536546
for (AtlasRelatedCategoryHeader childCategoryHeader : childCategories) {
537547
AtlasGlossaryCategory child = dataAccess.load(getAtlasGlossaryCategorySkeleton(childCategoryHeader.getCategoryGuid()));
538-
String qualifiedName = child.getName() + ".";
539548
String childAnchorGuid = child.getAnchor().getGlossaryGuid();
549+
String qualifiedName = "";
550+
540551
if (isParentRemoved) {
541552
if (LOG.isDebugEnabled()) {
542553
LOG.debug("Parent removed, deriving qualifiedName using Glossary");
543554
}
544555
AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(childAnchorGuid));
545-
qualifiedName += glossary.getQualifiedName();
556+
qualifiedName = getNanoid(child.getQualifiedName()) + glossary.getQualifiedName();
546557
child.setParentCategory(null);
547558
} else {
548559
if (LOG.isDebugEnabled()) {
549560
LOG.debug("Using parent to derive qualifiedName");
550561
}
551-
qualifiedName += parentCategory.getQualifiedName();
562+
AtlasGlossaryCategory category = new AtlasGlossaryCategory(child);
563+
AtlasRelatedCategoryHeader parentCat = new AtlasRelatedCategoryHeader();
564+
parentCat.setCategoryGuid(parentCategory.getGuid());
565+
category.setParentCategory(parentCat);
566+
qualifiedName = createQualifiedName(category, parentCategory, false);
552567
}
553568
child.setQualifiedName(qualifiedName);
554569

@@ -576,4 +591,52 @@ private void updateChildCategories(AtlasGlossaryCategory parentCategory, Collect
576591
}
577592
}
578593

594+
protected String createQualifiedName(AtlasGlossaryCategory cat) throws AtlasBaseException {
595+
return createQualifiedName(cat, null, false);
596+
}
597+
598+
protected String createQualifiedName(AtlasGlossaryCategory cat, boolean parentRemoval) throws AtlasBaseException {
599+
return createQualifiedName(cat, null, parentRemoval);
600+
}
601+
602+
protected String createQualifiedName(AtlasGlossaryCategory cat, AtlasGlossaryCategory parentCategory, boolean parentRemoval) throws AtlasBaseException {
603+
String ret = "" ;
604+
String qName = "";
605+
606+
if (!StringUtils.isEmpty(cat.getQualifiedName())) {
607+
//extract existing nanoid for category
608+
String[] t1 = cat.getQualifiedName().split("\\.");
609+
qName = t1[t1.length -1].split("@")[0];
610+
}
611+
612+
qName = StringUtils.isEmpty(qName) ? getUUID() : qName;
613+
if (parentRemoval) {
614+
AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(cat.getAnchor().getGlossaryGuid()));
615+
ret = qName + "@" + glossary.getQualifiedName();
616+
617+
} else if (parentCategory != null) {
618+
String[] parentCatQname = parentCategory.getQualifiedName().split("@");
619+
ret = parentCatQname[0] + "." + qName + "@" + parentCatQname[1];
620+
621+
} else if (cat.getParentCategory() != null) {
622+
AtlasGlossaryCategory parentCat = dataAccess.load(getAtlasGlossaryCategorySkeleton(cat.getParentCategory().getCategoryGuid()));
623+
String[] parentCatQname = parentCat.getQualifiedName().split("@");
624+
ret = parentCatQname[0] + "." + qName + "@" + parentCatQname[1];
625+
626+
} else {
627+
String anchorGlossaryGuid = cat.getAnchor().getGlossaryGuid();
628+
AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
629+
if (glossary == null) {
630+
throw new AtlasBaseException("Glossary not found with guid: " + anchorGlossaryGuid);
631+
}
632+
ret = qName + "@" + glossary.getQualifiedName();
633+
}
634+
return ret;
635+
}
636+
637+
private String getNanoid(String qualifiedName){
638+
String[] split_0 = qualifiedName.split("@");
639+
String[] split_1 = split_0[0].split("\\.");
640+
return split_1[split_1.length-1];
641+
}
579642
}

repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java

+24-29
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,12 @@ public AtlasGlossary createGlossary(AtlasGlossary atlasGlossary) throws AtlasBas
143143
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Glossary definition missing");
144144
}
145145

146+
if (isNameInvalid(atlasGlossary.getName())) {
147+
throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME);
148+
}
149+
146150
if (StringUtils.isEmpty(atlasGlossary.getQualifiedName())) {
147-
if (StringUtils.isEmpty(atlasGlossary.getName())) {
148-
throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_QUALIFIED_NAME_CANT_BE_DERIVED);
149-
}
150-
if (isNameInvalid(atlasGlossary.getName())){
151-
throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME);
152-
} else {
153-
atlasGlossary.setQualifiedName(atlasGlossary.getName());
154-
}
151+
atlasGlossary.setQualifiedName(GlossaryUtils.createQualifiedName());
155152
}
156153

157154
if (glossaryExists(atlasGlossary)) {
@@ -343,15 +340,12 @@ public AtlasGlossaryTerm createTerm(AtlasGlossaryTerm glossaryTerm) throws Atlas
343340

344341
if (isNameInvalid(glossaryTerm.getName())){
345342
throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME);
346-
} else {
347-
// Derive the qualifiedName
348-
String anchorGlossaryGuid = glossaryTerm.getAnchor().getGlossaryGuid();
349-
AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
350-
glossaryTerm.setQualifiedName(glossaryTerm.getName() + "@" + glossary.getQualifiedName());
343+
}
351344

352-
if (LOG.isDebugEnabled()) {
353-
LOG.debug("Derived qualifiedName = {}", glossaryTerm.getQualifiedName());
354-
}
345+
glossaryTerm.setQualifiedName(glossaryTermUtils.createQualifiedName(glossaryTerm));
346+
347+
if (LOG.isDebugEnabled()) {
348+
LOG.debug("Derived qualifiedName = {}", glossaryTerm.getQualifiedName());
355349
}
356350

357351
// This might fail for the case when the term's qualifiedName has been updated and the duplicate request comes in with old name
@@ -410,7 +404,7 @@ public AtlasGlossaryTerm updateTerm(AtlasGlossaryTerm atlasGlossaryTerm, boolean
410404
}
411405

412406
if (StringUtils.isEmpty(atlasGlossaryTerm.getName())) {
413-
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "DisplayName can't be null/empty");
407+
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Name can't be null/empty");
414408
}
415409

416410
if (isNameInvalid(atlasGlossaryTerm.getName())) {
@@ -426,6 +420,11 @@ public AtlasGlossaryTerm updateTerm(AtlasGlossaryTerm atlasGlossaryTerm, boolean
426420
}
427421

428422
AtlasGlossaryTerm storeObject = dataAccess.load(atlasGlossaryTerm);
423+
424+
if (!storeObject.getAnchor().getGlossaryGuid().equals(atlasGlossaryTerm.getAnchor().getGlossaryGuid())){
425+
throw new AtlasBaseException(AtlasErrorCode.ACHOR_UPDATION_NOT_SUPPORTED);
426+
}
427+
429428
if (!storeObject.equals(atlasGlossaryTerm)) {
430429
atlasGlossaryTerm.setGuid(storeObject.getGuid());
431430
atlasGlossaryTerm.setQualifiedName(storeObject.getQualifiedName());
@@ -560,19 +559,11 @@ public AtlasGlossaryCategory createCategory(AtlasGlossaryCategory glossaryCatego
560559
}
561560
if (isNameInvalid(glossaryCategory.getName())){
562561
throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME);
563-
} else {
564-
// Derive the qualifiedName
565-
String anchorGlossaryGuid = glossaryCategory.getAnchor().getGlossaryGuid();
566-
AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
567-
glossaryCategory.setQualifiedName(glossaryCategory.getName()+ "@" + glossary.getQualifiedName());
568-
569-
if (LOG.isDebugEnabled()) {
570-
LOG.debug("Derived qualifiedName = {}", glossaryCategory.getQualifiedName());
571-
}
572-
573-
574562
}
575563

564+
// Derive the qualifiedName
565+
glossaryCategory.setQualifiedName(glossaryCategoryUtils.createQualifiedName(glossaryCategory));
566+
576567
// This might fail for the case when the category's qualifiedName has been updated during a hierarchy change
577568
// and the duplicate request comes in with old name
578569
if (categoryExists(glossaryCategory)) {
@@ -639,7 +630,7 @@ public AtlasGlossaryCategory updateCategory(AtlasGlossaryCategory glossaryCatego
639630
}
640631

641632
if (StringUtils.isEmpty(glossaryCategory.getName())) {
642-
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "DisplayName can't be null/empty");
633+
throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Name can't be null/empty");
643634
}
644635

645636
if (isNameInvalid(glossaryCategory.getName())) {
@@ -648,6 +639,10 @@ public AtlasGlossaryCategory updateCategory(AtlasGlossaryCategory glossaryCatego
648639

649640
AtlasGlossaryCategory storeObject = dataAccess.load(glossaryCategory);
650641

642+
if (!storeObject.getAnchor().getGlossaryGuid().equals(glossaryCategory.getAnchor().getGlossaryGuid())){
643+
throw new AtlasBaseException(AtlasErrorCode.ACHOR_UPDATION_NOT_SUPPORTED);
644+
}
645+
651646
if (!storeObject.equals(glossaryCategory)) {
652647
try {
653648
glossaryCategory.setGuid(storeObject.getGuid());

repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java

+17
Original file line numberDiff line numberDiff line change
@@ -975,4 +975,21 @@ private void copyRelations(AtlasGlossaryTerm toGlossaryTerm, AtlasGlossaryTerm f
975975
}
976976
}
977977
}
978+
979+
protected String createQualifiedName(AtlasGlossaryTerm term) throws AtlasBaseException{
980+
String qName = "";
981+
if (!StringUtils.isEmpty(term.getQualifiedName())) {
982+
//extract existing nanoid for term
983+
qName = term.getQualifiedName().split("@")[0];
984+
}
985+
qName = StringUtils.isEmpty(qName) ? getUUID() : qName;
986+
987+
988+
String anchorGlossaryGuid = term.getAnchor().getGlossaryGuid();
989+
AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
990+
if (glossary == null) {
991+
throw new AtlasBaseException("Glossary not found with guid: " + anchorGlossaryGuid);
992+
}
993+
return qName + "@" + glossary.getQualifiedName();
994+
}
978995
}

repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java

+8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.atlas.repository.ogm.DataAccess;
2727
import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
2828
import org.apache.atlas.type.AtlasTypeRegistry;
29+
import org.apache.atlas.util.NanoIdUtils;
2930

3031
import java.util.Objects;
3132

@@ -109,4 +110,11 @@ protected void updateRelationshipAttributes(AtlasRelationship relationship, Atla
109110
enum RelationshipOperation {
110111
CREATE, UPDATE, DELETE
111112
}
113+
114+
protected static String createQualifiedName() {
115+
return getUUID();
116+
}
117+
protected static String getUUID(){
118+
return NanoIdUtils.randomNanoId();
119+
}
112120
}

0 commit comments

Comments
 (0)