Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into Qlik-Connector-Integration
  • Loading branch information
shubhamjagtap639 committed Feb 16, 2024
2 parents c2dd545 + 045c76a commit 1dadb27
Show file tree
Hide file tree
Showing 173 changed files with 6,899 additions and 737 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ private Constants() {}
public static final String LINEAGE_SCHEMA_FILE = "lineage.graphql";
public static final String PROPERTIES_SCHEMA_FILE = "properties.graphql";
public static final String FORMS_SCHEMA_FILE = "forms.graphql";
public static final String INCIDENTS_SCHEMA_FILE = "incident.graphql";
public static final String BROWSE_PATH_DELIMITER = "/";
public static final String BROWSE_PATH_V2_DELIMITER = "␟";
public static final String VERSION_STAMP_FIELD_NAME = "versionStamp";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import com.linkedin.datahub.graphql.generated.GlossaryNode;
import com.linkedin.datahub.graphql.generated.GlossaryTerm;
import com.linkedin.datahub.graphql.generated.GlossaryTermAssociation;
import com.linkedin.datahub.graphql.generated.IncidentSource;
import com.linkedin.datahub.graphql.generated.IngestionSource;
import com.linkedin.datahub.graphql.generated.InstitutionalMemoryMetadata;
import com.linkedin.datahub.graphql.generated.LineageRelationship;
Expand Down Expand Up @@ -125,7 +126,6 @@
import com.linkedin.datahub.graphql.resolvers.dataproduct.DeleteDataProductResolver;
import com.linkedin.datahub.graphql.resolvers.dataproduct.ListDataProductAssetsResolver;
import com.linkedin.datahub.graphql.resolvers.dataproduct.UpdateDataProductResolver;
import com.linkedin.datahub.graphql.resolvers.dataset.DatasetHealthResolver;
import com.linkedin.datahub.graphql.resolvers.dataset.DatasetStatsSummaryResolver;
import com.linkedin.datahub.graphql.resolvers.dataset.DatasetUsageStatsResolver;
import com.linkedin.datahub.graphql.resolvers.deprecation.UpdateDeprecationResolver;
Expand Down Expand Up @@ -158,6 +158,10 @@
import com.linkedin.datahub.graphql.resolvers.group.ListGroupsResolver;
import com.linkedin.datahub.graphql.resolvers.group.RemoveGroupMembersResolver;
import com.linkedin.datahub.graphql.resolvers.group.RemoveGroupResolver;
import com.linkedin.datahub.graphql.resolvers.health.EntityHealthResolver;
import com.linkedin.datahub.graphql.resolvers.incident.EntityIncidentsResolver;
import com.linkedin.datahub.graphql.resolvers.incident.RaiseIncidentResolver;
import com.linkedin.datahub.graphql.resolvers.incident.UpdateIncidentStatusResolver;
import com.linkedin.datahub.graphql.resolvers.ingest.execution.CancelIngestionExecutionRequestResolver;
import com.linkedin.datahub.graphql.resolvers.ingest.execution.CreateIngestionExecutionRequestResolver;
import com.linkedin.datahub.graphql.resolvers.ingest.execution.CreateTestConnectionRequestResolver;
Expand Down Expand Up @@ -305,6 +309,7 @@
import com.linkedin.datahub.graphql.types.form.FormType;
import com.linkedin.datahub.graphql.types.glossary.GlossaryNodeType;
import com.linkedin.datahub.graphql.types.glossary.GlossaryTermType;
import com.linkedin.datahub.graphql.types.incident.IncidentType;
import com.linkedin.datahub.graphql.types.mlmodel.MLFeatureTableType;
import com.linkedin.datahub.graphql.types.mlmodel.MLFeatureType;
import com.linkedin.datahub.graphql.types.mlmodel.MLModelGroupType;
Expand Down Expand Up @@ -460,6 +465,7 @@ public class GmsGraphQLEngine {
private final DataTypeType dataTypeType;
private final EntityTypeType entityTypeType;
private final FormType formType;
private final IncidentType incidentType;

private final int graphQLQueryComplexityLimit;
private final int graphQLQueryDepthLimit;
Expand Down Expand Up @@ -567,6 +573,7 @@ public GmsGraphQLEngine(final GmsGraphQLEngineArgs args) {
this.dataTypeType = new DataTypeType(entityClient);
this.entityTypeType = new EntityTypeType(entityClient);
this.formType = new FormType(entityClient);
this.incidentType = new IncidentType(entityClient);

this.graphQLQueryComplexityLimit = args.graphQLQueryComplexityLimit;
this.graphQLQueryDepthLimit = args.graphQLQueryDepthLimit;
Expand Down Expand Up @@ -609,7 +616,8 @@ public GmsGraphQLEngine(final GmsGraphQLEngineArgs args) {
structuredPropertyType,
dataTypeType,
entityTypeType,
formType);
formType,
incidentType);
this.loadableTypes = new ArrayList<>(entityTypes);
// Extend loadable types with types from the plugins
// This allows us to offer search and browse capabilities out of the box for those types
Expand Down Expand Up @@ -698,6 +706,7 @@ public void configureRuntimeWiring(final RuntimeWiring.Builder builder) {
configurePluginResolvers(builder);
configureStructuredPropertyResolvers(builder);
configureFormResolvers(builder);
configureIncidentResolvers(builder);
}

private void configureOrganisationRoleResolvers(RuntimeWiring.Builder builder) {
Expand Down Expand Up @@ -747,7 +756,8 @@ public GraphQLEngine.Builder builder() {
.addSchema(fileBasedSchema(STEPS_SCHEMA_FILE))
.addSchema(fileBasedSchema(LINEAGE_SCHEMA_FILE))
.addSchema(fileBasedSchema(PROPERTIES_SCHEMA_FILE))
.addSchema(fileBasedSchema(FORMS_SCHEMA_FILE));
.addSchema(fileBasedSchema(FORMS_SCHEMA_FILE))
.addSchema(fileBasedSchema(INCIDENTS_SCHEMA_FILE));

for (GmsGraphQLPlugin plugin : this.graphQLPlugins) {
List<String> pluginSchemaFiles = plugin.getSchemaFiles();
Expand Down Expand Up @@ -1202,7 +1212,11 @@ private void configureMutationResolvers(final RuntimeWiring.Builder builder) {
"createDynamicFormAssignment",
new CreateDynamicFormAssignmentResolver(this.formService))
.dataFetcher(
"verifyForm", new VerifyFormResolver(this.formService, this.groupService)));
"verifyForm", new VerifyFormResolver(this.formService, this.groupService))
.dataFetcher("raiseIncident", new RaiseIncidentResolver(this.entityClient))
.dataFetcher(
"updateIncidentStatus",
new UpdateIncidentStatusResolver(this.entityClient, this.entityService)));
}

private void configureGenericEntityResolvers(final RuntimeWiring.Builder builder) {
Expand Down Expand Up @@ -1485,7 +1499,12 @@ private void configureDatasetResolvers(final RuntimeWiring.Builder builder) {
.dataFetcher("usageStats", new DatasetUsageStatsResolver(this.usageClient))
.dataFetcher("statsSummary", new DatasetStatsSummaryResolver(this.usageClient))
.dataFetcher(
"health", new DatasetHealthResolver(graphClient, timeseriesAspectService))
"health",
new EntityHealthResolver(
entityClient,
graphClient,
timeseriesAspectService,
new EntityHealthResolver.Config(true, true)))
.dataFetcher("schemaMetadata", new AspectResolver())
.dataFetcher(
"assertions", new EntityAssertionsResolver(entityClient, graphClient))
Expand Down Expand Up @@ -1834,7 +1853,14 @@ private void configureDashboardResolvers(final RuntimeWiring.Builder builder) {
.dataFetcher(
"statsSummary", new DashboardStatsSummaryResolver(timeseriesAspectService))
.dataFetcher("privileges", new EntityPrivilegesResolver(entityClient))
.dataFetcher("exists", new EntityExistsResolver(entityService)));
.dataFetcher("exists", new EntityExistsResolver(entityService))
.dataFetcher(
"health",
new EntityHealthResolver(
entityClient,
graphClient,
timeseriesAspectService,
new EntityHealthResolver.Config(false, true))));
builder.type(
"DashboardInfo",
typeWiring ->
Expand Down Expand Up @@ -1951,7 +1977,14 @@ private void configureChartResolvers(final RuntimeWiring.Builder builder) {
.dataFetcher(
"statsSummary", new ChartStatsSummaryResolver(this.timeseriesAspectService))
.dataFetcher("privileges", new EntityPrivilegesResolver(entityClient))
.dataFetcher("exists", new EntityExistsResolver(entityService)));
.dataFetcher("exists", new EntityExistsResolver(entityService))
.dataFetcher(
"health",
new EntityHealthResolver(
entityClient,
graphClient,
timeseriesAspectService,
new EntityHealthResolver.Config(false, true))));
builder.type(
"ChartInfo",
typeWiring ->
Expand Down Expand Up @@ -2056,7 +2089,14 @@ private void configureDataJobResolvers(final RuntimeWiring.Builder builder) {
}))
.dataFetcher("runs", new DataJobRunsResolver(entityClient))
.dataFetcher("privileges", new EntityPrivilegesResolver(entityClient))
.dataFetcher("exists", new EntityExistsResolver(entityService)))
.dataFetcher("exists", new EntityExistsResolver(entityService))
.dataFetcher(
"health",
new EntityHealthResolver(
entityClient,
graphClient,
timeseriesAspectService,
new EntityHealthResolver.Config(false, true))))
.type(
"DataJobInputOutput",
typeWiring ->
Expand Down Expand Up @@ -2119,7 +2159,14 @@ private void configureDataFlowResolvers(final RuntimeWiring.Builder builder) {
return dataFlow.getDataPlatformInstance() != null
? dataFlow.getDataPlatformInstance().getUrn()
: null;
})));
}))
.dataFetcher(
"health",
new EntityHealthResolver(
entityClient,
graphClient,
timeseriesAspectService,
new EntityHealthResolver.Config(false, true))));
}

/**
Expand Down Expand Up @@ -2660,4 +2707,35 @@ private void configureIngestionSourceResolvers(final RuntimeWiring.Builder build
: null;
})));
}

private void configureIncidentResolvers(final RuntimeWiring.Builder builder) {
builder.type(
"Incident",
typeWiring ->
typeWiring.dataFetcher(
"relationships", new EntityRelationshipsResultResolver(graphClient)));
builder.type(
"IncidentSource",
typeWiring ->
typeWiring.dataFetcher(
"source",
new LoadableTypeResolver<>(
this.assertionType,
(env) -> {
final IncidentSource incidentSource = env.getSource();
return incidentSource.getSource() != null
? incidentSource.getSource().getUrn()
: null;
})));

// Add incidents attribute to all entities that support it
final List<String> entitiesWithIncidents =
ImmutableList.of("Dataset", "DataJob", "DataFlow", "Dashboard", "Chart");
for (String entity : entitiesWithIncidents) {
builder.type(
entity,
typeWiring ->
typeWiring.dataFetcher("incidents", new EntityIncidentsResolver(entityClient)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,5 +219,13 @@ public static boolean isAuthorized(
return AuthUtil.isAuthorized(authorizer, actor, Optional.of(resourceSpec), privilegeGroup);
}

public static boolean isViewDatasetUsageAuthorized(
final Urn resourceUrn, final QueryContext context) {
return isAuthorized(
context,
Optional.of(new EntitySpec(resourceUrn.getEntityType(), resourceUrn.toString())),
PoliciesConfig.VIEW_DATASET_USAGE_PRIVILEGE);
}

private AuthorizationUtils() {}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
package com.linkedin.datahub.graphql.resolvers.chart;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.linkedin.common.urn.Urn;
import com.linkedin.datahub.graphql.generated.ChartStatsSummary;
import com.linkedin.metadata.timeseries.TimeseriesAspectService;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ChartStatsSummaryResolver
implements DataFetcher<CompletableFuture<ChartStatsSummary>> {

private final TimeseriesAspectService timeseriesAspectService;
private final Cache<Urn, ChartStatsSummary> summaryCache;

public ChartStatsSummaryResolver(final TimeseriesAspectService timeseriesAspectService) {
this.timeseriesAspectService = timeseriesAspectService;
this.summaryCache =
CacheBuilder.newBuilder().maximumSize(10000).expireAfterWrite(6, TimeUnit.HOURS).build();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.linkedin.datahub.graphql.resolvers.dashboard;

import static com.linkedin.datahub.graphql.authorization.AuthorizationUtils.isViewDatasetUsageAuthorized;
import static com.linkedin.datahub.graphql.resolvers.dashboard.DashboardUsageStatsUtils.*;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.linkedin.common.urn.Urn;
import com.linkedin.common.urn.UrnUtils;
import com.linkedin.datahub.graphql.QueryContext;
import com.linkedin.datahub.graphql.generated.CorpUser;
import com.linkedin.datahub.graphql.generated.DashboardStatsSummary;
import com.linkedin.datahub.graphql.generated.DashboardUsageMetrics;
Expand All @@ -17,7 +17,6 @@
import graphql.schema.DataFetchingEnvironment;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -29,31 +28,30 @@ public class DashboardStatsSummaryResolver
private static final Integer MAX_TOP_USERS = 5;

private final TimeseriesAspectService timeseriesAspectService;
private final Cache<Urn, DashboardStatsSummary> summaryCache;

public DashboardStatsSummaryResolver(final TimeseriesAspectService timeseriesAspectService) {
this.timeseriesAspectService = timeseriesAspectService;
this.summaryCache =
CacheBuilder.newBuilder()
.maximumSize(10000)
.expireAfterWrite(
6, TimeUnit.HOURS) // TODO: Make caching duration configurable externally.
.build();
}

@Override
public CompletableFuture<DashboardStatsSummary> get(DataFetchingEnvironment environment)
throws Exception {
final Urn resourceUrn = UrnUtils.getUrn(((Entity) environment.getSource()).getUrn());
final QueryContext context = environment.getContext();

return CompletableFuture.supplyAsync(
() -> {
if (this.summaryCache.getIfPresent(resourceUrn) != null) {
return this.summaryCache.getIfPresent(resourceUrn);
}

try {

// TODO: We don't have a dashboard specific priv
if (!isViewDatasetUsageAuthorized(resourceUrn, context)) {
log.debug(
"User {} is not authorized to view usage information for {}",
context.getActorUrn(),
resourceUrn.toString());
return null;
}

final DashboardStatsSummary result = new DashboardStatsSummary();

// Obtain total dashboard view count, by viewing the latest reported dashboard metrics.
Expand All @@ -73,7 +71,6 @@ public CompletableFuture<DashboardStatsSummary> get(DataFetchingEnvironment envi
.map(DashboardUserUsageCounts::getUser)
.collect(Collectors.toList())));

this.summaryCache.put(resourceUrn, result);
return result;

} catch (Exception e) {
Expand Down
Loading

0 comments on commit 1dadb27

Please sign in to comment.