Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@
import org.openmetadata.schema.utils.JsonUtils;
import org.openmetadata.schema.utils.ResultList;
import org.openmetadata.sdk.client.OpenMetadataClient;
import org.openmetadata.sdk.exceptions.ApiException;
import org.openmetadata.sdk.exceptions.InvalidRequestException;
import org.openmetadata.sdk.models.ListParams;
import org.openmetadata.sdk.models.ListResponse;
import org.openmetadata.sdk.network.HttpMethod;
import org.openmetadata.sdk.network.RequestOptions;

/**
* Integration tests for DataProduct entity operations.
Expand Down Expand Up @@ -214,6 +216,110 @@ protected DataProduct getVersion(UUID id, Double version) {
// DATA PRODUCT-SPECIFIC TESTS
// ===================================================================

@Test
void put_addFollowerForAnotherUser_403(TestNamespace ns) {
DataProduct dataProduct = createEntity(createMinimalRequest(ns));

ApiException exception =
assertThrows(
ApiException.class,
() -> addFollower(SdkClients.user2Client(), dataProduct.getId(), testUser3().getId()));

assertEquals(403, exception.getStatusCode());
assertFalse(hasFollower(dataProduct.getId(), testUser3().getId()));
}

@Test
void delete_followerForSelf_200(TestNamespace ns) {
DataProduct dataProduct = createEntity(createMinimalRequest(ns));
OpenMetadataClient client = SdkClients.user2Client();
UUID userId = testUser2().getId();

addFollower(client, dataProduct.getId(), userId);
assertTrue(hasFollower(dataProduct.getId(), userId));

deleteFollower(client, dataProduct.getId(), userId);
assertFalse(hasFollower(dataProduct.getId(), userId));
}

@Test
void delete_followerForAnotherUserAsAdmin_200(TestNamespace ns) {
DataProduct dataProduct = createEntity(createMinimalRequest(ns));
OpenMetadataClient client = SdkClients.adminClient();
UUID userId = testUser3().getId();

addFollower(client, dataProduct.getId(), userId);
assertTrue(hasFollower(dataProduct.getId(), userId));

deleteFollower(client, dataProduct.getId(), userId);
assertFalse(hasFollower(dataProduct.getId(), userId));
}

@Test
void put_addFollowerWithNullUserId_400(TestNamespace ns) {
DataProduct dataProduct = createEntity(createMinimalRequest(ns));

InvalidRequestException exception =
assertThrows(
InvalidRequestException.class,
() ->
SdkClients.user2Client()
.getHttpClient()
.execute(
HttpMethod.PUT,
"/v1/dataProducts/" + dataProduct.getId() + "/followers",
"null",
ChangeEvent.class,
RequestOptions.builder()
.header("Content-Type", "application/json")
.build()));

assertEquals(400, exception.getStatusCode());
assertEquals("userId is required", exception.getMessage());
}

@Test
void delete_removeFollowerForAnotherUser_403(TestNamespace ns) {
DataProduct dataProduct = createEntity(createMinimalRequest(ns));
addFollower(SdkClients.user3Client(), dataProduct.getId(), testUser3().getId());

ApiException exception =
assertThrows(
ApiException.class,
() ->
deleteFollower(SdkClients.user2Client(), dataProduct.getId(), testUser3().getId()));

assertEquals(403, exception.getStatusCode());
assertTrue(hasFollower(dataProduct.getId(), testUser3().getId()));
}

private void addFollower(OpenMetadataClient client, UUID dataProductId, UUID userId) {
client
.getHttpClient()
.execute(
HttpMethod.PUT,
"/v1/dataProducts/" + dataProductId + "/followers",
userId,
ChangeEvent.class);
}

private void deleteFollower(OpenMetadataClient client, UUID dataProductId, UUID userId) {
client
.getHttpClient()
.execute(
HttpMethod.DELETE,
"/v1/dataProducts/" + dataProductId + "/followers/" + userId,
null,
ChangeEvent.class);
}

private boolean hasFollower(UUID dataProductId, UUID userId) {
DataProduct dataProduct = getEntityWithFields(dataProductId.toString(), "followers");
return dataProduct.getFollowers() != null
&& dataProduct.getFollowers().stream()
.anyMatch(follower -> userId.equals(follower.getId()));
}

@Test
void post_dataProductWithStyle_200_OK(TestNamespace ns) {
OpenMetadataClient client = SdkClients.adminClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@
@Getter protected final Set<String> allowedFields;
public final boolean supportsSoftDelete;
@Getter protected final boolean supportsTags;
@Getter protected final boolean supportsOwners;

Check warning on line 540 in openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java

View workflow job for this annotation

GitHub Actions / python / Build Backend Distribution

Not generating isSupportsOwners(): A method with that name already exists

Check warning on line 540 in openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java

View workflow job for this annotation

GitHub Actions / Build Integration Test Runtime

Not generating isSupportsOwners(): A method with that name already exists

Check warning on line 540 in openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java

View workflow job for this annotation

GitHub Actions / Build Integration Test Runtime

Not generating isSupportsOwners(): A method with that name already exists

Check warning on line 540 in openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java

View workflow job for this annotation

GitHub Actions / python / Build Backend Distribution

Not generating isSupportsOwners(): A method with that name already exists

Check warning on line 540 in openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java

View workflow job for this annotation

GitHub Actions / Build Integration Test Runtime

Not generating isSupportsOwners(): A method with that name already exists
@Getter protected final boolean supportsStyle;
@Getter protected final boolean supportsLifeCycle;
@Getter protected final boolean supportsCertification;
Expand Down Expand Up @@ -1767,8 +1767,9 @@
return bundle;
}

boolean onlyNonDeleted = isReadPlanNonDeletedOnly(readPlan);
CachedReadBundle bundleCache = onlyNonDeleted ? CacheBundle.getCachedReadBundle() : null;
boolean cacheReadBundle =
isReadPlanNonDeletedOnly(readPlan) && isCacheableEntityType(entityType);
CachedReadBundle bundleCache = cacheReadBundle ? CacheBundle.getCachedReadBundle() : null;

java.util.concurrent.locks.Lock loadLock = null;
CachedReadBundle.Dto initialDto = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
Expand Down Expand Up @@ -72,6 +73,7 @@
import org.openmetadata.service.OpenMetadataApplicationConfig;
import org.openmetadata.service.cache.CacheBundle;
import org.openmetadata.service.cache.CacheProvider;
import org.openmetadata.service.exception.BadRequestException;
import org.openmetadata.service.exception.CatalogExceptionMessage;
import org.openmetadata.service.jdbi3.DeadlockRetry;
import org.openmetadata.service.jdbi3.EntityRepository;
Expand Down Expand Up @@ -160,6 +162,32 @@ protected T addHref(UriInfo uriInfo, T entity) {
}
}

protected Response addFollowerInternal(
SecurityContext securityContext, UUID entityId, UUID userId) {
authorizeFollowerMutation(securityContext, userId);
return repository
.addFollower(securityContext.getUserPrincipal().getName(), entityId, userId)
.toResponse();
}

protected Response deleteFollowerInternal(
SecurityContext securityContext, UUID entityId, UUID userId) {
authorizeFollowerMutation(securityContext, userId);
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), entityId, userId)
.toResponse();
}

private void authorizeFollowerMutation(SecurityContext securityContext, UUID userId) {
if (userId == null) {
throw new BadRequestException("userId is required");
}
SubjectContext subjectContext = getSubjectContext(securityContext);
if (!Objects.equals(subjectContext.user().getId(), userId)) {
authorizer.authorizeAdmin(securityContext);
}
}

protected List<MetadataOperation> getEntitySpecificOperations() {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,7 @@ public Response addFollower(
description = "Id of the user to be added as follower",
schema = @Schema(type = "UUID"))
UUID userId) {
return repository
.addFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return addFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand Down Expand Up @@ -399,9 +397,7 @@ public Response deleteFollower(
schema = @Schema(type = "UUID"))
@PathParam("userId")
UUID userId) {
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return deleteFollowerInternal(securityContext, id, userId);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,7 @@ public Response addFollower(
description = "Id of the user to be added as follower",
schema = @Schema(type = "UUID"))
UUID userId) {
return repository
.addFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return addFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand Down Expand Up @@ -384,9 +382,7 @@ public Response deleteFollower(
schema = @Schema(type = "UUID"))
@PathParam("userId")
UUID userId) {
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return deleteFollowerInternal(securityContext, id, userId);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,9 +362,7 @@ public Response addFollower(
description = "Id of the user to be added as follower",
schema = @Schema(type = "UUID"))
UUID userId) {
return repository
.addFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return addFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand Down Expand Up @@ -393,9 +391,7 @@ public Response deleteFollower(
schema = @Schema(type = "UUID"))
@PathParam("userId")
UUID userId) {
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return deleteFollowerInternal(securityContext, id, userId);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,7 @@ public Response addFollower(
description = "Id of the user to be added as follower",
schema = @Schema(type = "UUID"))
UUID userId) {
return repository
.addFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return addFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand Down Expand Up @@ -410,9 +408,7 @@ public Response deleteFollower(
schema = @Schema(type = "UUID"))
@PathParam("userId")
UUID userId) {
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return deleteFollowerInternal(securityContext, id, userId);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,7 @@ public Response addFollower(
description = "Id of the user to be added as follower",
schema = @Schema(type = "UUID"))
UUID userId) {
return repository
.addFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return addFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand Down Expand Up @@ -382,9 +380,7 @@ public Response deleteFollower(
schema = @Schema(type = "UUID"))
@PathParam("userId")
UUID userId) {
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return deleteFollowerInternal(securityContext, id, userId);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -479,9 +479,7 @@ public Response addFollower(
description = "Id of the user to be added as follower",
schema = @Schema(type = "UUID"))
UUID userId) {
return repository
.addFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return addFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand Down Expand Up @@ -509,9 +507,7 @@ public Response deleteFollower(
schema = @Schema(type = "string"))
@PathParam("userId")
String userId) {
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId))
.toResponse();
return deleteFollowerInternal(securityContext, id, UUID.fromString(userId));
}

@PUT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,9 +460,7 @@ public Response addFollower(
description = "Id of the user to be added as follower",
schema = @Schema(type = "UUID"))
UUID userId) {
return repository
.addFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return addFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand All @@ -481,9 +479,7 @@ public Response deleteFollower(
schema = @Schema(type = "UUID"))
@PathParam("userId")
UUID userId) {
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return deleteFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -475,9 +475,7 @@ public Response addFollower(
description = "Id of the user to be added as follower",
schema = @Schema(type = "UUID"))
UUID userId) {
return repository
.addFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return addFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand All @@ -497,9 +495,7 @@ public Response deleteFollower(
schema = @Schema(type = "UUID"))
@PathParam("userId")
UUID userId) {
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), id, userId)
.toResponse();
return deleteFollowerInternal(securityContext, id, userId);
}

@PUT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -880,9 +880,7 @@ public Response addFollower(
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();
return addFollowerInternal(securityContext, id, userId);
}

@DELETE
Expand Down Expand Up @@ -910,8 +908,6 @@ public Response deleteFollower(
schema = @Schema(type = "string"))
@PathParam("userId")
String userId) {
return repository
.deleteFollower(securityContext.getUserPrincipal().getName(), id, UUID.fromString(userId))
.toResponse();
return deleteFollowerInternal(securityContext, id, UUID.fromString(userId));
}
}
Loading
Loading