diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/databases/DatabaseSchemaResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/databases/DatabaseSchemaResource.java index 34883694fb9..460824b22ba 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/databases/DatabaseSchemaResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/databases/DatabaseSchemaResource.java @@ -77,7 +77,8 @@ public class DatabaseSchemaResource extends EntityResource { private final DatabaseSchemaMapper mapper = new DatabaseSchemaMapper(); public static final String COLLECTION_PATH = "v1/databaseSchemas/"; - static final String FIELDS = "owners,tables,usageSummary,tags,extension,domain,sourceHash"; + static final String FIELDS = + "owners,tables,usageSummary,tags,extension,domain,sourceHash,followers"; @Override public DatabaseSchema addHref(UriInfo uriInfo, DatabaseSchema schema) { @@ -315,6 +316,69 @@ public class DatabaseSchemaResource return create(uriInfo, securityContext, schema); } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToDatabaseSchema", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this Database Schema", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Dashboard Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Database Schema", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @PATCH @Path("/{id}") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/databases/TableResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/databases/TableResource.java index ab3c70b4456..22e452ff1dc 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/databases/TableResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/databases/TableResource.java @@ -1294,7 +1294,7 @@ public class TableResource extends EntityResource { @Operation( operationId = "deleteFollower", summary = "Remove a follower", - description = "Remove the user identified `userId` as a follower of the table.", + description = "Remove the user identified `userId` as a follower of the entity.", responses = { @ApiResponse( responseCode = "200", @@ -1307,7 +1307,7 @@ public class TableResource extends EntityResource { public Response deleteFollower( @Context UriInfo uriInfo, @Context SecurityContext securityContext, - @Parameter(description = "Id of the table", schema = @Schema(type = "UUID")) @PathParam("id") + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") UUID id, @Parameter( description = "Id of the user being removed as follower", diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/apiservices/APIServiceResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/apiservices/APIServiceResource.java index fe21a3c192e..2a1a281f088 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/apiservices/APIServiceResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/apiservices/APIServiceResource.java @@ -52,6 +52,7 @@ import org.openmetadata.schema.entity.services.ApiService; import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.connections.TestConnectionResult; import org.openmetadata.schema.type.ApiConnection; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.MetadataOperation; @@ -78,7 +79,7 @@ public class APIServiceResource extends ServiceEntityResource { private final APIServiceMapper mapper = new APIServiceMapper(); public static final String COLLECTION_PATH = "v1/services/apiServices/"; - static final String FIELDS = "pipelines,owners,tags,domain"; + public static final String FIELDS = "pipelines,owners,tags,domain,followers"; @Override public ApiService addHref(UriInfo uriInfo, ApiService service) { @@ -524,6 +525,69 @@ public class APIServiceResource uriInfo, securityContext, EntityInterfaceUtil.quoteName(fqn), recursive, hardDelete); } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToApiService", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this api service", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Api Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Api Service", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @PUT @Path("/restore") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/dashboard/DashboardServiceResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/dashboard/DashboardServiceResource.java index f78ef3e6f5e..2e22f61bdfd 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/dashboard/DashboardServiceResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/dashboard/DashboardServiceResource.java @@ -50,6 +50,7 @@ import org.openmetadata.schema.api.services.CreateDashboardService; import org.openmetadata.schema.entity.services.DashboardService; import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.connections.TestConnectionResult; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.DashboardConnection; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; @@ -74,7 +75,7 @@ public class DashboardServiceResource DashboardService, DashboardServiceRepository, DashboardConnection> { private final DashboardServiceMapper mapper = new DashboardServiceMapper(); public static final String COLLECTION_PATH = "v1/services/dashboardServices"; - static final String FIELDS = "owners,domain"; + public static final String FIELDS = "owners,domain,followers"; public DashboardServiceResource(Authorizer authorizer, Limits limits) { super(Entity.DASHBOARD_SERVICE, authorizer, limits, ServiceType.DASHBOARD); @@ -173,6 +174,69 @@ public class DashboardServiceResource return decryptOrNullify(securityContext, dashboardService); } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToDashboardService", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this Dashboard service", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Dashboard Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Dashboard Service", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @GET @Path("/name/{name}") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/database/DatabaseServiceResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/database/DatabaseServiceResource.java index 91ef7d7b0fe..c7a1484d997 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/database/DatabaseServiceResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/database/DatabaseServiceResource.java @@ -53,6 +53,7 @@ import org.openmetadata.schema.api.services.DatabaseConnection; import org.openmetadata.schema.entity.services.DatabaseService; import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.connections.TestConnectionResult; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.MetadataOperation; @@ -82,7 +83,7 @@ public class DatabaseServiceResource extends ServiceEntityResource { private final DatabaseServiceMapper mapper = new DatabaseServiceMapper(); public static final String COLLECTION_PATH = "v1/services/databaseServices/"; - static final String FIELDS = "pipelines,owners,tags,domain"; + public static final String FIELDS = "pipelines,owners,tags,domain,followers"; @Override public DatabaseService addHref(UriInfo uriInfo, DatabaseService service) { @@ -386,6 +387,69 @@ public class DatabaseServiceResource return response; } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToDatabaseService", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this database service", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Database Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Database Service", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @PATCH @Path("/{id}") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/ingestionpipelines/IngestionPipelineResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/ingestionpipelines/IngestionPipelineResource.java index 4df2c7d3243..2adee68cdba 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/ingestionpipelines/IngestionPipelineResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/ingestionpipelines/IngestionPipelineResource.java @@ -63,6 +63,7 @@ import org.openmetadata.schema.entity.services.ingestionPipelines.IngestionPipel import org.openmetadata.schema.entity.services.ingestionPipelines.PipelineServiceClientResponse; import org.openmetadata.schema.entity.services.ingestionPipelines.PipelineStatus; import org.openmetadata.schema.services.connections.metadata.OpenMetadataConnection; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.MetadataOperation; @@ -101,7 +102,7 @@ public class IngestionPipelineResource public static final String COLLECTION_PATH = "v1/services/ingestionPipelines/"; private PipelineServiceClientInterface pipelineServiceClient; private OpenMetadataApplicationConfig openMetadataApplicationConfig; - static final String FIELDS = FIELD_OWNERS; + static final String FIELDS = "owners,followers"; @Override public IngestionPipeline addHref(UriInfo uriInfo, IngestionPipeline ingestionPipeline) { @@ -259,6 +260,69 @@ public class IngestionPipelineResource return ingestionPipelines; } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToIngestionPipeline", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this ingestion pipeline", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Ingestion Pipeline for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Ingestion Pipeline", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @GET @Path("/{id}/versions") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/messaging/MessagingServiceResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/messaging/MessagingServiceResource.java index 5462027247c..67a13153442 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/messaging/MessagingServiceResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/messaging/MessagingServiceResource.java @@ -50,6 +50,7 @@ import org.openmetadata.schema.api.services.CreateMessagingService; import org.openmetadata.schema.entity.services.MessagingService; import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.connections.TestConnectionResult; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.MessagingConnection; @@ -74,7 +75,7 @@ public class MessagingServiceResource MessagingService, MessagingServiceRepository, MessagingConnection> { private final MessagingServiceMapper mapper = new MessagingServiceMapper(); public static final String COLLECTION_PATH = "v1/services/messagingServices/"; - public static final String FIELDS = "owners,domain"; + public static final String FIELDS = "owners,domain,followers"; public MessagingServiceResource(Authorizer authorizer, Limits limits) { super(Entity.MESSAGING_SERVICE, authorizer, limits, ServiceType.MESSAGING); @@ -247,6 +248,69 @@ public class MessagingServiceResource return decryptOrNullify(securityContext, service); } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToDatabaseService", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this messaging service", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Messaging Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Messaging Service", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @GET @Path("/{id}/versions") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/metadata/MetadataServiceResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/metadata/MetadataServiceResource.java index f2249aced16..8fa1c42bff3 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/metadata/MetadataServiceResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/metadata/MetadataServiceResource.java @@ -47,6 +47,7 @@ import org.openmetadata.schema.service.configuration.elasticsearch.ElasticSearch import org.openmetadata.schema.services.connections.metadata.ComponentConfig; import org.openmetadata.schema.services.connections.metadata.ElasticsSearch; import org.openmetadata.schema.services.connections.metadata.OpenMetadataConnection; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.MetadataOperation; @@ -77,7 +78,7 @@ public class MetadataServiceResource private final MetadataServiceMapper mapper = new MetadataServiceMapper(); public static final String OPENMETADATA_SERVICE = "OpenMetadata"; public static final String COLLECTION_PATH = "v1/services/metadataServices/"; - public static final String FIELDS = "pipelines,owners,tags"; + public static final String FIELDS = "pipelines,owners,tags,followers"; @Override public void initialize(OpenMetadataApplicationConfig config) throws IOException { @@ -257,6 +258,69 @@ public class MetadataServiceResource return decryptOrNullify(securityContext, metadataService); } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToMetadataService", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this Metadata service", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Metadata Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Metadata Service", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @PUT @Path("/{id}/testConnectionResult") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/mlmodel/MlModelServiceResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/mlmodel/MlModelServiceResource.java index bb3e421d40e..474a88aaa14 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/mlmodel/MlModelServiceResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/mlmodel/MlModelServiceResource.java @@ -52,6 +52,7 @@ import org.openmetadata.schema.api.services.CreateMlModelService; import org.openmetadata.schema.entity.services.MlModelService; import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.connections.TestConnectionResult; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.MetadataOperation; @@ -75,7 +76,7 @@ public class MlModelServiceResource extends ServiceEntityResource { private final MlModelServiceMapper mapper = new MlModelServiceMapper(); public static final String COLLECTION_PATH = "v1/services/mlmodelServices/"; - public static final String FIELDS = "pipelines,owners,tags,domain"; + public static final String FIELDS = "pipelines,owners,tags,domain,followers"; @Override public MlModelService addHref(UriInfo uriInfo, MlModelService service) { @@ -232,6 +233,69 @@ public class MlModelServiceResource return decryptOrNullify(securityContext, mlModelService); } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToMlModelService", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this MlModel service", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "MlModel Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the MlModel Service", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @PUT @Path("/{id}/testConnectionResult") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/pipeline/PipelineServiceResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/pipeline/PipelineServiceResource.java index 0a200c69f2b..52ac79d0f33 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/pipeline/PipelineServiceResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/pipeline/PipelineServiceResource.java @@ -50,6 +50,7 @@ import org.openmetadata.schema.api.services.CreatePipelineService; import org.openmetadata.schema.entity.services.PipelineService; import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.connections.TestConnectionResult; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.MetadataOperation; @@ -73,7 +74,7 @@ public class PipelineServiceResource extends ServiceEntityResource { private final PipelineServiceMapper mapper = new PipelineServiceMapper(); public static final String COLLECTION_PATH = "v1/services/pipelineServices/"; - static final String FIELDS = "pipelines,owners,domain"; + public static final String FIELDS = "pipelines,owners,domain,followers"; @Override public PipelineService addHref(UriInfo uriInfo, PipelineService service) { @@ -233,6 +234,69 @@ public class PipelineServiceResource return decryptOrNullify(securityContext, pipelineService); } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToDatabaseService", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this pipeline service", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Pipeline Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Pipeline Service", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @PUT @Path("/{id}/testConnectionResult") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/searchIndexes/SearchServiceResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/searchIndexes/SearchServiceResource.java index b4a777c2547..57c44734fde 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/searchIndexes/SearchServiceResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/searchIndexes/SearchServiceResource.java @@ -38,6 +38,7 @@ import org.openmetadata.schema.api.services.CreateSearchService; import org.openmetadata.schema.entity.services.SearchService; import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.connections.TestConnectionResult; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.MetadataOperation; @@ -65,7 +66,7 @@ public class SearchServiceResource extends ServiceEntityResource { private final SearchServiceMapper mapper = new SearchServiceMapper(); public static final String COLLECTION_PATH = "v1/services/searchServices/"; - static final String FIELDS = "pipelines,owners,tags,domain"; + public static final String FIELDS = "pipelines,owners,tags,domain,followers"; @Override public SearchService addHref(UriInfo uriInfo, SearchService service) { @@ -241,6 +242,69 @@ public class SearchServiceResource return decryptOrNullify(securityContext, service); } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToDatabaseService", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this Search Index service", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Search Index Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Search Index Service", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @GET @Path("/{id}/versions") @Operation( diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/storage/StorageServiceResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/storage/StorageServiceResource.java index b9bafe4e8cf..ddf0c72579f 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/storage/StorageServiceResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/services/storage/StorageServiceResource.java @@ -39,6 +39,7 @@ import org.openmetadata.schema.entity.services.DatabaseService; import org.openmetadata.schema.entity.services.ServiceType; import org.openmetadata.schema.entity.services.StorageService; import org.openmetadata.schema.entity.services.connections.TestConnectionResult; +import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.EntityHistory; import org.openmetadata.schema.type.Include; import org.openmetadata.schema.type.MetadataOperation; @@ -65,7 +66,7 @@ public class StorageServiceResource extends ServiceEntityResource { private final StorageServiceMapper mapper = new StorageServiceMapper(); public static final String COLLECTION_PATH = "v1/services/storageServices/"; - static final String FIELDS = "pipelines,owners,tags,domain"; + public static final String FIELDS = "pipelines,owners,tags,domain,followers"; @Override public StorageService addHref(UriInfo uriInfo, StorageService service) { @@ -212,6 +213,69 @@ public class StorageServiceResource return decryptOrNullify(securityContext, storageService); } + @PUT + @Path("/{id}/followers") + @Operation( + operationId = "addFollowerToDatabaseService", + summary = "Add a follower", + description = "Add a user identified by `userId` as followed of this Storage service", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))), + @ApiResponse( + responseCode = "404", + description = "Storage Service for instance {id} is not found") + }) + public Response addFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Storage Service", schema = @Schema(type = "UUID")) + @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user to be added as follower", + schema = @Schema(type = "string")) + UUID userId) { + return repository + .addFollower(securityContext.getUserPrincipal().getName(), id, userId) + .toResponse(); + } + + @DELETE + @Path("/{id}/followers/{userId}") + @Operation( + operationId = "deleteFollower", + summary = "Remove a follower", + description = "Remove the user identified `userId` as a follower of the entity.", + responses = { + @ApiResponse( + responseCode = "200", + description = "OK", + content = + @Content( + mediaType = "application/json", + schema = @Schema(implementation = ChangeEvent.class))) + }) + public Response deleteFollower( + @Context UriInfo uriInfo, + @Context SecurityContext securityContext, + @Parameter(description = "Id of the Entity", schema = @Schema(type = "UUID")) @PathParam("id") + UUID id, + @Parameter( + description = "Id of the user being removed as follower", + schema = @Schema(type = "string")) + @PathParam("userId") + String userId) { + return repository + .deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId)) + .toResponse(); + } + @PUT @Path("/{id}/testConnectionResult") @Operation( diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/databases/DatabaseSchemaResourceTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/databases/DatabaseSchemaResourceTest.java index 8524069ab72..2f03a54e4dd 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/resources/databases/DatabaseSchemaResourceTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/databases/DatabaseSchemaResourceTest.java @@ -262,7 +262,7 @@ public class DatabaseSchemaResourceTest assertListNotNull(schema.getService(), schema.getServiceType(), schema.getDatabase()); assertListNull(schema.getOwners(), schema.getTables()); - fields = "owners,tags,tables"; + fields = "owners,tags,tables,followers"; schema = byName ? getEntityByName(schema.getFullyQualifiedName(), fields, ADMIN_AUTH_HEADERS) diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/services/APIServiceResourceTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/services/APIServiceResourceTest.java index c54077a72fb..c1d70286b32 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/resources/services/APIServiceResourceTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/services/APIServiceResourceTest.java @@ -41,7 +41,7 @@ public class APIServiceResourceTest extends ServiceResourceTest