Fixes #1001 - Move add and delete follower functionality based on EntityRepository

This commit is contained in:
sureshms 2021-10-31 13:41:49 -07:00
parent c83bb0f768
commit 24d6131553
27 changed files with 251 additions and 397 deletions

View File

@ -26,6 +26,7 @@ import org.openmetadata.catalog.util.EntityInterface;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
@ -108,6 +109,14 @@ public class BotsRepository extends EntityRepository<Bots>{
@Override
public Date getUpdatedAt() { return entity.getUpdatedAt(); }
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("Dashboard service does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -31,7 +31,6 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.JsonUtils;
import javax.ws.rs.core.Response.Status;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
@ -165,19 +164,6 @@ public class ChartRepository extends EntityRepository<Chart> {
return service;
}
@Transaction
public Status addFollower(UUID chartId, UUID userId) throws IOException {
dao.chartDAO().findEntityById(chartId);
return EntityUtil.addFollower(dao.relationshipDAO(), dao.userDAO(), chartId, Entity.CHART, userId, Entity.USER) ?
Status.CREATED : Status.OK;
}
@Transaction
public void deleteFollower(UUID chartId, UUID userId) {
EntityUtil.validateUser(dao.userDAO(), userId);
EntityUtil.removeFollower(dao.relationshipDAO(), chartId, userId);
}
public static class ChartEntityInterface implements EntityInterface<Chart> {
private final Chart entity;
@ -227,6 +213,9 @@ public class ChartRepository extends EntityRepository<Chart> {
return entity.getHref();
}
@Override
public List<EntityReference> getFollowers() { return entity.getFollowers(); }
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -30,7 +30,6 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.JsonUtils;
import javax.ws.rs.core.Response.Status;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
@ -62,20 +61,6 @@ public class DashboardRepository extends EntityRepository<Dashboard> {
return new DashboardEntityInterface(entity);
}
@Transaction
public Status addFollower(UUID dashboardId, UUID userId) throws IOException {
dao.dashboardDAO().findEntityById(dashboardId);
return EntityUtil.addFollower(dao.relationshipDAO(), dao.userDAO(), dashboardId, Entity.DASHBOARD, userId,
Entity.USER) ?
Status.CREATED : Status.OK;
}
@Transaction
public void deleteFollower(UUID dashboardId, UUID userId) {
EntityUtil.validateUser(dao.userDAO(), userId);
EntityUtil.removeFollower(dao.relationshipDAO(), dashboardId, userId);
}
@Transaction
public void delete(UUID id) {
if (dao.relationshipDAO().findToCount(id.toString(), Relationship.CONTAINS.ordinal(), Entity.DASHBOARD) > 0) {
@ -292,6 +277,9 @@ public class DashboardRepository extends EntityRepository<Dashboard> {
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() { return entity.getFollowers(); }
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -136,6 +136,14 @@ public class DashboardServiceRepository extends EntityRepository<DashboardServic
@Override
public Date getUpdatedAt() { return entity.getUpdatedAt(); }
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("Dashboard service does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -199,6 +199,11 @@ public class DatabaseRepository extends EntityRepository<Database> {
return entity.getHref();
}
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("Database does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -31,6 +31,7 @@ import org.openmetadata.catalog.util.JsonUtils;
import org.openmetadata.catalog.util.Utils;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
@ -134,6 +135,14 @@ public class DatabaseServiceRepository extends EntityRepository<DatabaseService>
@Override
public Date getUpdatedAt() { return entity.getUpdatedAt(); }
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("Database service does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -1,6 +1,7 @@
package org.openmetadata.catalog.jdbi3;
import org.jdbi.v3.sqlobject.transaction.Transaction;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.jdbi3.CollectionDAO.EntityVersionPair;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.EntityHistory;
@ -178,6 +179,19 @@ public abstract class EntityRepository<T> {
return updated;
}
@Transaction
public Status addFollower(UUID entityId, UUID userId) throws IOException {
dao.findEntityById(entityId);
return EntityUtil.addFollower(daoCollection.relationshipDAO(), daoCollection.userDAO(), entityId,
entityName, userId, Entity.USER) ? Status.CREATED : Status.OK;
}
@Transaction
public void deleteFollower(UUID entityId, UUID userId) {
EntityUtil.validateUser(daoCollection.userDAO(), userId);
EntityUtil.removeFollower(daoCollection.relationshipDAO(), entityId, userId);
}
public final String getFullyQualifiedName(T entity) {
return getEntityInterface(entity).getFullyQualifiedName();
}

View File

@ -137,6 +137,14 @@ public class MessagingServiceRepository extends EntityRepository<MessagingServic
@Override
public Date getUpdatedAt() { return entity.getUpdatedAt(); }
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("Messaging service does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -28,6 +28,7 @@ import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.JsonUtils;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
@ -175,6 +176,14 @@ public class MetricsRepository extends EntityRepository<Metrics> {
@Override
public Date getUpdatedAt() { return entity.getUpdatedAt(); }
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("Metrics does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -31,8 +31,8 @@ import org.openmetadata.catalog.util.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.core.Response.Status;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
@ -58,20 +58,6 @@ public class ModelRepository extends EntityRepository<Model> {
return (model.getName());
}
@Transaction
public Status addFollower(UUID modelId, UUID userId) throws IOException {
dao.modelDAO().findEntityById(modelId);
return EntityUtil.addFollower(dao.relationshipDAO(), dao.userDAO(), modelId, Entity.MODEL, userId,
Entity.USER) ?
Status.CREATED : Status.OK;
}
@Transaction
public void deleteFollower(UUID modelId, UUID userId) {
EntityUtil.validateUser(dao.userDAO(), userId);
EntityUtil.removeFollower(dao.relationshipDAO(), modelId, userId);
}
@Transaction
public void delete(UUID id) {
if (dao.relationshipDAO().findToCount(id.toString(), Relationship.CONTAINS.ordinal(), Entity.MODEL) > 0) {
@ -249,6 +235,12 @@ public class ModelRepository extends EntityRepository<Model> {
@Override
public Date getUpdatedAt() { return entity.getUpdatedAt(); }
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() { return entity.getFollowers(); }
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -31,7 +31,6 @@ import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.JsonUtils;
import javax.ws.rs.core.Response.Status;
import java.io.IOException;
import java.net.URI;
import java.text.ParseException;
@ -61,20 +60,6 @@ public class PipelineRepository extends EntityRepository<Pipeline> {
return (pipeline.getService().getName() + "." + pipeline.getName());
}
@Transaction
public Status addFollower(UUID pipelineId, UUID userId) throws IOException {
dao.pipelineDAO().findEntityById(pipelineId);
return EntityUtil.addFollower(dao.relationshipDAO(), dao.userDAO(), pipelineId, Entity.PIPELINE, userId,
Entity.USER) ?
Status.CREATED : Status.OK;
}
@Transaction
public void deleteFollower(UUID pipelineId, UUID userId) {
EntityUtil.validateUser(dao.userDAO(), userId);
EntityUtil.removeFollower(dao.relationshipDAO(), pipelineId, userId);
}
@Transaction
public void delete(UUID id) {
if (dao.relationshipDAO().findToCount(id.toString(), Relationship.CONTAINS.ordinal(), Entity.PIPELINE) > 0) {
@ -257,6 +242,9 @@ public class PipelineRepository extends EntityRepository<Pipeline> {
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() { return entity.getFollowers(); }
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -139,6 +139,14 @@ public class PipelineServiceRepository extends EntityRepository<PipelineService>
@Override
public Date getUpdatedAt() { return entity.getUpdatedAt(); }
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("Pipeline service does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -19,18 +19,15 @@ package org.openmetadata.catalog.jdbi3;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.entity.data.Report;
import org.openmetadata.catalog.resources.reports.ReportResource;
import org.openmetadata.catalog.resources.reports.ReportResource.ReportList;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.TagLabel;
import org.openmetadata.catalog.util.EntityInterface;
import org.openmetadata.catalog.util.EntityUtil;
import org.openmetadata.catalog.util.EntityUtil.Fields;
import org.openmetadata.catalog.util.ResultList;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.net.URI;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
@ -159,6 +156,14 @@ public class ReportRepository extends EntityRepository<Report> {
@Override
public Date getUpdatedAt() { return entity.getUpdatedAt(); }
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("Report does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -119,14 +119,6 @@ public class TableRepository extends EntityRepository<Table> {
dao.relationshipDAO().deleteAll(id.toString()); // Remove all relationships
}
@Transaction
public Status addFollower(UUID tableId, UUID userId) throws IOException {
dao.tableDAO().findEntityById(tableId);
return EntityUtil.addFollower(dao.relationshipDAO(), dao.userDAO(), tableId, Entity.TABLE, userId,
Entity.USER) ?
Status.CREATED : Status.OK;
}
@Transaction
public void addJoins(UUID tableId, TableJoins joins) throws IOException, ParseException {
// Validate the request content
@ -192,12 +184,6 @@ public class TableRepository extends EntityRepository<Table> {
JsonUtils.pojoToJson(updatedProfiles));
}
@Transaction
public void deleteFollower(UUID tableId, UUID userId) {
EntityUtil.validateUser(dao.userDAO(), userId);
EntityUtil.removeFollower(dao.relationshipDAO(), tableId, userId);
}
@Transaction
public EntityReference getOwnerReference(Table table) throws IOException {
return EntityUtil.populateOwner(dao.userDAO(), dao.teamDAO(), table.getOwner());
@ -590,6 +576,9 @@ public class TableRepository extends EntityRepository<Table> {
return entity.getHref();
}
@Override
public List<EntityReference> getFollowers() { return entity.getFollowers(); }
@Override
public Table getEntity() { return entity; }

View File

@ -199,6 +199,11 @@ public class TeamRepository extends EntityRepository<Team> {
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("Team does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -175,19 +175,6 @@ public class TopicRepository extends EntityRepository<Topic> {
}
}
@Transaction
public Status addFollower(UUID topicId, UUID userId) throws IOException {
dao.topicDAO().findEntityById(topicId);
return EntityUtil.addFollower(dao.relationshipDAO(), dao.userDAO(), topicId, Entity.TOPIC, userId, Entity.USER) ?
Status.CREATED : Status.OK;
}
@Transaction
public void deleteFollower(UUID topicId, UUID userId) {
EntityUtil.validateUser(dao.userDAO(), userId);
EntityUtil.removeFollower(dao.relationshipDAO(), topicId, userId);
}
public static class TopicEntityInterface implements EntityInterface<Topic> {
private final Topic entity;
@ -237,6 +224,9 @@ public class TopicRepository extends EntityRepository<Topic> {
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() { return entity.getFollowers(); }
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -236,6 +236,11 @@ public class UserRepository extends EntityRepository<User> {
@Override
public URI getHref() { return entity.getHref(); }
@Override
public List<EntityReference> getFollowers() {
throw new UnsupportedOperationException("User does not support followers");
}
@Override
public EntityReference getEntityReference() {
return new EntityReference().withId(getId()).withName(getFullyQualifiedName()).withDescription(getDescription())

View File

@ -22,9 +22,8 @@ public interface EntityInterface<T> {
Double getVersion();
String getUpdatedBy();
Date getUpdatedAt();
default URI getHref() {
return null; // Remove this implementation once all entities implement this
}
URI getHref();
List<EntityReference> getFollowers();
EntityReference getEntityReference();
T getEntity();

View File

@ -18,6 +18,7 @@ import org.openmetadata.catalog.entity.services.MessagingService;
import org.openmetadata.catalog.entity.services.PipelineService;
import org.openmetadata.catalog.entity.teams.Team;
import org.openmetadata.catalog.entity.teams.User;
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
import org.openmetadata.catalog.jdbi3.DatabaseServiceRepository.DatabaseServiceEntityInterface;
import org.openmetadata.catalog.jdbi3.MessagingServiceRepository.MessagingServiceEntityInterface;
import org.openmetadata.catalog.jdbi3.PipelineServiceRepository.PipelineServiceEntityInterface;
@ -49,21 +50,30 @@ import java.util.Map;
import java.util.UUID;
import static javax.ws.rs.core.Response.Status.CREATED;
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.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.resources.services.PipelineServiceResourceTest.createService;
import static org.openmetadata.catalog.util.TestUtils.NON_EXISTENT_ENTITY;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MINOR_UPDATE;
import static org.openmetadata.catalog.util.TestUtils.UpdateType.NO_CHANGE;
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import static org.openmetadata.catalog.util.TestUtils.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.checkUserFollowing;
import static org.openmetadata.catalog.util.TestUtils.userAuthHeaders;
public abstract class EntityResourceTest<T> extends CatalogApplicationTest {
private final Class<T> entityClass;
private final String collectionName;
private final String allFields;
private final boolean supportsFollowers;
public static User USER1;
public static EntityReference USER_OWNER1;
@ -85,10 +95,11 @@ public abstract class EntityResourceTest<T> extends CatalogApplicationTest {
public static final TagLabel TIER1_TAG_LABEL = new TagLabel().withTagFQN("Tier.Tier1");
public static final TagLabel TIER2_TAG_LABEL = new TagLabel().withTagFQN("Tier.Tier2");
public EntityResourceTest(Class<T> entityClass, String collectionName, String fields) {
public EntityResourceTest(Class<T> entityClass, String collectionName, String fields, boolean supportsFollowers) {
this.entityClass = entityClass;
this.collectionName = collectionName;
this.allFields = fields;
this.supportsFollowers = supportsFollowers;
}
@BeforeAll
@ -283,6 +294,51 @@ public abstract class EntityResourceTest<T> extends CatalogApplicationTest {
assertEquals("description", entityInterface.getDescription()); // Description did not change
}
@Test
public void put_addDeleteFollower_200(TestInfo test) throws HttpResponseException, URISyntaxException {
if (!supportsFollowers) {
return; // Entity does not support following
}
Object request = createRequest(test, "description", "displayName", null);
T entity = createAndCheckEntity(request, adminAuthHeaders());
UUID entityId = getEntityInterface(entity).getId();
// Add follower to the entity
User user1 = UserResourceTest.createUser(UserResourceTest.create(test, 1), userAuthHeaders());
addAndCheckFollower(entityId, user1.getId(), CREATED, 1, userAuthHeaders());
// Add the same user as follower and make sure no errors are thrown and return response is OK (and not CREATED)
addAndCheckFollower(entityId, user1.getId(), OK, 1, userAuthHeaders());
// Add a new follower to the entity
User user2 = UserResourceTest.createUser(UserResourceTest.create(test, 2), userAuthHeaders());
addAndCheckFollower(entityId, user2.getId(), CREATED, 2, userAuthHeaders());
// Delete followers and make sure they are deleted
deleteAndCheckFollower(entityId, user1.getId(), 1, userAuthHeaders());
deleteAndCheckFollower(entityId, user2.getId(), 0, userAuthHeaders());
}
@Test
public void put_addDeleteInvalidFollower_200(TestInfo test) throws HttpResponseException, URISyntaxException {
if (!supportsFollowers) {
return; // Entity does not support following
}
Object request = createRequest(test, "description", "displayName", null);
T entity = createAndCheckEntity(request, adminAuthHeaders());
UUID entityId = getEntityInterface(entity).getId();
// Add non existent user as follower to the entity
HttpResponseException exception = assertThrows(HttpResponseException.class, () ->
addAndCheckFollower(entityId, NON_EXISTENT_ENTITY, CREATED, 1, adminAuthHeaders()));
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityNotFound("User", NON_EXISTENT_ENTITY));
// Delete non existent user as follower to the entity
exception = assertThrows(HttpResponseException.class, () ->
deleteAndCheckFollower(entityId, NON_EXISTENT_ENTITY, 1, adminAuthHeaders()));
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityNotFound("User", NON_EXISTENT_ENTITY));
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Common entity functionality for tests
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -294,6 +350,14 @@ public abstract class EntityResourceTest<T> extends CatalogApplicationTest {
return getResource(collectionName + "/" + id);
}
protected final WebTarget getFollowersCollection(UUID id) {
return getResource(collectionName + "/" + id + "/followers");
}
protected final WebTarget getFollowerResource(UUID id, UUID userId) {
return getResource(collectionName + "/" + id + "/followers/" + userId);
}
protected final T getEntity(UUID id, Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = getResource(id);
target = target.queryParam("fields", allFields);
@ -312,8 +376,8 @@ public abstract class EntityResourceTest<T> extends CatalogApplicationTest {
protected final T patchEntity(UUID id, String originalJson, T updated, Map<String, String> authHeaders)
throws JsonProcessingException, HttpResponseException {
String updatedTableJson = JsonUtils.pojoToJson(updated);
JsonPatch patch = JsonSchemaUtil.getJsonPatch(originalJson, updatedTableJson);
String updatedEntityJson = JsonUtils.pojoToJson(updated);
JsonPatch patch = JsonSchemaUtil.getJsonPatch(originalJson, updatedEntityJson);
return TestUtils.patch(getResource(id), patch, entityClass, authHeaders);
}
@ -482,4 +546,60 @@ public abstract class EntityResourceTest<T> extends CatalogApplicationTest {
assertEquals(expectedOwning, owning, "Ownership not correct in the owns list for " + owner.getType());
}
}
public void addAndCheckFollower(UUID entityId, UUID userId, Status status, int totalFollowerCount,
Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = getFollowersCollection(entityId);
TestUtils.put(target, userId.toString(), status, authHeaders);
// GET .../entity/{entityId} returns newly added follower
T getEntity = getEntity(entityId, authHeaders);
EntityInterface<T> entityInterface = getEntityInterface(getEntity);
List<EntityReference> followers = entityInterface.getFollowers();
assertEquals(totalFollowerCount, followers.size());
TestUtils.validateEntityReference(followers);
boolean followerFound = false;
for (EntityReference follower : followers) {
if (follower.getId().equals(userId)) {
followerFound = true;
break;
}
}
assertTrue(followerFound, "Follower added was not found in " + entityClass + " get response");
// GET .../users/{userId} shows user as following the entity
checkUserFollowing(userId, entityId, true, authHeaders);
}
protected void deleteAndCheckFollower(UUID entityId, UUID userId, int totalFollowerCount,
Map<String, String> authHeaders) throws HttpResponseException {
// Delete the follower
WebTarget target = getFollowerResource(entityId, userId);
TestUtils.delete(target, authHeaders);
// Get the entity and ensure the deleted follower is not in the followers list
T getEntity = checkFollowerDeleted(entityId, userId, authHeaders);
assertEquals(totalFollowerCount, getEntityInterface(getEntity).getFollowers().size());
}
public T checkFollowerDeleted(UUID entityId, UUID userId, Map<String, String> authHeaders)
throws HttpResponseException {
// Get the entity and ensure the deleted follower is not in the followers list
T getEntity = getEntity(entityId, authHeaders);
List<EntityReference> followers = getEntityInterface(getEntity).getFollowers();
TestUtils.validateEntityReference(followers);
boolean followerFound = false;
for (EntityReference follower : followers) {
if (follower.getId().equals(userId)) {
followerFound = true;
break;
}
}
assertFalse(followerFound, "Follower deleted is still found in " + entityClass + " get response");
// GET .../users/{userId} shows user as following the entity
checkUserFollowing(userId, entityId, false, authHeaders);
return getEntity;
}
}

View File

@ -21,21 +21,17 @@ import org.apache.http.client.HttpResponseException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.openmetadata.catalog.CatalogApplicationTest;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.api.data.CreateChart;
import org.openmetadata.catalog.api.services.CreateDashboardService;
import org.openmetadata.catalog.api.services.CreateDashboardService.DashboardServiceType;
import org.openmetadata.catalog.entity.data.Chart;
import org.openmetadata.catalog.entity.services.DashboardService;
import org.openmetadata.catalog.entity.teams.User;
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
import org.openmetadata.catalog.jdbi3.ChartRepository.ChartEntityInterface;
import org.openmetadata.catalog.jdbi3.DashboardServiceRepository.DashboardServiceEntityInterface;
import org.openmetadata.catalog.resources.EntityResourceTest;
import org.openmetadata.catalog.resources.charts.ChartResource.ChartList;
import org.openmetadata.catalog.resources.services.DashboardServiceResourceTest;
import org.openmetadata.catalog.resources.teams.UserResourceTest;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.ChartType;
import org.openmetadata.catalog.type.EntityReference;
@ -47,7 +43,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response.Status;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
@ -57,16 +52,12 @@ import java.util.UUID;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.CONFLICT;
import static javax.ws.rs.core.Response.Status.CREATED;
import static javax.ws.rs.core.Response.Status.FORBIDDEN;
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.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.ENTITY_ALREADY_EXISTS;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.entityNotFound;
import static org.openmetadata.catalog.util.TestUtils.LONG_ENTITY_NAME;
@ -76,8 +67,6 @@ import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertEntityPagination;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import static org.openmetadata.catalog.util.TestUtils.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.checkUserFollowing;
import static org.openmetadata.catalog.util.TestUtils.userAuthHeaders;
public class ChartResourceTest extends EntityResourceTest<Chart> {
private static final Logger LOG = LoggerFactory.getLogger(ChartResourceTest.class);
@ -87,7 +76,7 @@ public class ChartResourceTest extends EntityResourceTest<Chart> {
public static final TagLabel TIER_1 = new TagLabel().withTagFQN("Tier.Tier1");
public ChartResourceTest() {
super(Chart.class, "charts", ChartResource.FIELDS);
super(Chart.class, "charts", ChartResource.FIELDS, true);
}
@BeforeAll
@ -353,40 +342,6 @@ public class ChartResourceTest extends EntityResourceTest<Chart> {
// TODO
}
@Test
public void put_addDeleteFollower_200(TestInfo test) throws HttpResponseException {
Chart chart = createAndCheckEntity(create(test), adminAuthHeaders());
// Add follower to the chart
User user1 = UserResourceTest.createUser(UserResourceTest.create(test, 1), userAuthHeaders());
addAndCheckFollower(chart, user1.getId(), CREATED, 1, userAuthHeaders());
// Add the same user as follower and make sure no errors are thrown and return response is OK (and not CREATED)
addAndCheckFollower(chart, user1.getId(), OK, 1, userAuthHeaders());
// Add a new follower to the chart
User user2 = UserResourceTest.createUser(UserResourceTest.create(test, 2), userAuthHeaders());
addAndCheckFollower(chart, user2.getId(), CREATED, 2, userAuthHeaders());
// Delete followers and make sure they are deleted
deleteAndCheckFollower(chart, user1.getId(), 1, userAuthHeaders());
deleteAndCheckFollower(chart, user2.getId(), 0, userAuthHeaders());
}
@Test
public void put_addDeleteInvalidFollower_200(TestInfo test) throws HttpResponseException {
Chart chart = createAndCheckEntity(create(test), adminAuthHeaders());
// Add non existent user as follower to the chart
assertResponse(() -> addAndCheckFollower(chart, NON_EXISTENT_ENTITY, CREATED, 1, adminAuthHeaders()),
NOT_FOUND, CatalogExceptionMessage.entityNotFound("User", NON_EXISTENT_ENTITY));
// Delete non existent user as follower to the chart
assertResponse(() -> deleteAndCheckFollower(chart, NON_EXISTENT_ENTITY, 1, adminAuthHeaders()),
NOT_FOUND, CatalogExceptionMessage.entityNotFound("User", NON_EXISTENT_ENTITY));
}
@Test
public void delete_nonExistentChart_404() {
assertResponse(() -> deleteChart(NON_EXISTENT_ENTITY, adminAuthHeaders()), NOT_FOUND,
@ -483,56 +438,6 @@ public class ChartResourceTest extends EntityResourceTest<Chart> {
.withChartType(ChartType.Area);
}
public static void addAndCheckFollower(Chart chart, UUID userId, Status status, int totalFollowerCount,
Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource(String.format("charts/%s/followers", chart.getId()));
TestUtils.put(target, userId.toString(), status, authHeaders);
// GET .../charts/{chartId} returns newly added follower
Chart getChart = getChart(chart.getId(), "followers", authHeaders);
assertEquals(totalFollowerCount, getChart.getFollowers().size());
TestUtils.validateEntityReference(getChart.getFollowers());
boolean followerFound = false;
for (EntityReference followers : getChart.getFollowers()) {
if (followers.getId().equals(userId)) {
followerFound = true;
break;
}
}
assertTrue(followerFound, "Follower added was not found in chart get response");
// GET .../users/{userId} shows user as following table
checkUserFollowing(userId, chart.getId(), true, authHeaders);
}
private void deleteAndCheckFollower(Chart chart, UUID userId, int totalFollowerCount,
Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource(String.format("charts/%s/followers/%s",
chart.getId(), userId));
TestUtils.delete(target, authHeaders);
Chart getChart = checkFollowerDeleted(chart.getId(), userId, authHeaders);
assertEquals(totalFollowerCount, getChart.getFollowers().size());
}
public static Chart checkFollowerDeleted(UUID chartId, UUID userId, Map<String, String> authHeaders)
throws HttpResponseException {
Chart getChart = getChart(chartId, "followers", authHeaders);
TestUtils.validateEntityReference(getChart.getFollowers());
boolean followerFound = false;
for (EntityReference followers : getChart.getFollowers()) {
if (followers.getId().equals(userId)) {
followerFound = true;
break;
}
}
assertFalse(followerFound, "Follower deleted is still found in table get response");
// GET .../users/{userId} shows user as following table
checkUserFollowing(userId, chartId, false, authHeaders);
return getChart;
}
@Override
public Object createRequest(TestInfo test, String description, String displayName, EntityReference owner) {
return create(test).withDescription(description).withDisplayName(displayName).withOwner(owner);

View File

@ -82,7 +82,7 @@ public class DashboardResourceTest extends EntityResourceTest<Dashboard> {
public static List<EntityReference> CHART_REFERENCES;
public DashboardResourceTest() {
super(Dashboard.class, "dashboards", DashboardResource.FIELDS);
super(Dashboard.class, "dashboards", DashboardResource.FIELDS, true);
}

View File

@ -24,16 +24,11 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.api.data.CreateDatabase;
import org.openmetadata.catalog.api.services.CreateDatabaseService;
import org.openmetadata.catalog.api.services.CreateDatabaseService.DatabaseServiceType;
import org.openmetadata.catalog.entity.data.Database;
import org.openmetadata.catalog.entity.services.DatabaseService;
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
import org.openmetadata.catalog.jdbi3.DatabaseRepository.DatabaseEntityInterface;
import org.openmetadata.catalog.jdbi3.DatabaseServiceRepository.DatabaseServiceEntityInterface;
import org.openmetadata.catalog.resources.EntityResourceTest;
import org.openmetadata.catalog.resources.databases.DatabaseResource.DatabaseList;
import org.openmetadata.catalog.resources.services.DatabaseServiceResourceTest;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.util.EntityInterface;
@ -67,7 +62,7 @@ public class DatabaseResourceTest extends EntityResourceTest<Database> {
private static final Logger LOG = LoggerFactory.getLogger(DatabaseResourceTest.class);
public DatabaseResourceTest() {
super(Database.class, "databases", DatabaseResource.FIELDS);
super(Database.class, "databases", DatabaseResource.FIELDS, false);
}
@BeforeAll

View File

@ -31,14 +31,12 @@ import org.openmetadata.catalog.api.data.CreateTable;
import org.openmetadata.catalog.entity.data.Database;
import org.openmetadata.catalog.entity.data.Table;
import org.openmetadata.catalog.entity.services.DatabaseService;
import org.openmetadata.catalog.entity.teams.User;
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
import org.openmetadata.catalog.jdbi3.TableRepository.TableEntityInterface;
import org.openmetadata.catalog.resources.EntityResourceTest;
import org.openmetadata.catalog.resources.databases.TableResource.TableList;
import org.openmetadata.catalog.resources.services.DatabaseServiceResourceTest;
import org.openmetadata.catalog.resources.tags.TagResourceTest;
import org.openmetadata.catalog.resources.teams.UserResourceTest;
import org.openmetadata.catalog.type.ChangeDescription;
import org.openmetadata.catalog.type.Column;
import org.openmetadata.catalog.type.ColumnConstraint;
@ -79,16 +77,13 @@ import java.util.UUID;
import static java.util.Collections.singletonList;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.CONFLICT;
import static javax.ws.rs.core.Response.Status.CREATED;
import static javax.ws.rs.core.Response.Status.FORBIDDEN;
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.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.resources.databases.DatabaseResourceTest.createAndCheckDatabase;
import static org.openmetadata.catalog.resources.services.DatabaseServiceResourceTest.createService;
import static org.openmetadata.catalog.type.ColumnDataType.ARRAY;
@ -107,7 +102,6 @@ import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertEntityPagination;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import static org.openmetadata.catalog.util.TestUtils.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.checkUserFollowing;
import static org.openmetadata.catalog.util.TestUtils.userAuthHeaders;
import static org.openmetadata.common.utils.CommonUtil.getDateStringByOffset;
@ -123,7 +117,7 @@ public class TableResourceTest extends EntityResourceTest<Table> {
public TableResourceTest() {
super(Table.class, "tables", TableResource.FIELDS);
super(Table.class, "tables", TableResource.FIELDS, true);
}
@BeforeAll
@ -1062,40 +1056,6 @@ public class TableResourceTest extends EntityResourceTest<Table> {
validateColumns(columns, table.getColumns());
}
@Test
public void put_addDeleteFollower_200(TestInfo test) throws HttpResponseException {
Table table = createAndCheckEntity(create(test), adminAuthHeaders());
// Add follower to the table
User user1 = UserResourceTest.createUser(UserResourceTest.create(test, 1), userAuthHeaders());
addAndCheckFollower(table, user1.getId(), CREATED, 1, userAuthHeaders());
// Add the same user as follower and make sure no errors are thrown and return response is OK (and not CREATED)
addAndCheckFollower(table, user1.getId(), OK, 1, userAuthHeaders());
// Add a new follower to the table
User user2 = UserResourceTest.createUser(UserResourceTest.create(test, 2), userAuthHeaders());
addAndCheckFollower(table, user2.getId(), CREATED, 2, userAuthHeaders());
// Delete followers and make sure they are deleted
deleteAndCheckFollower(table, user1.getId(), 1, userAuthHeaders());
deleteAndCheckFollower(table, user2.getId(), 0, userAuthHeaders());
}
@Test
public void put_addDeleteInvalidFollower_200(TestInfo test) throws HttpResponseException {
Table table = createAndCheckEntity(create(test), adminAuthHeaders());
// Add non existent user as follower to the table
HttpResponseException exception = assertThrows(HttpResponseException.class, () ->
addAndCheckFollower(table, NON_EXISTENT_ENTITY, CREATED, 1, adminAuthHeaders()));
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityNotFound("User", NON_EXISTENT_ENTITY));
// Delete non existent user as follower to the table
exception = assertThrows(HttpResponseException.class, () ->
deleteAndCheckFollower(table, NON_EXISTENT_ENTITY, 1, adminAuthHeaders()));
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityNotFound("User", NON_EXISTENT_ENTITY));
}
void assertFields(List<Table> tableList, String fieldsParam) {
tableList.forEach(t -> assertFields(t, fieldsParam));
@ -1279,57 +1239,6 @@ public class TableResourceTest extends EntityResourceTest<Table> {
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityNotFound(Entity.TABLE, id));
}
public static void addAndCheckFollower(Table table, UUID userId, Status status, int totalFollowerCount,
Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource(String.format("tables/%s/followers", table.getId()));
TestUtils.put(target, userId.toString(), status, authHeaders);
// GET .../tables/{tableId} returns newly added follower
Table getTable = getTable(table.getId(), "followers", authHeaders);
assertEquals(totalFollowerCount, getTable.getFollowers().size());
TestUtils.validateEntityReference(getTable.getFollowers());
boolean followerFound = false;
for (EntityReference followers : getTable.getFollowers()) {
if (followers.getId().equals(userId)) {
followerFound = true;
break;
}
}
assertTrue(followerFound, "Follower added was not found in table get response");
// GET .../users/{userId} shows user as following table
checkUserFollowing(userId, table.getId(), true, authHeaders);
}
private void deleteAndCheckFollower(Table table, UUID userId, int totalFollowerCount,
Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource(String.format("tables/%s/followers/%s",
table.getId(), userId));
TestUtils.delete(target, authHeaders);
Table getTable = checkFollowerDeleted(table.getId(), userId, authHeaders);
assertEquals(totalFollowerCount, getTable.getFollowers().size());
}
public static Table checkFollowerDeleted(UUID tableId, UUID userId, Map<String, String> authHeaders)
throws HttpResponseException {
Table getTable = getTable(tableId, "followers", authHeaders);
TestUtils.validateEntityReference(getTable.getFollowers());
boolean followerFound = false;
for (EntityReference followers : getTable.getFollowers()) {
if (followers.getId().equals(userId)) {
followerFound = true;
break;
}
}
assertFalse(followerFound, "Follower deleted is still found in table get response");
// GET .../users/{userId} shows user as following table
checkUserFollowing(userId, tableId, false, authHeaders);
return getTable;
}
private static int getTagUsageCount(String tagFQN, Map<String, String> authHeaders) throws HttpResponseException {
return TagResourceTest.getTag(tagFQN, "usageCount", authHeaders).getUsageCount();
}

View File

@ -75,7 +75,7 @@ public class PipelineResourceTest extends EntityResourceTest<Pipeline> {
public static final TagLabel USER_ADDRESS_TAG_LABEL = new TagLabel().withTagFQN("User.Address");
public PipelineResourceTest() {
super(Pipeline.class, "pipelines", PipelineResource.FIELDS);
super(Pipeline.class, "pipelines", PipelineResource.FIELDS, true);
}

View File

@ -77,7 +77,7 @@ public class TeamResourceTest extends EntityResourceTest<Team> {
final Profile PROFILE = new Profile().withImages(new ImageList().withImage(URI.create("http://image.com")));
public TeamResourceTest() {
super(Team.class, "teams", TeamResource.FIELDS);
super(Team.class, "teams", TeamResource.FIELDS, false);
}
@Test
@ -291,7 +291,7 @@ public class TeamResourceTest extends EntityResourceTest<Team> {
LOG.info("before {} after {} ", list.getPaging().getBefore(), list.getPaging().getAfter());
}
/**
* @see TableResourceTest#put_addDeleteFollower_200
* @see EntityResourceTest#put_addDeleteFollower_200
* for tests related getting team with entities owned by the team
*/

View File

@ -85,7 +85,7 @@ public class UserResourceTest extends EntityResourceTest<User> {
final Profile PROFILE = new Profile().withImages(new ImageList().withImage(URI.create("http://image.com")));
public UserResourceTest() {
super(User.class, "users", UserResource.FIELDS);
super(User.class, "users", UserResource.FIELDS, false);
}
@Test
@ -359,9 +359,9 @@ public class UserResourceTest extends EntityResourceTest<User> {
}
/**
* @see TableResourceTest#put_addDeleteFollower_200 test for tests related to GET user with owns field parameter
* @see EntityResourceTest#put_addDeleteFollower_200 test for tests related to GET user with owns field parameter
*
* @see TableResourceTest#put_addDeleteFollower_200 for tests related getting user with follows list
* @see EntityResourceTest#put_addDeleteFollower_200 for tests related getting user with follows list
*
* @see TableResourceTest also tests GET user returns owns list
*/
@ -479,7 +479,8 @@ public class UserResourceTest extends EntityResourceTest<User> {
// Add user as follower to a table
Table table = TableResourceTest.createTable(test, 1);
TableResourceTest.addAndCheckFollower(table, user.getId(), CREATED, 1, adminAuthHeaders());
TableResourceTest tableResource = new TableResourceTest();
tableResource.addAndCheckFollower(table.getId(), user.getId(), CREATED, 1, adminAuthHeaders());
deleteUser(user.getId(), adminAuthHeaders());
@ -490,7 +491,7 @@ public class UserResourceTest extends EntityResourceTest<User> {
// Make sure the user is no longer following the table
team = TeamResourceTest.getTeam(team.getId(), "users", adminAuthHeaders());
assertTrue(team.getUsers().isEmpty());
TableResourceTest.checkFollowerDeleted(table.getId(), user.getId(), adminAuthHeaders());
tableResource.checkFollowerDeleted(table.getId(), user.getId(), adminAuthHeaders());
// Get deactivated user and ensure the name and display name has deactivated
User deactivatedUser = getUser(user.getId(), adminAuthHeaders());
@ -499,7 +500,7 @@ public class UserResourceTest extends EntityResourceTest<User> {
// User can no longer follow other entities
HttpResponseException exception = assertThrows(HttpResponseException.class, () ->
TableResourceTest.addAndCheckFollower(table, user.getId(), CREATED, 1, adminAuthHeaders()));
tableResource.addAndCheckFollower(table.getId(), user.getId(), CREATED, 1, adminAuthHeaders()));
assertResponse(exception, BAD_REQUEST, deactivatedUser(user.getId()));
// TODO deactivated user can't be made owner

View File

@ -20,15 +20,12 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.http.client.HttpResponseException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.openmetadata.catalog.CatalogApplicationTest;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.api.data.CreateTopic;
import org.openmetadata.catalog.entity.data.Topic;
import org.openmetadata.catalog.entity.teams.User;
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
import org.openmetadata.catalog.jdbi3.TopicRepository.TopicEntityInterface;
import org.openmetadata.catalog.resources.EntityResourceTest;
import org.openmetadata.catalog.resources.teams.UserResourceTest;
import org.openmetadata.catalog.resources.topics.TopicResource.TopicList;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.TagLabel;
@ -42,23 +39,18 @@ import org.slf4j.LoggerFactory;
import javax.json.JsonPatch;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response.Status;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import static javax.ws.rs.core.Response.Status.CONFLICT;
import static javax.ws.rs.core.Response.Status.CREATED;
import static javax.ws.rs.core.Response.Status.FORBIDDEN;
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.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.entityNotFound;
import static org.openmetadata.catalog.util.TestUtils.LONG_ENTITY_NAME;
import static org.openmetadata.catalog.util.TestUtils.NON_EXISTENT_ENTITY;
@ -67,14 +59,12 @@ import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
import static org.openmetadata.catalog.util.TestUtils.assertEntityPagination;
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
import static org.openmetadata.catalog.util.TestUtils.authHeaders;
import static org.openmetadata.catalog.util.TestUtils.checkUserFollowing;
import static org.openmetadata.catalog.util.TestUtils.userAuthHeaders;
public class TopicResourceTest extends EntityResourceTest<Topic> {
private static final Logger LOG = LoggerFactory.getLogger(TopicResourceTest.class);
public TopicResourceTest() {
super(Topic.class, "topics", TopicResource.FIELDS);
super(Topic.class, "topics", TopicResource.FIELDS, true);
}
@Test
@ -338,42 +328,6 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
// TODO
}
@Test
public void put_addDeleteFollower_200(TestInfo test) throws HttpResponseException {
Topic topic = createAndCheckEntity(create(test), adminAuthHeaders());
// Add follower to the table
User user1 = UserResourceTest.createUser(UserResourceTest.create(test, 1), userAuthHeaders());
addAndCheckFollower(topic, user1.getId(), CREATED, 1, userAuthHeaders());
// Add the same user as follower and make sure no errors are thrown and return response is OK (and not CREATED)
addAndCheckFollower(topic, user1.getId(), OK, 1, userAuthHeaders());
// Add a new follower to the table
User user2 = UserResourceTest.createUser(UserResourceTest.create(test, 2), userAuthHeaders());
addAndCheckFollower(topic, user2.getId(), CREATED, 2, userAuthHeaders());
// Delete followers and make sure they are deleted
deleteAndCheckFollower(topic, user1.getId(), 1, userAuthHeaders());
deleteAndCheckFollower(topic, user2.getId(), 0, userAuthHeaders());
}
@Test
public void put_addDeleteInvalidFollower_200(TestInfo test) throws HttpResponseException {
Topic topic = createAndCheckEntity(create(test), adminAuthHeaders());
// Add non existent user as follower to the table
HttpResponseException exception = assertThrows(HttpResponseException.class, () ->
addAndCheckFollower(topic, NON_EXISTENT_ENTITY, CREATED, 1, adminAuthHeaders()));
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityNotFound("User", NON_EXISTENT_ENTITY));
// Delete non existent user as follower to the table
exception = assertThrows(HttpResponseException.class, () ->
deleteAndCheckFollower(topic, NON_EXISTENT_ENTITY, 1, adminAuthHeaders()));
assertResponse(exception, NOT_FOUND, CatalogExceptionMessage.entityNotFound("User", NON_EXISTENT_ENTITY));
}
@Test
public void delete_nonExistentTopic_404() {
HttpResponseException exception = assertThrows(HttpResponseException.class, () ->
@ -539,56 +493,6 @@ public class TopicResourceTest extends EntityResourceTest<Topic> {
return new CreateTopic().withName(getTopicName(test, index)).withService(KAFKA_REFERENCE).withPartitions(1);
}
public static void addAndCheckFollower(Topic topic, UUID userId, Status status, int totalFollowerCount,
Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource(String.format("topics/%s/followers", topic.getId()));
TestUtils.put(target, userId.toString(), status, authHeaders);
// GET .../topics/{topicId} returns newly added follower
Topic getTopic = getTopic(topic.getId(), "followers", authHeaders);
assertEquals(totalFollowerCount, getTopic.getFollowers().size());
TestUtils.validateEntityReference(getTopic.getFollowers());
boolean followerFound = false;
for (EntityReference followers : getTopic.getFollowers()) {
if (followers.getId().equals(userId)) {
followerFound = true;
break;
}
}
assertTrue(followerFound, "Follower added was not found in topic get response");
// GET .../users/{userId} shows user as following table
checkUserFollowing(userId, topic.getId(), true, authHeaders);
}
private void deleteAndCheckFollower(Topic topic, UUID userId, int totalFollowerCount,
Map<String, String> authHeaders) throws HttpResponseException {
WebTarget target = CatalogApplicationTest.getResource(String.format("topics/%s/followers/%s",
topic.getId(), userId));
TestUtils.delete(target, authHeaders);
Topic getTopic = checkFollowerDeleted(topic.getId(), userId, authHeaders);
assertEquals(totalFollowerCount, getTopic.getFollowers().size());
}
public static Topic checkFollowerDeleted(UUID topicId, UUID userId, Map<String, String> authHeaders)
throws HttpResponseException {
Topic getTopic = getTopic(topicId, "followers", authHeaders);
TestUtils.validateEntityReference(getTopic.getFollowers());
boolean followerFound = false;
for (EntityReference followers : getTopic.getFollowers()) {
if (followers.getId().equals(userId)) {
followerFound = true;
break;
}
}
assertFalse(followerFound, "Follower deleted is still found in table get response");
// GET .../users/{userId} shows user as following table
checkUserFollowing(userId, topicId, false, authHeaders);
return getTopic;
}
@Override
public CreateTopic createRequest(TestInfo test, String description, String displayName, EntityReference owner) {
return create(test).withDescription(description).withOwner(owner);