Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui/java) Update domains to be nested #8841

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
143 commits
Select commit Hold shift + click to select a range
6447d3a
Add feature flag for Nested Domains work
chriscollins3456 Aug 24, 2023
2be1631
feat(nested-domains): parentDomain model change
Aug 24, 2023
0372cde
Add feature flag for Nested Domains work (#1672)
chriscollins3456 Aug 24, 2023
6079f1c
feat(nested-domains): parentDomain model change (#1674)
joshuaeilers Aug 24, 2023
9814f02
set up skeleton for new manage domains page
chriscollins3456 Aug 24, 2023
a179c68
get sidebar and header of page together
chriscollins3456 Aug 24, 2023
90cdea8
show root domains
chriscollins3456 Aug 24, 2023
0e1fbdf
display domains sidebar on domain profile page
chriscollins3456 Aug 24, 2023
c45803c
update styling
chriscollins3456 Aug 24, 2023
339a947
fix routing situation when flag is off
chriscollins3456 Aug 24, 2023
0893ee4
feat(nested-domains): parentDomain in listDomains resolver
Aug 24, 2023
3c552e2
add parentDomain input to create domain resolver
Aug 25, 2023
4decf3e
back out a gql field
Aug 25, 2023
56644fc
add todos
Aug 25, 2023
2c84014
get test to pass
Aug 25, 2023
3548a4e
feat(nested-domains): parentDomain in listDomains/create resolvers (#…
joshuaeilers Aug 25, 2023
cd1a627
PR edits
chriscollins3456 Aug 25, 2023
00d9c3e
chore(nested-domains): list and create tests
Aug 25, 2023
efcc8cb
Add new Domains home page behind feature flag (#1678)
chriscollins3456 Aug 25, 2023
0fa4c3f
feat(nested-domains): support children relationship query
Aug 25, 2023
0fbc505
chore(nested-domains): list and create tests (#1683)
joshuaeilers Aug 25, 2023
8a551c3
feat(nested-domains): support children relationship query (#1684)
joshuaeilers Aug 25, 2023
2eb31ab
feat(nested-domains): validate domain names
Aug 25, 2023
8da12db
improve validation
Aug 25, 2023
d851e87
plug in more usage of static const
Aug 25, 2023
d4b4e95
remove todo
Aug 25, 2023
297f26e
add DomainNavigator and allow exploration of domains
chriscollins3456 Aug 28, 2023
4638ada
set entity data and show styled selected domain in sidebar
chriscollins3456 Aug 28, 2023
2a94f29
remove a filter mock we don't need
Aug 28, 2023
554bf70
feat(nested-domains): validate domain names (#1685)
joshuaeilers Aug 28, 2023
d111394
feat(nested-domains): validate name is unique per level
Aug 28, 2023
fb0595c
feat(nested-domains): validate name is unique per level (#1686)
joshuaeilers Aug 28, 2023
9c8b342
hide toggle if no domain children
chriscollins3456 Aug 28, 2023
4dfe084
Do not allow deleting a domain with child domains
Aug 28, 2023
a8d8c15
feat(nested-domains): ParentDomainsResolver
Aug 28, 2023
814227e
back out parentDomains from list resolver for now
Aug 28, 2023
eacccb0
s/thenThrow/assertThrow
Aug 28, 2023
87a0808
feat(ui) Creeate and display Domains Navigator (#1689)
chriscollins3456 Aug 28, 2023
d98cf77
more generic graphql resolver
Aug 28, 2023
b54da1d
first pass
eboneil Aug 29, 2023
1e28dc4
clean up a bit
eboneil Aug 29, 2023
d2d5584
feat(domains): Do not allow deleting a domain with child domains (#1690)
iprentic Aug 29, 2023
687d860
feat(nested-domains): ParentDomainsResolver (#1691)
joshuaeilers Aug 29, 2023
0cba2c4
remove console.log
Aug 29, 2023
9fe4e83
Update Domain search result card to include more info
chriscollins3456 Aug 29, 2023
3b4a779
merge in nested-domains-feature-branch and resolve conflict
chriscollins3456 Aug 29, 2023
8d0d13f
get the rest
eboneil Aug 29, 2023
ca726d2
clean up
eboneil Aug 29, 2023
87eb38d
PR comment
eboneil Aug 29, 2023
a0804b6
before testing subdomains
eboneil Aug 29, 2023
ed842a1
tweak
eboneil Aug 29, 2023
f270ae7
Auto open domain navigator to current domain
chriscollins3456 Aug 29, 2023
72f266b
feat(nested-domains) consistent domain logos (#1698)
eboneil Aug 29, 2023
9d1b78e
fix(nested-domains): better error handling on name collisions
Aug 30, 2023
beedf64
fix(nested-domains): better error handling on name collisions (#1705)
joshuaeilers Aug 30, 2023
291c77e
add parent node field in modal and set things up
chriscollins3456 Aug 28, 2023
1a46978
allow selecting of parents in modals and update parent cache
chriscollins3456 Aug 28, 2023
4d79622
implement parentDomainsToUpdate after creating a domain
chriscollins3456 Aug 28, 2023
465a875
final pieces for create domain
chriscollins3456 Aug 28, 2023
0581fde
update useEffect
chriscollins3456 Aug 30, 2023
ba43023
Allow creating nested domains from the FE (#1694)
chriscollins3456 Aug 30, 2023
e1ca302
Handle deleting a domain and update sidebar
chriscollins3456 Aug 29, 2023
b0c4da4
Merge branch 'nested-domains-feature-branch' into cc--domain-search-card
chriscollins3456 Aug 30, 2023
3f7cc30
Update Domain search result card to include more info (#1697)
chriscollins3456 Aug 30, 2023
5d84bea
Handle deleting a domain and update sidebar (#1708)
joshuaeilers Aug 30, 2023
8be73d6
fix(nested-domains): unbreak gql file
Aug 30, 2023
e087183
add search to sidebar
eboneil Aug 29, 2023
9f38b2a
fix(nested-domains): unbreak gql file (#1709)
chriscollins3456 Aug 30, 2023
9f18dc9
Merge branch 'nested-domains-feature-branch' into manage_domains_sear…
eboneil Aug 30, 2023
7f71bb2
add search bar
eboneil Aug 30, 2023
7bb7075
clean up
eboneil Aug 30, 2023
5b4e16d
feat(nested-domains) Disable delete if domain has subdomains (#1700)
eboneil Aug 30, 2023
1d93263
feat(nested-domains): authorization by parent domain
Aug 31, 2023
f9007f7
Add debounce
eboneil Aug 31, 2023
3c0742b
Display parent domain path in various places for domains
chriscollins3456 Aug 31, 2023
e21a94c
chore(nested-domains): test for parent domain auth
Aug 31, 2023
f73018b
rm logs
Aug 31, 2023
16b573d
fix bug in ParentEntities
chriscollins3456 Aug 31, 2023
035e03a
Fix typo in nested domains context
chriscollins3456 Aug 31, 2023
614afe1
feat(nested-domains): authorization by parent domain (#1713)
joshuaeilers Aug 31, 2023
ac47b6b
tests for parent domain auth (#1720)
joshuaeilers Aug 31, 2023
acfa15a
feat(nested-domains) Manage domains search (#1711)
eboneil Aug 31, 2023
d70dae6
Update domains section on homepage
chriscollins3456 Aug 31, 2023
c585d7b
chore(nested-domains): more auth tests
Aug 31, 2023
b4af40d
feat(nested-domains): adjust copy on policy builder
Aug 31, 2023
fdaf0b8
Fix typo in nested domains context (#1721)
chriscollins3456 Sep 1, 2023
1c5a7fc
merge in nested-domains-feature-branch, resolve conflicts
chriscollins3456 Sep 1, 2023
5102174
Auto open domain navigator to current domain (#1701)
chriscollins3456 Sep 1, 2023
6aac656
Display parent domain path in various places for domains (#1719)
chriscollins3456 Sep 1, 2023
3d64d33
fix weird filter logic
chriscollins3456 Sep 1, 2023
3f7342e
Update domains section on homepage (#1722)
chriscollins3456 Sep 1, 2023
34ce378
update caching function
chriscollins3456 Sep 1, 2023
fad75de
chore(nested-domains): more auth tests (#1724)
joshuaeilers Sep 1, 2023
5102e46
adjust copy some more
Sep 1, 2023
6aaf767
more copy
Sep 1, 2023
9f6af1b
adjust
Sep 1, 2023
bb54f72
adjust copy on policy builder (#1725)
joshuaeilers Sep 1, 2023
1c4b064
use navigator when selecting a domain
chriscollins3456 Sep 5, 2023
90d7be2
feat(nested-domains): move domain resolver
Sep 5, 2023
a04f9a4
use navigator in polict builder
chriscollins3456 Sep 5, 2023
6bb4e6b
test updates
Sep 5, 2023
cc1dd38
Reuse domain navigator for selecting domains in remaining places (#1731)
chriscollins3456 Sep 5, 2023
c8bf2a8
move domain resolver (#1732)
joshuaeilers Sep 5, 2023
aaa745a
fix(nested-domains): do not overlap button icon
Sep 5, 2023
3c04bfd
remove an unused graphql definition that wasn't compiling
Sep 5, 2023
cdd1bc8
feat(nested-domains): move parent
Sep 5, 2023
af7712d
fix(nested-domains): do not overlap button icon (#1733)
joshuaeilers Sep 6, 2023
41bfaae
wip
Sep 6, 2023
862274e
Merge remote-tracking branch 'private/nested-domains-feature-branch' …
Sep 6, 2023
dff1fe7
big wip
Sep 7, 2023
aa2dd03
fix(nested-domains): prevent parent cycles
Sep 7, 2023
bf4a676
cmt
Sep 7, 2023
60cf7f4
fix(nested-domains): Hide child when moving
Sep 7, 2023
06ba5e8
sort domains by display name
Sep 7, 2023
3d4b064
code review feedback
Sep 7, 2023
1e5cfb6
feat(nested-domains): move parent (#1734)
joshuaeilers Sep 7, 2023
5d5261c
prevent parent domain cycles in auth / resolver (#1738)
joshuaeilers Sep 7, 2023
7ce14da
fix(nested-domains): Hide child when moving (#1739)
joshuaeilers Sep 7, 2023
b101f41
sort domains by name (#1741)
joshuaeilers Sep 7, 2023
e2345d9
feat(nested-domains): domain autocomplete improvements
Sep 7, 2023
7502f94
nested domain analytics
Sep 7, 2023
1ac8a76
feat(nested-domains): domain autocomplete improvements (#1742)
joshuaeilers Sep 7, 2023
b8aa3e6
remove log
Sep 7, 2023
396b6ac
Merge branch 'nested-domains-feature-branch' into je--nested-domain-a…
joshuaeilers Sep 7, 2023
27ddd91
remove "your domains" header
Sep 7, 2023
7439bfe
styling feedback
Sep 7, 2023
048cdc7
better clear handling
Sep 7, 2023
f4330e2
tidy up
Sep 7, 2023
99fe0b5
nested domain analytics (#1743)
joshuaeilers Sep 8, 2023
4b3ddda
Create domain modal ui tweaks (#1744)
joshuaeilers Sep 8, 2023
af9310e
feature flag wire up
Sep 8, 2023
a8575d1
use domains context in v1
Sep 8, 2023
e0be65d
fix move link condition
Sep 8, 2023
550ab19
feature flag wire up (#1749)
joshuaeilers Sep 8, 2023
8728358
fix(nested-domains): show parent path in modals
Sep 13, 2023
fe7160f
fix(nested-domains): show parent path in modals (#1769)
joshuaeilers Sep 13, 2023
162ffe9
merge in master, resolve conflicts
chriscollins3456 Sep 14, 2023
96917fb
remove unneeded stuff
chriscollins3456 Sep 14, 2023
948eb2c
remove slf4j from test
chriscollins3456 Sep 14, 2023
d13eddc
format tests
chriscollins3456 Sep 14, 2023
89f23e3
fix broken test
chriscollins3456 Sep 15, 2023
b9d4a2e
fix cypress tests
chriscollins3456 Sep 15, 2023
86cfb06
fix cypress tests (finally)
chriscollins3456 Sep 18, 2023
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 @@ -81,6 +81,7 @@
import com.linkedin.datahub.graphql.generated.Notebook;
import com.linkedin.datahub.graphql.generated.Owner;
import com.linkedin.datahub.graphql.generated.OwnershipTypeEntity;
import com.linkedin.datahub.graphql.generated.ParentDomainsResult;
import com.linkedin.datahub.graphql.generated.PolicyMatchCriterionValue;
import com.linkedin.datahub.graphql.generated.QueryEntity;
import com.linkedin.datahub.graphql.generated.QuerySubject;
Expand Down Expand Up @@ -124,6 +125,7 @@
import com.linkedin.datahub.graphql.resolvers.domain.DeleteDomainResolver;
import com.linkedin.datahub.graphql.resolvers.domain.DomainEntitiesResolver;
import com.linkedin.datahub.graphql.resolvers.domain.ListDomainsResolver;
import com.linkedin.datahub.graphql.resolvers.domain.ParentDomainsResolver;
import com.linkedin.datahub.graphql.resolvers.domain.SetDomainResolver;
import com.linkedin.datahub.graphql.resolvers.domain.UnsetDomainResolver;
import com.linkedin.datahub.graphql.resolvers.embed.UpdateEmbedResolver;
Expand Down Expand Up @@ -186,6 +188,7 @@
import com.linkedin.datahub.graphql.resolvers.mutate.BatchSetDomainResolver;
import com.linkedin.datahub.graphql.resolvers.mutate.BatchUpdateDeprecationResolver;
import com.linkedin.datahub.graphql.resolvers.mutate.BatchUpdateSoftDeletedResolver;
import com.linkedin.datahub.graphql.resolvers.mutate.MoveDomainResolver;
import com.linkedin.datahub.graphql.resolvers.mutate.MutableTypeBatchResolver;
import com.linkedin.datahub.graphql.resolvers.mutate.MutableTypeResolver;
import com.linkedin.datahub.graphql.resolvers.mutate.RemoveLinkResolver;
Expand Down Expand Up @@ -944,6 +947,7 @@ private void configureMutationResolvers(final RuntimeWiring.Builder builder) {
.dataFetcher("removeGroup", new RemoveGroupResolver(this.entityClient))
.dataFetcher("updateUserStatus", new UpdateUserStatusResolver(this.entityClient))
.dataFetcher("createDomain", new CreateDomainResolver(this.entityClient, this.entityService))
.dataFetcher("moveDomain", new MoveDomainResolver(this.entityService, this.entityClient))
.dataFetcher("deleteDomain", new DeleteDomainResolver(entityClient))
.dataFetcher("setDomain", new SetDomainResolver(this.entityClient, this.entityService))
.dataFetcher("batchSetDomain", new BatchSetDomainResolver(this.entityService))
Expand Down Expand Up @@ -1029,6 +1033,13 @@ private void configureGenericEntityResolvers(final RuntimeWiring.Builder builder
.dataFetcher("entities", new EntityTypeBatchResolver(entityTypes,
(env) -> ((BrowseResults) env.getSource()).getEntities()))
)
.type("ParentDomainsResult", typeWiring -> typeWiring
.dataFetcher("domains", new EntityTypeBatchResolver(entityTypes,
(env) -> {
final ParentDomainsResult result = env.getSource();
return result != null ? result.getDomains() : null;
}))
)
.type("EntityRelationshipLegacy", typeWiring -> typeWiring
.dataFetcher("entity", new EntityTypeResolver(entityTypes,
(env) -> ((EntityRelationshipLegacy) env.getSource()).getEntity()))
Expand Down Expand Up @@ -1675,8 +1686,8 @@ private void configureGlossaryRelationshipResolvers(final RuntimeWiring.Builder
private void configureDomainResolvers(final RuntimeWiring.Builder builder) {
builder.type("Domain", typeWiring -> typeWiring
.dataFetcher("entities", new DomainEntitiesResolver(this.entityClient))
.dataFetcher("relationships", new EntityRelationshipsResultResolver(graphClient)
)
.dataFetcher("parentDomains", new ParentDomainsResolver(this.entityClient))
.dataFetcher("relationships", new EntityRelationshipsResultResolver(graphClient))
);
builder.type("DomainAssociation", typeWiring -> typeWiring
.dataFetcher("domain",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public enum DataHubGraphQLErrorCode {
BAD_REQUEST(400),
UNAUTHORIZED(403),
NOT_FOUND(404),
CONFLICT(409),
SERVER_ERROR(500);

private final int _code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ public class FeatureFlags {
private PreProcessHooks preProcessHooks;
private boolean showAcrylInfo = false;
private boolean showAccessManagement = false;
private boolean nestedDomainsEnabled = false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ public CompletableFuture<AppConfig> get(final DataFetchingEnvironment environmen
.setShowBrowseV2(_featureFlags.isShowBrowseV2())
.setShowAcrylInfo(_featureFlags.isShowAcrylInfo())
.setShowAccessManagement(_featureFlags.isShowAccessManagement())
.setNestedDomainsEnabled(_featureFlags.isNestedDomainsEnabled())
.build();

appConfig.setFeatureFlags(featureFlagsConfig);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.linkedin.datahub.graphql.resolvers.domain;

import com.linkedin.common.AuditStamp;
import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
import com.linkedin.data.template.SetMode;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.authorization.AuthorizationUtils;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.exception.DataHubGraphQLErrorCode;
import com.linkedin.datahub.graphql.exception.DataHubGraphQLException;
import com.linkedin.datahub.graphql.generated.CreateDomainInput;
import com.linkedin.datahub.graphql.generated.OwnerEntityType;
import com.linkedin.datahub.graphql.generated.OwnershipType;
import com.linkedin.datahub.graphql.resolvers.mutate.util.DomainUtils;
import com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils;
import com.linkedin.domain.DomainProperties;
import com.linkedin.entity.client.EntityClient;
Expand All @@ -19,8 +23,11 @@
import com.linkedin.mxe.MetadataChangeProposal;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;

import java.net.URISyntaxException;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -45,9 +52,9 @@ public CompletableFuture<String> get(DataFetchingEnvironment environment) throws

final QueryContext context = environment.getContext();
final CreateDomainInput input = bindArgument(environment.getArgument("input"), CreateDomainInput.class);
final Urn parentDomain = input.getParentDomain() != null ? UrnUtils.getUrn(input.getParentDomain()) : null;

return CompletableFuture.supplyAsync(() -> {

if (!AuthorizationUtils.canCreateDomains(context)) {
throw new AuthorizationException("Unauthorized to perform this action. Please contact your DataHub administrator.");
}
Expand All @@ -64,6 +71,17 @@ public CompletableFuture<String> get(DataFetchingEnvironment environment) throws
throw new IllegalArgumentException("This Domain already exists!");
}

if (parentDomain != null && !_entityClient.exists(parentDomain, context.getAuthentication())) {
throw new IllegalArgumentException("Parent Domain does not exist!");
}

if (DomainUtils.hasNameConflict(input.getName(), parentDomain, context, _entityClient)) {
throw new DataHubGraphQLException(
String.format("\"%s\" already exists in this domain. Please pick a unique name.", input.getName()),
DataHubGraphQLErrorCode.CONFLICT
);
}

// Create the MCP
final MetadataChangeProposal proposal = buildMetadataChangeProposalWithKey(key, DOMAIN_ENTITY_NAME,
DOMAIN_PROPERTIES_ASPECT_NAME, mapDomainProperties(input, context));
Expand All @@ -77,6 +95,8 @@ public CompletableFuture<String> get(DataFetchingEnvironment environment) throws
}
OwnerUtils.addCreatorAsOwner(context, domainUrn, OwnerEntityType.CORP_USER, ownershipType, _entityService);
return domainUrn;
} catch (DataHubGraphQLException e) {
throw e;
} catch (Exception e) {
log.error("Failed to create Domain with id: {}, name: {}: {}", input.getId(), input.getName(), e.getMessage());
throw new RuntimeException(String.format("Failed to create Domain with id: %s, name: %s", input.getId(), input.getName()), e);
Expand All @@ -89,6 +109,13 @@ private DomainProperties mapDomainProperties(final CreateDomainInput input, fina
result.setName(input.getName());
result.setDescription(input.getDescription(), SetMode.IGNORE_NULL);
result.setCreated(new AuditStamp().setActor(UrnUtils.getUrn(context.getActorUrn())).setTime(System.currentTimeMillis()));
if (input.getParentDomain() != null) {
try {
result.setParentDomain(Urn.createFromString(input.getParentDomain()));
} catch (URISyntaxException e) {
throw new RuntimeException(String.format("Failed to create Domain Urn from string: %s", input.getParentDomain()), e);
}
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.authorization.AuthorizationUtils;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.resolvers.mutate.util.DomainUtils;
import com.linkedin.entity.client.EntityClient;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
Expand Down Expand Up @@ -32,6 +33,11 @@ public CompletableFuture<Boolean> get(final DataFetchingEnvironment environment)

if (AuthorizationUtils.canManageDomains(context) || AuthorizationUtils.canDeleteEntity(urn, context)) {
try {
// Make sure there are no child domains
if (DomainUtils.hasChildDomains(urn, context, _entityClient)) {
throw new RuntimeException(String.format("Cannot delete domain %s which has child domains", domainUrn));
}

_entityClient.deleteEntity(urn, context.getAuthentication());
log.info(String.format("I've successfully deleted the entity %s with urn", domainUrn));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.linkedin.datahub.graphql.resolvers.domain;

import com.google.common.collect.ImmutableList;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.generated.Domain;
import com.linkedin.datahub.graphql.generated.DomainEntitiesInput;
Expand Down Expand Up @@ -67,17 +66,22 @@ public CompletableFuture<SearchResults> get(final DataFetchingEnvironment enviro

try {

final CriterionArray criteria = new CriterionArray();
final Criterion filterCriterion = new Criterion()
.setField(DOMAINS_FIELD_NAME + ".keyword")
.setCondition(Condition.EQUAL)
.setValue(urn);
criteria.add(filterCriterion);
if (input.getFilters() != null) {
input.getFilters().forEach(filter -> {
criteria.add(new Criterion().setField(filter.getField()).setValue(filter.getValue()));
});
}

return UrnSearchResultsMapper.map(_entityClient.searchAcrossEntities(
SEARCHABLE_ENTITY_TYPES.stream().map(EntityTypeMapper::getName).collect(Collectors.toList()),
query,
new Filter().setOr(new ConjunctiveCriterionArray(
new ConjunctiveCriterion().setAnd(new CriterionArray(ImmutableList.of(filterCriterion)))
)),
new Filter().setOr(new ConjunctiveCriterionArray(new ConjunctiveCriterion().setAnd(criteria))),
start,
count,
null,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
package com.linkedin.datahub.graphql.resolvers.domain;

import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.authorization.AuthorizationUtils;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.Domain;
import com.linkedin.datahub.graphql.generated.EntityType;
import com.linkedin.datahub.graphql.generated.ListDomainsInput;
import com.linkedin.datahub.graphql.generated.ListDomainsResult;
import com.linkedin.datahub.graphql.resolvers.mutate.util.DomainUtils;
import com.linkedin.entity.client.EntityClient;
import com.linkedin.metadata.Constants;
import com.linkedin.metadata.query.SearchFlags;
import com.linkedin.metadata.query.filter.Filter;
import com.linkedin.metadata.query.filter.SortCriterion;
import com.linkedin.metadata.query.filter.SortOrder;
import com.linkedin.metadata.search.SearchEntity;
import com.linkedin.metadata.search.SearchResult;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
Expand All @@ -30,7 +32,6 @@
* Resolver used for listing all Domains defined within DataHub. Requires the MANAGE_DOMAINS platform privilege.
*/
public class ListDomainsResolver implements DataFetcher<CompletableFuture<ListDomainsResult>> {

private static final Integer DEFAULT_START = 0;
private static final Integer DEFAULT_COUNT = 20;
private static final String DEFAULT_QUERY = "";
Expand All @@ -48,18 +49,19 @@ public CompletableFuture<ListDomainsResult> get(final DataFetchingEnvironment en

return CompletableFuture.supplyAsync(() -> {

if (AuthorizationUtils.canCreateDomains(context)) {
final ListDomainsInput input = bindArgument(environment.getArgument("input"), ListDomainsInput.class);
final Integer start = input.getStart() == null ? DEFAULT_START : input.getStart();
final Integer count = input.getCount() == null ? DEFAULT_COUNT : input.getCount();
final String query = input.getQuery() == null ? DEFAULT_QUERY : input.getQuery();
final Urn parentDomainUrn = input.getParentDomain() != null ? UrnUtils.getUrn(input.getParentDomain()) : null;
final Filter filter = DomainUtils.buildParentDomainFilter(parentDomainUrn);

try {
// First, get all group Urns.
// First, get all domain Urns.
final SearchResult gmsResult = _entityClient.search(
Constants.DOMAIN_ENTITY_NAME,
query,
null,
filter,
new SortCriterion().setField(DOMAIN_CREATED_TIME_INDEX_FIELD_NAME).setOrder(SortOrder.DESCENDING),
start,
count,
Expand All @@ -78,8 +80,6 @@ public CompletableFuture<ListDomainsResult> get(final DataFetchingEnvironment en
} catch (Exception e) {
throw new RuntimeException("Failed to list domains", e);
}
}
throw new AuthorizationException("Unauthorized to perform this action. Please contact your DataHub administrator.");
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.linkedin.datahub.graphql.resolvers.domain;

import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.generated.Entity;
import com.linkedin.datahub.graphql.generated.ParentDomainsResult;
import com.linkedin.datahub.graphql.resolvers.mutate.util.DomainUtils;
import com.linkedin.entity.client.EntityClient;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;

import static com.linkedin.metadata.Constants.DOMAIN_ENTITY_NAME;

public class ParentDomainsResolver implements DataFetcher<CompletableFuture<ParentDomainsResult>> {

private final EntityClient _entityClient;

public ParentDomainsResolver(final EntityClient entityClient) {
_entityClient = entityClient;
}

@Override
public CompletableFuture<ParentDomainsResult> get(DataFetchingEnvironment environment) {
final QueryContext context = environment.getContext();
final Urn urn = UrnUtils.getUrn(((Entity) environment.getSource()).getUrn());
final List<Entity> parentDomains = new ArrayList<>();
final Set<String> visitedParentUrns = new HashSet<>();

if (!DOMAIN_ENTITY_NAME.equals(urn.getEntityType())) {
throw new IllegalArgumentException(String.format("Failed to resolve parents for entity type %s", urn));
}

return CompletableFuture.supplyAsync(() -> {
try {
Entity parentDomain = DomainUtils.getParentDomain(urn, context, _entityClient);

while (parentDomain != null && !visitedParentUrns.contains(parentDomain.getUrn())) {
parentDomains.add(parentDomain);
visitedParentUrns.add(parentDomain.getUrn());
parentDomain = DomainUtils.getParentDomain(Urn.createFromString(parentDomain.getUrn()), context, _entityClient);
}

final ParentDomainsResult result = new ParentDomainsResult();
result.setCount(parentDomains.size());
result.setDomains(parentDomains);
return result;
} catch (Exception e) {
throw new RuntimeException(String.format("Failed to load parent domains for entity %s", urn), e);
}
});
}
}
Loading
Loading