diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/Entity.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/Entity.java index 049808bdf48..5126ccc3638 100644 --- a/catalog-rest-service/src/main/java/org/openmetadata/catalog/Entity.java +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/Entity.java @@ -107,6 +107,11 @@ public final class Entity { // public static final String POLICY = "policy"; + // + // Service + // + public static final String SERVICE = "service"; + // // Role, team and user entities // 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 03b2d5eb3c2..057f5b736e9 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 @@ -27,6 +27,7 @@ import lombok.Getter; import org.apache.commons.lang3.tuple.Triple; import org.jdbi.v3.core.mapper.RowMapper; import org.jdbi.v3.core.statement.StatementContext; +import org.jdbi.v3.core.statement.StatementException; import org.jdbi.v3.sqlobject.CreateSqlObject; import org.jdbi.v3.sqlobject.config.RegisterRowMapper; import org.jdbi.v3.sqlobject.customizer.Bind; @@ -77,7 +78,9 @@ import org.openmetadata.catalog.type.ThreadType; import org.openmetadata.catalog.type.UsageDetails; import org.openmetadata.catalog.type.UsageStats; import org.openmetadata.catalog.type.Webhook; +import org.openmetadata.catalog.util.EntitiesCount; import org.openmetadata.catalog.util.EntityUtil; +import org.openmetadata.catalog.util.ServicesCount; import org.openmetadata.common.utils.CommonUtil; public interface CollectionDAO { @@ -198,6 +201,9 @@ public interface CollectionDAO { @CreateSqlObject TestCaseDAO testCaseDAO(); + @CreateSqlObject + UtilDAO utilDAO(); + interface DashboardDAO extends EntityDAO { @Override default String getTableName() { @@ -2158,4 +2164,75 @@ public interface CollectionDAO { return listCount(getTableName(), getNameColumn(), condition); } } + + class EntitiesCountRowMapper implements RowMapper { + @Override + public EntitiesCount map(ResultSet rs, StatementContext ctx) throws SQLException { + return new EntitiesCount() + .withTableCount(rs.getInt("tableCount")) + .withTopicCount(rs.getInt("topicCount")) + .withDashboardCount(rs.getInt("dashboardCount")) + .withPipelineCount(rs.getInt("pipelineCount")) + .withMlmodelCount(rs.getInt("mlmodelCount")) + .withServicesCount(rs.getInt("servicesCount")) + .withUserCount(rs.getInt("userCount")) + .withTeamCount(rs.getInt("teamCount")); + } + } + + class ServicesCountRowMapper implements RowMapper { + @Override + public ServicesCount map(ResultSet rs, StatementContext ctx) throws SQLException { + return new ServicesCount() + .withDatabaseServiceCount(rs.getInt("databaseServiceCount")) + .withMessagingServiceCount(rs.getInt("messagingServiceCount")) + .withDashboardServiceCount(rs.getInt("dashboardServiceCount")) + .withPipelineServiceCounte(rs.getInt("pipelineServiceCount")) + .withMlModelServiceCount(rs.getInt("mlModelServiceCount")); + } + } + + interface UtilDAO { + @ConnectionAwareSqlQuery( + value = + "SELECT (SELECT COUNT(*) FROM table_entity) as tableCount, " + + "(SELECT COUNT(*) FROM topic_entity) as topicCount, " + + "(SELECT COUNT(*) FROM dashboard_entity) as dashboardCount, " + + "(SELECT COUNT(*) FROM pipeline_entity) as pipelineCount, " + + "(SELECT COUNT(*) FROM ml_model_entity) as mlmodelCount, " + + "(SELECT (SELECT COUNT(*) FROM database_entity) + " + + "(SELECT COUNT(*) FROM messaging_service_entity)+ " + + "(SELECT COUNT(*) FROM dashboard_service_entity)+ " + + "(SELECT COUNT(*) FROM pipeline_service_entity)+ " + + "(SELECT COUNT(*) FROM mlmodel_service_entity)) as servicesCount, " + + "(SELECT COUNT(*) FROM user_entity WHERE JSON_EXTRACT(json, '$.isBot') is NULL) as userCount, " + + "(SELECT COUNT(*) FROM team_entity) as teamCount", + connectionType = MYSQL) + @ConnectionAwareSqlQuery( + value = + "SELECT (SELECT COUNT(*) FROM table_entity) as tableCount, " + + "(SELECT COUNT(*) FROM topic_entity) as topicCount, " + + "(SELECT COUNT(*) FROM dashboard_entity) as dashboardCount, " + + "(SELECT COUNT(*) FROM pipeline_entity) as pipelineCount, " + + "(SELECT COUNT(*) FROM ml_model_entity) as mlmodelCount, " + + "(SELECT (SELECT COUNT(*) FROM database_entity) + " + + "(SELECT COUNT(*) FROM messaging_service_entity)+ " + + "(SELECT COUNT(*) FROM dashboard_service_entity)+ " + + "(SELECT COUNT(*) FROM pipeline_service_entity)+ " + + "(SELECT COUNT(*) FROM mlmodel_service_entity)) as servicesCount, " + + "(SELECT COUNT(*) FROM user_entity WHERE json#>'{isBot}' is NULL) as userCount, " + + "(SELECT COUNT(*) FROM team_entity) as teamCount", + connectionType = POSTGRES) + @RegisterRowMapper(EntitiesCountRowMapper.class) + EntitiesCount getAggregatedEntitiesCount() throws StatementException; + + @SqlQuery( + "SELECT (SELECT COUNT(*) FROM database_entity) as databaseServiceCount, " + + "(SELECT COUNT(*) FROM messaging_service_entity) as messagingServiceCount, " + + "(SELECT COUNT(*) FROM dashboard_service_entity) as dashboardServiceCount, " + + "(SELECT COUNT(*) FROM pipeline_service_entity) as pipelineServiceCount, " + + "(SELECT COUNT(*) FROM mlmodel_service_entity) as mlModelServiceCount") + @RegisterRowMapper(ServicesCountRowMapper.class) + ServicesCount getAggregatedServicesCount() throws StatementException; + } } diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/UtilRepository.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/UtilRepository.java new file mode 100644 index 00000000000..6fb670602da --- /dev/null +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/jdbi3/UtilRepository.java @@ -0,0 +1,52 @@ +package org.openmetadata.catalog.jdbi3; + +import static org.openmetadata.catalog.Entity.DASHBOARD; +import static org.openmetadata.catalog.Entity.MLMODEL; +import static org.openmetadata.catalog.Entity.PIPELINE; +import static org.openmetadata.catalog.Entity.SERVICE; +import static org.openmetadata.catalog.Entity.TABLE; +import static org.openmetadata.catalog.Entity.TEAM; +import static org.openmetadata.catalog.Entity.TOPIC; +import static org.openmetadata.catalog.Entity.USER; + +import org.openmetadata.catalog.util.EntitiesCount; +import org.openmetadata.catalog.util.ServicesCount; + +public class UtilRepository { + private final CollectionDAO.UtilDAO dao; + + public UtilRepository(CollectionDAO.UtilDAO dao) { + this.dao = dao; + } + + public EntitiesCount getAllEntitiesCount() { + return dao.getAggregatedEntitiesCount(); + } + + public ServicesCount getAllServicesCount() { + return dao.getAggregatedServicesCount(); + } + + public Object getIndividualEntityCount(String entity) { + switch (entity) { + case TABLE: + return dao.getAggregatedEntitiesCount().getTableCount(); + case TOPIC: + return dao.getAggregatedEntitiesCount().getTopicCount(); + case DASHBOARD: + return dao.getAggregatedEntitiesCount().getDashboardCount(); + case PIPELINE: + return dao.getAggregatedEntitiesCount().getPipelineCount(); + case MLMODEL: + return dao.getAggregatedEntitiesCount().getMlmodelCount(); + case SERVICE: + return dao.getAggregatedEntitiesCount().getServicesCount(); + case USER: + return dao.getAggregatedEntitiesCount().getUserCount(); + case TEAM: + return dao.getAggregatedEntitiesCount().getTeamCount(); + default: + return "Invalid Entity"; + } + } +} diff --git a/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/util/UtilResource.java b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/util/UtilResource.java new file mode 100644 index 00000000000..d96271d47b1 --- /dev/null +++ b/catalog-rest-service/src/main/java/org/openmetadata/catalog/resources/util/UtilResource.java @@ -0,0 +1,100 @@ +package org.openmetadata.catalog.resources.util; + +import io.swagger.annotations.Api; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import java.util.Objects; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; +import lombok.extern.slf4j.Slf4j; +import org.openmetadata.catalog.jdbi3.CollectionDAO; +import org.openmetadata.catalog.jdbi3.UtilRepository; +import org.openmetadata.catalog.resources.Collection; +import org.openmetadata.catalog.security.Authorizer; +import org.openmetadata.catalog.util.EntitiesCount; +import org.openmetadata.catalog.util.ServicesCount; + +@Path("/v1/util") +@Api(value = "Util collection", tags = "Util collection") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Collection(name = "util") +@Slf4j +public class UtilResource { + public static final String COLLECTION_PATH = "/v1/util"; + private final UtilRepository utilRepository; + private final Authorizer authorizer; + + public UtilResource(CollectionDAO dao, Authorizer authorizer) { + Objects.requireNonNull(dao, "UtilRepository must not be null"); + this.utilRepository = new UtilRepository(dao.utilDAO()); + this.authorizer = authorizer; + } + + @GET + @Path("/entities/count") + @Operation( + operationId = "listEntitiesCount", + summary = "List All Entities Counts", + tags = "util", + description = "Get a List of all Entities Count", + responses = { + @ApiResponse( + responseCode = "200", + description = "List of Entities Count", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = EntitiesCount.class))) + }) + public EntitiesCount listEntitiesCount(@Context UriInfo uriInfo) { + return utilRepository.getAllEntitiesCount(); + } + + @GET + @Path("/services/count") + @Operation( + operationId = "listServicesCount", + summary = "List All Services Counts", + tags = "util", + description = "Get a List of all Entities Count", + responses = { + @ApiResponse( + responseCode = "200", + description = "List of Services Count", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = ServicesCount.class))) + }) + public ServicesCount listServicesCount(@Context UriInfo uriInfo) { + return utilRepository.getAllServicesCount(); + } + + @GET + @Path("/{entity}/count") + @Operation( + operationId = "listEntityCount", + summary = "List Individual Entity Count", + tags = "util", + description = "Get total count of an Entity", + responses = { + @ApiResponse( + responseCode = "200", + description = "List of Services Count", + content = @Content(mediaType = "application/json")) + }) + public Object listEntityCount( + @Context UriInfo uriInfo, + @Parameter( + description = "Entity type for which usage is requested", + required = true, + schema = @Schema(type = "string", example = "table, pipeline, topic, or dashboard")) + @PathParam("entity") + String entity) { + return utilRepository.getIndividualEntityCount(entity); + } +} diff --git a/catalog-rest-service/src/main/resources/json/schema/entity/utils/entitiesCount.json b/catalog-rest-service/src/main/resources/json/schema/entity/utils/entitiesCount.json new file mode 100644 index 00000000000..53cc670b622 --- /dev/null +++ b/catalog-rest-service/src/main/resources/json/schema/entity/utils/entitiesCount.json @@ -0,0 +1,43 @@ +{ + "$id": "https://open-metadata.org/schema/entity/tags/entitiesCount.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Entities Count", + "description": "This schema defines Entities Count. This contains aggregated entities count.", + "type": "object", + "javaType": "org.openmetadata.catalog.util.EntitiesCount", + "properties": { + "tableCount": { + "description": "Table Count", + "type": "integer" + }, + "topicCount": { + "description": "Topic Count", + "type": "integer" + }, + "dashboardCount": { + "description": "Dashboard Count", + "type": "integer" + }, + "pipelineCount": { + "description": "Pipeline Count", + "type": "integer" + }, + "mlmodelCount": { + "description": "MlModel Count", + "type": "integer" + }, + "servicesCount": { + "description": "Services Count", + "type": "integer" + }, + "userCount": { + "description": "User Count", + "type": "integer" + }, + "teamCount": { + "description": "Team Count", + "type": "integer" + } + }, + "additionalProperties": false +} \ No newline at end of file diff --git a/catalog-rest-service/src/main/resources/json/schema/entity/utils/servicesCount.json b/catalog-rest-service/src/main/resources/json/schema/entity/utils/servicesCount.json new file mode 100644 index 00000000000..7492ce8fd33 --- /dev/null +++ b/catalog-rest-service/src/main/resources/json/schema/entity/utils/servicesCount.json @@ -0,0 +1,31 @@ +{ + "$id": "https://open-metadata.org/schema/entity/tags/servicesCount.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Services Count", + "description": "This schema defines Services Count. This contains aggregated services count.", + "type": "object", + "javaType": "org.openmetadata.catalog.util.ServicesCount", + "properties": { + "databaseServiceCount": { + "description": "Database Service Count", + "type": "integer" + }, + "messagingServiceCount": { + "description": "Messaging Service Count", + "type": "integer" + }, + "dashboardServiceCount": { + "description": "Dashboard Service Count", + "type": "integer" + }, + "pipelineServiceCounte": { + "description": "Pipeline Service Count", + "type": "integer" + }, + "mlModelServiceCount": { + "description": "MlModel Service Count", + "type": "integer" + } + }, + "additionalProperties": false +} \ No newline at end of file diff --git a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/mlmodels/MlModelResourceTest.java b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/mlmodels/MlModelResourceTest.java index a4541cce76b..b2e01a7628d 100644 --- a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/mlmodels/MlModelResourceTest.java +++ b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/mlmodels/MlModelResourceTest.java @@ -63,7 +63,7 @@ import org.openmetadata.catalog.util.TestUtils; @Slf4j @TestMethodOrder(MethodOrderer.OrderAnnotation.class) -class MlModelResourceTest extends EntityResourceTest { +public class MlModelResourceTest extends EntityResourceTest { public static final String ALGORITHM = "regression"; public static Dashboard DASHBOARD; diff --git a/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/util/UtilResourceTest.java b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/util/UtilResourceTest.java new file mode 100644 index 00000000000..61595b4d3ed --- /dev/null +++ b/catalog-rest-service/src/test/java/org/openmetadata/catalog/resources/util/UtilResourceTest.java @@ -0,0 +1,218 @@ +package org.openmetadata.catalog.resources.util; + +import static org.openmetadata.catalog.Entity.DASHBOARD; +import static org.openmetadata.catalog.Entity.TABLE; +import static org.openmetadata.catalog.Entity.TOPIC; +import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS; + +import java.io.IOException; +import java.net.URISyntaxException; +import javax.ws.rs.client.WebTarget; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.client.HttpResponseException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.TestMethodOrder; +import org.openmetadata.catalog.CatalogApplicationTest; +import org.openmetadata.catalog.api.data.CreateDashboard; +import org.openmetadata.catalog.api.data.CreatePipeline; +import org.openmetadata.catalog.api.data.CreateTable; +import org.openmetadata.catalog.api.data.CreateTopic; +import org.openmetadata.catalog.api.services.CreateDashboardService; +import org.openmetadata.catalog.api.services.CreateDatabaseService; +import org.openmetadata.catalog.api.services.CreateMessagingService; +import org.openmetadata.catalog.api.services.CreateMlModelService; +import org.openmetadata.catalog.api.services.CreatePipelineService; +import org.openmetadata.catalog.api.teams.CreateTeam; +import org.openmetadata.catalog.api.teams.CreateUser; +import org.openmetadata.catalog.entity.data.Table; +import org.openmetadata.catalog.resources.EntityResourceTest; +import org.openmetadata.catalog.resources.dashboards.DashboardResourceTest; +import org.openmetadata.catalog.resources.databases.TableResourceTest; +import org.openmetadata.catalog.resources.pipelines.PipelineResourceTest; +import org.openmetadata.catalog.resources.services.DashboardServiceResourceTest; +import org.openmetadata.catalog.resources.services.DatabaseServiceResourceTest; +import org.openmetadata.catalog.resources.services.MessagingServiceResourceTest; +import org.openmetadata.catalog.resources.services.MlModelServiceResourceTest; +import org.openmetadata.catalog.resources.services.PipelineServiceResourceTest; +import org.openmetadata.catalog.resources.teams.TeamResourceTest; +import org.openmetadata.catalog.resources.teams.UserResourceTest; +import org.openmetadata.catalog.resources.topics.TopicResourceTest; +import org.openmetadata.catalog.util.EntitiesCount; +import org.openmetadata.catalog.util.ServicesCount; +import org.openmetadata.catalog.util.TestUtils; + +@Slf4j +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class UtilResourceTest extends CatalogApplicationTest { + + @BeforeAll + public static void setup(TestInfo test) throws IOException, URISyntaxException { + EntityResourceTest entityResourceTest = new TableResourceTest(); + entityResourceTest.setup(test); + } + + public static EntitiesCount getEntitiesCount() throws HttpResponseException { + WebTarget target = CatalogApplicationTest.getResource("util/entities/count"); + return TestUtils.get(target, EntitiesCount.class, ADMIN_AUTH_HEADERS); + } + + public static ServicesCount getServicesCount() throws HttpResponseException { + WebTarget target = CatalogApplicationTest.getResource("util/services/count"); + return TestUtils.get(target, ServicesCount.class, ADMIN_AUTH_HEADERS); + } + + public static Object getIndividualEntityCount(String entity) throws HttpResponseException { + WebTarget target = CatalogApplicationTest.getResource("util/" + entity + "/count"); + return TestUtils.get(target, Object.class, ADMIN_AUTH_HEADERS); + } + + @Test + public void entitiesCount(TestInfo test) throws HttpResponseException { + + // Get count before adding entities + int beforeTableCount = getEntitiesCount().getTableCount(); + int beforeDashboardCount = getEntitiesCount().getDashboardCount(); + int beforePipelineCount = getEntitiesCount().getPipelineCount(); + int beforeTopicCount = getEntitiesCount().getTopicCount(); + int beforeServiceCount = getEntitiesCount().getServicesCount(); + int beforeUserCount = getEntitiesCount().getUserCount(); + int beforeTeamCount = getEntitiesCount().getTeamCount(); + + // Create Table + TableResourceTest tableResourceTest = new TableResourceTest(); + CreateTable createTable = tableResourceTest.createRequest(test); + tableResourceTest.createEntity(createTable, ADMIN_AUTH_HEADERS); + + // Create Dashboard + DashboardResourceTest dashboardResourceTest = new DashboardResourceTest(); + CreateDashboard createDashboard = dashboardResourceTest.createRequest(test); + dashboardResourceTest.createEntity(createDashboard, ADMIN_AUTH_HEADERS); + + // Create Topic + TopicResourceTest topicResourceTest = new TopicResourceTest(); + CreateTopic createTopic = topicResourceTest.createRequest(test); + topicResourceTest.createEntity(createTopic, ADMIN_AUTH_HEADERS); + + // Create Pipeline + PipelineResourceTest pipelineResourceTest = new PipelineResourceTest(); + CreatePipeline createPipeline = pipelineResourceTest.createRequest(test); + pipelineResourceTest.createEntity(createPipeline, ADMIN_AUTH_HEADERS); + + // Create Service + MessagingServiceResourceTest messagingServiceResourceTest = new MessagingServiceResourceTest(); + CreateMessagingService createMessagingService = messagingServiceResourceTest.createRequest(test); + messagingServiceResourceTest.createEntity(createMessagingService, ADMIN_AUTH_HEADERS); + + // Create User + UserResourceTest userResourceTest = new UserResourceTest(); + CreateUser createUser = userResourceTest.createRequest(test); + userResourceTest.createEntity(createUser, ADMIN_AUTH_HEADERS); + + // Create Team + TeamResourceTest teamResourceTest = new TeamResourceTest(); + CreateTeam createTeam = teamResourceTest.createRequest(test); + teamResourceTest.createEntity(createTeam, ADMIN_AUTH_HEADERS); + + // Get count after adding entities + int afterTableCount = getEntitiesCount().getTableCount(); + int afterDashboardCount = getEntitiesCount().getDashboardCount(); + int afterPipelineCount = getEntitiesCount().getPipelineCount(); + int afterTopicCount = getEntitiesCount().getTopicCount(); + int afterServiceCount = getEntitiesCount().getServicesCount(); + int afterUserCount = getEntitiesCount().getUserCount(); + int afterTeamCount = getEntitiesCount().getTeamCount(); + + int actualCount = 1; + + Assertions.assertEquals(afterDashboardCount - beforeDashboardCount, actualCount); + Assertions.assertEquals(afterPipelineCount - beforePipelineCount, actualCount); + Assertions.assertEquals(afterServiceCount - beforeServiceCount, actualCount); + Assertions.assertEquals(afterUserCount - beforeUserCount, actualCount); + Assertions.assertEquals(afterTableCount - beforeTableCount, actualCount); + Assertions.assertEquals(afterTeamCount - beforeTeamCount, actualCount); + Assertions.assertEquals(afterTopicCount - beforeTopicCount, actualCount); + } + + @Test + public void servicesCount(TestInfo test) throws HttpResponseException { + + // Get count before adding services + int beforeMessagingServiceCount = getServicesCount().getMessagingServiceCount(); + int beforeDashboardServiceCount = getServicesCount().getDashboardServiceCount(); + int beforePipelineServiceCount = getServicesCount().getPipelineServiceCounte(); + int beforeMlModelServiceCount = getServicesCount().getMlModelServiceCount(); + + // Create Database Service + DatabaseServiceResourceTest databaseServiceResourceTest = new DatabaseServiceResourceTest(); + CreateDatabaseService createDatabaseService = databaseServiceResourceTest.createRequest(test); + databaseServiceResourceTest.createEntity(createDatabaseService, ADMIN_AUTH_HEADERS); + + // Create Messaging Service + MessagingServiceResourceTest messagingServiceResourceTest = new MessagingServiceResourceTest(); + CreateMessagingService createMessagingService = messagingServiceResourceTest.createRequest(test); + messagingServiceResourceTest.createEntity(createMessagingService, ADMIN_AUTH_HEADERS); + + // Create Dashboard Service + DashboardServiceResourceTest dashboardServiceResourceTest = new DashboardServiceResourceTest(); + CreateDashboardService createDashboardService = dashboardServiceResourceTest.createRequest(test); + dashboardServiceResourceTest.createEntity(createDashboardService, ADMIN_AUTH_HEADERS); + + // Create Pipeline Service + PipelineServiceResourceTest pipelineServiceResourceTest = new PipelineServiceResourceTest(); + CreatePipelineService createPipelineService = pipelineServiceResourceTest.createRequest(test); + pipelineServiceResourceTest.createEntity(createPipelineService, ADMIN_AUTH_HEADERS); + + // Create MlModel Service + MlModelServiceResourceTest mlModelServiceResourceTest = new MlModelServiceResourceTest(); + CreateMlModelService createMlModelService = mlModelServiceResourceTest.createRequest(test); + mlModelServiceResourceTest.createEntity(createMlModelService, ADMIN_AUTH_HEADERS); + + // Get count after creating services + int afterMessagingServiceCount = getServicesCount().getMessagingServiceCount(); + int afterDashboardServiceCount = getServicesCount().getDashboardServiceCount(); + int afterPipelineServiceCount = getServicesCount().getPipelineServiceCounte(); + int afterMlModelServiceCount = getServicesCount().getMlModelServiceCount(); + int actualCount = 1; + + Assertions.assertEquals(afterMessagingServiceCount - beforeMessagingServiceCount, actualCount); + Assertions.assertEquals(afterDashboardServiceCount - beforeDashboardServiceCount, actualCount); + Assertions.assertEquals(afterPipelineServiceCount - beforePipelineServiceCount, actualCount); + Assertions.assertEquals(afterMlModelServiceCount - beforeMlModelServiceCount, actualCount); + } + + @Test + public void individualEntityCount(TestInfo test) throws HttpResponseException { + + int beforeTableCount = (int) getIndividualEntityCount(TABLE); + int beforeDashboardCount = (int) getIndividualEntityCount(DASHBOARD); + int beforeTopicCount = (int) getIndividualEntityCount(TOPIC); + + TableResourceTest tableResourceTest = new TableResourceTest(); + CreateTable createTable = tableResourceTest.createRequest(test); + tableResourceTest.createEntity(createTable, ADMIN_AUTH_HEADERS); + + // Create Dashboard + DashboardResourceTest dashboardResourceTest = new DashboardResourceTest(); + CreateDashboard createDashboard = dashboardResourceTest.createRequest(test); + dashboardResourceTest.createEntity(createDashboard, ADMIN_AUTH_HEADERS); + + // Create Topic + TopicResourceTest topicResourceTest = new TopicResourceTest(); + CreateTopic createTopic = topicResourceTest.createRequest(test); + topicResourceTest.createEntity(createTopic, ADMIN_AUTH_HEADERS); + + int afterTableCount = (int) getIndividualEntityCount(TABLE); + int afterDashboardCount = (int) getIndividualEntityCount(DASHBOARD); + int afterTopicCount = (int) getIndividualEntityCount(TOPIC); + + int actualCount = 1; + + Assertions.assertEquals(afterDashboardCount - beforeDashboardCount, actualCount); + Assertions.assertEquals(afterTableCount - beforeTableCount, actualCount); + Assertions.assertEquals(afterTopicCount - beforeTopicCount, actualCount); + } +}