Commit 72cc566a by Graham Wallis Committed by David Radley

ATLAS-2523 Add HomeId and allow GUIDs to be specified on creates

parent 69ea3348
......@@ -81,6 +81,18 @@ public final class Constants {
public static final String CREATED_BY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "createdBy";
public static final String MODIFIED_BY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "modifiedBy";
/**
* The homeId field is used when saving into Atlas a copy of an object that is being imported from another
* repository. The homeId will be set to a String that identifies the other repository. The specific format
* of repository identifiers is domain dependent. Where it is set by Open Metadata Repository Services it will
* be a MetadataCollectionId.
* An object that is mastered by the Atlas repository, will have a null homeId field. This represents a locally
* mastered object that can be manipulated by Atlas and its applications as normal.
* An object with a non-null homeId is a copy of an object mastered by a different repository and the object
* should only be updated via the notifications and calls from Open Metadata Repository Services.
*/
public static final String HOME_ID_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "homeId";
public static final String TIMESTAMP_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "timestamp";
public static final String MODIFICATION_TIMESTAMP_PROPERTY_KEY =
......
......@@ -60,6 +60,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
private static final long serialVersionUID = 1L;
public static final String KEY_GUID = "guid";
public static final String KEY_HOME_ID = "homeId";
public static final String KEY_STATUS = "status";
public static final String KEY_CREATED_BY = "createdBy";
public static final String KEY_UPDATED_BY = "updatedBy";
......@@ -73,6 +74,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
public enum Status { ACTIVE, DELETED }
private String guid = null;
private String homeId = null;
private Status status = Status.ACTIVE;
private String createdBy = null;
private String updatedBy = null;
......@@ -116,6 +118,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
if (map != null) {
Object oGuid = map.get(KEY_GUID);
Object homeId = map.get(KEY_HOME_ID);
Object status = map.get(KEY_STATUS);
Object createdBy = map.get(KEY_CREATED_BY);
Object updatedBy = map.get(KEY_UPDATED_BY);
......@@ -127,6 +130,10 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
setGuid(oGuid.toString());
}
if (homeId != null) {
setHomeId(homeId.toString());
}
if (status != null) {
setStatus(Status.valueOf(status.toString()));
}
......@@ -158,6 +165,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
if (other != null) {
setGuid(other.getGuid());
setHomeId(other.getHomeId());
setStatus(other.getStatus());
setCreatedBy(other.getCreatedBy());
setUpdatedBy(other.getUpdatedBy());
......@@ -176,6 +184,14 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
this.guid = guid;
}
public String getHomeId() {
return homeId;
}
public void setHomeId(String homeId) {
this.homeId = homeId;
}
public Status getStatus() {
return status;
}
......@@ -291,6 +307,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
private void init() {
setGuid(nextInternalId());
setHomeId(null);
setStatus(null);
setCreatedBy(null);
setUpdatedBy(null);
......@@ -313,6 +330,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
sb.append("AtlasEntity{");
super.toString(sb);
sb.append("guid='").append(guid).append('\'');
sb.append(", homeId='").append(homeId).append('\'');
sb.append(", status=").append(status);
sb.append(", createdBy='").append(createdBy).append('\'');
sb.append(", updatedBy='").append(updatedBy).append('\'');
......@@ -341,6 +359,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
AtlasEntity that = (AtlasEntity) o;
return Objects.equals(guid, that.guid) &&
Objects.equals(homeId, that.homeId) &&
status == that.status &&
Objects.equals(createdBy, that.createdBy) &&
Objects.equals(updatedBy, that.updatedBy) &&
......@@ -353,7 +372,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), guid, status, createdBy, updatedBy, createTime, updateTime, version,
return Objects.hash(super.hashCode(), guid, homeId, status, createdBy, updatedBy, createTime, updateTime, version,
relationshipAttributes, classifications);
}
......
......@@ -55,6 +55,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
private static final long serialVersionUID = 1L;
public static final String KEY_GUID = "guid";
public static final String KEY_HOME_ID = "homeId";
public static final String KEY_STATUS = "status";
public static final String KEY_CREATED_BY = "createdBy";
public static final String KEY_UPDATED_BY = "updatedBy";
......@@ -70,6 +71,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
public static final String KEY_PROPAGATED_CLASSIFICATIONS = "propagatedClassifications";
private String guid = null;
private String homeId = null;
private AtlasObjectId end1 = null;
private AtlasObjectId end2 = null;
private String label = null;
......@@ -108,13 +110,13 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
public AtlasRelationship(String typeName, AtlasObjectId end1, AtlasObjectId end2) {
super(typeName);
init(nextInternalId(), end1, end2, null, null, null, null, null, null, null, 0L, null, null);
init(nextInternalId(), null, end1, end2, null, null, null, null, null, null, null, 0L, null, null);
}
public AtlasRelationship(String typeName, AtlasObjectId end1, AtlasObjectId end2, Map<String, Object> attributes) {
super(typeName, attributes);
init(nextInternalId(), end1, end2, null, null, null, null, null, null, null, 0L, null, null);
init(nextInternalId(), null, end1, end2, null, null, null, null, null, null, null, 0L, null, null);
}
public AtlasRelationship(String typeName, String attrName, Object attrValue) {
......@@ -132,6 +134,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
if (map != null) {
Object oGuid = map.get(KEY_GUID);
Object homeId = map.get(KEY_HOME_ID);
Object oEnd1 = map.get(KEY_END1);
Object oEnd2 = map.get(KEY_END2);
Object label = map.get(KEY_LABEL);
......@@ -150,6 +153,10 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
setGuid(oGuid.toString());
}
if (homeId != null) {
setHomeId(homeId.toString());
}
if (oEnd1 != null) {
if (oEnd1 instanceof AtlasObjectId) {
setEnd1((AtlasObjectId) oEnd1);
......@@ -228,7 +235,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
super(other);
if (other != null) {
init(other.guid, other.end1, other.end2, other.label, other.propagateTags, other.status, other.createdBy, other.updatedBy,
init(other.guid, other.homeId, other.end1, other.end2, other.label, other.propagateTags, other.status, other.createdBy, other.updatedBy,
other.createTime, other.updateTime, other.version, other.propagatedClassifications, other.blockedPropagatedClassifications);
}
}
......@@ -241,6 +248,14 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
this.guid = guid;
}
public String getHomeId() {
return homeId;
}
public void setHomeId(String homeId) {
this.homeId = homeId;
}
public Status getStatus() {
return status;
}
......@@ -326,13 +341,14 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
}
private void init() {
init(nextInternalId(), null, null, null, null, null, null, null, null, null, 0L, null, null);
init(nextInternalId(), null, null, null, null, null, null, null, null, null, null, 0L, null, null);
}
private void init(String guid, AtlasObjectId end1, AtlasObjectId end2, String label, PropagateTags propagateTags,
private void init(String guid, String homeId, AtlasObjectId end1, AtlasObjectId end2, String label, PropagateTags propagateTags,
Status status, String createdBy, String updatedBy, Date createTime, Date updateTime, Long version,
Set<AtlasClassification> propagatedClassifications, Set<AtlasClassification> blockedPropagatedClassifications) {
setGuid(guid);
setHomeId(homeId);
setEnd1(end1);
setEnd2(end2);
setLabel(label);
......@@ -356,6 +372,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
sb.append("AtlasRelationship{");
super.toString(sb);
sb.append("guid='").append(guid).append('\'');
sb.append(", homeId='").append(homeId).append('\'');
sb.append(", end1=").append(end1);
sb.append(", end2=").append(end2);
sb.append(", label='").append(label).append('\'');
......@@ -385,6 +402,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
AtlasRelationship that = (AtlasRelationship) o;
return Objects.equals(guid, that.guid) &&
Objects.equals(homeId, that.homeId) &&
Objects.equals(end1, that.end1) &&
Objects.equals(end2, that.end2) &&
Objects.equals(label, that.label) &&
......@@ -401,7 +419,7 @@ public class AtlasRelationship extends AtlasStruct implements Serializable {
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), guid, end1, end2, label, propagateTags, status, createdBy, updatedBy,
return Objects.hash(super.hashCode(), guid, homeId, end1, end2, label, propagateTags, status, createdBy, updatedBy,
createTime, updateTime, version, propagatedClassifications, blockedPropagatedClassifications);
}
......
......@@ -55,6 +55,7 @@ import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.*;
* Utility methods for AtlasType/AtlasTypeDef.
*/
public class AtlasTypeUtil {
private static final Set<String> ATLAS_BUILTIN_TYPENAMES = new HashSet<>();
private static final String NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_ ]*";
private static final String TRAIT_NAME_REGEX = "[a-zA-Z][a-zA-Z0-9_ .]*";
......@@ -380,13 +381,21 @@ public class AtlasTypeUtil {
}
public static boolean isAssignedGuid(String guid) {
/**
* The rule for whether a GUID is 'assigned' is that it must always be non-null, non-empty
* and must not start with a '-' character, because in Atlas the '-' prefix character
* signifies an Atlas 'unassigned' GUID. There are no other GUID formatting constraints.
*
* An object from a remote repository can be saved into Atlas with its existing (external) GUID
* if that GUID conforms to the same 3 conditions. If, in future, it is required to save objects from
* a remote repository that assigns GUIDs that can start with the '-' character, then it will be
* necessary to enhance this isAssignedGUID() method to accepts and check the object's homeId, such
* that if homeId is not null (the object is from a remote repository), then the '-' prefix constraint
* is relaxed. Such a change would require a pervasive change to Atlas classes and therefore should
* only be implemented if it is found to be necessary.
*/
if (guid != null) {
try {
UUID.fromString(guid);
return true;
} catch (IllegalArgumentException e) {
// ignore
}
return guid != null && guid.length() > 0 && guid.charAt(0) != '-';
}
return false;
}
......
......@@ -34,7 +34,9 @@ class RegistryBasedLookup implements Lookup {
Constants.CREATED_BY_KEY,
Constants.STATE_PROPERTY_KEY,
Constants.TIMESTAMP_PROPERTY_KEY,
Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY));
Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY,
Constants.HOME_ID_KEY
));
private static final Map<String, String> NUMERIC_ATTRIBUTES = new HashMap<String, String>() {{
put(AtlasBaseTypeDef.ATLAS_TYPE_SHORT, "");
......
......@@ -1142,6 +1142,10 @@ public final class GraphHelper {
return element.<String>getProperty(Constants.GUID_PROPERTY_KEY, String.class);
}
public static String getHomeId(AtlasElement element) {
return element.getProperty(Constants.HOME_ID_KEY, String.class);
}
public static String getTypeName(AtlasElement element) {
return element.getProperty(Constants.ENTITY_TYPE_PROPERTY_KEY, String.class);
}
......
......@@ -713,7 +713,9 @@ public class AtlasRelationshipStoreV2 implements AtlasRelationshipStore {
// map additional properties to relationship edge
if (ret != null) {
final String guid = UUID.randomUUID().toString();
// Accept a valid (assigned) guid from the supplied relationship, or generate one.
String relationshipGuid = relationship.getGuid();
final String guid = AtlasTypeUtil.isAssignedGuid(relationshipGuid) ? relationshipGuid : UUID.randomUUID().toString();
AtlasGraphUtilsV2.setProperty(ret, Constants.ENTITY_TYPE_PROPERTY_KEY, relationship.getTypeName());
AtlasGraphUtilsV2.setProperty(ret, Constants.RELATIONSHIP_GUID_PROPERTY_KEY, guid);
......
......@@ -167,6 +167,10 @@ public class EntityGraphMapper {
if (StringUtils.isNotEmpty(entity.getUpdatedBy())) {
AtlasGraphUtilsV2.setProperty(vertex, Constants.MODIFIED_BY_KEY, entity.getUpdatedBy());
}
if (StringUtils.isNotEmpty(entity.getHomeId())) {
AtlasGraphUtilsV2.setProperty(vertex, Constants.HOME_ID_KEY, entity.getHomeId());
}
}
public EntityMutationResponse mapAttributesAndClassifications(EntityMutationContext context, final boolean isPartialUpdate, final boolean replaceClassifications) throws AtlasBaseException {
......
......@@ -465,6 +465,8 @@ public final class EntityGraphRetriever {
entity.setCreateTime(new Date(GraphHelper.getCreatedTime(entityVertex)));
entity.setUpdateTime(new Date(GraphHelper.getModifiedTime(entityVertex)));
entity.setHomeId(GraphHelper.getHomeId(entityVertex));
return entity;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment