Fixes #6554 Add support for team of type Group (#6588)

* Fixes #6554 Add support for team of type Group

* Fixing test failure
This commit is contained in:
Suresh Srinivas 2022-08-05 10:49:42 -07:00 committed by GitHub
parent 29248437c3
commit 7825986105
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 101 additions and 79 deletions

View File

@ -1,5 +1,5 @@
UPDATE team_entity
SET json = JSON_INSERT(json, '$.teamType', 'Department');
SET json = JSON_INSERT(json, '$.teamType', 'Group');
ALTER TABLE team_entity
ADD teamType VARCHAR(64) GENERATED ALWAYS AS (json ->> '$.teamType') NOT NULL;

View File

@ -1,5 +1,5 @@
UPDATE team_entity
SET json = JSONB_SET(json, '{teamType}', '"Department"', true);
SET json = JSONB_SET(json, '{teamType}', '"Group"', true);
ALTER TABLE team_entity
ADD teamType VARCHAR(64) GENERATED ALWAYS AS (json ->> 'teamType') STORED NOT NULL;

View File

@ -138,4 +138,12 @@ public final class CatalogExceptionMessage {
public static String createOrganization() {
return "Only one Organization is allowed. New Organization type can't be created";
}
public static String createGroup() {
return "Team of type Group can't have children of type team. Only users are allowed as part of the team";
}
public static String invalidTeamOwner(TeamType teamType) {
return String.format("Team of type %s can't own entities. Only Team of type Group can own entities.", teamType);
}
}

View File

@ -60,7 +60,6 @@ public class ChartRepository extends EntityRepository<Chart> {
chart.setService(dashboardService.getEntityReference());
chart.setServiceType(dashboardService.getServiceType());
setFullyQualifiedName(chart);
chart.setOwner(Entity.getEntityReference(chart.getOwner()));
chart.setTags(addDerivedTags(chart.getTags()));
}

View File

@ -108,7 +108,6 @@ public class DashboardRepository extends EntityRepository<Dashboard> {
public void prepare(Dashboard dashboard) throws IOException {
populateService(dashboard);
setFullyQualifiedName(dashboard);
populateOwner(dashboard.getOwner()); // Validate owner
dashboard.setTags(addDerivedTags(dashboard.getTags()));
dashboard.setCharts(getCharts(dashboard.getCharts()));
}

View File

@ -63,7 +63,6 @@ public class DatabaseRepository extends EntityRepository<Database> {
public void prepare(Database database) throws IOException {
populateService(database);
setFullyQualifiedName(database);
populateOwner(database.getOwner()); // Validate owner
}
@Override

View File

@ -56,7 +56,6 @@ public class DatabaseSchemaRepository extends EntityRepository<DatabaseSchema> {
public void prepare(DatabaseSchema schema) throws IOException {
populateDatabase(schema);
setFullyQualifiedName(schema);
populateOwner(schema.getOwner()); // Validate owner
}
@Override

View File

@ -464,6 +464,7 @@ public abstract class EntityRepository<T extends EntityInterface> {
updated.setUpdatedAt(System.currentTimeMillis());
prepare(updated);
populateOwner(updated.getOwner());
validateExtension(updated);
restorePatchAttributes(original, updated);

View File

@ -60,7 +60,6 @@ public class GlossaryRepository extends EntityRepository<Glossary> {
@Override
public void prepare(Glossary glossary) throws IOException {
setFullyQualifiedName(glossary);
glossary.setOwner(Entity.getEntityReference(glossary.getOwner()));
validateUsers(glossary.getReviewers());
glossary.setTags(addDerivedTags(glossary.getTags()));
}

View File

@ -67,7 +67,6 @@ public class IngestionPipelineRepository extends EntityRepository<IngestionPipel
EntityReference entityReference = Entity.getEntityReference(ingestionPipeline.getService());
ingestionPipeline.setService(entityReference);
setFullyQualifiedName(ingestionPipeline);
ingestionPipeline.setOwner(Entity.getEntityReference(ingestionPipeline.getOwner()));
}
@Override

View File

@ -166,7 +166,6 @@ public class LocationRepository extends EntityRepository<Location> {
location.setService(storageService.getEntityReference());
location.setServiceType(storageService.getServiceType());
setFullyQualifiedName(location);
populateOwner(location.getOwner()); // Validate owner
location.setTags(addDerivedTags(location.getTags()));
}

View File

@ -59,7 +59,6 @@ public class MetricsRepository extends EntityRepository<Metrics> {
@Override
public void prepare(Metrics metrics) throws IOException {
populateOwner(metrics.getOwner()); // Validate owner
metrics.setService(getService(metrics.getService()));
setFullyQualifiedName(metrics);
metrics.setTags(addDerivedTags(metrics.getTags()));

View File

@ -141,9 +141,6 @@ public class MlModelRepository extends EntityRepository<MlModel> {
setMlFeatureFQN(mlModel.getFullyQualifiedName(), mlModel.getMlFeatures());
}
// Check if owner is valid and set the relationship
populateOwner(mlModel.getOwner());
// Check that the dashboard exists
if (mlModel.getDashboard() != null) {
daoCollection.dashboardDAO().findEntityReferenceById(mlModel.getDashboard().getId());

View File

@ -214,7 +214,6 @@ public class PipelineRepository extends EntityRepository<Pipeline> {
public void prepare(Pipeline pipeline) throws IOException {
populateService(pipeline);
setFullyQualifiedName(pipeline);
populateOwner(pipeline.getOwner()); // Validate owner
pipeline.setTags(addDerivedTags(pipeline.getTags()));
}

View File

@ -85,8 +85,6 @@ public class PolicyRepository extends EntityRepository<Policy> {
setFullyQualifiedName(policy);
validateRules(policy);
policy.setLocation(getLocationReference(policy));
// Check if owner is valid and set the relationship
populateOwner(policy.getOwner());
}
@Override

View File

@ -46,7 +46,6 @@ public class ReportRepository extends EntityRepository<Report> {
public void prepare(Report report) throws IOException {
// TODO report does not have service yet
setFullyQualifiedName(report);
report.setOwner(Entity.getEntityReference(report.getOwner()));
}
@Override

View File

@ -4,7 +4,6 @@ import static org.openmetadata.catalog.Entity.FIELD_OWNER;
import static org.openmetadata.catalog.util.EntityUtil.objectMatch;
import java.io.IOException;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.ServiceConnectionEntityInterface;
import org.openmetadata.catalog.ServiceEntityInterface;
import org.openmetadata.catalog.entity.services.ServiceType;
@ -64,8 +63,6 @@ public abstract class ServiceRepository<T extends ServiceEntityInterface, S exte
@Override
public void prepare(T service) throws IOException {
setFullyQualifiedName(service);
// Check if owner is valid and set the relationship
service.setOwner(Entity.getEntityReference(service.getOwner()));
}
protected abstract String getServiceType(T service);

View File

@ -46,8 +46,6 @@ public class StorageServiceRepository extends EntityRepository<StorageService> {
@Override
public void prepare(StorageService entity) throws IOException {
setFullyQualifiedName(entity);
// Check if owner is valid and set the relationship
entity.setOwner(Entity.getEntityReference(entity.getOwner()));
}
@Override

View File

@ -642,9 +642,6 @@ public class TableRepository extends EntityRepository<Table> {
setColumnFQN(table.getFullyQualifiedName(), table.getColumns());
// Check if owner is valid and set the relationship
table.setOwner(Entity.getEntityReference(table.getOwner()));
// Validate table tags and add derived tags to the list
table.setTags(addDerivedTags(table.getTags()));

View File

@ -82,7 +82,6 @@ public class TeamRepository extends EntityRepository<Team> {
@Override
public void prepare(Team team) throws IOException {
setFullyQualifiedName(team);
populateOwner(team.getOwner()); // Validate owner
populateParents(team); // Validate parents
populateChildren(team); // Validate children
validateUsers(team.getUsers());

View File

@ -65,7 +65,6 @@ public class TestCaseRepository extends EntityRepository<TestCase> {
Entity.getEntity(test.getTestDefinition(), EntityUtil.Fields.EMPTY_FIELDS, Include.NON_DELETED);
validateTestParameters(test.getParameterValues(), testDefinition.getParameterDefinition());
test.setFullyQualifiedName(FullyQualifiedName.add(tableRef.getFullyQualifiedName(), test.getName()));
test.setOwner(Entity.getEntityReference(test.getOwner()));
}
private EntityReference getEntity(TestCase test) throws IOException {

View File

@ -3,7 +3,6 @@ package org.openmetadata.catalog.jdbi3;
import static org.openmetadata.catalog.Entity.TEST_DEFINITION;
import java.io.IOException;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.resources.dqtests.TestDefinitionResource;
import org.openmetadata.catalog.tests.TestDefinition;
import org.openmetadata.catalog.type.EntityReference;
@ -33,7 +32,6 @@ public class TestDefinitionRepository extends EntityRepository<TestDefinition> {
@Override
public void prepare(TestDefinition entity) throws IOException {
setFullyQualifiedName(entity);
entity.setOwner(Entity.getEntityReference(entity.getOwner()));
// validate test platforms
if (entity.getTestPlatforms() == null || entity.getTestPlatforms().isEmpty()) {
throw new IllegalArgumentException("testPlatforms must not be empty");

View File

@ -3,7 +3,6 @@ package org.openmetadata.catalog.jdbi3;
import static org.openmetadata.catalog.Entity.TEST_SUITE;
import java.io.IOException;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.resources.dqtests.TestSuiteResource;
import org.openmetadata.catalog.tests.TestSuite;
import org.openmetadata.catalog.type.EntityReference;
@ -33,7 +32,6 @@ public class TestSuiteRepository extends EntityRepository<TestSuite> {
@Override
public void prepare(TestSuite entity) throws IOException {
setFullyQualifiedName(entity);
entity.setOwner(Entity.getEntityReference(entity.getOwner()));
}
@Override

View File

@ -64,7 +64,6 @@ public class TopicRepository extends EntityRepository<Topic> {
topic.setService(messagingService.getEntityReference());
topic.setServiceType(messagingService.getServiceType());
setFullyQualifiedName(topic);
topic.setOwner(Entity.getEntityReference(topic.getOwner()));
topic.setTags(addDerivedTags(topic.getTags()));
}

View File

@ -14,11 +14,15 @@ import lombok.extern.slf4j.Slf4j;
import org.openmetadata.catalog.CreateEntity;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.EntityInterface;
import org.openmetadata.catalog.api.teams.CreateTeam.TeamType;
import org.openmetadata.catalog.entity.teams.Team;
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
import org.openmetadata.catalog.jdbi3.EntityRepository;
import org.openmetadata.catalog.jdbi3.ListFilter;
import org.openmetadata.catalog.security.Authorizer;
import org.openmetadata.catalog.security.policyevaluator.OperationContext;
import org.openmetadata.catalog.security.policyevaluator.ResourceContext;
import org.openmetadata.catalog.type.EntityReference;
import org.openmetadata.catalog.type.Include;
import org.openmetadata.catalog.type.MetadataOperation;
import org.openmetadata.catalog.util.EntityUtil.Fields;
@ -164,18 +168,33 @@ public abstract class EntityResource<T extends EntityInterface, K extends Entity
return response.toResponse();
}
public T copy(T entity, CreateEntity request, String updatedBy) {
public T copy(T entity, CreateEntity request, String updatedBy) throws IOException {
EntityReference owner = validateOwner(request.getOwner());
entity.setId(UUID.randomUUID());
entity.setName(request.getName());
entity.setDisplayName(request.getDisplayName());
entity.setDescription(request.getDescription());
entity.setOwner(request.getOwner());
entity.setOwner(owner);
entity.setExtension(request.getExtension());
entity.setUpdatedBy(updatedBy);
entity.setUpdatedAt(System.currentTimeMillis());
return entity;
}
private EntityReference validateOwner(EntityReference owner) throws IOException {
if (owner == null) {
return null;
}
if (owner.getType().equals(Entity.TEAM)) {
Team team = Entity.getEntity(Entity.TEAM, owner.getId(), Fields.EMPTY_FIELDS, Include.ALL);
if (!team.getTeamType().equals(TeamType.GROUP)) {
throw new IllegalArgumentException(CatalogExceptionMessage.invalidTeamOwner(team.getTeamType()));
}
return team.getEntityReference();
}
return Entity.getEntityReferenceById(owner.getType(), owner.getId(), Include.ALL);
}
protected ResourceContext getResourceContext() {
return ResourceContext.builder().resource(entityType).entityRepository(dao).build();
}

View File

@ -307,7 +307,7 @@ public class BotResource extends EntityResource<Bot, BotRepository> {
return delete(uriInfo, securityContext, id, true, hardDelete, false);
}
private Bot getBot(CreateBot create, String user) {
private Bot getBot(CreateBot create, String user) throws IOException {
return copy(new Bot(), create, user).withBotUser(create.getBotUser());
}
}

View File

@ -387,7 +387,7 @@ public class ChartResource extends EntityResource<Chart, ChartRepository> {
return delete(uriInfo, securityContext, id, false, hardDelete, true);
}
private Chart getChart(CreateChart create, String user) {
private Chart getChart(CreateChart create, String user) throws IOException {
return copy(new Chart(), create, user)
.withService(create.getService())
.withChartType(create.getChartType())

View File

@ -391,7 +391,7 @@ public class DashboardResource extends EntityResource<Dashboard, DashboardReposi
return delete(uriInfo, securityContext, id, false, hardDelete, true);
}
private Dashboard getDashboard(CreateDashboard create, String user) {
private Dashboard getDashboard(CreateDashboard create, String user) throws IOException {
return copy(new Dashboard(), create, user)
.withService(create.getService())
.withCharts(create.getCharts())

View File

@ -366,7 +366,7 @@ public class DatabaseResource extends EntityResource<Database, DatabaseRepositor
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private Database getDatabase(CreateDatabase create, String user) {
private Database getDatabase(CreateDatabase create, String user) throws IOException {
return copy(new Database(), create, user).withService(create.getService());
}
}

View File

@ -353,7 +353,7 @@ public class DatabaseSchemaResource extends EntityResource<DatabaseSchema, Datab
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private DatabaseSchema getDatabaseSchema(CreateDatabaseSchema create, String user) {
private DatabaseSchema getDatabaseSchema(CreateDatabaseSchema create, String user) throws IOException {
return copy(new DatabaseSchema(), create, user).withDatabase(create.getDatabase());
}
}

View File

@ -944,7 +944,7 @@ public class TableResource extends EntityResource<Table, TableRepository> {
return table;
}
private Table getTable(CreateTable create, String user) {
private Table getTable(CreateTable create, String user) throws IOException {
return validateNewTable(
copy(new Table(), create, user)
.withColumns(create.getColumns())

View File

@ -473,7 +473,7 @@ public class TestCaseResource extends EntityResource<TestCase, TestCaseRepositor
return addHref(uriInfo, testCase);
}
private TestCase getTestCase(CreateTestCase create, String user) {
private TestCase getTestCase(CreateTestCase create, String user) throws IOException {
return copy(new TestCase(), create, user)
.withDescription(create.getDescription())
.withName(create.getName())

View File

@ -376,7 +376,7 @@ public class TestDefinitionResource extends EntityResource<TestDefinition, TestD
return delete(uriInfo, securityContext, id, false, hardDelete, true);
}
private TestDefinition getTestDefinition(CreateTestDefinition create, String user) {
private TestDefinition getTestDefinition(CreateTestDefinition create, String user) throws IOException {
return copy(new TestDefinition(), create, user)
.withDescription(create.getDescription())
.withEntityType(create.getEntityType())

View File

@ -333,7 +333,7 @@ public class TestSuiteResource extends EntityResource<TestSuite, TestSuiteReposi
return delete(uriInfo, securityContext, id, false, hardDelete, true);
}
private TestSuite getTestSuite(CreateTestSuite create, String user) {
private TestSuite getTestSuite(CreateTestSuite create, String user) throws IOException {
return copy(new TestSuite(), create, user)
.withDescription(create.getDescription())
.withScheduleInterval(create.getScheduleInterval())

View File

@ -345,7 +345,7 @@ public class WebhookResource extends EntityResource<Webhook, WebhookRepository>
return response;
}
public Webhook getWebhook(CreateWebhook create, String user) {
public Webhook getWebhook(CreateWebhook create, String user) throws IOException {
// Add filter for soft delete events if delete event type is requested
EntityUtil.addSoftDeleteFilter(create.getEventFilters());
return copy(new Webhook(), create, user)

View File

@ -349,7 +349,7 @@ public class GlossaryResource extends EntityResource<Glossary, GlossaryRepositor
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private Glossary getGlossary(CreateGlossary create, String user) {
private Glossary getGlossary(CreateGlossary create, String user) throws IOException {
return copy(new Glossary(), create, user).withReviewers(create.getReviewers()).withTags(create.getTags());
}
}

View File

@ -398,7 +398,7 @@ public class GlossaryTermResource extends EntityResource<GlossaryTerm, GlossaryT
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private GlossaryTerm getGlossaryTerm(CreateGlossaryTerm create, String user) {
private GlossaryTerm getGlossaryTerm(CreateGlossaryTerm create, String user) throws IOException {
return copy(new GlossaryTerm(), create, user)
.withSynonyms(create.getSynonyms())
.withGlossary(create.getGlossary())

View File

@ -490,7 +490,7 @@ public class LocationResource extends EntityResource<Location, LocationRepositor
return location;
}
private Location getLocation(CreateLocation create, String user) {
private Location getLocation(CreateLocation create, String user) throws IOException {
return copy(new Location(), create, user)
.withPath(create.getPath())
.withService(create.getService())

View File

@ -403,7 +403,7 @@ public class MlModelResource extends EntityResource<MlModel, MlModelRepository>
return delete(uriInfo, securityContext, id, false, hardDelete, true);
}
private MlModel getMlModel(CreateMlModel create, String user) {
private MlModel getMlModel(CreateMlModel create, String user) throws IOException {
return copy(new MlModel(), create, user)
.withService(create.getService())
.withDashboard(create.getDashboard())

View File

@ -528,7 +528,7 @@ public class PipelineResource extends EntityResource<Pipeline, PipelineRepositor
return delete(uriInfo, securityContext, id, false, hardDelete, true);
}
private Pipeline getPipeline(CreatePipeline create, String user) {
private Pipeline getPipeline(CreatePipeline create, String user) throws IOException {
return copy(new Pipeline(), create, user)
.withService(create.getService())
.withTasks(create.getTasks())

View File

@ -395,7 +395,7 @@ public class PolicyResource extends EntityResource<Policy, PolicyRepository> {
return response;
}
private Policy getPolicy(CreatePolicy create, String user) {
private Policy getPolicy(CreatePolicy create, String user) throws IOException {
Policy policy =
copy(new Policy(), create, user)
.withPolicyType(create.getPolicyType())

View File

@ -352,7 +352,7 @@ public class DashboardServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private DashboardService getService(CreateDashboardService create, String user) {
private DashboardService getService(CreateDashboardService create, String user) throws IOException {
return copy(new DashboardService(), create, user)
.withServiceType(create.getServiceType())
.withConnection(create.getConnection());

View File

@ -358,7 +358,7 @@ public class DatabaseServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private DatabaseService getService(CreateDatabaseService create, String user) {
private DatabaseService getService(CreateDatabaseService create, String user) throws IOException {
return copy(new DatabaseService(), create, user)
.withServiceType(create.getServiceType())
.withConnection(create.getConnection());

View File

@ -548,7 +548,7 @@ public class IngestionPipelineResource extends EntityResource<IngestionPipeline,
return Response.ok(lastIngestionLogs, MediaType.APPLICATION_JSON_TYPE).build();
}
private IngestionPipeline getIngestionPipeline(CreateIngestionPipeline create, String user) {
private IngestionPipeline getIngestionPipeline(CreateIngestionPipeline create, String user) throws IOException {
OpenMetadataServerConnection openMetadataServerConnection =
secretsManager.decryptServerConnection(airflowConfiguration);
openMetadataServerConnection.setSecretsManagerProvider(this.secretsManager.getSecretsManagerProvider());

View File

@ -358,7 +358,7 @@ public class MessagingServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private MessagingService getService(CreateMessagingService create, String user) {
private MessagingService getService(CreateMessagingService create, String user) throws IOException {
return copy(new MessagingService(), create, user)
.withConnection(create.getConnection())
.withServiceType(create.getServiceType());

View File

@ -354,7 +354,7 @@ public class MlModelServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private MlModelService getService(CreateMlModelService create, String user) {
private MlModelService getService(CreateMlModelService create, String user) throws IOException {
return copy(new MlModelService(), create, user)
.withServiceType(create.getServiceType())
.withConnection(create.getConnection());

View File

@ -353,7 +353,7 @@ public class PipelineServiceResource
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private PipelineService getService(CreatePipelineService create, String user) {
private PipelineService getService(CreatePipelineService create, String user) throws IOException {
return copy(new PipelineService(), create, user)
.withServiceType(create.getServiceType())
.withConnection(create.getConnection());

View File

@ -320,7 +320,7 @@ public class StorageServiceResource extends EntityResource<StorageService, Stora
return delete(uriInfo, securityContext, id, recursive, hardDelete, true);
}
private StorageService getService(CreateStorageService create, String user) {
private StorageService getService(CreateStorageService create, String user) throws IOException {
return copy(new StorageService(), create, user).withServiceType(create.getServiceType());
}
}

View File

@ -401,7 +401,7 @@ public class RoleResource extends EntityResource<Role, RoleRepository> {
return response;
}
private Role getRole(CreateRole create, String user) {
private Role getRole(CreateRole create, String user) throws IOException {
if (nullOrEmpty(create.getPolicies())) {
throw new IllegalArgumentException("At least one policy is required to create a role");
}

View File

@ -359,10 +359,13 @@ public class TeamResource extends EntityResource<Team, TeamRepository> {
return delete(uriInfo, securityContext, id, false, hardDelete, true);
}
private Team getTeam(CreateTeam ct, String user) {
private Team getTeam(CreateTeam ct, String user) throws IOException {
if (ct.getTeamType().equals(TeamType.ORGANIZATION)) {
throw new IllegalArgumentException(CatalogExceptionMessage.createOrganization());
}
if (ct.getTeamType().equals(TeamType.GROUP) && ct.getChildren() != null) {
throw new IllegalArgumentException(CatalogExceptionMessage.createGroup());
}
return copy(new Team(), ct, user)
.withProfile(ct.getProfile())
.withIsJoinable(ct.getIsJoinable())

View File

@ -422,7 +422,7 @@ public class TopicResource extends EntityResource<Topic, TopicRepository> {
return delete(uriInfo, securityContext, id, false, hardDelete, true);
}
private Topic getTopic(CreateTopic create, String user) {
private Topic getTopic(CreateTopic create, String user) throws IOException {
return copy(new Topic(), create, user)
.withService(create.getService())
.withPartitions(create.getPartitions())

View File

@ -394,7 +394,7 @@ public class TypeResource extends EntityResource<Type, TypeRepository> {
return response.toResponse();
}
private Type getType(CreateType create, String user) {
private Type getType(CreateType create, String user) throws IOException {
return copy(new Type(), create, user)
.withFullyQualifiedName(create.getName())
.withCategory(create.getCategory())

View File

@ -8,15 +8,16 @@
"javaInterfaces": ["org.openmetadata.catalog.EntityInterface"],
"definitions": {
"teamType" : {
"description" : "Organization is the highest level entity. An Organization has one of more Business Units, Division, or Departments. A Business Unit has one or more Divisions, or Departments. A Division has one or more Divisions or Departments. A Department has one or more Departments or users.",
"description" : "Organization is the highest level entity. An Organization has one of more Business Units, Division, Departments, Group, or Users. A Business Unit has one or more Divisions, Departments, Group, or Users. A Division has one or more Divisions, Departments, Group, or Users. A Department has one or more Departments, Group, or Users. A Group has a only Users",
"type" : "string",
"enum": [
"Group",
"Department",
"Division",
"BusinessUnit",
"Organization"
],
"default": "Department"
"default": "Group"
}
},
"properties": {

View File

@ -94,6 +94,7 @@ import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.EntityInterface;
import org.openmetadata.catalog.api.data.TermReference;
import org.openmetadata.catalog.api.teams.CreateTeam;
import org.openmetadata.catalog.api.teams.CreateTeam.TeamType;
import org.openmetadata.catalog.entity.Type;
import org.openmetadata.catalog.entity.data.Database;
import org.openmetadata.catalog.entity.data.DatabaseSchema;
@ -706,13 +707,25 @@ public abstract class EntityResourceTest<T extends EntityInterface, K extends Cr
}
@Test
void post_entityWithInvalidOwnerType_4xx(TestInfo test) {
void post_entityWithInvalidOwnerType_4xx(TestInfo test) throws HttpResponseException {
if (!supportsOwner) {
return;
}
EntityReference owner = new EntityReference().withId(TEAM1.getId()); /* No owner type is set */
K create = createRequest(getEntityName(test), "", "", owner);
assertResponseContains(() -> createEntity(create, ADMIN_AUTH_HEADERS), BAD_REQUEST, "type must not be null");
// Only Team of type Group is allowed to own entities
List<Team> teams =
new TeamResourceTest().getTeamOfTypes(test, TeamType.BUSINESS_UNIT, TeamType.DEPARTMENT, TeamType.DEPARTMENT);
teams.add(ORG_TEAM);
for (Team team : teams) {
K create1 = createRequest(getEntityName(test), "", "", team.getEntityReference());
assertResponseContains(
() -> createEntity(create1, ADMIN_AUTH_HEADERS),
BAD_REQUEST,
CatalogExceptionMessage.invalidTeamOwner(team.getTeamType()));
}
}
@Test

View File

@ -24,6 +24,7 @@ import static org.openmetadata.catalog.Entity.ORGANIZATION_NAME;
import static org.openmetadata.catalog.api.teams.CreateTeam.TeamType.BUSINESS_UNIT;
import static org.openmetadata.catalog.api.teams.CreateTeam.TeamType.DEPARTMENT;
import static org.openmetadata.catalog.api.teams.CreateTeam.TeamType.DIVISION;
import static org.openmetadata.catalog.api.teams.CreateTeam.TeamType.GROUP;
import static org.openmetadata.catalog.api.teams.CreateTeam.TeamType.ORGANIZATION;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.invalidParent;
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.invalidParentCount;
@ -381,19 +382,24 @@ public class TeamResourceTest extends EntityResourceTest<Team, CreateTeam> {
// Creating a parent with invalid children type is not allowed
// Department can't have Business unit as a child
assertResponse(
() -> createWithChildren("invalidTeam", DEPARTMENT, bu11.getEntityReference()),
() -> createWithChildren("invalidDepartment", DEPARTMENT, bu11.getEntityReference()),
BAD_REQUEST,
CatalogExceptionMessage.invalidChild("invalidTeam", DEPARTMENT, bu11));
CatalogExceptionMessage.invalidChild("invalidDepartment", DEPARTMENT, bu11));
// Department can't have Division as a child
assertResponse(
() -> createWithChildren("invalidTeam", DEPARTMENT, div12.getEntityReference()),
() -> createWithChildren("invalidDepartment", DEPARTMENT, div12.getEntityReference()),
BAD_REQUEST,
CatalogExceptionMessage.invalidChild("invalidTeam", DEPARTMENT, div12));
CatalogExceptionMessage.invalidChild("invalidDepartment", DEPARTMENT, div12));
// Division can't have BU as a child
assertResponse(
() -> createWithChildren("invalidTeam", DIVISION, bu11.getEntityReference()),
() -> createWithChildren("invalidDivision", DIVISION, bu11.getEntityReference()),
BAD_REQUEST,
CatalogExceptionMessage.invalidChild("invalidTeam", DIVISION, bu11));
CatalogExceptionMessage.invalidChild("invalidDivision", DIVISION, bu11));
// Group can't have other teams as children. Only users are allowed under the team
assertResponse(
() -> createWithChildren("invalidGroup", GROUP, bu11.getEntityReference()),
BAD_REQUEST,
CatalogExceptionMessage.createGroup());
}
@Test
@ -760,4 +766,13 @@ public class TeamResourceTest extends EntityResourceTest<Team, CreateTeam> {
.withRoles(List.of(teamManager.getId())),
ADMIN_AUTH_HEADERS);
}
public List<Team> getTeamOfTypes(TestInfo test, TeamType... teamTypes) throws HttpResponseException {
List<Team> teams = new ArrayList<>();
int i = 0;
for (TeamType type : teamTypes) {
teams.add(createEntity(createRequest(getEntityName(test, i++)).withTeamType(type), ADMIN_AUTH_HEADERS));
}
return teams;
}
}

View File

@ -7,5 +7,5 @@ Provides metadata version information.
from incremental import Version
__version__ = Version("metadata", 0, 12, 0, dev=7)
__version__ = Version("metadata", 0, 12, 0, dev=8)
__all__ = ["__version__"]

View File

@ -954,14 +954,6 @@ public abstract class EntityRepository<T extends EntityInterface> {
return getOwner(entity);
}
public void populateOwner(EntityReference owner) throws IOException {
if (owner == null) {
return;
}
EntityReference ref = Entity.getEntityReferenceById(owner.getType(), owner.getId(), ALL);
EntityUtil.copy(ref, owner);
}
protected void storeOwner(T entity, EntityReference owner) {
if (supportsOwner) {
// Add relationship owner --- owns ---> ownedEntity