Commit a02be15d by Madhan Neethiraj

ATLAS-2421: updated Atlas notificaiton module to support V2 data structures;…

ATLAS-2421: updated Atlas notificaiton module to support V2 data structures; updated HBase hook to use V2 notifications (cherry picked from commit 86c9b19316245c47301e5212552c35d362479fc7)
parent dcdd3d68
......@@ -20,9 +20,11 @@ package org.apache.atlas.hbase;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasClientV2;
import org.apache.atlas.hbase.bridge.HBaseAtlasHook;
import org.apache.atlas.hbase.model.HBaseDataTypes;
import org.apache.atlas.v1.model.instance.Referenceable;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
import org.apache.atlas.utils.AuthenticationUtil;
import org.apache.atlas.utils.ParamChecker;
import org.apache.hadoop.conf.Configuration;
......@@ -40,6 +42,7 @@ import org.testng.annotations.Test;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.Collections;
import java.util.Iterator;
import static org.testng.Assert.assertNotNull;
......@@ -47,12 +50,13 @@ import static org.testng.Assert.fail;
public class HBaseAtlasHookIT {
private static final Logger LOG = LoggerFactory.getLogger(HBaseAtlasHookIT.class);
protected static final String DGI_URL = "http://localhost:31000/";
private static final Logger LOG = LoggerFactory.getLogger(HBaseAtlasHookIT.class);
protected static final String ATLAS_URL = "http://localhost:31000/";
protected static final String CLUSTER_NAME = "primary";
private static HBaseTestingUtility utility;
private static int port;
private static AtlasClient atlasClient;
private HBaseTestingUtility utility;
private int port;
private AtlasClientV2 atlasClient;
@BeforeClass
......@@ -65,36 +69,42 @@ public class HBaseAtlasHookIT {
}
}
@AfterClass
public static void cleanup() throws Exception {
LOG.info(" Stopping mini cluster.. ");
public void cleanup() throws Exception {
LOG.info("Stopping mini cluster.. ");
utility.shutdownMiniCluster();
}
@Test
public void testCreateNamesapce() throws Exception {
final Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "localhost");
conf.set("hbase.zookeeper.property.clientPort", String.valueOf(port));
conf.set("zookeeper.znode.parent", "/hbase-unsecure");
Connection conn = ConnectionFactory.createConnection(conf);
Admin admin = conn.getAdmin();
NamespaceDescriptor ns = NamespaceDescriptor.create("test_namespace").build();
admin.createNamespace(ns);
String nameSpace = assertNameSpaceIsRegistered(ns.getName());
//assert on qualified name
Referenceable nameSpaceRef = getAtlasClient().getEntity(nameSpace);
String nameSpaceQualifiedName = HBaseAtlasHook.getNameSpaceQualifiedName(CLUSTER_NAME, ns.getName());
Assert.assertEquals(nameSpaceRef.get(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME), nameSpaceQualifiedName);
String nameSpace = assertNameSpaceIsRegistered(ns.getName());
AtlasEntityWithExtInfo nameSpaceRef = getAtlasClient().getEntityByGuid(nameSpace);
String nameSpaceQualifiedName = HBaseAtlasHook.getNameSpaceQualifiedName(CLUSTER_NAME, ns.getName());
Assert.assertEquals(nameSpaceRef.getEntity().getAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME), nameSpaceQualifiedName);
}
@Test
public void testCreateTable() throws Exception {
final Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "localhost");
conf.set("hbase.zookeeper.property.clientPort", String.valueOf(port));
conf.set("zookeeper.znode.parent", "/hbase-unsecure");
Connection conn = ConnectionFactory.createConnection(conf);
Admin admin = conn.getAdmin();
String namespace = "test_namespace1";
......@@ -103,27 +113,35 @@ public class HBaseAtlasHookIT {
// Create a table
if (!admin.tableExists(TableName.valueOf(namespace, tablename))) {
NamespaceDescriptor ns = NamespaceDescriptor.create(namespace).build();
admin.createNamespace(ns);
HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf(namespace, tablename));
tableDescriptor.addFamily(new HColumnDescriptor("colfam1"));
admin.createTable(tableDescriptor);
}
String table = assertTableIsRegistered(namespace, tablename);
//assert on qualified name
Referenceable tableRef = getAtlasClient().getEntity(table);
String entityName = HBaseAtlasHook.getTableQualifiedName(CLUSTER_NAME, namespace, tablename);
Assert.assertEquals(tableRef.get(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME), entityName);
String table = assertTableIsRegistered(namespace, tablename);
AtlasEntityWithExtInfo tableRef = getAtlasClient().getEntityByGuid(table);
String entityName = HBaseAtlasHook.getTableQualifiedName(CLUSTER_NAME, namespace, tablename);
Assert.assertEquals(tableRef.getEntity().getAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME), entityName);
}
// Methods for creating HBase
public static void createAtlasClient() {
private void createAtlasClient() {
try {
org.apache.commons.configuration.Configuration configuration = ApplicationProperties.get();
String[] atlasEndPoint = configuration.getStringArray(HBaseAtlasHook.ATTR_ATLAS_ENDPOINT);
configuration.setProperty("atlas.cluster.name", CLUSTER_NAME);
if (atlasEndPoint == null || atlasEndPoint.length == 0) {
atlasEndPoint = new String[]{DGI_URL};
atlasEndPoint = new String[]{ATLAS_URL};
}
Iterator<String> keys = configuration.getKeys();
......@@ -133,12 +151,10 @@ public class HBaseAtlasHookIT {
}
if (AuthenticationUtil.isKerberosAuthenticationEnabled()) {
atlasClient = new AtlasClient(configuration, atlasEndPoint);
atlasClient = new AtlasClientV2(configuration, atlasEndPoint, null);
} else {
atlasClient = new AtlasClient(configuration, atlasEndPoint, new String[]{"admin", "admin"});
atlasClient = new AtlasClientV2(configuration, atlasEndPoint, new String[]{"admin", "admin"});
}
} catch (Exception e) {
LOG.error("Unable to create AtlasClient for Testing ", e);
}
......@@ -147,15 +163,18 @@ public class HBaseAtlasHookIT {
private static int getFreePort() throws IOException {
ServerSocket serverSocket = new ServerSocket(0);
int port = serverSocket.getLocalPort();
serverSocket.close();
return port;
}
public static void createHBaseCluster() throws Exception {
private void createHBaseCluster() throws Exception {
LOG.info("Creating Hbase Admin...");
port = getFreePort();
port = getFreePort();
utility = new HBaseTestingUtility();
utility.getConfiguration().set("test.hbase.zookeeper.property.clientPort", String.valueOf(port));
utility.getConfiguration().set("hbase.master.port", String.valueOf(getFreePort()));
utility.getConfiguration().set("hbase.master.info.port", String.valueOf(getFreePort()));
......@@ -170,8 +189,8 @@ public class HBaseAtlasHookIT {
}
public AtlasClient getAtlasClient() {
AtlasClient ret = null;
public AtlasClientV2 getAtlasClient() {
AtlasClientV2 ret = null;
if (atlasClient != null) {
ret = atlasClient;
}
......@@ -205,7 +224,7 @@ public class HBaseAtlasHookIT {
}
public interface AssertPredicate {
void assertOnEntity(Referenceable entity) throws Exception;
void assertOnEntity(AtlasEntity entity) throws Exception;
}
public interface Predicate {
......@@ -224,15 +243,19 @@ public class HBaseAtlasHookIT {
waitFor(80000, new HBaseAtlasHookIT.Predicate() {
@Override
public void evaluate() throws Exception {
Referenceable entity = atlasClient.getEntity(typeName, property, value);
AtlasEntityWithExtInfo entity = atlasClient.getEntityByAttribute(typeName, Collections.singletonMap(property, value));
assertNotNull(entity);
if (assertPredicate != null) {
assertPredicate.assertOnEntity(entity);
assertPredicate.assertOnEntity(entity.getEntity());
}
}
});
Referenceable entity = atlasClient.getEntity(typeName, property, value);
return entity.getId()._getId();
AtlasEntityWithExtInfo entity = atlasClient.getEntityByAttribute(typeName, Collections.singletonMap(property, value));
return entity.getEntity().getGuid();
}
/**
......
......@@ -106,6 +106,10 @@ public class AtlasClientV2 extends AtlasBaseClient {
super(baseUrl, cookie);
}
public AtlasClientV2(Configuration configuration, String[] baseUrl, String[] basicAuthUserNamePassword) {
super(configuration, baseUrl, basicAuthUserNamePassword);
}
@VisibleForTesting
AtlasClientV2(WebResource service, Configuration configuration) {
super(service, configuration);
......
......@@ -21,12 +21,18 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.commons.lang.StringUtils;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
import java.util.List;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
......@@ -48,7 +54,8 @@ public class HookNotification implements Serializable {
* Type of the hook message.
*/
public enum HookNotificationType {
TYPE_CREATE, TYPE_UPDATE, ENTITY_CREATE, ENTITY_PARTIAL_UPDATE, ENTITY_FULL_UPDATE, ENTITY_DELETE
TYPE_CREATE, TYPE_UPDATE, ENTITY_CREATE, ENTITY_PARTIAL_UPDATE, ENTITY_FULL_UPDATE, ENTITY_DELETE,
ENTITY_CREATE_V2, ENTITY_PARTIAL_UPDATE_V2, ENTITY_FULL_UPDATE_V2, ENTITY_DELETE_V2
}
protected HookNotificationType type;
......@@ -101,4 +108,118 @@ public class HookNotification implements Serializable {
return sb;
}
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.ALWAYS)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class EntityCreateRequestV2 extends HookNotification implements Serializable {
private AtlasEntitiesWithExtInfo entities;
private EntityCreateRequestV2() {
}
public EntityCreateRequestV2(String user, AtlasEntitiesWithExtInfo entities) {
super(HookNotificationType.ENTITY_CREATE_V2, user);
this.entities = entities;
}
public AtlasEntitiesWithExtInfo getEntities() {
return entities;
}
@Override
public String toString() {
return entities == null ? "null" : entities.toString();
}
}
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.ALWAYS)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class EntityUpdateRequestV2 extends HookNotification implements Serializable {
private AtlasEntitiesWithExtInfo entities;
private EntityUpdateRequestV2() {
}
public EntityUpdateRequestV2(String user, AtlasEntitiesWithExtInfo entities) {
super(HookNotificationType.ENTITY_FULL_UPDATE_V2, user);
this.entities = entities;
}
public AtlasEntitiesWithExtInfo getEntities() {
return entities;
}
@Override
public String toString() {
return entities == null ? "null" : entities.toString();
}
}
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.ALWAYS)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class EntityPartialUpdateRequestV2 extends HookNotification implements Serializable {
private AtlasObjectId entityId;
private AtlasEntityWithExtInfo entity;
private EntityPartialUpdateRequestV2() {
}
public EntityPartialUpdateRequestV2(String user, AtlasObjectId entityId, AtlasEntityWithExtInfo entity) {
super(HookNotificationType.ENTITY_PARTIAL_UPDATE_V2, user);
this.entityId = entityId;
this.entity = entity;
}
public AtlasObjectId getEntityId() {
return entityId;
}
public AtlasEntityWithExtInfo getEntity() {
return entity;
}
@Override
public String toString() {
return "entityId=" + entityId + "; entity=" + entity;
}
}
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.ALWAYS)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class EntityDeleteRequestV2 extends HookNotification implements Serializable {
private List<AtlasObjectId> entities;
private EntityDeleteRequestV2() {
}
public EntityDeleteRequestV2(String user, List<AtlasObjectId> entities) {
super(HookNotificationType.ENTITY_DELETE_V2, user);
this.entities = entities;
}
public List<AtlasObjectId> getEntities() {
return entities;
}
@Override
public String toString() {
return entities == null ? "null" : entities.toString();
}
}
}
......@@ -347,6 +347,22 @@ public class AtlasTypeUtil {
return new AtlasObjectId(header.getGuid(), header.getTypeName());
}
public static List<AtlasObjectId> getAtlasObjectIds(List<AtlasEntity> entities) {
final List<AtlasObjectId> ret;
if (CollectionUtils.isNotEmpty(entities)) {
ret = new ArrayList<>(entities.size());
for (AtlasEntity entity : entities) {
ret.add(getAtlasObjectId(entity));
}
} else {
ret = new ArrayList<>();
}
return ret;
}
public static boolean isValidGuid(AtlasObjectId objId) {
return isValidGuid(objId.getGuid());
}
......
......@@ -29,6 +29,10 @@ import org.apache.atlas.model.notification.EntityNotification;
import org.apache.atlas.model.notification.EntityNotification.EntityNotificationType;
import org.apache.atlas.model.notification.HookNotification;
import org.apache.atlas.model.notification.HookNotification.HookNotificationType;
import org.apache.atlas.model.notification.HookNotification.EntityCreateRequestV2;
import org.apache.atlas.model.notification.HookNotification.EntityDeleteRequestV2;
import org.apache.atlas.model.notification.HookNotification.EntityPartialUpdateRequestV2;
import org.apache.atlas.model.notification.HookNotification.EntityUpdateRequestV2;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.apache.atlas.v1.model.instance.AtlasSystemAttributes;
import org.apache.atlas.v1.model.instance.Id;
......@@ -65,12 +69,23 @@ public class AtlasJson {
static {
SimpleModule atlasSerDeModule = new SimpleModule("AtlasSerDe", new Version(1, 0, 0, null));
atlasSerDeModule.addSerializer(Date.class, new DateSerializer());
atlasSerDeModule.addDeserializer(Date.class, new DateDeserializer());
atlasSerDeModule.addSerializer(Referenceable.class, new ReferenceableSerializer());
atlasSerDeModule.addDeserializer(Referenceable.class, new ReferenceableDeserializer());
atlasSerDeModule.addSerializer(Struct.class, new StructSerializer());
atlasSerDeModule.addDeserializer(Struct.class, new StructDeserializer());
atlasSerDeModule.addSerializer(Id.class, new IdSerializer());
atlasSerDeModule.addDeserializer(Id.class, new IdDeserializer());
atlasSerDeModule.addDeserializer(HookNotification.class, new HookNotificationDeserializer());
atlasSerDeModule.addDeserializer(EntityNotification.class, new EntityNotificationDeserializer());
mapperV1.registerModule(atlasSerDeModule);
mapper.registerModule(atlasSerDeModule);
SimpleModule atlasSerDeV1Module = new SimpleModule("AtlasSerDeV1", new Version(1, 0, 0, null));
atlasSerDeV1Module.addSerializer(Date.class, new DateSerializer());
atlasSerDeV1Module.addDeserializer(Date.class, new DateDeserializer());
mapperV1.registerModule(atlasSerDeV1Module);
SimpleModule searchResultV1SerDeModule = new SimpleModule("SearchResultV1SerDe", new Version(1, 0, 0, null));
......@@ -90,7 +105,7 @@ public class AtlasJson {
if (obj instanceof JsonNode && ((JsonNode) obj).isTextual()) {
ret = ((JsonNode) obj).textValue();
} else {
ret = mapperV1.writeValueAsString(obj);
ret = mapper.writeValueAsString(obj);
}
}catch (IOException e){
LOG.error("AtlasJson.toJson()", e);
......@@ -106,6 +121,10 @@ public class AtlasJson {
if (jsonStr != null) {
try {
ret = mapper.readValue(jsonStr, type);
if (ret instanceof Struct) {
((Struct) ret).normalize();
}
} catch (IOException e) {
LOG.error("AtlasType.fromJson()", e);
......@@ -116,34 +135,18 @@ public class AtlasJson {
return ret;
}
public static String toV1Json(Object obj) {
String ret;
try {
if (obj instanceof JsonNode && ((JsonNode) obj).isTextual()) {
ret = ((JsonNode) obj).textValue();
} else {
ret = mapperV1.writeValueAsString(obj);
}
} catch (IOException e) {
LOG.error("AtlasType.toV1Json()", e);
ret = null;
}
return ret;
}
public static <T> T fromV1Json(String jsonStr, Class<T> type) {
public static <T> T fromJson(String jsonStr, TypeReference<T> type) {
T ret = null;
if (jsonStr != null) {
try {
ret = mapperV1.readValue(jsonStr, type);
ret = mapper.readValue(jsonStr, type);
if (ret instanceof Struct) {
((Struct) ret).normalize();
}
} catch (IOException e) {
LOG.error("AtlasType.fromV1Json()", e);
LOG.error("AtlasType.fromJson()", e);
ret = null;
}
......@@ -152,20 +155,16 @@ public class AtlasJson {
return ret;
}
public static <T> T fromV1Json(String jsonStr, TypeReference<T> type) {
T ret = null;
if (jsonStr != null) {
try {
ret = mapperV1.readValue(jsonStr, type);
} catch (IOException e) {
LOG.error("AtlasType.toV1Json()", e);
public static String toV1Json(Object obj) {
return toJson(obj);
}
ret = null;
}
}
public static <T> T fromV1Json(String jsonStr, Class<T> type) {
return fromJson(jsonStr, type);
}
return ret;
public static <T> T fromV1Json(String jsonStr, TypeReference<T> type) {
return fromJson(jsonStr, type);
}
public static String toV1SearchJson(Object obj) {
......@@ -198,7 +197,7 @@ public class AtlasJson {
}
public static ArrayNode createV1ArrayNode(Collection<?> array) {
ArrayNode ret = mapperV1.createArrayNode();
ArrayNode ret = mapper.createArrayNode();
for (Object elem : array) {
ret.addPOJO(elem);
......@@ -209,13 +208,13 @@ public class AtlasJson {
public static JsonNode parseToV1JsonNode(String json) throws IOException {
JsonNode jsonNode = mapperV1.readTree(json);
JsonNode jsonNode = mapper.readTree(json);
return jsonNode;
}
public static ArrayNode parseToV1ArrayNode(String json) throws IOException {
JsonNode jsonNode = mapperV1.readTree(json);
JsonNode jsonNode = mapper.readTree(json);
if (jsonNode instanceof ArrayNode) {
return (ArrayNode)jsonNode;
......@@ -228,7 +227,7 @@ public class AtlasJson {
ArrayNode ret = createV1ArrayNode();
for (String json : jsonStrings) {
JsonNode jsonNode = mapperV1.readTree(json);
JsonNode jsonNode = mapper.readTree(json);
ret.add(jsonNode);
}
......@@ -263,6 +262,60 @@ public class AtlasJson {
}
}
static class ReferenceableSerializer extends JsonSerializer<Referenceable> {
@Override
public void serialize(Referenceable value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
if (value != null) {
mapperV1.writeValue(jgen, value);
}
}
}
static class ReferenceableDeserializer extends JsonDeserializer<Referenceable> {
@Override
public Referenceable deserialize(JsonParser parser, DeserializationContext context) throws IOException {
Referenceable ret = mapperV1.readValue(parser, Referenceable.class);
return ret;
}
}
static class StructSerializer extends JsonSerializer<Struct> {
@Override
public void serialize(Struct value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
if (value != null) {
mapperV1.writeValue(jgen, value);
}
}
}
static class StructDeserializer extends JsonDeserializer<Struct> {
@Override
public Struct deserialize(JsonParser parser, DeserializationContext context) throws IOException {
Struct ret = mapperV1.readValue(parser, Struct.class);
return ret;
}
}
static class IdSerializer extends JsonSerializer<Id> {
@Override
public void serialize(Id value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
if (value != null) {
mapperV1.writeValue(jgen, value);
}
}
}
static class IdDeserializer extends JsonDeserializer<Id> {
@Override
public Id deserialize(JsonParser parser, DeserializationContext context) throws IOException {
Id ret = mapperV1.readValue(parser, Id.class);
return ret;
}
}
static class HookNotificationDeserializer extends JsonDeserializer<HookNotification> {
@Override
public HookNotification deserialize(JsonParser parser, DeserializationContext context) throws IOException {
......@@ -295,6 +348,22 @@ public class AtlasJson {
case ENTITY_DELETE:
ret = mapper.treeToValue(root, EntityDeleteRequest.class);
break;
case ENTITY_CREATE_V2:
ret = mapper.treeToValue(root, EntityCreateRequestV2.class);
break;
case ENTITY_PARTIAL_UPDATE_V2:
ret = mapper.treeToValue(root, EntityPartialUpdateRequestV2.class);
break;
case ENTITY_FULL_UPDATE_V2:
ret = mapper.treeToValue(root, EntityUpdateRequestV2.class);
break;
case ENTITY_DELETE_V2:
ret = mapper.treeToValue(root, EntityDeleteRequestV2.class);
break;
}
}
......
......@@ -110,7 +110,7 @@ public abstract class AtlasNotificationMessageDeserializer<T> implements Message
AtlasNotificationBaseMessage msg = AtlasType.fromV1Json(messageJson, AtlasNotificationBaseMessage.class);
if (msg.getVersion() == null) { // older style messages not wrapped with AtlasNotificationMessage
if (msg == null || msg.getVersion() == null) { // older style messages not wrapped with AtlasNotificationMessage
ret = AtlasType.fromV1Json(messageJson, messageType);
} else {
String msgJson = messageJson;
......
......@@ -21,6 +21,7 @@ import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.instance.AtlasClassification;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.instance.EntityMutationResponse;
import org.apache.atlas.repository.store.graph.v1.EntityStream;
import org.apache.atlas.type.AtlasEntityType;
......@@ -85,6 +86,16 @@ public interface AtlasEntityStore {
/**
* Update a single entity
* @param objectId ID of the entity
* @param updatedEntityInfo updated entity information
* @return EntityMutationResponse details of the updates performed by this call
* @throws AtlasBaseException
*
*/
EntityMutationResponse updateEntity(AtlasObjectId objectId, AtlasEntityWithExtInfo updatedEntityInfo, boolean isPartialUpdate) throws AtlasBaseException;
/**
* Update a single entity
* @param entityType type of the entity
* @param uniqAttributes Attributes that uniquely identify the entity
* @return EntityMutationResponse details of the updates performed by this call
......
......@@ -226,6 +226,38 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
@Override
@GraphTransaction
public EntityMutationResponse updateEntity(AtlasObjectId objectId, AtlasEntityWithExtInfo updatedEntityInfo, boolean isPartialUpdate) throws AtlasBaseException {
if (LOG.isDebugEnabled()) {
LOG.debug("==> updateEntity({}, {}, {})", objectId, updatedEntityInfo, isPartialUpdate);
}
if (objectId == null || updatedEntityInfo == null || updatedEntityInfo.getEntity() == null) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "null entity-id/entity");
}
final String guid;
if (AtlasTypeUtil.isAssignedGuid(objectId.getGuid())) {
guid = objectId.getGuid();
} else {
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(objectId.getTypeName());
if (entityType == null) {
throw new AtlasBaseException(AtlasErrorCode.UNKNOWN_TYPENAME, objectId.getTypeName());
}
guid = AtlasGraphUtilsV1.getGuidByUniqueAttributes(typeRegistry.getEntityTypeByName(objectId.getTypeName()), objectId.getUniqueAttributes());
}
AtlasEntity entity = updatedEntityInfo.getEntity();
entity.setGuid(guid);
return createOrUpdate(new AtlasEntityStream(updatedEntityInfo), isPartialUpdate, false);
}
@Override
@GraphTransaction
public EntityMutationResponse updateByUniqueAttributes(AtlasEntityType entityType, Map<String, Object> uniqAttributes,
AtlasEntityWithExtInfo updatedEntityInfo) throws AtlasBaseException {
......
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