Commit b84ed999 by Madhan Neethiraj

ATLAS-3037: fixed entity-updated detection to handle object-id attributes correctly

parent 05e845f5
...@@ -22,6 +22,7 @@ package org.apache.atlas.authorize; ...@@ -22,6 +22,7 @@ package org.apache.atlas.authorize;
import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.RequestContext; import org.apache.atlas.RequestContext;
import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.utils.AtlasPerfMetrics.MetricRecorder;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -87,6 +88,8 @@ public class AtlasAuthorizationUtils { ...@@ -87,6 +88,8 @@ public class AtlasAuthorizationUtils {
} }
public static boolean isAccessAllowed(AtlasAdminAccessRequest request) { public static boolean isAccessAllowed(AtlasAdminAccessRequest request) {
MetricRecorder metric = RequestContext.get().startMetricRecord("isAccessAllowed");
boolean ret = false; boolean ret = false;
String userName = getCurrentUserName(); String userName = getCurrentUserName();
...@@ -104,10 +107,14 @@ public class AtlasAuthorizationUtils { ...@@ -104,10 +107,14 @@ public class AtlasAuthorizationUtils {
ret = true; ret = true;
} }
RequestContext.get().endMetricRecord(metric);
return ret; return ret;
} }
public static boolean isAccessAllowed(AtlasEntityAccessRequest request) { public static boolean isAccessAllowed(AtlasEntityAccessRequest request) {
MetricRecorder metric = RequestContext.get().startMetricRecord("isAccessAllowed");
boolean ret = false; boolean ret = false;
String userName = getCurrentUserName(); String userName = getCurrentUserName();
...@@ -125,10 +132,14 @@ public class AtlasAuthorizationUtils { ...@@ -125,10 +132,14 @@ public class AtlasAuthorizationUtils {
ret = true; ret = true;
} }
RequestContext.get().endMetricRecord(metric);
return ret; return ret;
} }
public static boolean isAccessAllowed(AtlasTypeAccessRequest request) { public static boolean isAccessAllowed(AtlasTypeAccessRequest request) {
MetricRecorder metric = RequestContext.get().startMetricRecord("isAccessAllowed");
boolean ret = false; boolean ret = false;
String userName = getCurrentUserName(); String userName = getCurrentUserName();
...@@ -146,10 +157,14 @@ public class AtlasAuthorizationUtils { ...@@ -146,10 +157,14 @@ public class AtlasAuthorizationUtils {
ret = true; ret = true;
} }
RequestContext.get().endMetricRecord(metric);
return ret; return ret;
} }
public static boolean isAccessAllowed(AtlasRelationshipAccessRequest request) { public static boolean isAccessAllowed(AtlasRelationshipAccessRequest request) {
MetricRecorder metric = RequestContext.get().startMetricRecord("isAccessAllowed");
boolean ret = false; boolean ret = false;
String userName = getCurrentUserName(); String userName = getCurrentUserName();
...@@ -167,6 +182,8 @@ public class AtlasAuthorizationUtils { ...@@ -167,6 +182,8 @@ public class AtlasAuthorizationUtils {
ret = true; ret = true;
} }
RequestContext.get().endMetricRecord(metric);
return ret; return ret;
} }
......
...@@ -28,6 +28,7 @@ import java.lang.reflect.Array; ...@@ -28,6 +28,7 @@ import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.SERVICE_TYPE_ATLAS_CORE; import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.SERVICE_TYPE_ATLAS_CORE;
...@@ -149,7 +150,7 @@ public class AtlasArrayType extends AtlasType { ...@@ -149,7 +150,7 @@ public class AtlasArrayType extends AtlasType {
} }
@Override @Override
public boolean areEqualValues(Object val1, Object val2) { public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
boolean ret = true; boolean ret = true;
if (val1 == null) { if (val1 == null) {
...@@ -164,7 +165,7 @@ public class AtlasArrayType extends AtlasType { ...@@ -164,7 +165,7 @@ public class AtlasArrayType extends AtlasType {
ret = false; ret = false;
} else { } else {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (!elementType.areEqualValues(Array.get(val1, i), Array.get(val2, i))) { if (!elementType.areEqualValues(Array.get(val1, i), Array.get(val2, i), guidAssignments)) {
ret = false; ret = false;
break; break;
...@@ -182,7 +183,7 @@ public class AtlasArrayType extends AtlasType { ...@@ -182,7 +183,7 @@ public class AtlasArrayType extends AtlasType {
boolean foundInSet2 = false; boolean foundInSet2 = false;
for (Object elem2 : set2) { for (Object elem2 : set2) {
if (elementType.areEqualValues(elem1, elem2)) { if (elementType.areEqualValues(elem1, elem2, guidAssignments)) {
foundInSet2 = true; foundInSet2 = true;
break; break;
...@@ -213,7 +214,7 @@ public class AtlasArrayType extends AtlasType { ...@@ -213,7 +214,7 @@ public class AtlasArrayType extends AtlasType {
ret = false; ret = false;
} else { } else {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
if (!elementType.areEqualValues(list1.get(i), list2.get(i))) { if (!elementType.areEqualValues(list1.get(i), list2.get(i), guidAssignments)) {
ret = false; ret = false;
break; break;
......
...@@ -29,6 +29,7 @@ import java.math.BigInteger; ...@@ -29,6 +29,7 @@ import java.math.BigInteger;
import java.text.ParseException; import java.text.ParseException;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.SERVICE_TYPE_ATLAS_CORE; import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.SERVICE_TYPE_ATLAS_CORE;
...@@ -277,7 +278,8 @@ public class AtlasBuiltInTypes { ...@@ -277,7 +278,8 @@ public class AtlasBuiltInTypes {
return getNormalizedValue(obj) != null; return getNormalizedValue(obj) != null;
} }
public boolean areEqualValues(Object val1, Object val2) { @Override
public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
final boolean ret; final boolean ret;
if (val1 == null) { if (val1 == null) {
...@@ -353,7 +355,8 @@ public class AtlasBuiltInTypes { ...@@ -353,7 +355,8 @@ public class AtlasBuiltInTypes {
return getNormalizedValue(obj) != null; return getNormalizedValue(obj) != null;
} }
public boolean areEqualValues(Object val1, Object val2) { @Override
public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
final boolean ret; final boolean ret;
if (val1 == null) { if (val1 == null) {
...@@ -626,6 +629,48 @@ public class AtlasBuiltInTypes { ...@@ -626,6 +629,48 @@ public class AtlasBuiltInTypes {
} }
@Override @Override
public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
boolean ret = true;
if (val1 == null) {
ret = val2 == null;
} else if (val2 == null) {
ret = false;
} else {
AtlasObjectId v1 = getNormalizedValue(val1);
AtlasObjectId v2 = getNormalizedValue(val2);
if (v1 == null || v2 == null) {
ret = false;
} else {
String guid1 = v1.getGuid();
String guid2 = v2.getGuid();
if (guidAssignments != null ) {
if (guidAssignments.containsKey(guid1)) {
guid1 = guidAssignments.get(guid1);
}
if (guidAssignments.containsKey(guid2)) {
guid2 = guidAssignments.get(guid2);
}
}
boolean isV1AssignedGuid = AtlasTypeUtil.isAssignedGuid(guid1);
boolean isV2AssignedGuid = AtlasTypeUtil.isAssignedGuid(guid2);
if (isV1AssignedGuid == isV2AssignedGuid) { // if both have assigned/unassigned guids, compare guids
ret = Objects.equals(guid1, guid2);
} else { // if one has assigned and other unassigned guid, compare typeName and unique-attribute
ret = Objects.equals(v1.getTypeName(), v2.getTypeName()) && Objects.equals(v1.getUniqueAttributes(), v2.getUniqueAttributes());
}
}
}
return ret;
}
@Override
public AtlasObjectId getNormalizedValue(Object obj) { public AtlasObjectId getNormalizedValue(Object obj) {
if (obj != null) { if (obj != null) {
if (obj instanceof AtlasObjectId) { if (obj instanceof AtlasObjectId) {
......
...@@ -315,14 +315,14 @@ public class AtlasClassificationType extends AtlasStructType { ...@@ -315,14 +315,14 @@ public class AtlasClassificationType extends AtlasStructType {
} }
@Override @Override
public boolean areEqualValues(Object val1, Object val2) { public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
for (AtlasClassificationType superType : superTypes) { for (AtlasClassificationType superType : superTypes) {
if (!superType.areEqualValues(val1, val2)) { if (!superType.areEqualValues(val1, val2, guidAssignments)) {
return false; return false;
} }
} }
return super.areEqualValues(val1, val2); return super.areEqualValues(val1, val2, guidAssignments);
} }
@Override @Override
......
...@@ -362,14 +362,14 @@ public class AtlasEntityType extends AtlasStructType { ...@@ -362,14 +362,14 @@ public class AtlasEntityType extends AtlasStructType {
} }
@Override @Override
public boolean areEqualValues(Object val1, Object val2) { public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
for (AtlasEntityType superType : superTypes) { for (AtlasEntityType superType : superTypes) {
if (!superType.areEqualValues(val1, val2)) { if (!superType.areEqualValues(val1, val2, guidAssignments)) {
return false; return false;
} }
} }
return super.areEqualValues(val1, val2); return super.areEqualValues(val1, val2, guidAssignments);
} }
@Override @Override
......
...@@ -119,7 +119,7 @@ public class AtlasMapType extends AtlasType { ...@@ -119,7 +119,7 @@ public class AtlasMapType extends AtlasType {
} }
@Override @Override
public boolean areEqualValues(Object val1, Object val2) { public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
boolean ret = true; boolean ret = true;
if (val1 == null) { if (val1 == null) {
...@@ -143,7 +143,7 @@ public class AtlasMapType extends AtlasType { ...@@ -143,7 +143,7 @@ public class AtlasMapType extends AtlasType {
ret = false; ret = false;
} else { } else {
for (Object key : map1.keySet()) { for (Object key : map1.keySet()) {
if (!valueType.areEqualValues(map1.get(key), map2.get(key))) { if (!valueType.areEqualValues(map1.get(key), map2.get(key), guidAssignments)) {
ret = false; ret = false;
break; break;
......
...@@ -172,7 +172,7 @@ public class AtlasRelationshipType extends AtlasStructType { ...@@ -172,7 +172,7 @@ public class AtlasRelationshipType extends AtlasStructType {
} }
@Override @Override
public boolean areEqualValues(Object val1, Object val2) { public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
final boolean ret; final boolean ret;
if (val1 == null) { if (val1 == null) {
...@@ -189,7 +189,7 @@ public class AtlasRelationshipType extends AtlasStructType { ...@@ -189,7 +189,7 @@ public class AtlasRelationshipType extends AtlasStructType {
if (rel2 == null) { if (rel2 == null) {
ret = false; ret = false;
} else if (!super.areEqualValues(rel1, rel2)) { } else if (!super.areEqualValues(rel1, rel2, guidAssignments)) {
ret = false; ret = false;
} else { } else {
ret = Objects.equals(rel1.getGuid(), rel2.getGuid()) && ret = Objects.equals(rel1.getGuid(), rel2.getGuid()) &&
......
...@@ -244,7 +244,7 @@ public class AtlasStructType extends AtlasType { ...@@ -244,7 +244,7 @@ public class AtlasStructType extends AtlasType {
} }
@Override @Override
public boolean areEqualValues(Object val1, Object val2) { public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
boolean ret = true; boolean ret = true;
if (val1 == null) { if (val1 == null) {
...@@ -264,21 +264,14 @@ public class AtlasStructType extends AtlasType { ...@@ -264,21 +264,14 @@ public class AtlasStructType extends AtlasType {
} else if (!StringUtils.equalsIgnoreCase(structVal1.getTypeName(), structVal2.getTypeName())) { } else if (!StringUtils.equalsIgnoreCase(structVal1.getTypeName(), structVal2.getTypeName())) {
ret = false; ret = false;
} else { } else {
for (Map.Entry<String, Object> entry : structVal1.getAttributes().entrySet()) { for (AtlasAttribute attribute : getAllAttributes().values()) {
String attrName = entry.getKey(); Object attrValue1 = structVal1.getAttribute(attribute.getName());
AtlasAttribute attribute = getAttribute(attrName); Object attrValue2 = structVal2.getAttribute(attribute.getName());
if (attribute == null) { // ignore unknown attribute if (!attribute.getAttributeType().areEqualValues(attrValue1, attrValue2, guidAssignments)) {
continue; ret = false;
} else {
Object attrValue1 = entry.getValue();
Object attrValue2 = structVal2.getAttribute(attrName);
if (!attribute.getAttributeType().areEqualValues(attrValue1, attrValue2)) { break;
ret = false;
break;
}
} }
} }
} }
......
...@@ -27,6 +27,7 @@ import org.slf4j.Logger; ...@@ -27,6 +27,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
...@@ -79,7 +80,7 @@ public abstract class AtlasType { ...@@ -79,7 +80,7 @@ public abstract class AtlasType {
public abstract boolean isValidValue(Object obj); public abstract boolean isValidValue(Object obj);
public boolean areEqualValues(Object val1, Object val2) { public boolean areEqualValues(Object val1, Object val2, Map<String, String> guidAssignments) {
final boolean ret; final boolean ret;
if (val1 == null) { if (val1 == null) {
......
...@@ -43,38 +43,6 @@ public class AtlasEntityUtil { ...@@ -43,38 +43,6 @@ public class AtlasEntityUtil {
private static final int SOFT_REFERENCE_FORMAT_INDEX_TYPE_NAME = 0; private static final int SOFT_REFERENCE_FORMAT_INDEX_TYPE_NAME = 0;
private static final int SOFT_REFERENCE_FORMAT_INDEX_GUID = 1; private static final int SOFT_REFERENCE_FORMAT_INDEX_GUID = 1;
public static boolean hasAnyAttributeUpdate(AtlasEntityType entityType, AtlasEntity currEntity, AtlasEntity newEntity) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> hasAnyAttributeUpdate(guid={}, typeName={})", currEntity.getGuid(), currEntity.getTypeName());
}
boolean ret = false;
for (AtlasAttribute attribute : entityType.getAllAttributes().values()) {
String attrName = attribute.getName();
AtlasType attrType = attribute.getAttributeType();
Object currValue = currEntity.getAttribute(attrName);
Object newValue = newEntity.getAttribute(attrName);
if (!attrType.areEqualValues(currEntity.getAttribute(attrName), newEntity.getAttribute(attrName))) {
ret = true;
if (LOG.isDebugEnabled()) {
LOG.debug("hasAnyAttributeUpdate(guid={}, typeName={}): attribute '{}' is found updated - currentValue={}, newValue={}",
currEntity.getGuid(), currEntity.getTypeName(), attrName, currValue, newValue);
}
break;
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== hasAnyAttributeUpdate(guid={}, typeName={}): ret={}", currEntity.getGuid(), currEntity.getTypeName(), ret);
}
return ret;
}
public static String formatSoftRefValue(String typeName, String guid) { public static String formatSoftRefValue(String typeName, String guid) {
return String.format(SOFT_REF_FORMAT, typeName, guid); return String.format(SOFT_REF_FORMAT, typeName, guid);
......
...@@ -40,7 +40,6 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute; ...@@ -40,7 +40,6 @@ import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
import org.apache.atlas.type.AtlasType; import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry; import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.type.AtlasTypeUtil; import org.apache.atlas.type.AtlasTypeUtil;
import org.apache.atlas.utils.AtlasEntityUtil;
import org.apache.atlas.utils.AtlasPerfMetrics.MetricRecorder; import org.apache.atlas.utils.AtlasPerfMetrics.MetricRecorder;
import org.apache.atlas.utils.AtlasPerfTracer; import org.apache.atlas.utils.AtlasPerfTracer;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
...@@ -694,24 +693,68 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { ...@@ -694,24 +693,68 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
// for existing entities, skip update if incoming entity doesn't have any change // for existing entities, skip update if incoming entity doesn't have any change
if (CollectionUtils.isNotEmpty(context.getUpdatedEntities())) { if (CollectionUtils.isNotEmpty(context.getUpdatedEntities())) {
MetricRecorder checkForUnchangedEntities = RequestContext.get().startMetricRecord("checkForUnchangedEntities");
List<AtlasEntity> entitiesToSkipUpdate = null; List<AtlasEntity> entitiesToSkipUpdate = null;
for (AtlasEntity entity : context.getUpdatedEntities()) { for (AtlasEntity entity : context.getUpdatedEntities()) {
String guid = entity.getGuid(); String guid = entity.getGuid();
AtlasVertex vertex = context.getVertex(guid); AtlasVertex vertex = context.getVertex(guid);
AtlasEntity entityInStore = entityRetriever.toAtlasEntity(vertex); AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName());
AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName()); boolean hasUpdates = false;
if (!AtlasEntityUtil.hasAnyAttributeUpdate(entityType, entity, entityInStore)) { if (MapUtils.isNotEmpty(entity.getRelationshipAttributes())) {
// if classifications are to be replaced as well, then skip updates only when no change in classifications as well hasUpdates = true; // if relationship attributes are provided, assume there is an update
if (!replaceClassifications || Objects.equals(entity.getClassifications(), entityInStore.getClassifications())) { }
if (entitiesToSkipUpdate == null) {
entitiesToSkipUpdate = new ArrayList<>(); if (!hasUpdates) {
hasUpdates = entity.getStatus() == AtlasEntity.Status.DELETED; // entity status could be updated during import
}
if (!hasUpdates) {
for (AtlasAttribute attribute : entityType.getAllAttributes().values()) {
if (!entity.getAttributes().containsKey(attribute.getName())) { // if value is not provided, current value will not be updated
continue;
} }
entitiesToSkipUpdate.add(entity); Object newVal = entity.getAttribute(attribute.getName());
Object currVal = entityRetriever.getEntityAttribute(vertex, attribute);
if (!attribute.getAttributeType().areEqualValues(currVal, newVal, context.getGuidAssignments())) {
hasUpdates = true;
if (LOG.isDebugEnabled()) {
LOG.debug("found attribute update: entity(guid={}, typeName={}), attrName={}, currValue={}, newValue={}", guid, entity.getTypeName(), attribute.getName(), currVal, newVal);
}
break;
}
} }
} }
// if classifications are to be replaced, then skip updates only when no change in classifications
if (!hasUpdates && replaceClassifications) {
List<AtlasClassification> newVal = entity.getClassifications();
List<AtlasClassification> currVal = entityRetriever.getAllClassifications(vertex);
if (!Objects.equals(currVal, newVal)) {
hasUpdates = true;
if (LOG.isDebugEnabled()) {
LOG.debug("found classifications update: entity(guid={}, typeName={}), currValue={}, newValue={}", guid, entity.getTypeName(), currVal, newVal);
}
}
}
if (!hasUpdates) {
if (entitiesToSkipUpdate == null) {
entitiesToSkipUpdate = new ArrayList<>();
}
LOG.info("skipping unchanged entity: {}", entity);
entitiesToSkipUpdate.add(entity);
}
} }
if (entitiesToSkipUpdate != null) { if (entitiesToSkipUpdate != null) {
...@@ -725,6 +768,8 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore { ...@@ -725,6 +768,8 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore {
"update entity: type=", entity.getTypeName()); "update entity: type=", entity.getTypeName());
} }
} }
RequestContext.get().endMetricRecord(checkForUnchangedEntities);
} }
EntityMutationResponse ret = entityGraphMapper.mapAttributesAndClassifications(context, isPartialUpdate, replaceClassifications); EntityMutationResponse ret = entityGraphMapper.mapAttributesAndClassifications(context, isPartialUpdate, replaceClassifications);
......
...@@ -197,6 +197,18 @@ public class EntityGraphRetriever { ...@@ -197,6 +197,18 @@ public class EntityGraphRetriever {
return ret; return ret;
} }
public Object getEntityAttribute(AtlasVertex entityVertex, AtlasAttribute attribute) {
Object ret = null;
try {
ret = getVertexAttribute(entityVertex, attribute);
} catch (AtlasBaseException excp) {
// ignore
}
return ret;
}
public AtlasEntityHeader toAtlasEntityHeader(AtlasEntity entity) { public AtlasEntityHeader toAtlasEntityHeader(AtlasEntity entity) {
AtlasEntityHeader ret = null; AtlasEntityHeader ret = null;
String typeName = entity.getTypeName(); String typeName = entity.getTypeName();
......
...@@ -388,6 +388,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase { ...@@ -388,6 +388,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
//Drop the first key and change the class type as well to col0 //Drop the first key and change the class type as well to col0
columnsMap.clear(); columnsMap.clear();
columnsMap.put("col0", AtlasTypeUtil.getAtlasObjectId(col0)); columnsMap.put("col0", AtlasTypeUtil.getAtlasObjectId(col0));
tableEntity.setAttribute(TestUtilsV2.COLUMNS_MAP, columnsMap);
init(); init();
response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false); response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
...@@ -420,6 +421,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase { ...@@ -420,6 +421,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
//Remove an entry //Remove an entry
paramsMap.remove("key1"); paramsMap.remove("key1");
tableEntity.setAttribute("parametersMap", paramsMap);
init(); init();
response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false); response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 1); validateMutationResponse(response, EntityMutations.EntityOperation.UPDATE, 1);
...@@ -446,21 +448,24 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase { ...@@ -446,21 +448,24 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
//add a new element to array of struct //add a new element to array of struct
partitions.add(new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "part3")); partitions.add(new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "part3"));
tableEntity.setAttribute("partitions", partitions);
init(); init();
response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false); response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE); updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
validateEntity(entitiesInfo, getEntityFromStore(updatedTable)); validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
//remove one of the struct values //remove one of the struct values
init();
partitions.remove(1); partitions.remove(1);
tableEntity.setAttribute("partitions", partitions);
init();
response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false); response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE); updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
validateEntity(entitiesInfo, getEntityFromStore(updatedTable)); validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
//Update struct value within array of struct //Update struct value within array of struct
init();
partitions.get(0).setAttribute(TestUtilsV2.NAME, "part4"); partitions.get(0).setAttribute(TestUtilsV2.NAME, "part4");
tableEntity.setAttribute("partitions", partitions);
init();
response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false); response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE); updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
validateEntity(entitiesInfo, getEntityFromStore(updatedTable)); validateEntity(entitiesInfo, getEntityFromStore(updatedTable));
...@@ -468,6 +473,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase { ...@@ -468,6 +473,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
//add a repeated element to array of struct //add a repeated element to array of struct
partitions.add(new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "part4")); partitions.add(new AtlasStruct(TestUtilsV2.PARTITION_STRUCT_TYPE, TestUtilsV2.NAME, "part4"));
tableEntity.setAttribute("partitions", partitions);
init(); init();
response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false); response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE); updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
...@@ -475,6 +481,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase { ...@@ -475,6 +481,7 @@ public class AtlasEntityStoreV2Test extends AtlasEntityTestBase {
// Remove all elements. Should set array attribute to null // Remove all elements. Should set array attribute to null
partitions.clear(); partitions.clear();
tableEntity.setAttribute("partitions", partitions);
init(); init();
response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false); response = entityStore.createOrUpdate(new AtlasEntityStream(entitiesInfo), false);
updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE); updatedTable = response.getFirstUpdatedEntityByTypeName(TABLE_TYPE);
......
...@@ -51,7 +51,7 @@ public class AdminExportImportTestIT extends BaseResourceIT { ...@@ -51,7 +51,7 @@ public class AdminExportImportTestIT extends BaseResourceIT {
static final String IMPORT_TRANSFORM_CLEAR_ATTRS = static final String IMPORT_TRANSFORM_CLEAR_ATTRS =
"{ \"Asset\": { \"*\":[ \"clearAttrValue:replicatedTo,replicatedFrom\" ] } }"; "{ \"Asset\": { \"*\":[ \"clearAttrValue:replicatedTo,replicatedFrom\" ] } }";
static final String IMPORT_TRANSFORM_SET_DELETED = static final String IMPORT_TRANSFORM_SET_DELETED =
"{ \"Asset\": { \"*\":[ \"setDeleted\" ] } }"; "{ \"Referenceable\": { \"*\":[ \"setDeleted\" ] } }";
@Test @Test
public void isActive() throws AtlasServiceException { public void isActive() throws AtlasServiceException {
......
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