
org.odpi.openmetadata.accessservices.subjectarea.handlers.SubjectAreaHandler Maven / Gradle / Ivy
/* SPDX-License-Identifier: Apache-2.0 */
/* Copyright Contributors to the ODPi Egeria project. */
package org.odpi.openmetadata.accessservices.subjectarea.handlers;
import org.odpi.openmetadata.accessservices.subjectarea.ffdc.SubjectAreaErrorCode;
import org.odpi.openmetadata.accessservices.subjectarea.ffdc.exceptions.SubjectAreaCheckedException;
import org.odpi.openmetadata.accessservices.subjectarea.properties.objects.OmasObject;
import org.odpi.openmetadata.accessservices.subjectarea.properties.objects.category.Category;
import org.odpi.openmetadata.accessservices.subjectarea.properties.objects.common.FindRequest;
import org.odpi.openmetadata.accessservices.subjectarea.properties.objects.glossary.Glossary;
import org.odpi.openmetadata.accessservices.subjectarea.properties.objects.graph.Relationship;
import org.odpi.openmetadata.accessservices.subjectarea.properties.objects.graph.Node;
import org.odpi.openmetadata.accessservices.subjectarea.properties.objects.nodesummary.CategorySummary;
import org.odpi.openmetadata.accessservices.subjectarea.properties.objects.nodesummary.GlossarySummary;
import org.odpi.openmetadata.accessservices.subjectarea.properties.relationships.CategoryAnchor;
import org.odpi.openmetadata.accessservices.subjectarea.properties.relationships.TermAnchor;
import org.odpi.openmetadata.accessservices.subjectarea.responses.SubjectAreaOMASAPIResponse;
import org.odpi.openmetadata.accessservices.subjectarea.server.mappers.IRelationshipMapper;
import org.odpi.openmetadata.accessservices.subjectarea.server.mappers.INodeMapper;
import org.odpi.openmetadata.accessservices.subjectarea.server.mappers.Mapper;
import org.odpi.openmetadata.accessservices.subjectarea.server.mappers.MappersFactory;
import org.odpi.openmetadata.accessservices.subjectarea.server.mappers.entities.CategoryMapper;
import org.odpi.openmetadata.accessservices.subjectarea.server.mappers.entities.GlossaryMapper;
import org.odpi.openmetadata.accessservices.subjectarea.utilities.SubjectAreaUtils;
import org.odpi.openmetadata.commonservices.ffdc.InvalidParameterHandler;
import org.odpi.openmetadata.frameworks.auditlog.messagesets.ExceptionMessageDefinition;
import org.odpi.openmetadata.frameworks.connectors.ffdc.InvalidParameterException;
import org.odpi.openmetadata.frameworks.connectors.ffdc.PropertyServerException;
import org.odpi.openmetadata.frameworks.connectors.ffdc.UserNotAuthorizedException;
import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.EntityDetail;
import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.InstanceHeader;
import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.properties.instances.InstanceProvenanceType;
import org.odpi.openmetadata.repositoryservices.connectors.stores.metadatacollectionstore.repositoryconnector.OMRSRepositoryHelper;
import org.odpi.openmetadata.commonservices.generichandlers.*;
import java.util.*;
/**
* SubjectAreaProjectHandler manages Project objects from the property server. It runs server-side in the subject Area
* OMAS and retrieves entities and relationships through the OMRSRepositoryConnector.
*/
public abstract class SubjectAreaHandler {
private static final String className = SubjectAreaHandler.class.getName();
protected final MappersFactory mappersFactory;
protected final OpenMetadataAPIGenericHandler genericHandler;
protected final int maxPageSize;
protected InvalidParameterHandler invalidParameterHandler = new InvalidParameterHandler();
/**
* Construct the Subject Area Handler
* needed to operate within a single server instance.
*
* @param genericHandler generic handler
* @param maxPageSize maximum page size
*/
public SubjectAreaHandler(OpenMetadataAPIGenericHandler genericHandler, int maxPageSize) {
this.genericHandler =genericHandler;
this.mappersFactory = new MappersFactory(genericHandler);
this.maxPageSize = maxPageSize;
invalidParameterHandler.setMaxPagingSize(this.maxPageSize);
}
public int getMaxPageSize() {
return maxPageSize;
}
/**
* Get glossary summary
* @param restAPIName rest API Name
* @param userId userid under which to issue to the get of the related media
* @param relationship glossary relationship {@link TermAnchor} or {@link CategoryAnchor}
* @return Glossary summary
*
* @throws InvalidParameterException one of the parameters is null or invalid.
* @throws UserNotAuthorizedException user not authorized to issue this request.
* @throws PropertyServerException problem retrieving the Glossary.
*/
GlossarySummary getGlossarySummary(String restAPIName,
String userId,
Relationship relationship) throws UserNotAuthorizedException,
PropertyServerException,
InvalidParameterException,
SubjectAreaCheckedException {
String guid = SubjectAreaUtils.getGlossaryGuidFromAnchor(relationship);
EntityDetail entityDetail = genericHandler.getEntityFromRepository(userId,
guid,
"guid",
OpenMetadataAPIMapper.GLOSSARY_TYPE_NAME,
null,
null,
false,
false,
null,
restAPIName);
GlossaryMapper glossaryMapper = mappersFactory.get(GlossaryMapper.class);
Glossary glossary = glossaryMapper.map(entityDetail);
// TODO sort out icons
return SubjectAreaUtils.extractGlossarySummaryFromGlossary(glossary, relationship);
}
/**
* Get category summary
* @param restAPIName rest API Name
* @param userId userid under which to issue to the get of the related media
* @param relationship category relationship {@link TermAnchor} or {@link CategoryAnchor}
* @return category summary
*
* @throws InvalidParameterException one of the parameters is null or invalid.
* @throws UserNotAuthorizedException user not authorized to issue this request.
* @throws PropertyServerException problem retrieving the Category.
*/
CategorySummary getCategorySummary(String restAPIName,
String userId,
Relationship relationship) throws UserNotAuthorizedException,
PropertyServerException,
InvalidParameterException,
SubjectAreaCheckedException
{
String categoryGuid = relationship.getEnd1().getNodeGuid();
EntityDetail entityDetail = genericHandler.getEntityFromRepository(userId,
categoryGuid,
"guid",
OpenMetadataAPIMapper.GLOSSARY_CATEGORY_TYPE_NAME,
null,
null,
false,
false,
null,
restAPIName);
CategoryMapper CategoryMapper = mappersFactory.get(CategoryMapper.class);
Category category = CategoryMapper.map(entityDetail);
// TODO sort out icons
return SubjectAreaUtils.extractCategorySummaryFromCategory(category, relationship);
}
protected String sanitiseFindRequest(String searchCriteria, boolean exactValue, boolean ignoreCase) {
OMRSRepositoryHelper omrsRepositoryHelper =genericHandler.getRepositoryHelper();
if (searchCriteria != null && "".equals(searchCriteria.trim())) {
// ignore the flags for an empty search criteria string - assume we want everything
searchCriteria = ".*";
} else {
// lose any leading and trailing blanks
searchCriteria = searchCriteria.trim();
if (exactValue) {
searchCriteria = omrsRepositoryHelper.getExactMatchRegex(searchCriteria, ignoreCase);
} else {
searchCriteria = omrsRepositoryHelper.getStartsWithRegex(searchCriteria, ignoreCase);
}
}
return searchCriteria;
}
/**
* Take a FindRequest and sanitise it.
*
* The FindRequest from the user could contain a regex expression which would cause the regex engine to loop.
* to avoid this, we turn what the user has given us into a literal and then use the exactValue and ignoreCase flags
* to add to the regular expression in a controlled way.
*
* @param findRequest supplied find request - that contains the search criteria
* @param exactValue flag indicating that exact value mathcing should be done
* @param ignoreCase flag indicating that case should be ignored
* @return sanitised find request
*/
protected FindRequest sanitiseFindRequest(FindRequest findRequest, boolean exactValue, boolean ignoreCase) {
FindRequest sanitisedFindRequest = findRequest;
String searchCriteria = sanitiseFindRequest(findRequest.getSearchCriteria(), exactValue, ignoreCase);
sanitisedFindRequest.setSearchCriteria(searchCriteria);
return sanitisedFindRequest;
}
protected List findNodes(String userId,
String typeEntityName,
String typeEntityGuid,
FindRequest findRequest,
boolean exactValue,
boolean ignoreCase,
Class extends INodeMapper> mapperClass,
String methodName) throws PropertyServerException,
UserNotAuthorizedException,
InvalidParameterException {
List entityDetails = null;
List foundEntities = null;
if (findRequest.getPageSize() == null) {
findRequest.setPageSize(invalidParameterHandler.getMaxPagingSize());
}
invalidParameterHandler.validatePaging(findRequest.getStartingFrom(), findRequest.getPageSize(), methodName);
if (findRequest.getSearchCriteria() == null) {
entityDetails = genericHandler.getEntitiesByType(userId,
typeEntityGuid,
typeEntityName,
findRequest.getSequencingProperty(),
false,
false,
findRequest.getStartingFrom(),
findRequest.getPageSize(),
null, // any effective date
methodName);
} else {
FindRequest sanitisedFindRequest = sanitiseFindRequest(findRequest, exactValue, ignoreCase);
entityDetails = genericHandler.findEntities(userId,
sanitisedFindRequest.getSearchCriteria(),
"searchCriteria",
typeEntityGuid,
typeEntityName,
null,
null,
findRequest.getSequencingProperty(),
findRequest.getStartingFrom(),
findRequest.getPageSize(),
null, // any effective date
methodName);
}
if (entityDetails != null) {
foundEntities = convertOmrsToOmas(entityDetails, mapperClass);
}
return foundEntities;
}
/**
* Get All relationships for Node
*
* @param methodName name of the method being called.
* @param userId unique identifier for requesting user, under which the request is performed
* @param guid guid
* @param findRequest {@link FindRequest}
* @param entityTypeName typpe name of the starting entity
* @return the relationships associated with the requested guid
* */
public SubjectAreaOMASAPIResponse getAllRelationshipsForEntity(String methodName,
String userId,
String guid,
FindRequest findRequest,
String entityTypeName)
{
SubjectAreaOMASAPIResponse response = new SubjectAreaOMASAPIResponse<>();
try {
if (findRequest.getPageSize() == null) {
findRequest.setPageSize(invalidParameterHandler.getMaxPagingSize());
}
invalidParameterHandler.validatePaging(findRequest.getStartingFrom(), findRequest.getPageSize(), methodName);
response.addAllResults(getAllRelationshipForEntity(methodName, userId, guid, findRequest, entityTypeName));
} catch (UserNotAuthorizedException | SubjectAreaCheckedException | PropertyServerException | InvalidParameterException e) {
response.setExceptionInfo(e, className);
}
return response;
}
/**
* Get the relationships keyed off an entity guid.
*
* @param restAPIName rest API name
* @param userId user identity
* @param entityGuid globally unique identifier
* @param findRequest {@link FindRequest}
* @param entityTypeName type name of the starting entity
* @return {@code List}
*
* @throws PropertyServerException something went wrong with the REST call stack.
* @throws UserNotAuthorizedException the requesting user is not authorized to issue this request.
* @throws SubjectAreaCheckedException standard exception Subject Area OMAS services
*/
public List getAllRelationshipForEntity(String restAPIName,
String userId,
String entityGuid,
FindRequest findRequest,
String entityTypeName) throws SubjectAreaCheckedException,
PropertyServerException,
UserNotAuthorizedException,
InvalidParameterException {
if (findRequest.getPageSize() == null) {
findRequest.setPageSize(invalidParameterHandler.getMaxPagingSize());
}
invalidParameterHandler.validatePaging(findRequest.getStartingFrom(), findRequest.getPageSize(), restAPIName);
List relationships =
genericHandler.getAttachmentLinks(userId,
entityGuid,
"guid",
entityTypeName,
null,
null,
null,
findRequest.getStartingFrom(),
findRequest.getPageSize(),
null, // any effective time
restAPIName);
return getRelationshipsFromRelationships(relationships);
}
/**
* Get the relationships keyed off an entity guid.
*
* @param restAPIName rest API name
* @param userId user identity
* @param entityGuid globally unique identifier
* @param findRequest {@link FindRequest}
* @param entityTypeName type name of the starting entity
* @param attachmentRelationshipTypeGUID attachment relationship type guid
* @param attachmentRelationshipTypeName attachment relationship type name
* @param attachmentEntityTypeName attached entity type name
* @return {@code List}
*
* @throws PropertyServerException something went wrong with the REST call stack.
* @throws UserNotAuthorizedException the requesting user is not authorized to issue this request.
* @throws SubjectAreaCheckedException standard exception Subject Area OMAS services
*/
public List getRelationshipsForEntityByType(String restAPIName,
String userId,
String entityGuid,
FindRequest findRequest,
String entityTypeName,
String attachmentRelationshipTypeGUID,
String attachmentRelationshipTypeName,
String attachmentEntityTypeName) throws SubjectAreaCheckedException,
PropertyServerException,
UserNotAuthorizedException,
InvalidParameterException {
if (findRequest.getPageSize() == null) {
findRequest.setPageSize(invalidParameterHandler.getMaxPagingSize());
}
invalidParameterHandler.validatePaging(findRequest.getStartingFrom(), findRequest.getPageSize(), restAPIName);
List relationships =
genericHandler.getAttachmentLinks(userId,
entityGuid,
"guid",
entityTypeName,
attachmentRelationshipTypeGUID,
attachmentRelationshipTypeName,
attachmentEntityTypeName,
findRequest.getStartingFrom(),
findRequest.getPageSize(),
null, // any effective time
restAPIName);
return getRelationshipsFromRelationships(relationships);
}
public List getRelationshipsFromRelationships(Collection relationships) {
return convertOmrsToOmas(relationships, IRelationshipMapper.class);
}
public List getNodesFromEntityDetails(Collection entityDetails){
return convertOmrsToOmas(entityDetails, INodeMapper.class);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public List
convertOmrsToOmas(Collection list, Class extends Mapper> mapperInterface)
{
List result = new ArrayList<>();
if (list != null) {
Map> cache = new HashMap<>();
for (R entityDetail : list) {
String typeDefName = entityDetail.getType().getTypeDefName();
if (cache.containsKey(typeDefName)) {
Mapper mapper = cache.get(typeDefName);
result.add(mapper.map(entityDetail));
} else {
Set> allMapperClasses = mappersFactory.getAllMapperClasses();
for (Class> mapperClass : allMapperClasses) {
if (mapperInterface.isAssignableFrom(mapperClass)) {
Mapper mapper = mapperInterface.cast(mappersFactory.get(mapperClass));
if (mapper.getTypeName().equals(typeDefName)) {
cache.put(typeDefName, mapper);
result.add(mapper.map(entityDetail));
}
}
}
}
}
}
return result;
}
/**
* This method validated for creation.
*
* @param userId userId under which the request is performed
* @param methodName method making the call
* @param suppliedGlossary glossary to validate against.
* @return SubjectAreaOMASAPIResponse this response is of type ResponseCategory.Category.Glossary if successful, otherwise there is an error response.
*
* @throws PropertyServerException something went wrong with the REST call stack.
* @throws UserNotAuthorizedException the requesting user is not authorized to issue this request.
* @throws InvalidParameterException one of the parameters is null or invalid
* @throws SubjectAreaCheckedException standard exception Subject Area OMAS services
*/
protected String validateGlossarySummaryDuringCreation(String userId,
String methodName,
GlossarySummary suppliedGlossary) throws UserNotAuthorizedException,
PropertyServerException,
InvalidParameterException,
SubjectAreaCheckedException {
/*
* There needs to be an associated glossary supplied
* The glossary could be of NodeType Glossary, Taxonomy , Canonical glossary or canonical and taxonomy.
* The Glossary summary contains 4 identifying fields. We only require one of these fields to be supplied.
* If more than one is supplied then we look for a glossary matching the supplied userId then matching the name.
* Note if a relationship userId is supplied - then we reject this request - as the relationship cannot exist before one of its ends exists.
*/
if (suppliedGlossary != null) {
String guid = suppliedGlossary.getGuid();
String relationshipGuid = suppliedGlossary.getRelationshipguid();
if (relationshipGuid != null) {
// glossary relationship cannot exist before the Term exists.
ExceptionMessageDefinition messageDefinition = SubjectAreaErrorCode.CREATE_WITH_GLOSSARY_RELATIONSHIP.getMessageDefinition();
throw new InvalidParameterException(
messageDefinition,
className,
methodName,
"glossary",
null);
}
// find by glossary by guid
EntityDetail entityDetail = genericHandler.getEntityFromRepository(userId,
guid,
"guid",
OpenMetadataAPIMapper.GLOSSARY_TYPE_NAME,
null,
null,
false,
false,
null,
methodName);
return entityDetail.getGUID();
} else {
// error - glossary is mandatory
ExceptionMessageDefinition messageDefinition = SubjectAreaErrorCode.CREATE_WITHOUT_GLOSSARY.getMessageDefinition(methodName);
throw new InvalidParameterException(
messageDefinition,
className,
methodName,
"glossary",
null);
}
}
/**
* Set unique qualifiedName into the supplied Node. The qualified name needs to be unique and is supplied on an addnEtity omrs call.
* Prior to the add, we do not know the guid of the entity. We do not want to add an entity, then immediately update it; as these changes to
* entity identity would be propagated across the cohort. So we set the qualified name by concatinating the supplied seed, an @ symbol and a newly generated UUID.
*
* The assumption is that this method is supplied a node that contains a name.
*
* @param node Node to set the unique qualified name into
*/
protected void setUniqueQualifiedNameIfBlank(Node node) {
String qualifiedName = node.getQualifiedName();
if (qualifiedName == null || qualifiedName.trim().equals("")) {
node.setQualifiedName(node.getName() + "@" + UUID.randomUUID().toString());
}
}
/**
* Set the effectivity to and from dates date for a Node
* @param userId calling user
* @param node node to update with effectivity dates if required
* @param methodName name of the calling method
* @param guid guid of the Bean to update
* @param typeGUID the guid of the associated type
* @param typeName the name of the associated type
* @throws InvalidParameterException invalid parameter
* @throws PropertyServerException there is a problem with the repositories
* @throws UserNotAuthorizedException the user is not allowed to update the security tags
*/
protected void setNodeEffectivity(String userId, Node node, String methodName, String guid, String typeGUID, String typeName) throws InvalidParameterException, PropertyServerException, UserNotAuthorizedException {
Long effectiveFromLong = node.getEffectiveFromTime();
Long effectiveToLong = node.getEffectiveToTime();
if (effectiveFromLong != null || effectiveToLong != null) {
Date effectiveFrom = null;
Date effectiveTo = null;
if (effectiveToLong != null) {
effectiveTo = new Date(effectiveToLong);
}
if (effectiveFromLong != null) {
effectiveFrom = new Date(effectiveFromLong);
}
genericHandler.updateBeanEffectivityDates(userId,
null,
null,
guid,
"guid",
typeGUID,
typeName,
false,
false,
effectiveFrom,
effectiveTo,
methodName);
}
}
/**
* Set the effectivity to and from dates date for a Relationship
* @param userId calling user
* @param node node to take the effectivity dates from
* @param methodName name of the calling method
* @param relationshipGUID relationshipGUID of the Relationship to update
* @param typeGUID the relationshipGUID of the associated type
* @param typeName the name of the associated type
* @throws InvalidParameterException invalid parameter
* @throws PropertyServerException there is a problem with the repositories
* @throws UserNotAuthorizedException the user is not allowed to update the security tags
*/
protected void setRelationshipEffectivity(String userId, Node node, String methodName, String relationshipGUID, String typeGUID, String typeName) throws InvalidParameterException, PropertyServerException, UserNotAuthorizedException {
Long effectiveFromLong = node.getEffectiveFromTime();
Long effectiveToLong = node.getEffectiveToTime();
if (effectiveFromLong != null || effectiveToLong != null) {
Date effectiveFrom = null;
Date effectiveTo = null;
if (effectiveToLong != null) {
effectiveTo = new Date(effectiveToLong);
}
if (effectiveFromLong != null) {
effectiveFrom = new Date(effectiveFromLong);
}
genericHandler.updateRelationshipEffectivityDates(userId,
null,
null,
relationshipGUID,
"relationshipGUID",
typeName,
effectiveFrom,
effectiveTo,
methodName);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy