Skip to content

Commit 0267ebd

Browse files
authored
Merge branch 'master' into feature/disable-access-mgmt-tab-when-no-roles
2 parents 5304459 + e4bc915 commit 0267ebd

File tree

215 files changed

+7814
-927
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

215 files changed

+7814
-927
lines changed

build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ project.ext.externalDependency = [
128128
'elasticSearchRest': 'org.opensearch.client:opensearch-rest-high-level-client:' + elasticsearchVersion,
129129
'elasticSearchJava': 'org.opensearch.client:opensearch-java:2.6.0',
130130
'findbugsAnnotations': 'com.google.code.findbugs:annotations:3.0.1',
131-
'graphqlJava': 'com.graphql-java:graphql-java:19.5',
132-
'graphqlJavaScalars': 'com.graphql-java:graphql-java-extended-scalars:19.1',
131+
'graphqlJava': 'com.graphql-java:graphql-java:21.3',
132+
'graphqlJavaScalars': 'com.graphql-java:graphql-java-extended-scalars:21.0',
133133
'gson': 'com.google.code.gson:gson:2.8.9',
134134
'guice': 'com.google.inject:guice:7.0.0',
135135
'guice4': 'com.google.inject:guice:4.2.3', // Used for frontend while still on old Play version

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/Constants.java

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ private Constants() {}
2121
public static final String LINEAGE_SCHEMA_FILE = "lineage.graphql";
2222
public static final String PROPERTIES_SCHEMA_FILE = "properties.graphql";
2323
public static final String FORMS_SCHEMA_FILE = "forms.graphql";
24+
public static final String INCIDENTS_SCHEMA_FILE = "incident.graphql";
2425
public static final String BROWSE_PATH_DELIMITER = "/";
2526
public static final String BROWSE_PATH_V2_DELIMITER = "␟";
2627
public static final String VERSION_STAMP_FIELD_NAME = "versionStamp";

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java

+107-10
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import com.linkedin.datahub.graphql.generated.GlossaryNode;
6464
import com.linkedin.datahub.graphql.generated.GlossaryTerm;
6565
import com.linkedin.datahub.graphql.generated.GlossaryTermAssociation;
66+
import com.linkedin.datahub.graphql.generated.IncidentSource;
6667
import com.linkedin.datahub.graphql.generated.IngestionSource;
6768
import com.linkedin.datahub.graphql.generated.InstitutionalMemoryMetadata;
6869
import com.linkedin.datahub.graphql.generated.LineageRelationship;
@@ -89,6 +90,7 @@
8990
import com.linkedin.datahub.graphql.generated.ParentDomainsResult;
9091
import com.linkedin.datahub.graphql.generated.PolicyMatchCriterionValue;
9192
import com.linkedin.datahub.graphql.generated.QueryEntity;
93+
import com.linkedin.datahub.graphql.generated.QueryProperties;
9294
import com.linkedin.datahub.graphql.generated.QuerySubject;
9395
import com.linkedin.datahub.graphql.generated.QuickFilter;
9496
import com.linkedin.datahub.graphql.generated.RecommendationContent;
@@ -125,7 +127,6 @@
125127
import com.linkedin.datahub.graphql.resolvers.dataproduct.DeleteDataProductResolver;
126128
import com.linkedin.datahub.graphql.resolvers.dataproduct.ListDataProductAssetsResolver;
127129
import com.linkedin.datahub.graphql.resolvers.dataproduct.UpdateDataProductResolver;
128-
import com.linkedin.datahub.graphql.resolvers.dataset.DatasetHealthResolver;
129130
import com.linkedin.datahub.graphql.resolvers.dataset.DatasetStatsSummaryResolver;
130131
import com.linkedin.datahub.graphql.resolvers.dataset.DatasetUsageStatsResolver;
131132
import com.linkedin.datahub.graphql.resolvers.deprecation.UpdateDeprecationResolver;
@@ -158,6 +159,10 @@
158159
import com.linkedin.datahub.graphql.resolvers.group.ListGroupsResolver;
159160
import com.linkedin.datahub.graphql.resolvers.group.RemoveGroupMembersResolver;
160161
import com.linkedin.datahub.graphql.resolvers.group.RemoveGroupResolver;
162+
import com.linkedin.datahub.graphql.resolvers.health.EntityHealthResolver;
163+
import com.linkedin.datahub.graphql.resolvers.incident.EntityIncidentsResolver;
164+
import com.linkedin.datahub.graphql.resolvers.incident.RaiseIncidentResolver;
165+
import com.linkedin.datahub.graphql.resolvers.incident.UpdateIncidentStatusResolver;
161166
import com.linkedin.datahub.graphql.resolvers.ingest.execution.CancelIngestionExecutionRequestResolver;
162167
import com.linkedin.datahub.graphql.resolvers.ingest.execution.CreateIngestionExecutionRequestResolver;
163168
import com.linkedin.datahub.graphql.resolvers.ingest.execution.CreateTestConnectionRequestResolver;
@@ -305,6 +310,7 @@
305310
import com.linkedin.datahub.graphql.types.form.FormType;
306311
import com.linkedin.datahub.graphql.types.glossary.GlossaryNodeType;
307312
import com.linkedin.datahub.graphql.types.glossary.GlossaryTermType;
313+
import com.linkedin.datahub.graphql.types.incident.IncidentType;
308314
import com.linkedin.datahub.graphql.types.mlmodel.MLFeatureTableType;
309315
import com.linkedin.datahub.graphql.types.mlmodel.MLFeatureType;
310316
import com.linkedin.datahub.graphql.types.mlmodel.MLModelGroupType;
@@ -460,6 +466,7 @@ public class GmsGraphQLEngine {
460466
private final DataTypeType dataTypeType;
461467
private final EntityTypeType entityTypeType;
462468
private final FormType formType;
469+
private final IncidentType incidentType;
463470

464471
private final int graphQLQueryComplexityLimit;
465472
private final int graphQLQueryDepthLimit;
@@ -567,6 +574,7 @@ public GmsGraphQLEngine(final GmsGraphQLEngineArgs args) {
567574
this.dataTypeType = new DataTypeType(entityClient);
568575
this.entityTypeType = new EntityTypeType(entityClient);
569576
this.formType = new FormType(entityClient);
577+
this.incidentType = new IncidentType(entityClient);
570578

571579
this.graphQLQueryComplexityLimit = args.graphQLQueryComplexityLimit;
572580
this.graphQLQueryDepthLimit = args.graphQLQueryDepthLimit;
@@ -609,7 +617,8 @@ public GmsGraphQLEngine(final GmsGraphQLEngineArgs args) {
609617
structuredPropertyType,
610618
dataTypeType,
611619
entityTypeType,
612-
formType);
620+
formType,
621+
incidentType);
613622
this.loadableTypes = new ArrayList<>(entityTypes);
614623
// Extend loadable types with types from the plugins
615624
// This allows us to offer search and browse capabilities out of the box for those types
@@ -698,6 +707,7 @@ public void configureRuntimeWiring(final RuntimeWiring.Builder builder) {
698707
configurePluginResolvers(builder);
699708
configureStructuredPropertyResolvers(builder);
700709
configureFormResolvers(builder);
710+
configureIncidentResolvers(builder);
701711
}
702712

703713
private void configureOrganisationRoleResolvers(RuntimeWiring.Builder builder) {
@@ -747,7 +757,8 @@ public GraphQLEngine.Builder builder() {
747757
.addSchema(fileBasedSchema(STEPS_SCHEMA_FILE))
748758
.addSchema(fileBasedSchema(LINEAGE_SCHEMA_FILE))
749759
.addSchema(fileBasedSchema(PROPERTIES_SCHEMA_FILE))
750-
.addSchema(fileBasedSchema(FORMS_SCHEMA_FILE));
760+
.addSchema(fileBasedSchema(FORMS_SCHEMA_FILE))
761+
.addSchema(fileBasedSchema(INCIDENTS_SCHEMA_FILE));
751762

752763
for (GmsGraphQLPlugin plugin : this.graphQLPlugins) {
753764
List<String> pluginSchemaFiles = plugin.getSchemaFiles();
@@ -1202,7 +1213,11 @@ private void configureMutationResolvers(final RuntimeWiring.Builder builder) {
12021213
"createDynamicFormAssignment",
12031214
new CreateDynamicFormAssignmentResolver(this.formService))
12041215
.dataFetcher(
1205-
"verifyForm", new VerifyFormResolver(this.formService, this.groupService)));
1216+
"verifyForm", new VerifyFormResolver(this.formService, this.groupService))
1217+
.dataFetcher("raiseIncident", new RaiseIncidentResolver(this.entityClient))
1218+
.dataFetcher(
1219+
"updateIncidentStatus",
1220+
new UpdateIncidentStatusResolver(this.entityClient, this.entityService)));
12061221
}
12071222

12081223
private void configureGenericEntityResolvers(final RuntimeWiring.Builder builder) {
@@ -1485,7 +1500,12 @@ private void configureDatasetResolvers(final RuntimeWiring.Builder builder) {
14851500
.dataFetcher("usageStats", new DatasetUsageStatsResolver(this.usageClient))
14861501
.dataFetcher("statsSummary", new DatasetStatsSummaryResolver(this.usageClient))
14871502
.dataFetcher(
1488-
"health", new DatasetHealthResolver(graphClient, timeseriesAspectService))
1503+
"health",
1504+
new EntityHealthResolver(
1505+
entityClient,
1506+
graphClient,
1507+
timeseriesAspectService,
1508+
new EntityHealthResolver.Config(true, true)))
14891509
.dataFetcher("schemaMetadata", new AspectResolver())
14901510
.dataFetcher(
14911511
"assertions", new EntityAssertionsResolver(entityClient, graphClient))
@@ -1834,7 +1854,14 @@ private void configureDashboardResolvers(final RuntimeWiring.Builder builder) {
18341854
.dataFetcher(
18351855
"statsSummary", new DashboardStatsSummaryResolver(timeseriesAspectService))
18361856
.dataFetcher("privileges", new EntityPrivilegesResolver(entityClient))
1837-
.dataFetcher("exists", new EntityExistsResolver(entityService)));
1857+
.dataFetcher("exists", new EntityExistsResolver(entityService))
1858+
.dataFetcher(
1859+
"health",
1860+
new EntityHealthResolver(
1861+
entityClient,
1862+
graphClient,
1863+
timeseriesAspectService,
1864+
new EntityHealthResolver.Config(false, true))));
18381865
builder.type(
18391866
"DashboardInfo",
18401867
typeWiring ->
@@ -1951,7 +1978,14 @@ private void configureChartResolvers(final RuntimeWiring.Builder builder) {
19511978
.dataFetcher(
19521979
"statsSummary", new ChartStatsSummaryResolver(this.timeseriesAspectService))
19531980
.dataFetcher("privileges", new EntityPrivilegesResolver(entityClient))
1954-
.dataFetcher("exists", new EntityExistsResolver(entityService)));
1981+
.dataFetcher("exists", new EntityExistsResolver(entityService))
1982+
.dataFetcher(
1983+
"health",
1984+
new EntityHealthResolver(
1985+
entityClient,
1986+
graphClient,
1987+
timeseriesAspectService,
1988+
new EntityHealthResolver.Config(false, true))));
19551989
builder.type(
19561990
"ChartInfo",
19571991
typeWiring ->
@@ -2056,7 +2090,14 @@ private void configureDataJobResolvers(final RuntimeWiring.Builder builder) {
20562090
}))
20572091
.dataFetcher("runs", new DataJobRunsResolver(entityClient))
20582092
.dataFetcher("privileges", new EntityPrivilegesResolver(entityClient))
2059-
.dataFetcher("exists", new EntityExistsResolver(entityService)))
2093+
.dataFetcher("exists", new EntityExistsResolver(entityService))
2094+
.dataFetcher(
2095+
"health",
2096+
new EntityHealthResolver(
2097+
entityClient,
2098+
graphClient,
2099+
timeseriesAspectService,
2100+
new EntityHealthResolver.Config(false, true))))
20602101
.type(
20612102
"DataJobInputOutput",
20622103
typeWiring ->
@@ -2119,7 +2160,14 @@ private void configureDataFlowResolvers(final RuntimeWiring.Builder builder) {
21192160
return dataFlow.getDataPlatformInstance() != null
21202161
? dataFlow.getDataPlatformInstance().getUrn()
21212162
: null;
2122-
})));
2163+
}))
2164+
.dataFetcher(
2165+
"health",
2166+
new EntityHealthResolver(
2167+
entityClient,
2168+
graphClient,
2169+
timeseriesAspectService,
2170+
new EntityHealthResolver.Config(false, true))));
21232171
}
21242172

21252173
/**
@@ -2536,9 +2584,27 @@ private void configureQueryEntityResolvers(final RuntimeWiring.Builder builder)
25362584
builder
25372585
.type(
25382586
"QueryEntity",
2587+
typeWiring ->
2588+
typeWiring
2589+
.dataFetcher(
2590+
"relationships", new EntityRelationshipsResultResolver(graphClient))
2591+
.dataFetcher(
2592+
"platform",
2593+
new LoadableTypeResolver<>(
2594+
dataPlatformType,
2595+
(env) -> {
2596+
final QueryEntity query = env.getSource();
2597+
return query.getPlatform() != null
2598+
? query.getPlatform().getUrn()
2599+
: null;
2600+
})))
2601+
.type(
2602+
"QueryProperties",
25392603
typeWiring ->
25402604
typeWiring.dataFetcher(
2541-
"relationships", new EntityRelationshipsResultResolver(graphClient)))
2605+
"origin",
2606+
new EntityTypeResolver(
2607+
entityTypes, (env) -> ((QueryProperties) env.getSource()).getOrigin())))
25422608
.type(
25432609
"ListQueriesResult",
25442610
typeWiring ->
@@ -2660,4 +2726,35 @@ private void configureIngestionSourceResolvers(final RuntimeWiring.Builder build
26602726
: null;
26612727
})));
26622728
}
2729+
2730+
private void configureIncidentResolvers(final RuntimeWiring.Builder builder) {
2731+
builder.type(
2732+
"Incident",
2733+
typeWiring ->
2734+
typeWiring.dataFetcher(
2735+
"relationships", new EntityRelationshipsResultResolver(graphClient)));
2736+
builder.type(
2737+
"IncidentSource",
2738+
typeWiring ->
2739+
typeWiring.dataFetcher(
2740+
"source",
2741+
new LoadableTypeResolver<>(
2742+
this.assertionType,
2743+
(env) -> {
2744+
final IncidentSource incidentSource = env.getSource();
2745+
return incidentSource.getSource() != null
2746+
? incidentSource.getSource().getUrn()
2747+
: null;
2748+
})));
2749+
2750+
// Add incidents attribute to all entities that support it
2751+
final List<String> entitiesWithIncidents =
2752+
ImmutableList.of("Dataset", "DataJob", "DataFlow", "Dashboard", "Chart");
2753+
for (String entity : entitiesWithIncidents) {
2754+
builder.type(
2755+
entity,
2756+
typeWiring ->
2757+
typeWiring.dataFetcher("incidents", new EntityIncidentsResolver(entityClient)));
2758+
}
2759+
}
26632760
}

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/authorization/AuthorizationUtils.java

+8
Original file line numberDiff line numberDiff line change
@@ -219,5 +219,13 @@ public static boolean isAuthorized(
219219
return AuthUtil.isAuthorized(authorizer, actor, Optional.of(resourceSpec), privilegeGroup);
220220
}
221221

222+
public static boolean isViewDatasetUsageAuthorized(
223+
final Urn resourceUrn, final QueryContext context) {
224+
return isAuthorized(
225+
context,
226+
Optional.of(new EntitySpec(resourceUrn.getEntityType(), resourceUrn.toString())),
227+
PoliciesConfig.VIEW_DATASET_USAGE_PRIVILEGE);
228+
}
229+
222230
private AuthorizationUtils() {}
223231
}

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/exception/DataHubDataFetcherExceptionHandler.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import graphql.execution.DataFetcherExceptionHandlerResult;
77
import graphql.execution.ResultPath;
88
import graphql.language.SourceLocation;
9+
import java.util.concurrent.CompletableFuture;
910
import lombok.extern.slf4j.Slf4j;
1011

1112
@PublicApi
@@ -15,7 +16,7 @@ public class DataHubDataFetcherExceptionHandler implements DataFetcherExceptionH
1516
private static final String DEFAULT_ERROR_MESSAGE = "An unknown error occurred.";
1617

1718
@Override
18-
public DataFetcherExceptionHandlerResult onException(
19+
public CompletableFuture<DataFetcherExceptionHandlerResult> handleException(
1920
DataFetcherExceptionHandlerParameters handlerParameters) {
2021
Throwable exception = handlerParameters.getException();
2122
SourceLocation sourceLocation = handlerParameters.getSourceLocation();
@@ -44,7 +45,8 @@ public DataFetcherExceptionHandlerResult onException(
4445
log.error("Failed to execute", exception);
4546
}
4647
DataHubGraphQLError error = new DataHubGraphQLError(message, path, sourceLocation, errorCode);
47-
return DataFetcherExceptionHandlerResult.newResult().error(error).build();
48+
return CompletableFuture.completedFuture(
49+
DataFetcherExceptionHandlerResult.newResult().error(error).build());
4850
}
4951

5052
<T extends Throwable> T findFirstThrowableCauseOfClass(Throwable throwable, Class<T> clazz) {

datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/chart/ChartStatsSummaryResolver.java

-7
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,20 @@
11
package com.linkedin.datahub.graphql.resolvers.chart;
22

3-
import com.google.common.cache.Cache;
4-
import com.google.common.cache.CacheBuilder;
5-
import com.linkedin.common.urn.Urn;
63
import com.linkedin.datahub.graphql.generated.ChartStatsSummary;
74
import com.linkedin.metadata.timeseries.TimeseriesAspectService;
85
import graphql.schema.DataFetcher;
96
import graphql.schema.DataFetchingEnvironment;
107
import java.util.concurrent.CompletableFuture;
11-
import java.util.concurrent.TimeUnit;
128
import lombok.extern.slf4j.Slf4j;
139

1410
@Slf4j
1511
public class ChartStatsSummaryResolver
1612
implements DataFetcher<CompletableFuture<ChartStatsSummary>> {
1713

1814
private final TimeseriesAspectService timeseriesAspectService;
19-
private final Cache<Urn, ChartStatsSummary> summaryCache;
2015

2116
public ChartStatsSummaryResolver(final TimeseriesAspectService timeseriesAspectService) {
2217
this.timeseriesAspectService = timeseriesAspectService;
23-
this.summaryCache =
24-
CacheBuilder.newBuilder().maximumSize(10000).expireAfterWrite(6, TimeUnit.HOURS).build();
2518
}
2619

2720
@Override

0 commit comments

Comments
 (0)