feat(propagation): Add models for Action feature settings (#11029)

This commit is contained in:
Sam Black 2024-07-30 13:49:14 -04:00 committed by GitHub
parent 43e3cd9602
commit c2470f1d9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 954 additions and 171 deletions

View File

@ -285,6 +285,8 @@ import com.linkedin.datahub.graphql.resolvers.search.ScrollAcrossLineageResolver
import com.linkedin.datahub.graphql.resolvers.search.SearchAcrossEntitiesResolver; import com.linkedin.datahub.graphql.resolvers.search.SearchAcrossEntitiesResolver;
import com.linkedin.datahub.graphql.resolvers.search.SearchAcrossLineageResolver; import com.linkedin.datahub.graphql.resolvers.search.SearchAcrossLineageResolver;
import com.linkedin.datahub.graphql.resolvers.search.SearchResolver; import com.linkedin.datahub.graphql.resolvers.search.SearchResolver;
import com.linkedin.datahub.graphql.resolvers.settings.docPropagation.DocPropagationSettingsResolver;
import com.linkedin.datahub.graphql.resolvers.settings.docPropagation.UpdateDocPropagationSettingsResolver;
import com.linkedin.datahub.graphql.resolvers.settings.user.UpdateCorpUserViewsSettingsResolver; import com.linkedin.datahub.graphql.resolvers.settings.user.UpdateCorpUserViewsSettingsResolver;
import com.linkedin.datahub.graphql.resolvers.settings.view.GlobalViewsSettingsResolver; import com.linkedin.datahub.graphql.resolvers.settings.view.GlobalViewsSettingsResolver;
import com.linkedin.datahub.graphql.resolvers.settings.view.UpdateGlobalViewsSettingsResolver; import com.linkedin.datahub.graphql.resolvers.settings.view.UpdateGlobalViewsSettingsResolver;
@ -1091,8 +1093,10 @@ public class GmsGraphQLEngine {
new BrowseV2Resolver(this.entityClient, this.viewService, this.formService)) new BrowseV2Resolver(this.entityClient, this.viewService, this.formService))
.dataFetcher("businessAttribute", getResolver(businessAttributeType)) .dataFetcher("businessAttribute", getResolver(businessAttributeType))
.dataFetcher( .dataFetcher(
"listBusinessAttributes", "listBusinessAttributes", new ListBusinessAttributesResolver(this.entityClient))
new ListBusinessAttributesResolver(this.entityClient))); .dataFetcher(
"docPropagationSettings",
new DocPropagationSettingsResolver(this.settingsService)));
} }
private DataFetcher getEntitiesResolver() { private DataFetcher getEntitiesResolver() {
@ -1344,7 +1348,11 @@ public class GmsGraphQLEngine {
.dataFetcher( .dataFetcher(
"createForm", new CreateFormResolver(this.entityClient, this.formService)) "createForm", new CreateFormResolver(this.entityClient, this.formService))
.dataFetcher("deleteForm", new DeleteFormResolver(this.entityClient)) .dataFetcher("deleteForm", new DeleteFormResolver(this.entityClient))
.dataFetcher("updateForm", new UpdateFormResolver(this.entityClient)); .dataFetcher("updateForm", new UpdateFormResolver(this.entityClient))
.dataFetcher(
"updateDocPropagationSettings",
new UpdateDocPropagationSettingsResolver(this.settingsService));
if (featureFlags.isBusinessAttributeEntityEnabled()) { if (featureFlags.isBusinessAttributeEntityEnabled()) {
typeWiring typeWiring
.dataFetcher( .dataFetcher(

View File

@ -398,6 +398,11 @@ public class AuthorizationUtils {
PoliciesConfig.MANAGE_DOCUMENTATION_FORMS_PRIVILEGE); PoliciesConfig.MANAGE_DOCUMENTATION_FORMS_PRIVILEGE);
} }
public static boolean canManageFeatures(@Nonnull QueryContext context) {
return AuthUtil.isAuthorized(
context.getAuthorizer(), context.getActorUrn(), PoliciesConfig.MANAGE_FEATURES_PRIVILEGE);
}
public static boolean isAuthorized( public static boolean isAuthorized(
@Nonnull Authorizer authorizer, @Nonnull Authorizer authorizer,
@Nonnull String actor, @Nonnull String actor,

View File

@ -0,0 +1,57 @@
package com.linkedin.datahub.graphql.resolvers.settings.docPropagation;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.concurrency.GraphQLConcurrencyUtils;
import com.linkedin.datahub.graphql.generated.DocPropagationSettings;
import com.linkedin.metadata.service.SettingsService;
import com.linkedin.settings.global.GlobalSettingsInfo;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull;
import lombok.extern.slf4j.Slf4j;
/** Retrieves the Global Settings related to the Actions feature. */
@Slf4j
public class DocPropagationSettingsResolver
implements DataFetcher<CompletableFuture<DocPropagationSettings>> {
private final SettingsService _settingsService;
public DocPropagationSettingsResolver(final SettingsService settingsService) {
_settingsService = Objects.requireNonNull(settingsService, "settingsService must not be null");
}
@Override
public CompletableFuture<DocPropagationSettings> get(final DataFetchingEnvironment environment)
throws Exception {
final QueryContext context = environment.getContext();
return GraphQLConcurrencyUtils.supplyAsync(
() -> {
try {
final GlobalSettingsInfo globalSettings =
_settingsService.getGlobalSettings(context.getOperationContext());
final DocPropagationSettings defaultSettings = new DocPropagationSettings();
defaultSettings.setDocColumnPropagation(true);
return globalSettings != null && globalSettings.hasDocPropagation()
? mapDocPropagationSettings(globalSettings.getDocPropagation())
: defaultSettings;
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve Action Settings", e);
}
},
this.getClass().getSimpleName(),
"get");
}
private static DocPropagationSettings mapDocPropagationSettings(
@Nonnull final com.linkedin.settings.global.DocPropagationFeatureSettings settings) {
final DocPropagationSettings result = new DocPropagationSettings();
// Map docColumnPropagation settings field
result.setDocColumnPropagation(settings.isColumnPropagationEnabled());
return result;
}
}

View File

@ -0,0 +1,77 @@
package com.linkedin.datahub.graphql.resolvers.settings.docPropagation;
import static com.linkedin.datahub.graphql.resolvers.ResolverUtils.*;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.authorization.AuthorizationUtils;
import com.linkedin.datahub.graphql.concurrency.GraphQLConcurrencyUtils;
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.UpdateDocPropagationSettingsInput;
import com.linkedin.metadata.service.SettingsService;
import com.linkedin.settings.global.DocPropagationFeatureSettings;
import com.linkedin.settings.global.GlobalSettingsInfo;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull;
/** Resolver responsible for updating the actions settings. */
public class UpdateDocPropagationSettingsResolver
implements DataFetcher<CompletableFuture<Boolean>> {
private final SettingsService _settingsService;
public UpdateDocPropagationSettingsResolver(@Nonnull final SettingsService settingsService) {
_settingsService = Objects.requireNonNull(settingsService, "settingsService must not be null");
}
@Override
public CompletableFuture<Boolean> get(final DataFetchingEnvironment environment)
throws Exception {
final QueryContext context = environment.getContext();
final UpdateDocPropagationSettingsInput input =
bindArgument(environment.getArgument("input"), UpdateDocPropagationSettingsInput.class);
return GraphQLConcurrencyUtils.supplyAsync(
() -> {
if (AuthorizationUtils.canManageFeatures(context)) {
try {
// First, fetch the existing global settings. This does a R-M-F.
final GlobalSettingsInfo maybeGlobalSettings =
_settingsService.getGlobalSettings(context.getOperationContext());
final GlobalSettingsInfo newGlobalSettings =
maybeGlobalSettings != null ? maybeGlobalSettings : new GlobalSettingsInfo();
final DocPropagationFeatureSettings newDocPropagationSettings =
newGlobalSettings.hasDocPropagation()
? newGlobalSettings.getDocPropagation()
: new DocPropagationFeatureSettings().setEnabled(true);
// Next, patch the actions settings.
updateDocPropagationSettings(newDocPropagationSettings, input);
newGlobalSettings.setDocPropagation(newDocPropagationSettings);
// Finally, write back to GMS.
_settingsService.updateGlobalSettings(
context.getOperationContext(), newGlobalSettings);
return true;
} catch (Exception e) {
throw new RuntimeException(
String.format("Failed to update action settings! %s", input), e);
}
}
throw new AuthorizationException(
"Unauthorized to perform this action. Please contact your DataHub administrator.");
},
this.getClass().getSimpleName(),
"get");
}
private static void updateDocPropagationSettings(
@Nonnull final com.linkedin.settings.global.DocPropagationFeatureSettings settings,
@Nonnull final UpdateDocPropagationSettingsInput input) {
settings.setColumnPropagationEnabled(input.getDocColumnPropagation());
}
}

View File

@ -17,6 +17,11 @@ extend type Query {
Requires the 'Manage Global Views' Platform Privilege. Requires the 'Manage Global Views' Platform Privilege.
""" """
globalViewsSettings: GlobalViewsSettings globalViewsSettings: GlobalViewsSettings
"""
Fetch the global settings related to the docs propagation feature.
"""
docPropagationSettings: DocPropagationSettings
} }
extend type Mutation { extend type Mutation {
@ -25,6 +30,11 @@ extend type Mutation {
Requires the 'Manage Global Views' Platform Privilege. Requires the 'Manage Global Views' Platform Privilege.
""" """
updateGlobalViewsSettings(input: UpdateGlobalViewsSettingsInput!): Boolean! updateGlobalViewsSettings(input: UpdateGlobalViewsSettingsInput!): Boolean!
"""
Update the doc propagation settings.
"""
updateDocPropagationSettings(input: UpdateDocPropagationSettingsInput!): Boolean!
} }
""" """
@ -525,3 +535,23 @@ type GlobalViewsSettings {
""" """
defaultView: String defaultView: String
} }
"""
Input required to update doc propagation settings.
"""
input UpdateDocPropagationSettingsInput {
"""
The default doc propagation setting for the platform.
"""
docColumnPropagation: Boolean
}
"""
Global (platform-level) settings related to the doc propagation feature
"""
type DocPropagationSettings {
"""
The default doc propagation setting for the platform.
"""
docColumnPropagation: Boolean
}

View File

@ -0,0 +1,8 @@
namespace com.linkedin.settings.global
record DocPropagationFeatureSettings includes FeatureSettings {
columnPropagationEnabled: boolean = true
}

View File

@ -0,0 +1,22 @@
namespace com.linkedin.settings.global
/**
* A standardized settings template for a feature.
*/
record FeatureSettings {
enabled: boolean
/**
* The configuration for the feature, in JSON format.
*/
config: optional string
/**
* The version of the configuration schema that has been used to serialize
the config.
* If not provided, the version is assumed to be the latest version.
*/
configVersion: optional string
}

View File

@ -16,4 +16,12 @@ record GlobalSettingsInfo {
* Settings related to the Views Feature * Settings related to the Views Feature
*/ */
views: optional GlobalViewsSettings views: optional GlobalViewsSettings
/**
* Settings related to the documentation propagation feature
*/
docPropagation: DocPropagationFeatureSettings = {
"enabled": true
"columnPropagationEnabled": true
}
} }

View File

@ -902,6 +902,51 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : {
"type" : "record",
"name" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"fields" : [ {
"name" : "time",
"type" : "Time",
"doc" : "When this metadata was updated."
}, {
"name" : "actor",
"type" : "Urn",
"doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation."
}, {
"name" : "source",
"type" : "Urn",
"doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.",
"optional" : true
}, {
"name" : "sourceDetail",
"type" : {
"type" : "map",
"values" : "string"
},
"doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.",
"default" : { }
} ]
},
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "tagAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "tagAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "tagAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
} }
}, },
@ -1010,6 +1055,25 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "termAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "termAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "termAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
}, "com.linkedin.common.GlossaryTermUrn", { }, "com.linkedin.common.GlossaryTermUrn", {
"type" : "record", "type" : "record",
@ -1121,7 +1185,7 @@
"owningTeam" : "urn:li:internalTeam:datahub" "owningTeam" : "urn:li:internalTeam:datahub"
} }
} }
}, { }, "com.linkedin.common.MetadataAttribution", {
"type" : "record", "type" : "record",
"name" : "Owner", "name" : "Owner",
"namespace" : "com.linkedin.common", "namespace" : "com.linkedin.common",
@ -3060,6 +3124,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "fieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "fieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "fieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldTags", "fieldName" : "fieldTags",
@ -3078,6 +3154,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "fieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "fieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "fieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldGlossaryTerms", "fieldName" : "fieldGlossaryTerms",
@ -3247,6 +3335,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "editedFieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "editedFieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "editedFieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldTags", "fieldName" : "editedFieldTags",
@ -3265,6 +3365,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "editedFieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "editedFieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "editedFieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldGlossaryTerms", "fieldName" : "editedFieldGlossaryTerms",

View File

@ -897,6 +897,51 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : {
"type" : "record",
"name" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"fields" : [ {
"name" : "time",
"type" : "Time",
"doc" : "When this metadata was updated."
}, {
"name" : "actor",
"type" : "Urn",
"doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation."
}, {
"name" : "source",
"type" : "Urn",
"doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.",
"optional" : true
}, {
"name" : "sourceDetail",
"type" : {
"type" : "map",
"values" : "string"
},
"doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.",
"default" : { }
} ]
},
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "tagAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "tagAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "tagAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
} }
}, },
@ -1005,6 +1050,25 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "termAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "termAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "termAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
}, "com.linkedin.common.GlossaryTermUrn", { }, "com.linkedin.common.GlossaryTermUrn", {
"type" : "record", "type" : "record",
@ -1152,7 +1216,7 @@
"owningTeam" : "urn:li:internalTeam:datahub" "owningTeam" : "urn:li:internalTeam:datahub"
} }
} }
}, { }, "com.linkedin.common.MetadataAttribution", {
"type" : "record", "type" : "record",
"name" : "Owner", "name" : "Owner",
"namespace" : "com.linkedin.common", "namespace" : "com.linkedin.common",
@ -3443,6 +3507,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "fieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "fieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "fieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldTags", "fieldName" : "fieldTags",
@ -3461,6 +3537,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "fieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "fieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "fieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldGlossaryTerms", "fieldName" : "fieldGlossaryTerms",
@ -3630,6 +3718,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "editedFieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "editedFieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "editedFieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldTags", "fieldName" : "editedFieldTags",
@ -3648,6 +3748,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "editedFieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "editedFieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "editedFieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldGlossaryTerms", "fieldName" : "editedFieldGlossaryTerms",

View File

@ -639,6 +639,51 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : {
"type" : "record",
"name" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"fields" : [ {
"name" : "time",
"type" : "Time",
"doc" : "When this metadata was updated."
}, {
"name" : "actor",
"type" : "Urn",
"doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation."
}, {
"name" : "source",
"type" : "Urn",
"doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.",
"optional" : true
}, {
"name" : "sourceDetail",
"type" : {
"type" : "map",
"values" : "string"
},
"doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.",
"default" : { }
} ]
},
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "tagAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "tagAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "tagAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
} }
}, },
@ -747,6 +792,25 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "termAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "termAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "termAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
}, "com.linkedin.common.GlossaryTermUrn", { }, "com.linkedin.common.GlossaryTermUrn", {
"type" : "record", "type" : "record",
@ -858,7 +922,7 @@
"owningTeam" : "urn:li:internalTeam:datahub" "owningTeam" : "urn:li:internalTeam:datahub"
} }
} }
}, { }, "com.linkedin.common.MetadataAttribution", {
"type" : "record", "type" : "record",
"name" : "Owner", "name" : "Owner",
"namespace" : "com.linkedin.common", "namespace" : "com.linkedin.common",
@ -2788,6 +2852,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "fieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "fieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "fieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldTags", "fieldName" : "fieldTags",
@ -2806,6 +2882,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "fieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "fieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "fieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldGlossaryTerms", "fieldName" : "fieldGlossaryTerms",
@ -2975,6 +3063,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "editedFieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "editedFieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "editedFieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldTags", "fieldName" : "editedFieldTags",
@ -2993,6 +3093,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "editedFieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "editedFieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "editedFieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldGlossaryTerms", "fieldName" : "editedFieldGlossaryTerms",

View File

@ -639,6 +639,51 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : {
"type" : "record",
"name" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"fields" : [ {
"name" : "time",
"type" : "Time",
"doc" : "When this metadata was updated."
}, {
"name" : "actor",
"type" : "Urn",
"doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation."
}, {
"name" : "source",
"type" : "Urn",
"doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.",
"optional" : true
}, {
"name" : "sourceDetail",
"type" : {
"type" : "map",
"values" : "string"
},
"doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.",
"default" : { }
} ]
},
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "tagAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "tagAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "tagAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
} }
}, },
@ -747,6 +792,25 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "termAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "termAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "termAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
}, "com.linkedin.common.GlossaryTermUrn", { }, "com.linkedin.common.GlossaryTermUrn", {
"type" : "record", "type" : "record",
@ -858,7 +922,7 @@
"owningTeam" : "urn:li:internalTeam:datahub" "owningTeam" : "urn:li:internalTeam:datahub"
} }
} }
}, { }, "com.linkedin.common.MetadataAttribution", {
"type" : "record", "type" : "record",
"name" : "Owner", "name" : "Owner",
"namespace" : "com.linkedin.common", "namespace" : "com.linkedin.common",
@ -2782,6 +2846,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "fieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "fieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "fieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldTags", "fieldName" : "fieldTags",
@ -2800,6 +2876,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "fieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "fieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "fieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldGlossaryTerms", "fieldName" : "fieldGlossaryTerms",
@ -2969,6 +3057,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "editedFieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "editedFieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "editedFieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldTags", "fieldName" : "editedFieldTags",
@ -2987,6 +3087,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "editedFieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "editedFieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "editedFieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldGlossaryTerms", "fieldName" : "editedFieldGlossaryTerms",

View File

@ -897,6 +897,51 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : {
"type" : "record",
"name" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"fields" : [ {
"name" : "time",
"type" : "Time",
"doc" : "When this metadata was updated."
}, {
"name" : "actor",
"type" : "Urn",
"doc" : "The entity (e.g. a member URN) responsible for applying the assocated metadata. This can\neither be a user (in case of UI edits) or the datahub system for automation."
}, {
"name" : "source",
"type" : "Urn",
"doc" : "The DataHub source responsible for applying the associated metadata. This will only be filled out\nwhen a DataHub source is responsible. This includes the specific metadata test urn, the automation urn.",
"optional" : true
}, {
"name" : "sourceDetail",
"type" : {
"type" : "map",
"values" : "string"
},
"doc" : "The details associated with why this metadata was applied. For example, this could include\nthe actual regex rule, sql statement, ingestion pipeline ID, etc.",
"default" : { }
} ]
},
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "tagAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "tagAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "tagAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
} }
}, },
@ -1005,6 +1050,25 @@
"type" : "string", "type" : "string",
"doc" : "Additional context about the association", "doc" : "Additional context about the association",
"optional" : true "optional" : true
}, {
"name" : "attribution",
"type" : "MetadataAttribution",
"doc" : "Information about who, why, and how this metadata was applied",
"optional" : true,
"Searchable" : {
"/actor" : {
"fieldName" : "termAttributionActors",
"fieldType" : "URN"
},
"/source" : {
"fieldName" : "termAttributionSources",
"fieldType" : "URN"
},
"/time" : {
"fieldName" : "termAttributionDates",
"fieldType" : "DATETIME"
}
}
} ] } ]
}, "com.linkedin.common.GlossaryTermUrn", { }, "com.linkedin.common.GlossaryTermUrn", {
"type" : "record", "type" : "record",
@ -1152,7 +1216,7 @@
"owningTeam" : "urn:li:internalTeam:datahub" "owningTeam" : "urn:li:internalTeam:datahub"
} }
} }
}, { }, "com.linkedin.common.MetadataAttribution", {
"type" : "record", "type" : "record",
"name" : "Owner", "name" : "Owner",
"namespace" : "com.linkedin.common", "namespace" : "com.linkedin.common",
@ -3437,6 +3501,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "fieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "fieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "fieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldTags", "fieldName" : "fieldTags",
@ -3455,6 +3531,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "fieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "fieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "fieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "fieldGlossaryTerms", "fieldName" : "fieldGlossaryTerms",
@ -3624,6 +3712,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/tags/*/attribution/actor" : {
"fieldName" : "editedFieldTagAttributionActors",
"fieldType" : "URN"
},
"/tags/*/attribution/source" : {
"fieldName" : "editedFieldTagAttributionSources",
"fieldType" : "URN"
},
"/tags/*/attribution/time" : {
"fieldName" : "editedFieldTagAttributionDates",
"fieldType" : "DATETIME"
},
"/tags/*/tag" : { "/tags/*/tag" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldTags", "fieldName" : "editedFieldTags",
@ -3642,6 +3742,18 @@
} }
}, },
"Searchable" : { "Searchable" : {
"/terms/*/attribution/actor" : {
"fieldName" : "editedFieldTermAttributionActors",
"fieldType" : "URN"
},
"/terms/*/attribution/source" : {
"fieldName" : "editedFieldTermAttributionSources",
"fieldType" : "URN"
},
"/terms/*/attribution/time" : {
"fieldName" : "editedFieldTermAttributionDates",
"fieldType" : "DATETIME"
},
"/terms/*/urn" : { "/terms/*/urn" : {
"boostScore" : 0.5, "boostScore" : 0.5,
"fieldName" : "editedFieldGlossaryTerms", "fieldName" : "editedFieldGlossaryTerms",

View File

@ -36,7 +36,8 @@
"CREATE_BUSINESS_ATTRIBUTE", "CREATE_BUSINESS_ATTRIBUTE",
"MANAGE_BUSINESS_ATTRIBUTE", "MANAGE_BUSINESS_ATTRIBUTE",
"MANAGE_STRUCTURED_PROPERTIES", "MANAGE_STRUCTURED_PROPERTIES",
"MANAGE_DOCUMENTATION_FORMS" "MANAGE_DOCUMENTATION_FORMS",
"MANAGE_FEATURES"
], ],
"displayName": "Root User - All Platform Privileges", "displayName": "Root User - All Platform Privileges",
"description": "Grants all platform privileges to root user.", "description": "Grants all platform privileges to root user.",
@ -183,7 +184,8 @@
"CREATE_BUSINESS_ATTRIBUTE", "CREATE_BUSINESS_ATTRIBUTE",
"MANAGE_BUSINESS_ATTRIBUTE", "MANAGE_BUSINESS_ATTRIBUTE",
"MANAGE_STRUCTURED_PROPERTIES", "MANAGE_STRUCTURED_PROPERTIES",
"MANAGE_DOCUMENTATION_FORMS" "MANAGE_DOCUMENTATION_FORMS",
"MANAGE_FEATURES"
], ],
"displayName": "Admins - Platform Policy", "displayName": "Admins - Platform Policy",
"description": "Admins have all platform privileges.", "description": "Admins have all platform privileges.",
@ -271,7 +273,8 @@
"MANAGE_TAGS", "MANAGE_TAGS",
"MANAGE_BUSINESS_ATTRIBUTE", "MANAGE_BUSINESS_ATTRIBUTE",
"MANAGE_STRUCTURED_PROPERTIES", "MANAGE_STRUCTURED_PROPERTIES",
"MANAGE_DOCUMENTATION_FORMS" "MANAGE_DOCUMENTATION_FORMS",
"MANAGE_FEATURES"
], ],
"displayName": "Editors - Platform Policy", "displayName": "Editors - Platform Policy",
"description": "Editors can manage ingestion and view analytics.", "description": "Editors can manage ingestion and view analytics.",

View File

@ -163,6 +163,10 @@ public class PoliciesConfig {
"Manage Documentation Forms", "Manage Documentation Forms",
"Manage forms assigned to assets to assist in documentation efforts."); "Manage forms assigned to assets to assist in documentation efforts.");
public static final Privilege MANAGE_FEATURES_PRIVILEGE =
Privilege.of(
"MANAGE_FEATURES", "Manage Features", "Umbrella privilege to manage all features.");
public static final List<Privilege> PLATFORM_PRIVILEGES = public static final List<Privilege> PLATFORM_PRIVILEGES =
ImmutableList.of( ImmutableList.of(
MANAGE_POLICIES_PRIVILEGE, MANAGE_POLICIES_PRIVILEGE,
@ -189,7 +193,8 @@ public class PoliciesConfig {
MANAGE_BUSINESS_ATTRIBUTE_PRIVILEGE, MANAGE_BUSINESS_ATTRIBUTE_PRIVILEGE,
MANAGE_CONNECTIONS_PRIVILEGE, MANAGE_CONNECTIONS_PRIVILEGE,
MANAGE_STRUCTURED_PROPERTIES_PRIVILEGE, MANAGE_STRUCTURED_PROPERTIES_PRIVILEGE,
MANAGE_DOCUMENTATION_FORMS_PRIVILEGE); MANAGE_DOCUMENTATION_FORMS_PRIVILEGE,
MANAGE_FEATURES_PRIVILEGE);
// Resource Privileges // // Resource Privileges //