Skip to content

Commit e12275d

Browse files
chriscollins3456chakru-r
authored andcommitted
feat(structuredProperties) Add new settings aspect plus graphql changes for structured props (datahub-project#12052)
1 parent 3c50ffe commit e12275d

File tree

37 files changed

+913
-124
lines changed

37 files changed

+913
-124
lines changed

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/structuredproperties/CreateStructuredPropertyResolver.java

+89-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package com.linkedin.datahub.graphql.resolvers.structuredproperties;
22

33
import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.bindArgument;
4-
import static com.linkedin.metadata.Constants.STRUCTURED_PROPERTY_ENTITY_NAME;
4+
import static com.linkedin.datahub.graphql.resolvers.mutate.MutationUtils.buildMetadataChangeProposalWithUrn;
5+
import static com.linkedin.metadata.Constants.*;
56

67
import com.linkedin.common.urn.Urn;
78
import com.linkedin.data.template.SetMode;
@@ -12,20 +13,24 @@
1213
import com.linkedin.datahub.graphql.exception.AuthorizationException;
1314
import com.linkedin.datahub.graphql.generated.CreateStructuredPropertyInput;
1415
import com.linkedin.datahub.graphql.generated.StructuredPropertyEntity;
16+
import com.linkedin.datahub.graphql.generated.StructuredPropertySettingsInput;
1517
import com.linkedin.datahub.graphql.types.structuredproperty.StructuredPropertyMapper;
1618
import com.linkedin.entity.EntityResponse;
1719
import com.linkedin.entity.client.EntityClient;
1820
import com.linkedin.metadata.aspect.patch.builder.StructuredPropertyDefinitionPatchBuilder;
21+
import com.linkedin.metadata.models.StructuredPropertyUtils;
1922
import com.linkedin.metadata.utils.EntityKeyUtils;
2023
import com.linkedin.mxe.MetadataChangeProposal;
2124
import com.linkedin.structured.PrimitivePropertyValue;
2225
import com.linkedin.structured.PropertyCardinality;
2326
import com.linkedin.structured.PropertyValue;
2427
import com.linkedin.structured.StructuredPropertyKey;
28+
import com.linkedin.structured.StructuredPropertySettings;
2529
import graphql.schema.DataFetcher;
2630
import graphql.schema.DataFetchingEnvironment;
31+
import java.util.ArrayList;
32+
import java.util.List;
2733
import java.util.Objects;
28-
import java.util.UUID;
2934
import java.util.concurrent.CompletableFuture;
3035
import javax.annotation.Nonnull;
3136

@@ -54,40 +59,28 @@ public CompletableFuture<StructuredPropertyEntity> get(final DataFetchingEnviron
5459
"Unable to create structured property. Please contact your admin.");
5560
}
5661
final StructuredPropertyKey key = new StructuredPropertyKey();
57-
final String id = input.getId() != null ? input.getId() : UUID.randomUUID().toString();
62+
final String id =
63+
StructuredPropertyUtils.getPropertyId(input.getId(), input.getQualifiedName());
5864
key.setId(id);
5965
final Urn propertyUrn =
6066
EntityKeyUtils.convertEntityKeyToUrn(key, STRUCTURED_PROPERTY_ENTITY_NAME);
61-
StructuredPropertyDefinitionPatchBuilder builder =
62-
new StructuredPropertyDefinitionPatchBuilder().urn(propertyUrn);
63-
64-
builder.setQualifiedName(input.getQualifiedName());
65-
builder.setValueType(input.getValueType());
66-
input.getEntityTypes().forEach(builder::addEntityType);
67-
if (input.getDisplayName() != null) {
68-
builder.setDisplayName(input.getDisplayName());
69-
}
70-
if (input.getDescription() != null) {
71-
builder.setDescription(input.getDescription());
72-
}
73-
if (input.getImmutable() != null) {
74-
builder.setImmutable(input.getImmutable());
75-
}
76-
if (input.getTypeQualifier() != null) {
77-
buildTypeQualifier(input, builder);
78-
}
79-
if (input.getAllowedValues() != null) {
80-
buildAllowedValues(input, builder);
67+
68+
if (_entityClient.exists(context.getOperationContext(), propertyUrn)) {
69+
throw new IllegalArgumentException(
70+
"A structured property already exists with this urn");
8171
}
82-
if (input.getCardinality() != null) {
83-
builder.setCardinality(
84-
PropertyCardinality.valueOf(input.getCardinality().toString()));
72+
73+
List<MetadataChangeProposal> mcps = new ArrayList<>();
74+
75+
// first, create the property definition itself
76+
mcps.add(createPropertyDefinition(context, propertyUrn, id, input));
77+
78+
// then add the settings aspect if we're adding any settings inputs
79+
if (input.getSettings() != null) {
80+
mcps.add(createPropertySettings(context, propertyUrn, input.getSettings()));
8581
}
86-
builder.setCreated(context.getOperationContext().getAuditStamp());
87-
builder.setLastModified(context.getOperationContext().getAuditStamp());
8882

89-
MetadataChangeProposal mcp = builder.build();
90-
_entityClient.ingestProposal(context.getOperationContext(), mcp, false);
83+
_entityClient.batchIngestProposals(context.getOperationContext(), mcps, false);
9184

9285
EntityResponse response =
9386
_entityClient.getV2(
@@ -103,6 +96,72 @@ public CompletableFuture<StructuredPropertyEntity> get(final DataFetchingEnviron
10396
});
10497
}
10598

99+
private MetadataChangeProposal createPropertySettings(
100+
@Nonnull final QueryContext context,
101+
@Nonnull final Urn propertyUrn,
102+
final StructuredPropertySettingsInput settingsInput)
103+
throws Exception {
104+
StructuredPropertySettings settings = new StructuredPropertySettings();
105+
106+
if (settingsInput.getIsHidden() != null) {
107+
settings.setIsHidden(settingsInput.getIsHidden());
108+
}
109+
if (settingsInput.getShowInSearchFilters() != null) {
110+
settings.setShowInSearchFilters(settingsInput.getShowInSearchFilters());
111+
}
112+
if (settingsInput.getShowInAssetSummary() != null) {
113+
settings.setShowInAssetSummary(settingsInput.getShowInAssetSummary());
114+
}
115+
if (settingsInput.getShowAsAssetBadge() != null) {
116+
settings.setShowAsAssetBadge(settingsInput.getShowAsAssetBadge());
117+
}
118+
if (settingsInput.getShowInColumnsTable() != null) {
119+
settings.setShowInColumnsTable(settingsInput.getShowInColumnsTable());
120+
}
121+
settings.setLastModified(context.getOperationContext().getAuditStamp());
122+
123+
StructuredPropertyUtils.validatePropertySettings(settings, true);
124+
125+
return buildMetadataChangeProposalWithUrn(
126+
propertyUrn, STRUCTURED_PROPERTY_SETTINGS_ASPECT_NAME, settings);
127+
}
128+
129+
private MetadataChangeProposal createPropertyDefinition(
130+
@Nonnull final QueryContext context,
131+
@Nonnull final Urn propertyUrn,
132+
@Nonnull final String id,
133+
final CreateStructuredPropertyInput input)
134+
throws Exception {
135+
StructuredPropertyDefinitionPatchBuilder builder =
136+
new StructuredPropertyDefinitionPatchBuilder().urn(propertyUrn);
137+
138+
builder.setQualifiedName(id);
139+
builder.setValueType(input.getValueType());
140+
input.getEntityTypes().forEach(builder::addEntityType);
141+
if (input.getDisplayName() != null) {
142+
builder.setDisplayName(input.getDisplayName());
143+
}
144+
if (input.getDescription() != null) {
145+
builder.setDescription(input.getDescription());
146+
}
147+
if (input.getImmutable() != null) {
148+
builder.setImmutable(input.getImmutable());
149+
}
150+
if (input.getTypeQualifier() != null) {
151+
buildTypeQualifier(input, builder);
152+
}
153+
if (input.getAllowedValues() != null) {
154+
buildAllowedValues(input, builder);
155+
}
156+
if (input.getCardinality() != null) {
157+
builder.setCardinality(PropertyCardinality.valueOf(input.getCardinality().toString()));
158+
}
159+
builder.setCreated(context.getOperationContext().getAuditStamp());
160+
builder.setLastModified(context.getOperationContext().getAuditStamp());
161+
162+
return builder.build();
163+
}
164+
106165
private void buildTypeQualifier(
107166
@Nonnull final CreateStructuredPropertyInput input,
108167
@Nonnull final StructuredPropertyDefinitionPatchBuilder builder) {

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/structuredproperties/DeleteStructuredPropertyResolver.java

+18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.linkedin.common.urn.UrnUtils;
77
import com.linkedin.datahub.graphql.QueryContext;
88
import com.linkedin.datahub.graphql.authorization.AuthorizationUtils;
9+
import com.linkedin.datahub.graphql.concurrency.GraphQLConcurrencyUtils;
910
import com.linkedin.datahub.graphql.exception.AuthorizationException;
1011
import com.linkedin.datahub.graphql.generated.DeleteStructuredPropertyInput;
1112
import com.linkedin.entity.client.EntityClient;
@@ -42,6 +43,23 @@ public CompletableFuture<Boolean> get(final DataFetchingEnvironment environment)
4243
"Unable to delete structured property. Please contact your admin.");
4344
}
4445
_entityClient.deleteEntity(context.getOperationContext(), propertyUrn);
46+
// Asynchronously Delete all references to the entity (to return quickly)
47+
GraphQLConcurrencyUtils.supplyAsync(
48+
() -> {
49+
try {
50+
_entityClient.deleteEntityReferences(
51+
context.getOperationContext(), propertyUrn);
52+
} catch (Exception e) {
53+
log.error(
54+
String.format(
55+
"Caught exception while attempting to clear all entity references for Structured Property with urn %s",
56+
propertyUrn),
57+
e);
58+
}
59+
return null;
60+
},
61+
this.getClass().getSimpleName(),
62+
"get");
4563
return true;
4664
} catch (Exception e) {
4765
throw new RuntimeException(

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/structuredproperties/RemoveStructuredPropertiesResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public CompletableFuture<com.linkedin.datahub.graphql.generated.StructuredProper
9393
.getValue()
9494
.data());
9595

96-
return StructuredPropertiesMapper.map(context, structuredProperties);
96+
return StructuredPropertiesMapper.map(context, structuredProperties, assetUrn);
9797
} catch (Exception e) {
9898
throw new RuntimeException(
9999
String.format("Failed to perform update against input %s", input), e);

0 commit comments

Comments
 (0)