mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-30 01:23:08 +00:00
This commit is contained in:
parent
ff1d2c251a
commit
a8732c8e89
@ -72,6 +72,7 @@ import org.openmetadata.catalog.jdbi3.CollectionDAO.EntityRelationshipRecord;
|
||||
import org.openmetadata.catalog.jdbi3.CollectionDAO.EntityVersionPair;
|
||||
import org.openmetadata.catalog.jdbi3.CollectionDAO.ExtensionRecord;
|
||||
import org.openmetadata.catalog.jdbi3.TableRepository.TableUpdater;
|
||||
import org.openmetadata.catalog.security.policyevaluator.SubjectCache;
|
||||
import org.openmetadata.catalog.type.ChangeDescription;
|
||||
import org.openmetadata.catalog.type.ChangeEvent;
|
||||
import org.openmetadata.catalog.type.EntityHistory;
|
||||
@ -136,7 +137,6 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
@Getter protected final boolean supportsTags;
|
||||
@Getter protected final boolean supportsOwner;
|
||||
protected final boolean supportsFollower;
|
||||
protected boolean allowEdits = false;
|
||||
|
||||
/** Fields that can be updated during PATCH operation */
|
||||
private final Fields patchFields;
|
||||
@ -1122,12 +1122,14 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
protected final Operation operation;
|
||||
protected final ChangeDescription changeDescription = new ChangeDescription();
|
||||
protected boolean majorVersionChange = false;
|
||||
protected final User updatingUser;
|
||||
private boolean entityRestored = false;
|
||||
|
||||
public EntityUpdater(T original, T updated, Operation operation) {
|
||||
this.original = original;
|
||||
this.updated = updated;
|
||||
this.operation = operation;
|
||||
this.updatingUser = SubjectCache.getInstance().getSubjectContext(updated.getUpdatedBy()).getUser();
|
||||
}
|
||||
|
||||
/** Compare original and updated entities and perform updates. Update the entity version and track changes. */
|
||||
@ -1154,11 +1156,8 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
}
|
||||
|
||||
private void updateDescription() throws JsonProcessingException {
|
||||
if (operation.isPut()
|
||||
&& original.getDescription() != null
|
||||
&& !original.getDescription().isEmpty()
|
||||
&& !allowEdits) {
|
||||
// Update description only when stored is empty to retain user authored descriptions
|
||||
if (operation.isPut() && !nullOrEmpty(original.getDescription()) && updatedByBot()) {
|
||||
// Revert change to non-empty description if it is being updated by a bot
|
||||
updated.setDescription(original.getDescription());
|
||||
return;
|
||||
}
|
||||
@ -1183,11 +1182,8 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
}
|
||||
|
||||
private void updateDisplayName() throws JsonProcessingException {
|
||||
if (operation.isPut()
|
||||
&& original.getDisplayName() != null
|
||||
&& !original.getDisplayName().isEmpty()
|
||||
&& !allowEdits) {
|
||||
// Update displayName only when stored is empty to retain user authored descriptions
|
||||
if (operation.isPut() && !nullOrEmpty(original.getDisplayName()) && updatedByBot()) {
|
||||
// Revert change to non-empty description if it is being updated by a bot
|
||||
updated.setDisplayName(original.getDisplayName());
|
||||
return;
|
||||
}
|
||||
@ -1231,9 +1227,14 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
}
|
||||
|
||||
private void updateExtension() throws JsonProcessingException {
|
||||
if (updatedByBot()) {
|
||||
// Revert changes to extension field, if being updated by a bot
|
||||
updated.setExtension(original.getExtension());
|
||||
return;
|
||||
}
|
||||
|
||||
removeExtension(original);
|
||||
storeExtension(updated);
|
||||
// TODO change descriptions for custom attributes
|
||||
}
|
||||
|
||||
public final boolean updateVersion(Double oldVersion) {
|
||||
@ -1279,7 +1280,7 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
public final <K> boolean recordChange(
|
||||
String field, K orig, K updated, boolean jsonValue, BiPredicate<K, K> typeMatch)
|
||||
throws JsonProcessingException {
|
||||
if (orig == null && updated == null) {
|
||||
if (orig == updated) {
|
||||
return false;
|
||||
}
|
||||
FieldChange fieldChange =
|
||||
@ -1422,5 +1423,9 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
private void storeNewVersion() throws IOException {
|
||||
EntityRepository.this.storeEntity(updated, true);
|
||||
}
|
||||
|
||||
public final boolean updatedByBot() {
|
||||
return Boolean.TRUE.equals(updatingUser.getIsBot());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +49,6 @@ public class IngestionPipelineRepository extends EntityRepository<IngestionPipel
|
||||
dao,
|
||||
PATCH_FIELDS,
|
||||
UPDATE_FIELDS);
|
||||
this.allowEdits = true;
|
||||
this.secretsManager = secretsManager;
|
||||
}
|
||||
|
||||
|
||||
@ -311,8 +311,8 @@ public class PipelineRepository extends EntityRepository<Pipeline> {
|
||||
}
|
||||
|
||||
private void updateTaskDescription(Task origTask, Task updatedTask) throws JsonProcessingException {
|
||||
if (operation.isPut() && !nullOrEmpty(origTask.getDescription())) {
|
||||
// Update description only when stored is empty to retain user authored descriptions
|
||||
if (operation.isPut() && !nullOrEmpty(origTask.getDescription()) && updatedByBot()) {
|
||||
// Revert the non-empty task description if being updated by a bot
|
||||
updatedTask.setDescription(origTask.getDescription());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -148,7 +148,6 @@ public class PolicyRepository extends EntityRepository<Policy> {
|
||||
if (listOrEmpty(rules).isEmpty()) {
|
||||
throw new IllegalArgumentException(CatalogExceptionMessage.EMPTY_RULES_IN_POLICY);
|
||||
}
|
||||
System.out.println("XXX rules count " + rules.size());
|
||||
|
||||
// Validate all the expressions in the rule
|
||||
for (Rule rule : rules) {
|
||||
|
||||
@ -44,11 +44,7 @@ public abstract class ServiceEntityRepository<
|
||||
SecretsManager secretsManager,
|
||||
Class<S> serviceConnectionClass,
|
||||
ServiceType serviceType) {
|
||||
super(collectionPath, service, entityDAO.getEntityClass(), entityDAO, dao, "", UPDATE_FIELDS);
|
||||
this.allowEdits = true;
|
||||
this.secretsManager = secretsManager;
|
||||
this.serviceConnectionClass = serviceConnectionClass;
|
||||
this.serviceType = serviceType;
|
||||
this(collectionPath, service, dao, entityDAO, secretsManager, serviceConnectionClass, UPDATE_FIELDS, serviceType);
|
||||
}
|
||||
|
||||
protected ServiceEntityRepository(
|
||||
@ -61,7 +57,6 @@ public abstract class ServiceEntityRepository<
|
||||
String updatedFields,
|
||||
ServiceType serviceType) {
|
||||
super(collectionPath, service, entityDAO.getEntityClass(), entityDAO, dao, "", updatedFields);
|
||||
this.allowEdits = true;
|
||||
this.secretsManager = secretsManager;
|
||||
this.serviceConnectionClass = serviceConnectionClass;
|
||||
this.serviceType = serviceType;
|
||||
|
||||
@ -34,7 +34,6 @@ public class StorageServiceRepository extends EntityRepository<StorageService> {
|
||||
dao,
|
||||
"",
|
||||
UPDATE_FIELDS);
|
||||
this.allowEdits = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -17,6 +17,7 @@ import static java.util.stream.Collectors.groupingBy;
|
||||
import static java.util.stream.Collectors.toUnmodifiableList;
|
||||
import static org.openmetadata.catalog.Entity.DATABASE_SCHEMA;
|
||||
import static org.openmetadata.catalog.Entity.FIELD_DESCRIPTION;
|
||||
import static org.openmetadata.catalog.Entity.FIELD_DISPLAY_NAME;
|
||||
import static org.openmetadata.catalog.Entity.FIELD_FOLLOWERS;
|
||||
import static org.openmetadata.catalog.Entity.FIELD_OWNER;
|
||||
import static org.openmetadata.catalog.Entity.FIELD_TAGS;
|
||||
@ -842,7 +843,7 @@ public class TableRepository extends EntityRepository<Table> {
|
||||
* {@code entityRelationType}) are ({@link Table#getFullyQualifiedName()}, "table") and ({@link
|
||||
* Column#getFullyQualifiedName()}, "table.columns.column").
|
||||
*
|
||||
* <p>If for an field relation (any relation between {@code entityFQN} and a FQN from {@code joinedWithList}), after
|
||||
* <p>If for a field relation (any relation between {@code entityFQN} and a FQN from {@code joinedWithList}), after
|
||||
* combining the existing list of {@link DailyCount} with join data from {@code joinedWithList}, there are multiple
|
||||
* {@link DailyCount} with the {@link DailyCount#getDate()}, these will <bold>NOT</bold> be merged - the value of
|
||||
* {@link JoinedWith#getJoinCount()} will override the current value.
|
||||
@ -1004,7 +1005,7 @@ public class TableRepository extends EntityRepository<Table> {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private TableJoins getJoins(Table table) throws IOException {
|
||||
private TableJoins getJoins(Table table) {
|
||||
String today = RestUtil.DATE_FORMAT.format(new Date());
|
||||
String todayMinus30Days = CommonUtil.getDateStringByOffset(RestUtil.DATE_FORMAT, today, -30);
|
||||
return new TableJoins()
|
||||
@ -1014,7 +1015,7 @@ public class TableRepository extends EntityRepository<Table> {
|
||||
.withDirectTableJoins(getDirectTableJoins(table));
|
||||
}
|
||||
|
||||
private List<JoinedWith> getDirectTableJoins(Table table) throws IOException {
|
||||
private List<JoinedWith> getDirectTableJoins(Table table) {
|
||||
// Pair<toTableFQN, List<DailyCount>>
|
||||
List<Pair<String, List<DailyCount>>> entityRelations =
|
||||
daoCollection.fieldRelationshipDAO()
|
||||
@ -1036,7 +1037,7 @@ public class TableRepository extends EntityRepository<Table> {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<ColumnJoin> getColumnJoins(Table table) throws IOException {
|
||||
private List<ColumnJoin> getColumnJoins(Table table) {
|
||||
// Triple<fromRelativeColumnName, toFQN, List<DailyCount>>
|
||||
List<Triple<String, String, List<DailyCount>>> entityRelations =
|
||||
daoCollection.fieldRelationshipDAO()
|
||||
@ -1216,6 +1217,7 @@ public class TableRepository extends EntityRepository<Table> {
|
||||
}
|
||||
|
||||
updateColumnDescription(stored, updated);
|
||||
updateColumnDisplayName(stored, updated);
|
||||
updateColumnDataLength(stored, updated);
|
||||
updateColumnPrecision(stored, updated);
|
||||
updateColumnScale(stored, updated);
|
||||
@ -1236,8 +1238,8 @@ public class TableRepository extends EntityRepository<Table> {
|
||||
}
|
||||
|
||||
private void updateColumnDescription(Column origColumn, Column updatedColumn) throws JsonProcessingException {
|
||||
if (operation.isPut() && !nullOrEmpty(origColumn.getDescription())) {
|
||||
// Update description only when stored is empty to retain user authored descriptions
|
||||
if (operation.isPut() && !nullOrEmpty(origColumn.getDescription()) && updatedByBot()) {
|
||||
// Revert the non-empty task description if being updated by a bot
|
||||
updatedColumn.setDescription(origColumn.getDescription());
|
||||
return;
|
||||
}
|
||||
@ -1245,6 +1247,16 @@ public class TableRepository extends EntityRepository<Table> {
|
||||
recordChange(columnField, origColumn.getDescription(), updatedColumn.getDescription());
|
||||
}
|
||||
|
||||
private void updateColumnDisplayName(Column origColumn, Column updatedColumn) throws JsonProcessingException {
|
||||
if (operation.isPut() && !nullOrEmpty(origColumn.getDescription()) && updatedByBot()) {
|
||||
// Revert the non-empty task description if being updated by a bot
|
||||
updatedColumn.setDisplayName(origColumn.getDisplayName());
|
||||
return;
|
||||
}
|
||||
String columnField = getColumnField(original, origColumn, FIELD_DISPLAY_NAME);
|
||||
recordChange(columnField, origColumn.getDisplayName(), updatedColumn.getDisplayName());
|
||||
}
|
||||
|
||||
private void updateColumnConstraint(Column origColumn, Column updatedColumn) throws JsonProcessingException {
|
||||
String columnField = getColumnField(original, origColumn, "constraint");
|
||||
recordChange(columnField, origColumn.getConstraint(), updatedColumn.getConstraint());
|
||||
|
||||
@ -40,7 +40,6 @@ public class TagCategoryRepository extends EntityRepository<TagCategory> {
|
||||
|
||||
public TagCategoryRepository(CollectionDAO dao, TagRepository tagRepository) {
|
||||
super(TagResource.TAG_COLLECTION_PATH, Entity.TAG_CATEGORY, TagCategory.class, dao.tagCategoryDAO(), dao, "", "");
|
||||
allowEdits = true;
|
||||
this.tagRepository = tagRepository;
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,6 @@ import org.openmetadata.catalog.util.JsonUtils;
|
||||
public class TagRepository extends EntityRepository<Tag> {
|
||||
public TagRepository(CollectionDAO dao) {
|
||||
super(TagResource.TAG_COLLECTION_PATH, Entity.TAG, Tag.class, dao.tagDAO(), dao, "", "");
|
||||
allowEdits = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -47,7 +47,6 @@ public class TypeRepository extends EntityRepository<Type> {
|
||||
|
||||
public TypeRepository(CollectionDAO dao) {
|
||||
super(TypeResource.COLLECTION_PATH, Entity.TYPE, Type.class, dao.typeEntityDAO(), dao, PATCH_FIELDS, UPDATE_FIELDS);
|
||||
allowEdits = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -119,12 +119,9 @@ public class SubjectCache {
|
||||
}
|
||||
|
||||
public List<EntityReference> getRolesForTeams(List<EntityReference> teams) {
|
||||
System.out.println("Getting roles for teams " + teams);
|
||||
List<EntityReference> roles = new ArrayList<>();
|
||||
for (EntityReference teamRef : listOrEmpty(teams)) {
|
||||
System.out.println("roles for team " + teamRef.getName());
|
||||
Team team = getTeam(teamRef.getId());
|
||||
System.out.println("roles for team adding " + team.getDefaultRoles());
|
||||
roles.addAll(team.getDefaultRoles());
|
||||
roles.addAll(getRolesForTeams(team.getParents()));
|
||||
}
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
package org.openmetadata.catalog.jdbi3;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openmetadata.catalog.entity.data.Table;
|
||||
import org.openmetadata.catalog.type.Column;
|
||||
|
||||
public class TableRepositoryUnitTest {
|
||||
|
||||
@Test
|
||||
void testWhenUpdatingAColumnDataLengthWhichWasNotSet_issue6868() throws JsonProcessingException {
|
||||
TableRepository outerObject = new TableRepository(mock(CollectionDAO.class));
|
||||
Table origTable = new Table().withFullyQualifiedName("service.db.table");
|
||||
TableRepository.TableUpdater tableUpdater =
|
||||
outerObject.new TableUpdater(origTable, new Table(), EntityRepository.Operation.PUT);
|
||||
Column origColumn = new Column().withFullyQualifiedName("service.db.table.column");
|
||||
Column newColumn = new Column().withFullyQualifiedName("service.db.table.column").withDataLength(100);
|
||||
tableUpdater.updateColumnDataLength(origColumn, newColumn);
|
||||
assertTrue(tableUpdater.majorVersionChange);
|
||||
}
|
||||
}
|
||||
@ -41,6 +41,7 @@ import static org.openmetadata.catalog.exception.CatalogExceptionMessage.readOnl
|
||||
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
|
||||
import static org.openmetadata.catalog.security.SecurityUtil.getPrincipalName;
|
||||
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.BOT_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.ENTITY_NAME_LENGTH_ERROR;
|
||||
import static org.openmetadata.catalog.util.TestUtils.LONG_ENTITY_NAME;
|
||||
import static org.openmetadata.catalog.util.TestUtils.NON_EXISTENT_ENTITY;
|
||||
@ -104,13 +105,6 @@ import org.openmetadata.catalog.entity.data.GlossaryTerm;
|
||||
import org.openmetadata.catalog.entity.data.Table;
|
||||
import org.openmetadata.catalog.entity.policies.Policy;
|
||||
import org.openmetadata.catalog.entity.policies.accessControl.Rule;
|
||||
import org.openmetadata.catalog.entity.services.DashboardService;
|
||||
import org.openmetadata.catalog.entity.services.DatabaseService;
|
||||
import org.openmetadata.catalog.entity.services.MessagingService;
|
||||
import org.openmetadata.catalog.entity.services.MlModelService;
|
||||
import org.openmetadata.catalog.entity.services.PipelineService;
|
||||
import org.openmetadata.catalog.entity.services.StorageService;
|
||||
import org.openmetadata.catalog.entity.services.ingestionPipelines.IngestionPipeline;
|
||||
import org.openmetadata.catalog.entity.teams.Role;
|
||||
import org.openmetadata.catalog.entity.teams.Team;
|
||||
import org.openmetadata.catalog.entity.teams.User;
|
||||
@ -185,6 +179,7 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
public static User USER2;
|
||||
public static EntityReference USER2_REF;
|
||||
public static User USER_TEAM21;
|
||||
public static User BOT_USER;
|
||||
|
||||
public static Team ORG_TEAM;
|
||||
public static Team TEAM1;
|
||||
@ -352,6 +347,9 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
}
|
||||
|
||||
public final K createRequest(String name, String description, String displayName, EntityReference owner) {
|
||||
if (!supportsEmptyDescription && description == null) {
|
||||
throw new IllegalArgumentException("Entity " + entityType + " does not support empty description");
|
||||
}
|
||||
return createRequest(name)
|
||||
.withDescription(description)
|
||||
.withDisplayName(displayName)
|
||||
@ -383,17 +381,22 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
public abstract void validateCreatedEntity(T createdEntity, K request, Map<String, String> authHeaders)
|
||||
throws HttpResponseException;
|
||||
|
||||
// Entity specific validate for entity create using PUT
|
||||
public void validateUpdatedEntity(T updatedEntity, K request, Map<String, String> authHeaders)
|
||||
// Entity specific validate for entity created using PUT
|
||||
public void validateUpdatedEntity(T updatedEntity, K request, Map<String, String> authHeaders, UpdateType updateType)
|
||||
throws HttpResponseException {
|
||||
validateCommonEntityFields(updatedEntity, request, authHeaders);
|
||||
if (updateType == NO_CHANGE) {
|
||||
// Check updated entity only when a change is made
|
||||
assertListNotNull(updatedEntity.getId(), updatedEntity.getHref(), updatedEntity.getFullyQualifiedName());
|
||||
return;
|
||||
}
|
||||
validateCommonEntityFields(updatedEntity, request, getPrincipalName(authHeaders));
|
||||
validateCreatedEntity(updatedEntity, request, authHeaders);
|
||||
}
|
||||
|
||||
protected void validateDeletedEntity(
|
||||
K create, T entityBeforeDeletion, T entityAfterDeletion, Map<String, String> authHeaders)
|
||||
throws HttpResponseException {
|
||||
validateCommonEntityFields(entityAfterDeletion, create, authHeaders);
|
||||
validateCommonEntityFields(entityAfterDeletion, create, getPrincipalName(authHeaders));
|
||||
validateCreatedEntity(entityAfterDeletion, create, authHeaders);
|
||||
}
|
||||
|
||||
@ -993,31 +996,32 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
@Test
|
||||
void put_entityNonEmptyDescriptionUpdate_200(TestInfo test) throws IOException {
|
||||
// Create entity with non-empty description
|
||||
K request = createRequest(getEntityName(test), "description", "displayName", null);
|
||||
K request = createRequest(getEntityName(test), supportsEmptyDescription ? null : "description", null, null);
|
||||
T entity = createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Update non-empty description with a new description
|
||||
Double oldVersion = entity.getVersion();
|
||||
request = createRequest(getEntityName(test), "updatedDescription", "displayName", null);
|
||||
entity = updateEntity(request, OK, ADMIN_AUTH_HEADERS);
|
||||
// For service resources, we allow update of non-empty description via PUT
|
||||
List<Class<?>> services =
|
||||
Arrays.asList(
|
||||
DatabaseService.class,
|
||||
PipelineService.class,
|
||||
StorageService.class,
|
||||
DashboardService.class,
|
||||
MessagingService.class,
|
||||
IngestionPipeline.class,
|
||||
MlModelService.class,
|
||||
Type.class);
|
||||
if (services.contains(entity.getClass())) {
|
||||
assertNotEquals(oldVersion, entity.getVersion()); // Version did change
|
||||
assertEquals("updatedDescription", entity.getDescription()); // Description did change
|
||||
} else {
|
||||
assertEquals(oldVersion, entity.getVersion()); // Version did not change
|
||||
assertEquals("description", entity.getDescription()); // Description did not change
|
||||
// BOT user can update empty description and empty displayName
|
||||
ChangeDescription change = getChangeDescription(entity.getVersion());
|
||||
request = createRequest(getEntityName(test), "description", "displayName", null);
|
||||
if (supportsEmptyDescription) {
|
||||
change.getFieldsAdded().add(new FieldChange().withName("description").withNewValue("description"));
|
||||
}
|
||||
change.getFieldsAdded().add(new FieldChange().withName("displayName").withNewValue("displayName"));
|
||||
entity = updateAndCheckEntity(request, OK, BOT_AUTH_HEADERS, MINOR_UPDATE, change);
|
||||
|
||||
// Updating non-empty description and non-empty displayName is allowed for users other than bots
|
||||
request = createRequest(getEntityName(test), "updatedDescription", "updatedDisplayName", null);
|
||||
change = getChangeDescription(entity.getVersion());
|
||||
change
|
||||
.getFieldsAdded()
|
||||
.add(new FieldChange().withName("description").withOldValue("description").withNewValue("updatedDescription"));
|
||||
change
|
||||
.getFieldsAdded()
|
||||
.add(new FieldChange().withName("displayName").withOldValue("displayName").withNewValue("updatedDisplayName"));
|
||||
updateAndCheckEntity(request, OK, ADMIN_AUTH_HEADERS, NO_CHANGE, null);
|
||||
|
||||
// Updating non-empty description and non-empty displayName is not allowed for bot users
|
||||
request = createRequest(getEntityName(test), "updatedDescription2", "updatedDisplayName2", null);
|
||||
updateAndCheckEntity(request, OK, BOT_AUTH_HEADERS, NO_CHANGE, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1322,10 +1326,16 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
entity = patchEntity(entity.getId(), json, entity, ADMIN_AUTH_HEADERS);
|
||||
assertEquals(JsonUtils.valueToTree(jsonNode), JsonUtils.valueToTree(entity.getExtension()));
|
||||
|
||||
// PUT and remove field intA from the the entity extension
|
||||
// TODO to do change description for stored customProperties
|
||||
// PUT and remove field intA from the entity extension - for BOT this should be ignored
|
||||
JsonNode oldNode = JsonUtils.valueToTree(entity.getExtension());
|
||||
jsonNode.remove("intA");
|
||||
create = createRequest(test).withExtension(jsonNode);
|
||||
entity = updateEntity(create, Status.OK, BOT_AUTH_HEADERS);
|
||||
assertNotEquals(JsonUtils.valueToTree(create.getExtension()), JsonUtils.valueToTree(entity.getExtension()));
|
||||
assertEquals(oldNode, JsonUtils.valueToTree(entity.getExtension())); // Extension remains as is
|
||||
|
||||
// PUT and remove field intA from the the entity extension
|
||||
// TODO to do change description for stored customProperties
|
||||
entity = updateEntity(create, Status.OK, ADMIN_AUTH_HEADERS);
|
||||
assertEquals(JsonUtils.valueToTree(create.getExtension()), JsonUtils.valueToTree(entity.getExtension()));
|
||||
|
||||
@ -1596,31 +1606,27 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
return entity;
|
||||
}
|
||||
|
||||
public final T createAndCheckEntity(K create, Map<String, String> authHeaders) throws IOException {
|
||||
return createAndCheckEntity(create, authHeaders, create);
|
||||
}
|
||||
|
||||
/** Helper function to create an entity, submit POST API request and validate response. */
|
||||
public final T createAndCheckEntity(K create, Map<String, String> authHeaders, K created) throws IOException {
|
||||
public final T createAndCheckEntity(K create, Map<String, String> authHeaders) throws IOException {
|
||||
// Validate an entity that is created has all the information set in create request
|
||||
String updatedBy = SecurityUtil.getPrincipalName(authHeaders);
|
||||
T entity = createEntity(create, authHeaders);
|
||||
|
||||
assertEquals(updatedBy, entity.getUpdatedBy());
|
||||
assertEquals(0.1, entity.getVersion()); // First version of the entity
|
||||
validateCommonEntityFields(entity, created, authHeaders);
|
||||
validateCreatedEntity(entity, created, authHeaders);
|
||||
validateCommonEntityFields(entity, create, updatedBy);
|
||||
validateCreatedEntity(entity, create, authHeaders);
|
||||
|
||||
// GET the entity created and ensure it has all the information set in create request
|
||||
T getEntity = getEntity(entity.getId(), authHeaders);
|
||||
assertEquals(0.1, entity.getVersion()); // First version of the entity
|
||||
validateCommonEntityFields(entity, created, authHeaders);
|
||||
validateCreatedEntity(getEntity, created, authHeaders);
|
||||
validateCommonEntityFields(entity, create, updatedBy);
|
||||
validateCreatedEntity(getEntity, create, authHeaders);
|
||||
|
||||
getEntity = getEntityByName(entity.getFullyQualifiedName(), allFields, authHeaders);
|
||||
assertEquals(0.1, entity.getVersion()); // First version of the entity
|
||||
validateCommonEntityFields(entity, created, authHeaders);
|
||||
validateCreatedEntity(getEntity, created, authHeaders);
|
||||
validateCommonEntityFields(entity, create, updatedBy);
|
||||
validateCreatedEntity(getEntity, create, authHeaders);
|
||||
|
||||
// Validate that change event was created
|
||||
validateChangeEvents(entity, entity.getUpdatedAt(), EventType.ENTITY_CREATED, null, authHeaders);
|
||||
@ -1635,14 +1641,14 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
ChangeDescription changeDescription)
|
||||
throws IOException {
|
||||
T updated = updateEntity(request, status, authHeaders);
|
||||
validateUpdatedEntity(updated, request, authHeaders);
|
||||
validateUpdatedEntity(updated, request, authHeaders, updateType);
|
||||
validateChangeDescription(updated, updateType, changeDescription);
|
||||
validateEntityHistory(updated.getId(), updateType, changeDescription, authHeaders);
|
||||
validateLatestVersion(updated, updateType, changeDescription, authHeaders);
|
||||
|
||||
// GET the newly updated entity and validate
|
||||
T getEntity = getEntity(updated.getId(), authHeaders);
|
||||
validateUpdatedEntity(getEntity, request, authHeaders);
|
||||
validateUpdatedEntity(getEntity, request, authHeaders, updateType);
|
||||
validateChangeDescription(getEntity, updateType, changeDescription);
|
||||
|
||||
// Check if the entity change events are record
|
||||
@ -1699,10 +1705,12 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
ChangeDescription expectedChange)
|
||||
throws IOException {
|
||||
|
||||
String updatedBy = updateType == NO_CHANGE ? updated.getUpdatedBy() : getPrincipalName(authHeaders);
|
||||
|
||||
// Validate information returned in patch response has the updates
|
||||
T returned = patchEntity(updated.getId(), originalJson, updated, authHeaders);
|
||||
|
||||
validateCommonEntityFields(updated, returned, authHeaders);
|
||||
validateCommonEntityFields(updated, returned, updatedBy);
|
||||
compareEntities(updated, returned, authHeaders);
|
||||
validateChangeDescription(returned, updateType, expectedChange);
|
||||
validateEntityHistory(returned.getId(), updateType, expectedChange, authHeaders);
|
||||
@ -1710,7 +1718,7 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
|
||||
// GET the entity and Validate information returned
|
||||
T getEntity = getEntity(returned.getId(), authHeaders);
|
||||
validateCommonEntityFields(updated, returned, authHeaders);
|
||||
validateCommonEntityFields(updated, returned, updatedBy);
|
||||
compareEntities(updated, getEntity, authHeaders);
|
||||
validateChangeDescription(getEntity, updateType, expectedChange);
|
||||
|
||||
@ -1748,24 +1756,24 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
entity, originalJson, authHeaders(userName + "@open-metadata.org"), MINOR_UPDATE, change);
|
||||
}
|
||||
|
||||
protected final void validateCommonEntityFields(T entity, CreateEntity create, Map<String, String> authHeaders) {
|
||||
protected final void validateCommonEntityFields(T entity, CreateEntity create, String updatedBy) {
|
||||
assertListNotNull(entity.getId(), entity.getHref(), entity.getFullyQualifiedName());
|
||||
assertEquals(create.getName(), entity.getName());
|
||||
assertEquals(create.getDisplayName(), entity.getDisplayName());
|
||||
assertEquals(create.getDescription(), entity.getDescription());
|
||||
assertEquals(JsonUtils.valueToTree(create.getExtension()), JsonUtils.valueToTree(entity.getExtension()));
|
||||
assertReference(create.getOwner(), entity.getOwner());
|
||||
assertEquals(getPrincipalName(authHeaders), entity.getUpdatedBy());
|
||||
assertEquals(updatedBy, entity.getUpdatedBy());
|
||||
}
|
||||
|
||||
protected final void validateCommonEntityFields(T expected, T actual, Map<String, String> authHeaders) {
|
||||
protected final void validateCommonEntityFields(T expected, T actual, String updatedBy) {
|
||||
assertListNotNull(actual.getId(), actual.getHref(), actual.getFullyQualifiedName());
|
||||
assertEquals(expected.getName(), actual.getName());
|
||||
assertEquals(expected.getDisplayName(), actual.getDisplayName());
|
||||
assertEquals(expected.getDescription(), actual.getDescription());
|
||||
assertEquals(JsonUtils.valueToTree(expected.getExtension()), JsonUtils.valueToTree(actual.getExtension()));
|
||||
assertReference(expected.getOwner(), actual.getOwner());
|
||||
assertEquals(getPrincipalName(authHeaders), actual.getUpdatedBy());
|
||||
assertEquals(updatedBy, actual.getUpdatedBy());
|
||||
}
|
||||
|
||||
protected final void validateChangeDescription(T updated, UpdateType updateType, ChangeDescription expectedChange)
|
||||
@ -1773,9 +1781,9 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
if (updateType == UpdateType.CREATED) {
|
||||
return; // PUT operation was used to create an entity. No change description expected.
|
||||
}
|
||||
TestUtils.validateUpdate(expectedChange.getPreviousVersion(), updated.getVersion(), updateType);
|
||||
|
||||
if (updateType != UpdateType.NO_CHANGE) {
|
||||
TestUtils.validateUpdate(expectedChange.getPreviousVersion(), updated.getVersion(), updateType);
|
||||
assertChangeDescription(expectedChange, updated.getChangeDescription());
|
||||
}
|
||||
}
|
||||
@ -1866,7 +1874,7 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
|
||||
assertEquals(0.1, changeEvent.getPreviousVersion());
|
||||
assertNull(changeEvent.getChangeDescription());
|
||||
T changeEventEntity = JsonUtils.readValue((String) changeEvent.getEntity(), entityClass);
|
||||
validateCommonEntityFields(entity, changeEventEntity, authHeaders);
|
||||
validateCommonEntityFields(entity, changeEventEntity, getPrincipalName(authHeaders));
|
||||
compareChangeEventsEntities(entity, changeEventEntity, authHeaders);
|
||||
} else if (expectedEventType == EventType.ENTITY_UPDATED) {
|
||||
assertChangeDescription(expectedChangeDescription, changeEvent.getChangeDescription());
|
||||
|
||||
@ -38,6 +38,13 @@ class BotResourceTest extends EntityResourceTest<Bot, CreateBot> {
|
||||
botUserRef = botUser.getEntityReference();
|
||||
}
|
||||
|
||||
@Test
|
||||
void put_entityNonEmptyDescriptionUpdate_200(TestInfo test) throws IOException {
|
||||
// PUT based updates are categorized as create operation
|
||||
// PUT from a bot to update itself is rejected because of that
|
||||
// TODO turning off the test for now which requires BOT to make update using PUT
|
||||
}
|
||||
|
||||
@Test
|
||||
void delete_ensureBotUserDelete(TestInfo test) throws IOException {
|
||||
UserResourceTest userResourceTest = new UserResourceTest();
|
||||
|
||||
@ -41,6 +41,7 @@ import static org.openmetadata.catalog.util.EntityUtil.tagLabelMatch;
|
||||
import static org.openmetadata.catalog.util.FullyQualifiedName.build;
|
||||
import static org.openmetadata.catalog.util.RestUtil.DATE_FORMAT;
|
||||
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.BOT_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.NON_EXISTENT_ENTITY;
|
||||
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.UpdateType;
|
||||
@ -290,117 +291,118 @@ public class TableResourceTest extends EntityResourceTest<Table, CreateTable> {
|
||||
@Test
|
||||
void put_tableWithColumnWithOrdinalPositionAndWithoutOrdinalPosition(TestInfo test) throws IOException {
|
||||
CreateTable create = createRequest(test);
|
||||
List<Column> columns = new ArrayList<>();
|
||||
Column column1 = getColumn("column1", INT, null).withOrdinalPosition(1).withDescription("column1");
|
||||
Column column2 = getColumn("column2", INT, null).withOrdinalPosition(2).withDescription("column2");
|
||||
List<Column> origColumns = new ArrayList<>();
|
||||
origColumns.add(column1);
|
||||
origColumns.add(column2);
|
||||
// add 2 columns
|
||||
columns.add(column1);
|
||||
columns.add(column2);
|
||||
Column column1 = getColumn("column1", INT, null, "column1", "c1").withOrdinalPosition(1);
|
||||
Column column2 = getColumn("column2", INT, null, "column2", "c2").withOrdinalPosition(2);
|
||||
Column column3 =
|
||||
getColumn("column3", STRING, null, "column3", null)
|
||||
.withOrdinalPosition(3)
|
||||
.withTags(List.of(USER_ADDRESS_TAG_LABEL, GLOSSARY1_TERM1_LABEL));
|
||||
|
||||
TableConstraint constraint =
|
||||
new TableConstraint().withConstraintType(ConstraintType.UNIQUE).withColumns(List.of(columns.get(0).getName()));
|
||||
new TableConstraint().withConstraintType(ConstraintType.UNIQUE).withColumns(List.of(column1.getName()));
|
||||
TablePartition partition =
|
||||
new TablePartition()
|
||||
.withColumns(List.of(columns.get(0).getName(), columns.get(1).getName()))
|
||||
.withColumns(List.of(column1.getName(), column2.getName()))
|
||||
.withIntervalType(TablePartition.IntervalType.COLUMN_VALUE)
|
||||
.withInterval("column");
|
||||
create.setColumns(columns);
|
||||
|
||||
//
|
||||
// Create a table with two columns - column1, column2, table constraint and table partition
|
||||
//
|
||||
create.setColumns(new ArrayList<>(List.of(column1, column2)));
|
||||
create.setTableConstraints(List.of(constraint));
|
||||
create.setTablePartition(partition);
|
||||
Table created = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
|
||||
Column column = created.getColumns().get(0);
|
||||
assertEquals("column1", column.getName());
|
||||
assertEquals("column1", column.getDescription());
|
||||
assertTablePartition(partition, created.getTablePartition());
|
||||
createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// keep original ordinalPosition add a column at the end and do not pass descriptions for the first 2 columns
|
||||
// we should retain the original description
|
||||
//
|
||||
// Update the column description and display name as a BOT user.
|
||||
// The updates are ignored for a BOT user and the table version does not change
|
||||
//
|
||||
create.getColumns().set(0, getColumn("column1", INT, null, "x", "y"));
|
||||
Table table = updateAndCheckEntity(create, OK, BOT_AUTH_HEADERS, NO_CHANGE, null);
|
||||
create.getColumns().set(0, column1); // Revert to previous value
|
||||
|
||||
Column updateColumn1 = getColumn("column1", INT, null).withOrdinalPosition(1).withDescription("");
|
||||
Column updateColumn2 = getColumn("column2", INT, null).withOrdinalPosition(2).withDescription("");
|
||||
Column column3 =
|
||||
getColumn("column3", STRING, null)
|
||||
.withOrdinalPosition(3)
|
||||
.withDescription("column3")
|
||||
.withTags(List.of(USER_ADDRESS_TAG_LABEL, GLOSSARY1_TERM1_LABEL));
|
||||
columns = new ArrayList<>();
|
||||
columns.add(updateColumn1);
|
||||
columns.add(updateColumn2);
|
||||
columns.add(column3);
|
||||
//
|
||||
// Description and DisplayName can be updated by a non-bot user
|
||||
// Update column1 description and displayName.
|
||||
// Remove column2 display name.
|
||||
// Add a new column column3.
|
||||
// Update table partition
|
||||
//
|
||||
column1.withDescription("").withDisplayName("");
|
||||
column2.withDisplayName(null);
|
||||
create.getColumns().add(column3);
|
||||
partition =
|
||||
new TablePartition()
|
||||
.withColumns(List.of(columns.get(2).getName()))
|
||||
.withColumns(List.of(column3.getName()))
|
||||
.withIntervalType(TablePartition.IntervalType.COLUMN_VALUE)
|
||||
.withInterval("column");
|
||||
create.setColumns(columns);
|
||||
create.setTableConstraints(List.of(constraint));
|
||||
create.setTablePartition(partition);
|
||||
// Update the table with constraints and ensure minor version change
|
||||
ChangeDescription change = getChangeDescription(created.getVersion());
|
||||
|
||||
ChangeDescription change = getChangeDescription(table.getVersion());
|
||||
change.getFieldsAdded().add(new FieldChange().withName("columns").withNewValue(List.of(column3)));
|
||||
Table updatedTable = updateEntity(create, OK, ADMIN_AUTH_HEADERS);
|
||||
origColumns.add(column3);
|
||||
assertColumns(origColumns, updatedTable.getColumns());
|
||||
assertTablePartition(partition, updatedTable.getTablePartition());
|
||||
Table getTable = getEntity(updatedTable.getId(), "tablePartition", ADMIN_AUTH_HEADERS);
|
||||
assertTablePartition(partition, getTable.getTablePartition());
|
||||
change
|
||||
.getFieldsUpdated()
|
||||
.add(
|
||||
new FieldChange()
|
||||
.withName(build("columns", "column1", "description"))
|
||||
.withOldValue("column1")
|
||||
.withNewValue(""));
|
||||
change
|
||||
.getFieldsUpdated()
|
||||
.add(
|
||||
new FieldChange().withName(build("columns", "column1", "displayName")).withOldValue("c1").withNewValue(""));
|
||||
change
|
||||
.getFieldsDeleted()
|
||||
.add(new FieldChange().withName(build("columns", "column2", "displayName")).withOldValue("c2"));
|
||||
table = updateAndCheckEntity(create, OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
|
||||
|
||||
TestUtils.validateUpdate(created.getVersion(), updatedTable.getVersion(), MINOR_UPDATE);
|
||||
// keep ordinalPosition and add a column in between
|
||||
updateColumn1 = getColumn("column1", INT, null).withOrdinalPosition(1).withDescription("");
|
||||
Column updateColumn4 = getColumn("column4", STRING, null).withOrdinalPosition(2).withDescription("column4");
|
||||
updateColumn2 = getColumn("column2", INT, null).withOrdinalPosition(3).withDescription("");
|
||||
Column updateColumn3 = getColumn("column3", STRING, null).withOrdinalPosition(4).withDescription("");
|
||||
columns = new ArrayList<>();
|
||||
columns.add(updateColumn1);
|
||||
columns.add(updateColumn2);
|
||||
columns.add(updateColumn4);
|
||||
columns.add(updateColumn3);
|
||||
create.setColumns(columns);
|
||||
create.setTableConstraints(List.of(constraint));
|
||||
//
|
||||
// Change the ordinal position of column2 from 2 to 3.
|
||||
// Change the ordinal position of column3 from 3 to 4.
|
||||
// Add column4 with ordinal position 3.
|
||||
//
|
||||
// After the update: TODO is this correct?
|
||||
// Column 3 must retain the ordinal position as 3
|
||||
// Column 4 must change to ordinal position as 4
|
||||
//
|
||||
column2.setOrdinalPosition(3);
|
||||
column3.setOrdinalPosition(4);
|
||||
Column column4 = getColumn("column4", STRING, null, "column4", null).withOrdinalPosition(2);
|
||||
create.getColumns().add(2, column4);
|
||||
|
||||
Double prevVersion = updatedTable.getVersion();
|
||||
updatedTable = updateEntity(create, OK, ADMIN_AUTH_HEADERS);
|
||||
TestUtils.validateUpdate(prevVersion, updatedTable.getVersion(), MINOR_UPDATE);
|
||||
origColumns.add(2, updateColumn4);
|
||||
assertColumns(origColumns, updatedTable.getColumns());
|
||||
change = getChangeDescription(table.getVersion());
|
||||
change.getFieldsAdded().add(new FieldChange().withName("columns").withNewValue(List.of(column4)));
|
||||
table = updateAndCheckEntity(create, OK, ADMIN_AUTH_HEADERS, MINOR_UPDATE, change);
|
||||
|
||||
// Change data type to cause major update
|
||||
updateColumn3 = getColumn("column3", INT, null).withOrdinalPosition(4).withDescription("");
|
||||
columns = new ArrayList<>();
|
||||
columns.add(updateColumn1);
|
||||
columns.add(updateColumn2);
|
||||
columns.add(updateColumn4);
|
||||
columns.add(updateColumn3);
|
||||
create.setColumns(columns);
|
||||
create.setTableConstraints(List.of(constraint));
|
||||
prevVersion = updatedTable.getVersion();
|
||||
updatedTable = updateEntity(create, OK, ADMIN_AUTH_HEADERS);
|
||||
TestUtils.validateUpdate(prevVersion, updatedTable.getVersion(), MAJOR_UPDATE);
|
||||
origColumns.remove(3);
|
||||
origColumns.add(3, column3.withDataType(INT));
|
||||
assertColumns(origColumns, updatedTable.getColumns());
|
||||
// Change column1 data type from INT to STRING to cause major update
|
||||
Column updatedColumn1 = getColumn("column1", STRING, null, "column1", "c1").withOrdinalPosition(1);
|
||||
create.getColumns().set(0, updatedColumn1);
|
||||
change = getChangeDescription(table.getVersion());
|
||||
change.getFieldsDeleted().add(new FieldChange().withName("columns").withOldValue(List.of(column1)));
|
||||
change.getFieldsAdded().add(new FieldChange().withName("columns").withNewValue(List.of(updatedColumn1)));
|
||||
table = updateAndCheckEntity(create, OK, ADMIN_AUTH_HEADERS, MAJOR_UPDATE, change);
|
||||
|
||||
// Change the case of the column name and it should't update
|
||||
updateColumn2 = getColumn("COLUMN2", INT, null).withOrdinalPosition(2).withDescription("");
|
||||
columns = new ArrayList<>();
|
||||
columns.add(updateColumn1);
|
||||
columns.add(updateColumn2);
|
||||
columns.add(updateColumn4);
|
||||
columns.add(updateColumn3);
|
||||
create.setColumns(columns);
|
||||
create.setTableConstraints(List.of(constraint));
|
||||
prevVersion = updatedTable.getVersion();
|
||||
updatedTable = updateEntity(create, OK, ADMIN_AUTH_HEADERS);
|
||||
TestUtils.validateUpdate(prevVersion, updatedTable.getVersion(), NO_CHANGE);
|
||||
// Delete column4 to cause major update
|
||||
create.getColumns().remove(2);
|
||||
change = getChangeDescription(table.getVersion());
|
||||
change.getFieldsDeleted().add(new FieldChange().withName("columns").withOldValue(List.of(column4)));
|
||||
updateAndCheckEntity(create, OK, ADMIN_AUTH_HEADERS, MAJOR_UPDATE, change);
|
||||
|
||||
// Change the case of the column name for column2, and it shouldn't update
|
||||
column2.setName("COLUMN2");
|
||||
updateAndCheckEntity(create, OK, ADMIN_AUTH_HEADERS, NO_CHANGE, null);
|
||||
}
|
||||
|
||||
public static Column getColumn(String name, ColumnDataType columnDataType, TagLabel tag) {
|
||||
return getColumn(name, columnDataType, null, tag);
|
||||
}
|
||||
|
||||
public static Column getColumn(
|
||||
String name, ColumnDataType columnDataType, TagLabel tag, String description, String displayName) {
|
||||
return getColumn(name, columnDataType, null, tag).withDescription(description).withDisplayName(displayName);
|
||||
}
|
||||
|
||||
private static Column getColumn(String name, ColumnDataType columnDataType, String dataTypeDisplay, TagLabel tag) {
|
||||
List<TagLabel> tags = tag == null ? new ArrayList<>() : singletonList(tag);
|
||||
return new Column()
|
||||
@ -1991,14 +1993,19 @@ public class TableResourceTest extends EntityResourceTest<Table, CreateTable> {
|
||||
|
||||
private static void assertColumns(List<Column> expectedColumns, List<Column> actualColumns)
|
||||
throws HttpResponseException {
|
||||
if (expectedColumns == null && actualColumns == null) {
|
||||
if (expectedColumns == actualColumns) {
|
||||
return;
|
||||
}
|
||||
// Sort columns by name
|
||||
assertNotNull(expectedColumns);
|
||||
assertEquals(expectedColumns.size(), actualColumns.size());
|
||||
for (int i = 0; i < expectedColumns.size(); i++) {
|
||||
assertColumn(expectedColumns.get(i), actualColumns.get(i));
|
||||
|
||||
// Make a copy before sorting in case the lists are immutable
|
||||
List<Column> expected = new ArrayList<>(expectedColumns);
|
||||
List<Column> actual = new ArrayList<>(actualColumns);
|
||||
expected.sort(Comparator.comparing(Column::getName));
|
||||
actual.sort(Comparator.comparing(Column::getName));
|
||||
for (int i = 0; i < expected.size(); i++) {
|
||||
assertColumn(expected.get(i), actual.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2353,6 +2360,7 @@ public class TableResourceTest extends EntityResourceTest<Table, CreateTable> {
|
||||
validateEntityReference(createdEntity.getDatabase());
|
||||
validateEntityReference(createdEntity.getService());
|
||||
validateTableConstraints(createRequest.getTableConstraints(), createdEntity.getTableConstraints());
|
||||
assertTablePartition(createRequest.getTablePartition(), createdEntity.getTablePartition());
|
||||
TestUtils.validateTags(createRequest.getTags(), createdEntity.getTags());
|
||||
TestUtils.validateEntityReferences(createdEntity.getFollowers());
|
||||
assertListNotNull(createdEntity.getService(), createdEntity.getServiceType());
|
||||
@ -2421,12 +2429,15 @@ public class TableResourceTest extends EntityResourceTest<Table, CreateTable> {
|
||||
ColumnConstraint expectedConstraint = (ColumnConstraint) expected;
|
||||
ColumnConstraint actualConstraint = ColumnConstraint.fromValue((String) actual);
|
||||
assertEquals(expectedConstraint, actualConstraint);
|
||||
} else if (fieldName.startsWith("columns")
|
||||
&& (fieldName.endsWith("description") || fieldName.endsWith("displayName"))) {
|
||||
assertEquals(expected, actual);
|
||||
} else if (fieldName.endsWith("tableConstraints")) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<TableConstraint> expectedConstraints = (List<TableConstraint>) expected;
|
||||
List<TableConstraint> actualConstraints = JsonUtils.readObjects(actual.toString(), TableConstraint.class);
|
||||
assertEquals(expectedConstraints, actualConstraints);
|
||||
} else if (fieldName.contains("columns") && !fieldName.endsWith(FIELD_TAGS) && !fieldName.endsWith("description")) {
|
||||
} else if (fieldName.contains("columns") && !fieldName.endsWith(FIELD_TAGS)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Column> expectedRefs = (List<Column>) expected;
|
||||
List<Column> actualRefs = JsonUtils.readObjects(actual.toString(), Column.class);
|
||||
|
||||
@ -4,6 +4,7 @@ import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
|
||||
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
|
||||
import static javax.ws.rs.core.Response.Status.OK;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.openmetadata.catalog.security.SecurityUtil.getPrincipalName;
|
||||
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
|
||||
import static org.openmetadata.catalog.util.TestUtils.assertResponseContains;
|
||||
@ -428,7 +429,7 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
|
||||
@Override
|
||||
public void validateCreatedEntity(TestCase createdEntity, CreateTestCase request, Map<String, String> authHeaders)
|
||||
throws HttpResponseException {
|
||||
validateCommonEntityFields(createdEntity, request, authHeaders);
|
||||
validateCommonEntityFields(createdEntity, request, getPrincipalName(authHeaders));
|
||||
assertEquals(request.getEntityLink(), createdEntity.getEntityLink());
|
||||
assertEquals(request.getTestSuite(), createdEntity.getTestSuite());
|
||||
assertEquals(request.getTestDefinition(), createdEntity.getTestDefinition());
|
||||
@ -439,7 +440,7 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
|
||||
@Override
|
||||
public void compareEntities(TestCase expected, TestCase updated, Map<String, String> authHeaders)
|
||||
throws HttpResponseException {
|
||||
validateCommonEntityFields(expected, updated, authHeaders);
|
||||
validateCommonEntityFields(expected, updated, getPrincipalName(authHeaders));
|
||||
assertEquals(expected.getEntityLink(), updated.getEntityLink());
|
||||
assertEquals(expected.getTestSuite(), updated.getTestSuite());
|
||||
assertEquals(expected.getTestDefinition(), updated.getTestDefinition());
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
package org.openmetadata.catalog.resources.locations;
|
||||
|
||||
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
|
||||
import static javax.ws.rs.core.Response.Status.OK;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.assertListNotNull;
|
||||
@ -189,17 +188,6 @@ public class LocationResourceTest extends EntityResourceTest<Location, CreateLoc
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void put_locationNonEmptyDescriptionUpdate_200(TestInfo test) throws IOException {
|
||||
CreateLocation request =
|
||||
createRequest(test).withService(AWS_STORAGE_SERVICE_REFERENCE).withDescription("description");
|
||||
createAndCheckEntity(request, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Updating description is ignored when backend already has description
|
||||
Location location = updateLocation(request.withDescription("newDescription"), OK, ADMIN_AUTH_HEADERS);
|
||||
assertEquals("description", location.getDescription());
|
||||
}
|
||||
|
||||
public static Location updateLocation(CreateLocation create, Status status, Map<String, String> authHeaders)
|
||||
throws HttpResponseException {
|
||||
return TestUtils.put(getResource("locations"), create, Location.class, status, authHeaders);
|
||||
|
||||
@ -187,7 +187,6 @@ public class PolicyResourceTest extends EntityResourceTest<Policy, CreatePolicy>
|
||||
|
||||
// Ensure validation API works for the valid conditions
|
||||
for (String condition : List.of("isOwner()", "!isOwner()", "noOwner()", "isOwner() || noOwner()")) {
|
||||
System.out.println("XXX condition " + condition);
|
||||
validateCondition(condition); // No exception should be thrown
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.BOT_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
|
||||
|
||||
@ -231,7 +232,7 @@ public class DashboardServiceResourceTest extends EntityResourceTest<DashboardSe
|
||||
}
|
||||
assertEquals(expectedSupersetConnection.getHostPort(), actualSupersetConnection.getHostPort());
|
||||
assertEquals(expectedSupersetConnection.getProvider(), actualSupersetConnection.getProvider());
|
||||
if (ADMIN_AUTH_HEADERS.equals(authHeaders)) {
|
||||
if (ADMIN_AUTH_HEADERS.equals(authHeaders) || BOT_AUTH_HEADERS.equals(authHeaders)) {
|
||||
assertEquals(expectedSupersetConnection.getUsername(), actualSupersetConnection.getUsername());
|
||||
assertEquals(expectedSupersetConnection.getPassword(), actualSupersetConnection.getPassword());
|
||||
assertEquals(expectedSupersetConnection.getProvider(), actualSupersetConnection.getProvider());
|
||||
|
||||
@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.openmetadata.catalog.resources.services.DatabaseServiceResourceTest.validateMysqlConnection;
|
||||
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.AIRFLOW_CONNECTION;
|
||||
import static org.openmetadata.catalog.util.TestUtils.BOT_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.MYSQL_DATABASE_CONNECTION;
|
||||
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
|
||||
@ -274,7 +275,7 @@ public class PipelineServiceResourceTest extends EntityResourceTest<PipelineServ
|
||||
MysqlConnection expectedMysqlConnection = (MysqlConnection) expectedDatabaseConnection.getConfig();
|
||||
// Use the database service tests utilities for the comparison
|
||||
// only admin can see all connection parameters
|
||||
if (ADMIN_AUTH_HEADERS.equals(authHeaders)) {
|
||||
if (ADMIN_AUTH_HEADERS.equals(authHeaders) || BOT_AUTH_HEADERS.equals(authHeaders)) {
|
||||
DatabaseConnection actualDatabaseConnection =
|
||||
JsonUtils.convertValue(actualAirflowConnection.getConnection(), DatabaseConnection.class);
|
||||
MysqlConnection actualMysqlConnection =
|
||||
|
||||
@ -31,6 +31,7 @@ import static org.openmetadata.catalog.exception.CatalogExceptionMessage.notAdmi
|
||||
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.permissionNotAllowed;
|
||||
import static org.openmetadata.catalog.security.SecurityUtil.authHeaders;
|
||||
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.BOT_USER_NAME;
|
||||
import static org.openmetadata.catalog.util.TestUtils.TEST_AUTH_HEADERS;
|
||||
import static org.openmetadata.catalog.util.TestUtils.TEST_USER_NAME;
|
||||
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MINOR_UPDATE;
|
||||
@ -122,6 +123,9 @@ public class UserResourceTest extends EntityResourceTest<User, CreateUser> {
|
||||
create = createRequest(test, 2).withTeams(List.of(TEAM21.getId()));
|
||||
USER_TEAM21 = createEntity(create, ADMIN_AUTH_HEADERS);
|
||||
USER2_REF = USER2.getEntityReference();
|
||||
|
||||
create = createRequest(BOT_USER_NAME).withIsBot(true);
|
||||
BOT_USER = createEntity(create, ADMIN_AUTH_HEADERS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -246,7 +250,7 @@ public class UserResourceTest extends EntityResourceTest<User, CreateUser> {
|
||||
CreateUser create = createRequest(test).withRoles(roles);
|
||||
List<UUID> createdRoles = Arrays.asList(role1.getId(), role2.getId());
|
||||
CreateUser created = createRequest(test).withRoles(createdRoles);
|
||||
User user = createAndCheckEntity(create, ADMIN_AUTH_HEADERS, created);
|
||||
User user = createAndCheckEntity(create, ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Ensure User has relationship to these roles
|
||||
String[] expectedRoles = createdRoles.stream().map(UUID::toString).sorted().toArray(String[]::new);
|
||||
|
||||
@ -82,6 +82,8 @@ public final class TestUtils {
|
||||
|
||||
public static final String ADMIN_USER_NAME = "admin";
|
||||
public static final Map<String, String> ADMIN_AUTH_HEADERS = authHeaders(ADMIN_USER_NAME + "@open-metadata.org");
|
||||
public static final String BOT_USER_NAME = "bot";
|
||||
public static final Map<String, String> BOT_AUTH_HEADERS = authHeaders(BOT_USER_NAME + "@open-metadata.org");
|
||||
public static final String TEST_USER_NAME = "test";
|
||||
public static final Map<String, String> TEST_AUTH_HEADERS = authHeaders(TEST_USER_NAME + "@open-metadata.org");
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user