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(propagation): Add models for Action feature settings #11029

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@
import com.linkedin.datahub.graphql.resolvers.search.SearchAcrossEntitiesResolver;
import com.linkedin.datahub.graphql.resolvers.search.SearchAcrossLineageResolver;
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.view.GlobalViewsSettingsResolver;
import com.linkedin.datahub.graphql.resolvers.settings.view.UpdateGlobalViewsSettingsResolver;
Expand Down Expand Up @@ -1087,8 +1089,10 @@ private void configureQueryResolvers(final RuntimeWiring.Builder builder) {
new BrowseV2Resolver(this.entityClient, this.viewService, this.formService))
.dataFetcher("businessAttribute", getResolver(businessAttributeType))
.dataFetcher(
"listBusinessAttributes",
new ListBusinessAttributesResolver(this.entityClient)));
"listBusinessAttributes", new ListBusinessAttributesResolver(this.entityClient))
.dataFetcher(
"docPropagationSettings",
new DocPropagationSettingsResolver(this.settingsService)));
}

private DataFetcher getEntitiesResolver() {
Expand Down Expand Up @@ -1340,7 +1344,11 @@ private void configureMutationResolvers(final RuntimeWiring.Builder builder) {
.dataFetcher(
"createForm", new CreateFormResolver(this.entityClient, this.formService))
.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()) {
typeWiring
.dataFetcher(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,11 @@ public static boolean canManageForms(@Nonnull QueryContext context) {
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(
@Nonnull Authorizer authorizer,
@Nonnull String actor,
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
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());
}
}
30 changes: 30 additions & 0 deletions datahub-graphql-core/src/main/resources/app.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ extend type Query {
Requires the 'Manage Global Views' Platform Privilege.
"""
globalViewsSettings: GlobalViewsSettings

"""
Fetch the global settings related to the docs propagation feature.
"""
docPropagationSettings: DocPropagationSettings
}

extend type Mutation {
Expand All @@ -25,6 +30,11 @@ extend type Mutation {
Requires the 'Manage Global Views' Platform Privilege.
"""
updateGlobalViewsSettings(input: UpdateGlobalViewsSettingsInput!): Boolean!

"""
Update the doc propagation settings.
"""
updateDocPropagationSettings(input: UpdateDocPropagationSettingsInput!): Boolean!
}

"""
Expand Down Expand Up @@ -525,3 +535,23 @@ type GlobalViewsSettings {
"""
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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace com.linkedin.settings.global


record DocPropagationFeatureSettings includes FeatureSettings {

columnPropagationEnabled: boolean = true

}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@ record GlobalSettingsInfo {
* Settings related to the Views Feature
*/
views: optional GlobalViewsSettings
/**
* Settings related to the documentation propagation feature
*/
docPropagation: DocPropagationFeatureSettings = {
"enabled": true
"columnPropagationEnabled": true
}

}
Loading
Loading