All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.atlas.glossary.GlossaryService Maven / Gradle / Ivy

The newest version!
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.atlas.glossary; import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.SortOrder; import org.apache.atlas.annotation.GraphTransaction; import org.apache.atlas.bulkimport.BulkImportResponse; import org.apache.atlas.bulkimport.BulkImportResponse.ImportInfo; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.glossary.AtlasGlossary; import org.apache.atlas.model.glossary.AtlasGlossaryCategory; import org.apache.atlas.model.glossary.AtlasGlossaryTerm; import org.apache.atlas.model.glossary.relations.AtlasRelatedCategoryHeader; import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader; import org.apache.atlas.model.glossary.relations.AtlasTermCategorizationHeader; import org.apache.atlas.model.instance.AtlasEntity; import org.apache.atlas.model.instance.AtlasRelatedObjectId; import org.apache.atlas.repository.graphdb.AtlasEdge; import org.apache.atlas.repository.graphdb.AtlasEdgeDirection; import org.apache.atlas.repository.graphdb.AtlasVertex; import org.apache.atlas.repository.ogm.DataAccess; import org.apache.atlas.repository.ogm.glossary.AtlasGlossaryDTO; import org.apache.atlas.repository.store.graph.AtlasRelationshipStore; import org.apache.atlas.repository.store.graph.v2.AtlasEntityChangeNotifier; import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2; import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.util.FileUtils; import org.apache.atlas.utils.AtlasJson; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import javax.inject.Inject; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import static org.apache.atlas.bulkimport.BulkImportResponse.ImportStatus.FAILED; import static org.apache.atlas.bulkimport.BulkImportResponse.ImportStatus.SUCCESS; import static org.apache.atlas.glossary.GlossaryUtils.getAtlasGlossaryCategorySkeleton; import static org.apache.atlas.glossary.GlossaryUtils.getAtlasGlossaryTermSkeleton; import static org.apache.atlas.glossary.GlossaryUtils.getGlossarySkeleton; @Service public class GlossaryService { private static final Logger LOG = LoggerFactory.getLogger(GlossaryService.class); private static final boolean DEBUG_ENABLED = LOG.isDebugEnabled(); private static final String ATLAS_GLOSSARY_TERM = "AtlasGlossaryTerm"; private static final String NAME_ATTR = "name"; private static final String QUALIFIED_NAME_ATTR = "qualifiedName"; private static final String GLOSSARY_QUALIFIED_NAME_PROPERTY = "AtlasGlossary." + QUALIFIED_NAME_ATTR; private static final String GLOSSARY_CATEGORY_NAME_PROPERTY = "AtlasGlossaryCategory.name"; private static final String GLOSSARY_TERM_NAME_PROPERTY = ATLAS_GLOSSARY_TERM + "." + NAME_ATTR; private static final String GLOSSARY_TERM_QUALIFIED_NAME_PROPERTY = ATLAS_GLOSSARY_TERM + "." + QUALIFIED_NAME_ATTR; private static final String TERM_UNIQUE_QUALIFIED_NAME_PROPERTY = ATLAS_GLOSSARY_TERM + ".__u_" + QUALIFIED_NAME_ATTR; private static final String GLOSSARY_TERM_ANCHOR_EDGE_LABEL = "r:AtlasGlossaryTermAnchor"; private final DataAccess dataAccess; private final GlossaryTermUtils glossaryTermUtils; private final GlossaryCategoryUtils glossaryCategoryUtils; private final AtlasTypeRegistry atlasTypeRegistry; private final AtlasEntityChangeNotifier entityChangeNotifier; private final AtlasGlossaryDTO glossaryDTO; private static final char[] invalidNameChars = { '@', '.', '<', '>'}; private static final Map glossaryGuidQualifiedNameCache = new HashMap<>(); private static final Map categoryGuidNameCache = new HashMap<>(); @Inject public GlossaryService(DataAccess dataAccess, final AtlasRelationshipStore relationshipStore, final AtlasTypeRegistry typeRegistry, AtlasEntityChangeNotifier entityChangeNotifier, final AtlasGlossaryDTO glossaryDTO) { this.dataAccess = dataAccess; atlasTypeRegistry = typeRegistry; glossaryTermUtils = new GlossaryTermUtils(relationshipStore, typeRegistry, dataAccess); glossaryCategoryUtils = new GlossaryCategoryUtils(relationshipStore, typeRegistry, dataAccess); this.entityChangeNotifier = entityChangeNotifier; this.glossaryDTO = glossaryDTO; } /** * List all glossaries * * @param limit page size - no paging by default * @param offset offset for pagination * @param sortOrder ASC (default) or DESC * @return List of all glossaries * @throws AtlasBaseException */ @GraphTransaction public List getGlossaries(int limit, int offset, SortOrder sortOrder) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getGlossaries({}, {}, {})", limit, offset, sortOrder); } List glossaryGuids = AtlasGraphUtilsV2.findEntityGUIDsByType(GlossaryUtils.ATLAS_GLOSSARY_TYPENAME, sortOrder); PaginationHelper paginationHelper = new PaginationHelper<>(glossaryGuids, offset, limit); List ret; List guidsToLoad = paginationHelper.getPaginatedList(); AtlasEntity.AtlasEntitiesWithExtInfo glossaryEntities; if (CollectionUtils.isNotEmpty(guidsToLoad)) { glossaryEntities = dataAccess.getAtlasEntityStore().getByIds(guidsToLoad, true, false); ret = new ArrayList<>(); for (AtlasEntity glossaryEntity : glossaryEntities.getEntities()) { AtlasGlossary glossary = glossaryDTO.from(glossaryEntity); ret.add(glossary); } } else { ret = Collections.emptyList(); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getGlossaries() : {}", ret); } return ret; } /** * Create a glossary * * @param atlasGlossary Glossary specification to be created * @return Glossary definition * @throws AtlasBaseException */ @GraphTransaction public AtlasGlossary createGlossary(AtlasGlossary atlasGlossary) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.createGlossary({})", atlasGlossary); } if (Objects.isNull(atlasGlossary)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Glossary definition missing"); } if (StringUtils.isEmpty(atlasGlossary.getQualifiedName())) { if (StringUtils.isEmpty(atlasGlossary.getName())) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_QUALIFIED_NAME_CANT_BE_DERIVED); } if (isNameInvalid(atlasGlossary.getName())){ throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME); } else { atlasGlossary.setQualifiedName(atlasGlossary.getName()); } } if (glossaryExists(atlasGlossary)) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_ALREADY_EXISTS, atlasGlossary.getName()); } AtlasGlossary storeObject = dataAccess.save(atlasGlossary); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.createGlossary() : {}", storeObject); } return storeObject; } /** * Get specific glossary * * @param glossaryGuid unique identifier * @return Glossary corresponding to specified glossaryGuid * @throws AtlasBaseException */ @GraphTransaction public AtlasGlossary getGlossary(String glossaryGuid) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getGlossary({})", glossaryGuid); } if (Objects.isNull(glossaryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryGuid is null/empty"); } AtlasGlossary atlasGlossary = getGlossarySkeleton(glossaryGuid); AtlasGlossary ret = dataAccess.load(atlasGlossary); setInfoForRelations(ret); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getGlossary() : {}", ret); } return ret; } /** * Get specific glossary * * @param glossaryGuid unique identifier * @return Glossary corresponding to specified glossaryGuid * @throws AtlasBaseException */ @GraphTransaction public AtlasGlossary.AtlasGlossaryExtInfo getDetailedGlossary(String glossaryGuid) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getGlossary({})", glossaryGuid); } if (Objects.isNull(glossaryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryGuid is null/empty"); } AtlasGlossary atlasGlossary = getGlossarySkeleton(glossaryGuid); AtlasGlossary glossary = dataAccess.load(atlasGlossary); AtlasGlossary.AtlasGlossaryExtInfo ret = new AtlasGlossary.AtlasGlossaryExtInfo(glossary); // Load all linked terms if (CollectionUtils.isNotEmpty(ret.getTerms())) { List termsToLoad = ret.getTerms() .stream() .map(id -> getAtlasGlossaryTermSkeleton(id.getTermGuid())) .collect(Collectors.toList()); Iterable glossaryTerms = dataAccess.load(termsToLoad); glossaryTerms.forEach(ret::addTermInfo); } // Load all linked categories if (CollectionUtils.isNotEmpty(ret.getCategories())) { List categoriesToLoad = ret.getCategories() .stream() .map(id -> getAtlasGlossaryCategorySkeleton(id.getCategoryGuid())) .collect(Collectors.toList()); Iterable glossaryCategories = dataAccess.load(categoriesToLoad); glossaryCategories.forEach(ret::addCategoryInfo); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getGlossary() : {}", ret); } return ret; } @GraphTransaction public AtlasGlossary updateGlossary(AtlasGlossary atlasGlossary) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.updateGlossary({})", atlasGlossary); } if (Objects.isNull(atlasGlossary)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Glossary is null/empty"); } if (StringUtils.isEmpty(atlasGlossary.getName())) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "DisplayName can't be null/empty"); } if (isNameInvalid(atlasGlossary.getName())) { throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME); } AtlasGlossary storeObject = dataAccess.load(atlasGlossary); if (!storeObject.equals(atlasGlossary)) { atlasGlossary.setGuid(storeObject.getGuid()); atlasGlossary.setQualifiedName(storeObject.getQualifiedName()); storeObject = dataAccess.save(atlasGlossary); setInfoForRelations(storeObject); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.updateGlossary() : {}", storeObject); } return storeObject; } @GraphTransaction public void deleteGlossary(String glossaryGuid) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.deleteGlossary({})", glossaryGuid); } if (Objects.isNull(glossaryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryGuid is null/empty"); } AtlasGlossary storeObject = dataAccess.load(getGlossarySkeleton(glossaryGuid)); Set terms = storeObject.getTerms(); deleteTerms(storeObject, terms); Set categories = storeObject.getCategories(); deleteCategories(storeObject, categories); // Once all relations are deleted, then delete the Glossary dataAccess.delete(glossaryGuid); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.deleteGlossary()"); } } /* * GlossaryTerms related operations * */ @GraphTransaction public AtlasGlossaryTerm getTerm(String termGuid) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getTerm({})", termGuid); } if (Objects.isNull(termGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "termGuid is null/empty"); } AtlasGlossaryTerm atlasGlossary = getAtlasGlossaryTermSkeleton(termGuid); AtlasGlossaryTerm ret = dataAccess.load(atlasGlossary); setInfoForRelations(ret); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getTerm() : {}", ret); } return ret; } @GraphTransaction public AtlasGlossaryTerm createTerm(AtlasGlossaryTerm term) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.create({})", term); } if (Objects.isNull(term)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "GlossaryTerm definition missing"); } if (Objects.isNull(term.getAnchor())) { throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR); } if (StringUtils.isEmpty(term.getName())) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_QUALIFIED_NAME_CANT_BE_DERIVED); } if (isNameInvalid(term.getName())){ throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME); } else { // Derive the qualifiedName String anchorGlossaryGuid = term.getAnchor().getGlossaryGuid(); String glossaryQualifiedName = getGlossaryQualifiedName(anchorGlossaryGuid); if (StringUtils.isEmpty(glossaryQualifiedName)) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_QUALIFIED_NAME_CANT_BE_DERIVED); } term.setQualifiedName(term.getName() + "@" + glossaryQualifiedName); if (LOG.isDebugEnabled()) { LOG.debug("Derived qualifiedName = {}", term.getQualifiedName()); } } // This might fail for the case when the term's qualifiedName has been updated and the duplicate request comes in with old name if (termExists2(term)) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_ALREADY_EXISTS, term.getQualifiedName()); } AtlasGlossaryTerm storeGlossaryTerm = dataAccess.save(term); glossaryTermUtils.processTermRelations(storeGlossaryTerm, term, GlossaryUtils.RelationshipOperation.CREATE); // Re-load term after handling relations storeGlossaryTerm = dataAccess.load(term); setInfoForRelations(storeGlossaryTerm); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.create() : {}", storeGlossaryTerm); } return storeGlossaryTerm; } @GraphTransaction public List createTerms(List glossaryTerms) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.create({})", glossaryTerms); } if (Objects.isNull(glossaryTerms)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryTerm(s) is null/empty"); } List ret = new ArrayList<>(); for (AtlasGlossaryTerm glossaryTerm : glossaryTerms) { AtlasGlossaryTerm term = createTerm(glossaryTerm); ret.add(term); } if (LOG.isDebugEnabled()) { LOG.debug("<== GlossaryService.createTerms() : {}", ret); } return ret; } public AtlasGlossaryTerm updateTerm(AtlasGlossaryTerm atlasGlossaryTerm) throws AtlasBaseException { return updateTerm(atlasGlossaryTerm, true); } @GraphTransaction public AtlasGlossaryTerm updateTerm(AtlasGlossaryTerm atlasGlossaryTerm, boolean ignoreUpdateIfTermExists) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.updateTerm({})", atlasGlossaryTerm); } if (Objects.isNull(atlasGlossaryTerm)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "atlasGlossaryTerm is null/empty"); } if (StringUtils.isEmpty(atlasGlossaryTerm.getName())) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "DisplayName can't be null/empty"); } if (isNameInvalid(atlasGlossaryTerm.getName())) { throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME); } if (ignoreUpdateIfTermExists) { String qualifiedName = getDuplicateGlossaryRelatedTerm(atlasGlossaryTerm); if (StringUtils.isNotEmpty(qualifiedName)) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_ALREADY_EXISTS, qualifiedName); } } AtlasGlossaryTerm storeObject = dataAccess.load(atlasGlossaryTerm); if (!storeObject.equals(atlasGlossaryTerm)) { atlasGlossaryTerm.setGuid(storeObject.getGuid()); atlasGlossaryTerm.setQualifiedName(storeObject.getQualifiedName()); storeObject = dataAccess.save(atlasGlossaryTerm); glossaryTermUtils.processTermRelations(storeObject, atlasGlossaryTerm, GlossaryUtils.RelationshipOperation.UPDATE); // If qualifiedName changes due to anchor change, we need to persist the term again with updated qualifiedName if (StringUtils.equals(storeObject.getQualifiedName(), atlasGlossaryTerm.getQualifiedName())) { storeObject = dataAccess.load(atlasGlossaryTerm); } else { atlasGlossaryTerm.setQualifiedName(storeObject.getQualifiedName()); if (termExists(atlasGlossaryTerm)) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_ALREADY_EXISTS, atlasGlossaryTerm.getQualifiedName()); } storeObject = dataAccess.save(atlasGlossaryTerm); } } setInfoForRelations(storeObject); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.updateTerm() : {}", storeObject); } return storeObject; } @GraphTransaction public void deleteTerm(String termGuid) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.deleteTerm({})", termGuid); } if (Objects.isNull(termGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "termGuid is null/empty"); } AtlasGlossaryTerm storeObject = dataAccess.load(getAtlasGlossaryTermSkeleton(termGuid)); // Term can't be deleted if it is assigned to any entity if (CollectionUtils.isNotEmpty(storeObject.getAssignedEntities())) { throw new AtlasBaseException(AtlasErrorCode.TERM_HAS_ENTITY_ASSOCIATION, storeObject.getGuid(), String.valueOf(storeObject.getAssignedEntities().size())); } // Remove term from Glossary glossaryTermUtils.processTermRelations(storeObject, storeObject, GlossaryUtils.RelationshipOperation.DELETE); // Now delete the term dataAccess.delete(termGuid); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.deleteTerm()"); } } @GraphTransaction public void assignTermToEntities(String termGuid, List relatedObjectIds) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.assignTermToEntities({}, {})", termGuid, relatedObjectIds); } AtlasGlossaryTerm glossaryTerm = dataAccess.load(getAtlasGlossaryTermSkeleton(termGuid)); glossaryTermUtils.processTermAssignments(glossaryTerm, relatedObjectIds); entityChangeNotifier.onTermAddedToEntities(glossaryTerm, relatedObjectIds); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.assignTermToEntities()"); } } @GraphTransaction public void removeTermFromEntities(String termGuid, List relatedObjectIds) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.removeTermFromEntities({}, {})", termGuid, relatedObjectIds); } AtlasGlossaryTerm glossaryTerm = dataAccess.load(getAtlasGlossaryTermSkeleton(termGuid)); glossaryTermUtils.processTermDissociation(glossaryTerm, relatedObjectIds); entityChangeNotifier.onTermDeletedFromEntities(glossaryTerm, relatedObjectIds); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.removeTermFromEntities()"); } } /* * GlossaryCategory related operations * */ @GraphTransaction public AtlasGlossaryCategory getCategory(String categoryGuid) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getCategory({})", categoryGuid); } if (Objects.isNull(categoryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "categoryGuid is null/empty"); } AtlasGlossaryCategory atlasGlossary = getAtlasGlossaryCategorySkeleton(categoryGuid); AtlasGlossaryCategory ret = dataAccess.load(atlasGlossary); setInfoForRelations(ret); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getCategory() : {}", ret); } return ret; } @GraphTransaction public AtlasGlossaryCategory createCategory(AtlasGlossaryCategory glossaryCategory) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.createCategory({})", glossaryCategory); } if (Objects.isNull(glossaryCategory)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "GlossaryCategory definition missing"); } if (Objects.isNull(glossaryCategory.getAnchor())) { throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR); } if (StringUtils.isEmpty(glossaryCategory.getName())) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_CATEGORY_QUALIFIED_NAME_CANT_BE_DERIVED); } if (isNameInvalid(glossaryCategory.getName())){ throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME); } else { // Derive the qualifiedName String anchorGlossaryGuid = glossaryCategory.getAnchor().getGlossaryGuid(); AtlasGlossary glossary = dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid)); glossaryCategory.setQualifiedName(glossaryCategory.getName()+ "@" + glossary.getQualifiedName()); if (LOG.isDebugEnabled()) { LOG.debug("Derived qualifiedName = {}", glossaryCategory.getQualifiedName()); } } // This might fail for the case when the category's qualifiedName has been updated during a hierarchy change // and the duplicate request comes in with old name if (categoryExists(glossaryCategory)) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_CATEGORY_ALREADY_EXISTS, glossaryCategory.getQualifiedName()); } AtlasGlossaryCategory storeObject = dataAccess.save(glossaryCategory); // Attempt relation creation and gather all impacted categories Map impactedCategories = glossaryCategoryUtils.processCategoryRelations(storeObject, glossaryCategory, GlossaryUtils.RelationshipOperation.CREATE); // Since the current category is also affected, we need to update qualifiedName and save again if (StringUtils.equals(glossaryCategory.getQualifiedName(), storeObject.getQualifiedName())) { storeObject = dataAccess.load(glossaryCategory); } else { glossaryCategory.setQualifiedName(storeObject.getQualifiedName()); if (categoryExists(glossaryCategory)) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_CATEGORY_ALREADY_EXISTS, glossaryCategory.getQualifiedName()); } storeObject = dataAccess.save(glossaryCategory); } // Re save the categories in case any qualifiedName change has occurred dataAccess.save(impactedCategories.values()); setInfoForRelations(storeObject); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.createCategory() : {}", storeObject); } return storeObject; } @GraphTransaction public List createCategories(List glossaryCategory) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.createCategories({})", glossaryCategory); } if (Objects.isNull(glossaryCategory)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryCategory is null/empty"); } List ret = new ArrayList<>(); for (AtlasGlossaryCategory category : glossaryCategory) { ret.add(createCategory(category)); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.createCategories() : {}", ret); } return ret; } @GraphTransaction public AtlasGlossaryCategory updateCategory(AtlasGlossaryCategory glossaryCategory) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.updateCategory({})", glossaryCategory); } if (Objects.isNull(glossaryCategory)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "GlossaryCategory is null/empty"); } if (StringUtils.isEmpty(glossaryCategory.getName())) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "DisplayName can't be null/empty"); } if (isNameInvalid(glossaryCategory.getName())) { throw new AtlasBaseException(AtlasErrorCode.INVALID_DISPLAY_NAME); } AtlasGlossaryCategory storeObject = dataAccess.load(glossaryCategory); if (!storeObject.equals(glossaryCategory)) { try { glossaryCategory.setGuid(storeObject.getGuid()); glossaryCategory.setQualifiedName(storeObject.getQualifiedName()); storeObject = dataAccess.save(glossaryCategory); } catch (AtlasBaseException e) { LOG.debug("No immediate attribute update. Exception: {}", e.getMessage()); } Map impactedCategories = glossaryCategoryUtils.processCategoryRelations(storeObject, glossaryCategory, GlossaryUtils.RelationshipOperation.UPDATE); // Since the current category is also affected, we need to update qualifiedName and save again if (StringUtils.equals(glossaryCategory.getQualifiedName(), storeObject.getQualifiedName())) { storeObject = dataAccess.load(glossaryCategory); } else { glossaryCategory.setQualifiedName(storeObject.getQualifiedName()); if (categoryExists(glossaryCategory)) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_CATEGORY_ALREADY_EXISTS, glossaryCategory.getQualifiedName()); } storeObject = dataAccess.save(glossaryCategory); } dataAccess.save(impactedCategories.values()); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.updateCategory() : {}", storeObject); } setInfoForRelations(storeObject); return storeObject; } @GraphTransaction public void deleteCategory(String categoryGuid) throws AtlasBaseException { if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.deleteCategory({})", categoryGuid); } if (Objects.isNull(categoryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Category guid is null/empty"); } AtlasGlossaryCategory storeObject = dataAccess.load(getAtlasGlossaryCategorySkeleton(categoryGuid)); // Delete all relations glossaryCategoryUtils.processCategoryRelations(storeObject, storeObject, GlossaryUtils.RelationshipOperation.DELETE); // Now delete the category dataAccess.delete(categoryGuid); if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.deleteCategory()"); } } @GraphTransaction public List getGlossaryTermsHeaders(String glossaryGuid, int offset, int limit, SortOrder sortOrder) throws AtlasBaseException { if (Objects.isNull(glossaryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryGuid is null/empty"); } if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getGlossaryTermsHeaders({}, {}, {}, {})", glossaryGuid, offset, limit, sortOrder); } AtlasGlossary glossary = getGlossary(glossaryGuid); List ret; if (CollectionUtils.isNotEmpty(glossary.getTerms())) { List terms = new ArrayList<>(glossary.getTerms()); if (sortOrder != null) { terms.sort((o1, o2) -> sortOrder == SortOrder.ASCENDING ? o1.getDisplayText().compareTo(o2.getDisplayText()) : o2.getDisplayText().compareTo(o1.getDisplayText())); } ret = new PaginationHelper<>(terms, offset, limit).getPaginatedList(); } else { ret = Collections.emptyList(); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getGlossaryTermsHeaders() : {}", ret); } return ret; } @GraphTransaction public List getGlossaryTerms(String glossaryGuid, int offset, int limit, SortOrder sortOrder) throws AtlasBaseException { if (Objects.isNull(glossaryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryGuid is null/empty"); } if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getGlossaryTerms({}, {}, {}, {})", glossaryGuid, offset, limit, sortOrder); } List ret = new ArrayList<>(); List termHeaders = getGlossaryTermsHeaders(glossaryGuid, offset, limit, sortOrder); for (AtlasRelatedTermHeader header : termHeaders) { ret.add(dataAccess.load(getAtlasGlossaryTermSkeleton(header.getTermGuid()))); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getGlossaryTerms() : {}", ret); } return ret; } @GraphTransaction public List getGlossaryCategoriesHeaders(String glossaryGuid, int offset, int limit, SortOrder sortOrder) throws AtlasBaseException { if (Objects.isNull(glossaryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryGuid is null/empty"); } if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getGlossaryCategoriesHeaders({}, {}, {}, {})", glossaryGuid, offset, limit, sortOrder); } List ret; AtlasGlossary glossary = getGlossary(glossaryGuid); if (CollectionUtils.isNotEmpty(glossary.getCategories())) { List categories = new ArrayList<>(glossary.getCategories()); if (sortOrder != null) { categories.sort((o1, o2) -> sortOrder == SortOrder.ASCENDING ? o1.getDisplayText().compareTo(o2.getDisplayText()) : o2.getDisplayText().compareTo(o1.getDisplayText())); } ret = new PaginationHelper<>(categories, offset, limit).getPaginatedList(); } else { ret = Collections.emptyList(); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getGlossaryCategoriesHeaders() : {}", ret); } return ret; } @GraphTransaction public List getGlossaryCategories(String glossaryGuid, int offset, int limit, SortOrder sortOrder) throws AtlasBaseException { if (Objects.isNull(glossaryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "glossaryGuid is null/empty"); } if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getGlossaryCategories({}, {}, {}, {})", glossaryGuid, offset, limit, sortOrder); } List ret = new ArrayList<>(); List categoryHeaders = getGlossaryCategoriesHeaders(glossaryGuid, offset, limit, sortOrder); for (AtlasRelatedCategoryHeader header : categoryHeaders) { ret.add(dataAccess.load(getAtlasGlossaryCategorySkeleton(header.getCategoryGuid()))); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getGlossaryCategories() : {}", ret); } return ret; } @GraphTransaction public List getCategoryTerms(String categoryGuid, int offset, int limit, SortOrder sortOrder) throws AtlasBaseException { if (Objects.isNull(categoryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "categoryGuid is null/empty"); } if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getCategoryTerms({}, {}, {}, {})", categoryGuid, offset, limit, sortOrder); } List ret; AtlasGlossaryCategory glossaryCategory = getCategory(categoryGuid); if (CollectionUtils.isNotEmpty(glossaryCategory.getTerms())) { List terms = new ArrayList<>(glossaryCategory.getTerms()); if (sortOrder != null) { terms.sort((o1, o2) -> sortOrder == SortOrder.ASCENDING ? o1.getDisplayText().compareTo(o2.getDisplayText()) : o2.getDisplayText().compareTo(o1.getDisplayText())); } ret = new PaginationHelper<>(terms, offset, limit).getPaginatedList(); } else { ret = Collections.emptyList(); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getCategoryTerms() : {}", ret); } return ret; } @GraphTransaction public Map> getRelatedTerms(String termGuid, int offset, int limit, SortOrder sortOrder) throws AtlasBaseException { if (Objects.isNull(termGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "termGuid is null/empty"); } if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getRelatedTerms({}, {}, {}, {})", termGuid, offset, limit, sortOrder); } AtlasGlossaryTerm glossaryTerm = getTerm(termGuid); Map> ret; if (glossaryTerm.hasTerms()) { ret = glossaryTerm.getRelatedTerms(); } else { ret = Collections.emptyMap(); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getRelatedTerms() : {}", ret); } return ret; } @GraphTransaction public Map> getRelatedCategories(String categoryGuid, int offset, int limit, SortOrder sortOrder) throws AtlasBaseException { if (Objects.isNull(categoryGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "categoryGuid is null/empty"); } if (DEBUG_ENABLED) { LOG.debug("==> GlossaryService.getRelatedCategories({}, {}, {}, {})", categoryGuid, offset, limit, sortOrder); } AtlasGlossaryCategory glossaryCategory = getCategory(categoryGuid); Map> ret = new HashMap<>(); if (glossaryCategory.getParentCategory() != null) { ret.put("parent", new ArrayList() {{ add(glossaryCategory.getParentCategory()); }}); } if (CollectionUtils.isNotEmpty(glossaryCategory.getChildrenCategories())) { ret.put("children", new ArrayList<>(glossaryCategory.getChildrenCategories())); } if (DEBUG_ENABLED) { LOG.debug("<== GlossaryService.getRelatedCategories() : {}", ret); } return ret; } @GraphTransaction public List getAssignedEntities(final String termGuid, int offset, int limit, SortOrder sortOrder) throws AtlasBaseException { if (Objects.isNull(termGuid)) { throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "termGuid is null/empty"); } AtlasGlossaryTerm glossaryTerm = dataAccess.load(getAtlasGlossaryTermSkeleton(termGuid)); Set assignedEntities = glossaryTerm.getAssignedEntities(); List ret; if (CollectionUtils.isNotEmpty(assignedEntities)) { ret = new ArrayList<>(assignedEntities); if (sortOrder != null) { ret.sort((o1, o2) -> sortOrder == SortOrder.ASCENDING ? o1.getDisplayText().compareTo(o2.getDisplayText()) : o2.getDisplayText().compareTo(o1.getDisplayText())); } ret = new PaginationHelper<>(assignedEntities, offset, limit).getPaginatedList(); } else { ret = Collections.emptyList(); } return ret; } private boolean glossaryExists(AtlasGlossary atlasGlossary) { AtlasVertex vertex = AtlasGraphUtilsV2.findByUniqueAttributes(atlasTypeRegistry.getEntityTypeByName(GlossaryUtils.ATLAS_GLOSSARY_TYPENAME), new HashMap() {{ put(QUALIFIED_NAME_ATTR, atlasGlossary.getQualifiedName()); }}); return Objects.nonNull(vertex); } private String getGlossaryQualifiedName(String glossaryGuid) { String ret = glossaryGuidQualifiedNameCache.get(glossaryGuid); if (StringUtils.isEmpty(ret)) { AtlasVertex vertex = AtlasGraphUtilsV2.findByGuid(glossaryGuid); if (vertex != null) { ret = vertex.getProperty(GLOSSARY_QUALIFIED_NAME_PROPERTY, String.class); glossaryGuidQualifiedNameCache.put(glossaryGuid, ret); } } return ret; } private String getGlossaryCategoryName(String glossaryCategoryGuid) { String ret = categoryGuidNameCache.get(glossaryCategoryGuid); if (StringUtils.isEmpty(ret)) { AtlasVertex vertex = AtlasGraphUtilsV2.findByGuid(glossaryCategoryGuid); if (vertex != null) { ret = vertex.getProperty(GLOSSARY_CATEGORY_NAME_PROPERTY, String.class); categoryGuidNameCache.put(glossaryCategoryGuid, ret); } } return ret; } private boolean termExists(AtlasGlossaryTerm term) { AtlasVertex vertex = AtlasGraphUtilsV2.findByUniqueAttributes(atlasTypeRegistry.getEntityTypeByName(GlossaryUtils.ATLAS_GLOSSARY_TERM_TYPENAME), new HashMap() {{ put(QUALIFIED_NAME_ATTR, term.getQualifiedName()); }}); return Objects.nonNull(vertex); } private boolean termExists2(AtlasGlossaryTerm term) { boolean ret = false; AtlasVertex glossaryVertex = AtlasGraphUtilsV2.findByGuid(term.getAnchor().getGlossaryGuid()); Iterable glossaryTermEdges = glossaryVertex.getEdges(AtlasEdgeDirection.OUT, GLOSSARY_TERM_ANCHOR_EDGE_LABEL); for (Iterator iter = glossaryTermEdges.iterator(); iter.hasNext(); ) { AtlasVertex termVertex = iter.next().getInVertex(); String termQualifiedName = termVertex.getProperty(TERM_UNIQUE_QUALIFIED_NAME_PROPERTY, String.class); if (StringUtils.equals(termQualifiedName, term.getQualifiedName())) { ret = true; break; } } return ret; } private boolean categoryExists(AtlasGlossaryCategory category) { AtlasVertex vertex = AtlasGraphUtilsV2.findByUniqueAttributes(atlasTypeRegistry.getEntityTypeByName(GlossaryUtils.ATLAS_GLOSSARY_CATEGORY_TYPENAME), new HashMap() {{ put(QUALIFIED_NAME_ATTR, category.getQualifiedName()); }}); return Objects.nonNull(vertex); } private void deleteCategories(final AtlasGlossary storeObject, final Collection categories) throws AtlasBaseException { if (CollectionUtils.isNotEmpty(categories)) { if (DEBUG_ENABLED) { LOG.debug("Deleting categories within glossary guid = {}", storeObject.getGuid()); } for (AtlasRelatedCategoryHeader category : categories) { // Delete category deleteCategory(category.getCategoryGuid()); } } } private void deleteTerms(final AtlasGlossary storeObject, final Collection terms) throws AtlasBaseException { if (CollectionUtils.isNotEmpty(terms)) { if (DEBUG_ENABLED) { LOG.debug("Deleting terms within glossary guid = {}", storeObject.getGuid()); } for (AtlasRelatedTermHeader term : terms) { // Delete the term deleteTerm(term.getTermGuid()); } } } private void setInfoForRelations(final AtlasGlossary ret) throws AtlasBaseException { if (Objects.nonNull(ret.getTerms())) { setDisplayNameForTerms(ret.getTerms()); } if (Objects.nonNull(ret.getCategories())) { setInfoForRelatedCategories(ret.getCategories()); } } private void setInfoForRelations(final AtlasGlossaryTerm glossaryTerm) throws AtlasBaseException { setDisplayNameForCategories(glossaryTerm.getCategories()); if (Objects.nonNull(glossaryTerm.getRelatedTerms())) { for (Map.Entry> entry : glossaryTerm.getRelatedTerms().entrySet()) { setDisplayNameForTerms(entry.getValue()); setQualifiedNameForTerms(entry.getValue()); } } } private void setInfoForRelations(final AtlasGlossaryCategory glossaryCategory) throws AtlasBaseException { if (Objects.nonNull(glossaryCategory.getChildrenCategories())) { setInfoForRelatedCategories(glossaryCategory.getChildrenCategories()); } if (Objects.nonNull(glossaryCategory.getTerms())) { setDisplayNameForTerms(glossaryCategory.getTerms()); } } private void setDisplayNameForCategories(final Set categorizationHeaders) throws AtlasBaseException { if (CollectionUtils.isEmpty(categorizationHeaders)) { return; } for (AtlasTermCategorizationHeader termCategorizationHeader : categorizationHeaders) { String categoryGuid = termCategorizationHeader.getCategoryGuid(); String categoryName = getGlossaryCategoryName(categoryGuid); if (StringUtils.isNotEmpty(categoryName)) { termCategorizationHeader.setDisplayText(categoryName); } } } private void setInfoForRelatedCategories(final Collection categoryHeaders) throws AtlasBaseException { List categories = categoryHeaders .stream() .map(id -> getAtlasGlossaryCategorySkeleton(id.getCategoryGuid())) .collect(Collectors.toList()); Map categoryMap = new HashMap<>(); dataAccess.load(categories).forEach(c -> categoryMap.put(c.getGuid(), c)); for (AtlasRelatedCategoryHeader c : categoryHeaders) { AtlasGlossaryCategory category = categoryMap.get(c.getCategoryGuid()); c.setDisplayText(category.getName()); if (Objects.nonNull(category.getParentCategory())) { c.setParentCategoryGuid(category.getParentCategory().getCategoryGuid()); } } } private void setDisplayNameForTerms(final Collection termHeaders) throws AtlasBaseException { for (AtlasRelatedTermHeader termHeader : termHeaders) { String termGuid = termHeader.getTermGuid(); AtlasVertex termVertex = AtlasGraphUtilsV2.findByGuid(termGuid); String termDisplayText = termVertex.getProperty(GLOSSARY_TERM_NAME_PROPERTY, String.class); if (StringUtils.isNotEmpty(termDisplayText)) { termHeader.setDisplayText(termDisplayText); } } } private void setQualifiedNameForTerms(final Collection termHeaders) throws AtlasBaseException { for (AtlasRelatedTermHeader termHeader : termHeaders) { String termGuid = termHeader.getTermGuid(); AtlasVertex termVertex = AtlasGraphUtilsV2.findByGuid(termGuid); String termQualifiedName = termVertex.getProperty(GLOSSARY_TERM_QUALIFIED_NAME_PROPERTY, String.class); if (StringUtils.isNotEmpty(termQualifiedName)) { termHeader.setQualifiedName(termQualifiedName); } } } public static boolean isNameInvalid(String name) { return StringUtils.containsAny(name, invalidNameChars); } private String getDuplicateGlossaryRelatedTerm(AtlasGlossaryTerm atlasGlossaryTerm) throws AtlasBaseException { Map> relatedTermsMap = atlasGlossaryTerm.getRelatedTerms(); for (Map.Entry> relatedTermsMapEntry : relatedTermsMap.entrySet()) { Set termHeaders = relatedTermsMapEntry.getValue(); if (CollectionUtils.isNotEmpty(termHeaders)) { List duplicateTermHeaders = termHeaders.stream() .collect(Collectors.groupingBy(AtlasRelatedTermHeader::getTermGuid)) .values().stream() .filter(duplicates -> duplicates.size() > 1) .flatMap(Collection::stream) .collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(duplicateTermHeaders) && duplicateTermHeaders.size() > 0) { String dupTermGuid = duplicateTermHeaders.get(0).getTermGuid(); AtlasGlossaryTerm glossaryTerm = getTerm(dupTermGuid); return glossaryTerm.getQualifiedName(); } } } return StringUtils.EMPTY; } private String getDisplayText(AtlasGlossaryTerm term) { return term != null ? term.getName() : null; } static class PaginationHelper { private int pageStart; private int pageEnd; private int maxSize; private List items; PaginationHelper(Collection items, int offset, int limit) { Objects.requireNonNull(items, "items can't be empty/null"); this.items = new ArrayList<>(items); this.maxSize = items.size(); // If limit is negative then limit is effectively the maxSize, else the smaller one out of limit and maxSize int adjustedLimit = limit < 0 ? maxSize : Integer.min(maxSize, limit); // Page starting can only be between zero and adjustedLimit pageStart = Integer.max(0, offset); // Page end can't exceed the maxSize pageEnd = Integer.min(adjustedLimit + pageStart, maxSize); } List getPaginatedList() { List ret; if (isValidOffset()) { if (isPagingNeeded()) { ret = items.subList(pageStart, pageEnd); } else { ret = items; } } else { ret = Collections.emptyList(); } return ret; } private boolean isPagingNeeded() { return !(pageStart == 0 && pageEnd == maxSize) && pageStart <= pageEnd; } private boolean isValidOffset() { return pageStart <= maxSize; } } @GraphTransaction public BulkImportResponse importGlossaryData(InputStream inputStream, String fileName) throws AtlasBaseException { BulkImportResponse ret = new BulkImportResponse(); if (StringUtils.isBlank(fileName)) { throw new AtlasBaseException(AtlasErrorCode.INVALID_FILE_TYPE, fileName); } try { List fileData = FileUtils.readFileData(fileName, inputStream); List glossaryTermsWithoutRelations = glossaryTermUtils.getGlossaryTermDataWithoutRelations(fileData, ret); createGlossaryTerms(glossaryTermsWithoutRelations, ret); List glossaryTermsWithRelations = glossaryTermUtils.getGlossaryTermDataWithRelations(fileData, ret); updateGlossaryTermsRelation(glossaryTermsWithRelations, ret); } finally { glossaryTermUtils.clearImportCache(); } return ret; } private void createGlossaryTerms(List glossaryTerms, BulkImportResponse bulkImportResponse) throws AtlasBaseException { for (AtlasGlossaryTerm glossaryTerm : glossaryTerms) { String glossaryTermName = glossaryTerm.getName(); String glossaryName = getGlossaryName(glossaryTerm); try { AtlasGlossaryTerm createdTerm = createTerm(glossaryTerm); bulkImportResponse.addToSuccessImportInfoList(new ImportInfo(glossaryName, glossaryTermName, SUCCESS, AtlasJson.toJson(createdTerm.getGlossaryTermHeader()))); } catch (AtlasBaseException e) { LOG.error(AtlasErrorCode.FAILED_TO_CREATE_GLOSSARY_TERM.toString(), glossaryTermName, e); bulkImportResponse.addToFailedImportInfoList(new ImportInfo(glossaryName, glossaryTermName, FAILED, e.getMessage())); } } checkForSuccessImports(bulkImportResponse); } private void updateGlossaryTermsRelation(List glossaryTerms, BulkImportResponse bulkImportResponse) { for (AtlasGlossaryTerm glossaryTerm : glossaryTerms) { glossaryTermUtils.updateGlossaryTermRelations(glossaryTerm); if (glossaryTerm.hasTerms()) { String glossaryTermName = glossaryTerm.getName(); String glossaryName = getGlossaryName(glossaryTerm); try { updateTerm(glossaryTerm, false); } catch (AtlasBaseException e) { LOG.error(AtlasErrorCode.FAILED_TO_UPDATE_GLOSSARY_TERM.toString(), glossaryTermName, e); bulkImportResponse.addToFailedImportInfoList(new ImportInfo(glossaryName, glossaryTermName, FAILED, e.getMessage())); } } } } private String getGlossaryName(AtlasGlossaryTerm glossaryTerm) { String ret = ""; String glossaryTermQName = glossaryTerm.getQualifiedName(); if (StringUtils.isNotBlank(glossaryTermQName)){ String[] glossaryQnameSplit = glossaryTermQName.split("@"); ret = (glossaryQnameSplit.length == 2) ? glossaryQnameSplit[1] : ""; } return ret; } private void checkForSuccessImports(BulkImportResponse bulkImportResponse) throws AtlasBaseException { if (CollectionUtils.isEmpty(bulkImportResponse.getSuccessImportInfoList())) { throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_IMPORT_FAILED); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy