From 96168e77d4bfc57deef81846c9b99a672032813c Mon Sep 17 00:00:00 2001 From: Vivek Ratnavel Subramanian Date: Tue, 6 Sep 2022 22:12:46 -0700 Subject: [PATCH] Fix #6814 Backend: Feed API response doesn't include all tasks of user (#7284) --- .../catalog/jdbi3/CollectionDAO.java | 66 ++++++++++++++++++- .../catalog/jdbi3/FeedRepository.java | 28 +++++++- .../resources/feeds/FeedResourceTest.java | 4 ++ 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/CollectionDAO.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/CollectionDAO.java index b29f6e6b8de..7949c8f992b 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/CollectionDAO.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/CollectionDAO.java @@ -777,7 +777,7 @@ public interface CollectionDAO { connectionType = POSTGRES) @ConnectionAwareSqlQuery( value = - "SELECT count(id) FROM thread_entity WHERE " + "SELECT count(id) FROM thread_entity WHERE type='Task' AND " + "(:status IS NULL OR taskStatus = :status) AND " + "JSON_OVERLAPS(taskAssignees, :userTeamJsonMysql) ", connectionType = MYSQL) @@ -786,6 +786,70 @@ public interface CollectionDAO { @Bind("userTeamJsonMysql") String userTeamJsonMysql, @Bind("status") TaskStatus status); + @ConnectionAwareSqlQuery( + value = + "SELECT json FROM thread_entity WHERE type='Task' AND updatedAt > :before AND taskStatus = :status AND " + + "AND (taskAssignees @> ANY (ARRAY[]::jsonb[]) OR createdBy = :username) " + + "ORDER BY createdAt DESC " + + "LIMIT :limit", + connectionType = POSTGRES) + @ConnectionAwareSqlQuery( + value = + "SELECT json FROM thread_entity WHERE type='Task' AND updatedAt > :before AND taskStatus = :status AND " + + "AND (JSON_OVERLAPS(taskAssignees, :userTeamJsonMysql) OR createdBy = :username) " + + "ORDER BY createdAt DESC " + + "LIMIT :limit", + connectionType = MYSQL) + List listTasksOfUserBefore( + @BindList("userTeamJsonPostgres") List userTeamJsonPostgres, + @Bind("userTeamJsonMysql") String userTeamJsonMysql, + @Bind("username") String username, + @Bind("limit") int limit, + @Bind("before") long before, + @Bind("status") TaskStatus status); + + @ConnectionAwareSqlQuery( + value = + "SELECT json FROM thread_entity WHERE type='Task' AND updatedAt < :after " + + "AND (:status IS NULL OR taskStatus = :status) " + + "AND (taskAssignees @> ANY (ARRAY[]::jsonb[]) OR createdBy = :username) " + + "ORDER BY createdAt DESC " + + "LIMIT :limit", + connectionType = POSTGRES) + @ConnectionAwareSqlQuery( + value = + "SELECT json FROM thread_entity WHERE type='Task' AND updatedAt < :after " + + "AND (:status IS NULL OR taskStatus = :status) " + + "AND (JSON_OVERLAPS(taskAssignees, :userTeamJsonMysql) OR createdBy = :username) " + + "ORDER BY createdAt DESC " + + "LIMIT :limit", + connectionType = MYSQL) + List listTasksOfUserAfter( + @BindList("userTeamJsonPostgres") List userTeamJsonPostgres, + @Bind("userTeamJsonMysql") String userTeamJsonMysql, + @Bind("username") String username, + @Bind("limit") int limit, + @Bind("after") long after, + @Bind("status") TaskStatus status); + + @ConnectionAwareSqlQuery( + value = + "SELECT count(id) FROM thread_entity WHERE type='Task' " + + "AND (:status IS NULL OR taskStatus = :status) " + + "AND (taskAssignees @> ANY (ARRAY[]::jsonb[]) OR createdBy = :username) ", + connectionType = POSTGRES) + @ConnectionAwareSqlQuery( + value = + "SELECT count(id) FROM thread_entity WHERE type='Task' " + + "AND (:status IS NULL OR taskStatus = :status) " + + "AND (JSON_OVERLAPS(taskAssignees, :userTeamJsonMysql) OR createdBy = :username) ", + connectionType = MYSQL) + int listCountTasksOfUser( + @BindList("userTeamJsonPostgres") List userTeamJsonPostgres, + @Bind("userTeamJsonMysql") String userTeamJsonMysql, + @Bind("username") String username, + @Bind("status") TaskStatus status); + @SqlQuery( "SELECT json FROM thread_entity WHERE type='Task' AND updatedAt > :before " + "AND (:status IS NULL OR taskStatus = :status) " diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/FeedRepository.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/FeedRepository.java index 067178e6c72..06815ee19ee 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/FeedRepository.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/FeedRepository.java @@ -703,9 +703,11 @@ public class FeedRepository { // Only two filter types are supported for tasks -> ASSIGNED_TO, ASSIGNED_BY if (filterType == FilterType.ASSIGNED_BY) { filteredThreads = getTasksAssignedBy(userId, limit + 1, time, taskStatus, paginationType); - } else { - // make ASSIGNED_TO a default filter + } else if (filterType == FilterType.ASSIGNED_TO) { filteredThreads = getTasksAssignedTo(userId, limit + 1, time, taskStatus, paginationType); + } else { + // Get all the tasks assigned to or created by the user + filteredThreads = getTasksOfUser(userId, limit + 1, time, taskStatus, paginationType); } } else { if (filterType == FilterType.FOLLOWS) { @@ -999,6 +1001,28 @@ public class FeedRepository { return thread; } + /** Return the tasks created by or assigned to the user. */ + private FilteredThreads getTasksOfUser( + String userId, int limit, long time, TaskStatus status, PaginationType paginationType) throws IOException { + User user = dao.userDAO().findEntityById(UUID.fromString(userId)); + String username = user.getName(); + List teamIds = getTeamIds(userId); + List userTeamJsonPostgres = getUserTeamJsonPostgres(userId, teamIds); + String userTeamJsonMysql = getUserTeamJsonMysql(userId, teamIds); + List jsons; + if (paginationType == PaginationType.BEFORE) { + jsons = + dao.feedDAO().listTasksOfUserBefore(userTeamJsonPostgres, userTeamJsonMysql, username, limit, time, status); + } else { + jsons = + dao.feedDAO().listTasksOfUserAfter(userTeamJsonPostgres, userTeamJsonMysql, username, limit, time, status); + } + List threads = JsonUtils.readObjects(jsons, Thread.class); + int totalCount = dao.feedDAO().listCountTasksOfUser(userTeamJsonPostgres, userTeamJsonMysql, username, status); + sortPostsInThreads(threads); + return new FilteredThreads(threads, totalCount); + } + /** Return the tasks created by the user. */ private FilteredThreads getTasksAssignedBy( String userId, int limit, long time, TaskStatus status, PaginationType paginationType) throws IOException { diff --git a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/feeds/FeedResourceTest.java b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/feeds/FeedResourceTest.java index 7d91259cb9f..da135ed35e0 100644 --- a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/feeds/FeedResourceTest.java +++ b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/feeds/FeedResourceTest.java @@ -401,6 +401,10 @@ public class FeedResourceTest extends CatalogApplicationTest { assertEquals(assignedToCount + 1, tasks.getPaging().getTotal()); assertEquals(assignedToCount + 1, tasks.getData().size()); + tasks = listTasks(null, USER.getId().toString(), null, null, null, ADMIN_AUTH_HEADERS); + assertEquals(assignedToCount + assignedByCount + 2, tasks.getPaging().getTotal()); + assertEquals(assignedToCount + assignedByCount + 2, tasks.getData().size()); + ThreadCount count = listTasksCount(null, TaskStatus.Open, userAuthHeaders); int totalOpenTaskCount = count.getTotalCount(); count = listTasksCount(null, TaskStatus.Closed, userAuthHeaders);