Skip to content

Commit b5066c6

Browse files
authored
Merge branch 'master' into feat/update-mlflow-ui
2 parents b62ef19 + 05ed277 commit b5066c6

File tree

45 files changed

+694
-217
lines changed

Some content is hidden

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

45 files changed

+694
-217
lines changed

.github/workflows/documentation.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ on:
55
branches:
66
- "**"
77
paths:
8+
- ".github/workflows/documentation.yml"
89
- "metadata-ingestion/**"
910
- "metadata-models/**"
1011
- "docs/**"
@@ -13,6 +14,7 @@ on:
1314
branches:
1415
- master
1516
paths:
17+
- ".github/workflows/documentation.yml"
1618
- "metadata-ingestion/**"
1719
- "metadata-models/**"
1820
- "docs/**"
@@ -57,8 +59,12 @@ jobs:
5759
5860
- name: Deploy
5961
if: github.event_name == 'push' && github.repository == 'datahub-project/datahub'
60-
uses: peaceiris/actions-gh-pages@v3
62+
uses: peaceiris/actions-gh-pages@v4
6163
with:
6264
github_token: ${{ secrets.GITHUB_TOKEN }}
6365
publish_dir: ./docs-website/build
6466
cname: datahubproject.io
67+
# The gh-pages branch stores the built docs site. We don't need to preserve
68+
# the full history of the .html files, since they're generated from our
69+
# source files. Doing so significantly reduces the size of the repo's .git dir.
70+
force_orphan: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ metadata-service/plugin/src/test/resources/sample-plugins/**
8585
smoke-test/rollback-reports
8686
coverage*.xml
8787
.vercel
88+
.envrc
8889

8990
# A long series of binary directories we should ignore
9091
datahub-frontend/bin/main/

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ project.ext.externalDependency = [
193193
'junitJupiterEngine': "org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion",
194194
// avro-serde includes dependencies for `kafka-avro-serializer` `kafka-schema-registry-client` and `avro`
195195
'kafkaAvroSerde': "io.confluent:kafka-streams-avro-serde:$kafkaVersion",
196-
'kafkaAvroSerializer': 'io.confluent:kafka-avro-serializer:5.1.4',
196+
'kafkaAvroSerializer': "io.confluent:kafka-avro-serializer:$kafkaVersion",
197197
'kafkaClients': "org.apache.kafka:kafka-clients:$kafkaVersion-ccs",
198198
'snappy': 'org.xerial.snappy:snappy-java:1.1.10.5',
199199
'logbackClassic': "ch.qos.logback:logback-classic:$logbackClassic",

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ public static <T> T restrictEntity(@Nonnull Object entity, Class<T> clazz) {
232232
try {
233233
Object[] args =
234234
allFields.stream()
235+
// New versions of graphql.codegen generate serialVersionUID
236+
// We need to filter serialVersionUID out because serialVersionUID is
237+
// never part of the entity type constructor
238+
.filter(field -> !field.getName().contains("serialVersionUID"))
235239
.map(
236240
field -> {
237241
// properties are often not required but only because

datahub-graphql-core/src/test/java/com/linkedin/datahub/graphql/resolvers/entity/versioning/LinkAssetVersionResolverTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ public void testGetSuccessful() throws Exception {
5757
Mockito.when(mockEnv.getArgument(Mockito.eq("input"))).thenReturn(input);
5858
Mockito.when(mockEnv.getContext()).thenReturn(mockContext);
5959

60-
VersionSet result = resolver.get(mockEnv).get();
61-
assertEquals(result.getUrn(), TEST_ENTITY_URN);
60+
61+
assertEquals(resolver.get(mockEnv).get().getUrn(), TEST_VERSION_SET_URN);
6262
}
6363

6464
@Test

datahub-graphql-core/src/test/java/com/linkedin/datahub/graphql/resolvers/entity/versioning/UnlinkAssetVersionResolverTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ public void testGetSuccessful() throws Exception {
4848
Mockito.when(mockEnv.getArgument(Mockito.eq("input"))).thenReturn(input);
4949
Mockito.when(mockEnv.getContext()).thenReturn(mockContext);
5050

51-
assertNotNull(resolver.get(mockEnv).get());
51+
52+
assertEquals(resolver.get(mockEnv).get(), null);
5253

5354
Mockito.verify(mockService)
5455
.unlinkVersion(

datahub-web-react/src/Mocks.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ export const dataset3 = {
645645
structuredProperties: null,
646646
forms: null,
647647
activeIncidents: null,
648+
versionProperties: null,
648649
} as Dataset;
649650

650651
export const dataset3WithSchema = {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* Custom User Context State - This is a custom user context state and can be overriden in specific fork of DataHub.
3+
* The below type can be customized with specific object properties as well if needed.
4+
*/
5+
export type CustomUserContextState = Record<string, any>;
6+
7+
export const DEFAULT_CUSTOM_STATE: CustomUserContextState = {};

datahub-web-react/src/app/context/userContext.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { CorpUser, PlatformPrivileges } from '../../types.generated';
3+
import { CustomUserContextState, DEFAULT_CUSTOM_STATE } from './CustomUserContext';
34

45
/**
56
* Local State is persisted to local storage.
@@ -22,6 +23,7 @@ export type State = {
2223
loadedPersonalDefaultViewUrn: boolean;
2324
hasSetDefaultView: boolean;
2425
};
26+
customState?: CustomUserContextState;
2527
};
2628

2729
/**
@@ -51,6 +53,7 @@ export const DEFAULT_STATE: State = {
5153
loadedPersonalDefaultViewUrn: false,
5254
hasSetDefaultView: false,
5355
},
56+
customState: DEFAULT_CUSTOM_STATE,
5457
};
5558

5659
export const DEFAULT_CONTEXT = {

datahub-web-react/src/app/entity/shared/containers/profile/header/EntityName.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ function EntityName(props: Props) {
4848
setIsEditing(false);
4949
return;
5050
}
51-
setUpdatedName(name);
5251
updateName({ variables: { input: { name, urn } } })
5352
.then(() => {
53+
setUpdatedName(name);
5454
setIsEditing(false);
5555
message.success({ content: 'Name Updated', duration: 2 });
5656
refetch();

datahub-web-react/src/app/entity/shared/containers/profile/sidebar/Ownership/EditOwnersModal.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,26 @@ export const EditOwnersModal = ({
7878
const renderSearchResult = (entity: Entity) => {
7979
const avatarUrl =
8080
(entity.type === EntityType.CorpUser && (entity as CorpUser).editableProperties?.pictureLink) || undefined;
81+
const corpUserDepartmentName =
82+
(entity.type === EntityType.CorpUser && (entity as CorpUser).properties?.departmentName) || '';
83+
const corpUserId = (entity.type === EntityType.CorpUser && (entity as CorpUser).username) || '';
84+
const corpUserTitle = (entity.type === EntityType.CorpUser && (entity as CorpUser).properties?.title) || '';
8185
const displayName = entityRegistry.getDisplayName(entity.type, entity);
86+
8287
return (
83-
<Select.Option value={entity.urn} key={entity.urn}>
84-
<OwnerLabel name={displayName} avatarUrl={avatarUrl} type={entity.type} />
88+
<Select.Option
89+
key={entity.urn}
90+
value={entity.urn}
91+
label={<OwnerLabel name={displayName} avatarUrl={avatarUrl} type={entity.type} />}
92+
>
93+
<OwnerLabel
94+
name={displayName}
95+
avatarUrl={avatarUrl}
96+
type={entity.type}
97+
corpUserId={corpUserId}
98+
corpUserTitle={corpUserTitle}
99+
corpUserDepartmentName={corpUserDepartmentName}
100+
/>
85101
</Select.Option>
86102
);
87103
};
@@ -381,6 +397,7 @@ export const EditOwnersModal = ({
381397
value: owner.value.ownerUrn,
382398
label: owner.label,
383399
}))}
400+
optionLabelProp="label"
384401
>
385402
{ownerSearchOptions}
386403
</SelectInput>

datahub-web-react/src/app/shared/OwnerLabel.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,22 @@ type Props = {
2020
name: string;
2121
avatarUrl: string | undefined;
2222
type: EntityType;
23+
corpUserId?: string;
24+
corpUserTitle?: string;
25+
corpUserDepartmentName?: string;
2326
};
2427

25-
export const OwnerLabel = ({ name, avatarUrl, type }: Props) => {
28+
export const OwnerLabel = ({ name, avatarUrl, type, corpUserId, corpUserTitle, corpUserDepartmentName }: Props) => {
29+
const subHeader = [corpUserId, corpUserTitle, corpUserDepartmentName].filter(Boolean).join(' - ');
30+
2631
return (
2732
<OwnerContainerWrapper>
2833
<OwnerContentWrapper>
2934
<CustomAvatar size={24} name={name} photoUrl={avatarUrl} isGroup={type === EntityType.CorpGroup} />
30-
<div>{name}</div>
35+
<div>
36+
<div>{name}</div>
37+
{subHeader && <div style={{ color: 'gray' }}>{subHeader}</div>}
38+
</div>
3139
</OwnerContentWrapper>
3240
</OwnerContainerWrapper>
3341
);

datahub-web-react/src/appConfigContext.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const DEFAULT_APP_CONFIG = {
5757
editableDatasetNameEnabled: false,
5858
showSeparateSiblings: false,
5959
showManageStructuredProperties: false,
60+
entityVersioningEnabled: false,
6061
},
6162
};
6263

datahub-web-react/src/graphql/search.graphql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,8 @@ fragment searchResultsWithoutSchemaField on Entity {
433433
lastName
434434
fullName
435435
email
436+
departmentName
437+
title
436438
}
437439
info {
438440
active
@@ -442,6 +444,8 @@ fragment searchResultsWithoutSchemaField on Entity {
442444
lastName
443445
fullName
444446
email
447+
departmentName
448+
title
445449
}
446450
editableProperties {
447451
displayName

docs-website/docusaurus.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ module.exports = {
7777
announcementBar: {
7878
id: "announcement-3",
7979
content:
80-
'<div style="display: flex; justify-content: center; align-items: center;width: 100%;"><!--img src="/img/acryl-logo-white-mark.svg" / --><!--div style="font-size: .8rem; font-weight: 600; background-color: white; color: #111; padding: 0px 8px; border-radius: 4px; margin-right:12px;">NEW</div--><p>Watch Metadata & AI Summit sessions on-demand.</p><a href="https://www.youtube.com/@DataHubProject/videos" target="_blank" class="button">Watch Now<span> →</span></a></div>',
80+
'<div style="display: flex; justify-content: center; align-items: center;width: 100%;"><!--img src="/img/acryl-logo-white-mark.svg" / --><!--div style="font-size: .8rem; font-weight: 600; background-color: white; color: #111; padding: 0px 8px; border-radius: 4px; margin-right:12px;">NEW</div--><p>Learn about DataHub 1.0 launching at our 5th birthday party!</p><a href="https://lu.ma/0j5jcocn" target="_blank" class="button">Register<span> →</span></a></div>',
8181
backgroundColor: "#111",
8282
textColor: "#ffffff",
8383
isCloseable: false,

docs-website/src/components/SolutionsDropdown/SolutionsDropdownContent/solutionsDropdownContent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const solutionsDropdownContent = {
2424
title: "DataHub Core",
2525
description: "Get started with the Open Source platform.",
2626
iconImage: "/img/solutions/icon-dropdown-core.png",
27-
href: "/",
27+
href: "/docs/quickstart",
2828
},
2929
{
3030
title: "Cloud vs Core",

docs/cli.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,17 @@ datahub ingest -c ./examples/recipes/example_to_datahub_rest.dhub.yaml --dry-run
115115
datahub ingest -c ./examples/recipes/example_to_datahub_rest.dhub.yaml -n
116116
```
117117

118-
#### ingest --list-source-runs
118+
#### ingest list-source-runs
119119

120-
The `--list-source-runs` option of the `ingest` command lists the previous runs, displaying their run ID, source name,
120+
The `list-source-runs` option of the `ingest` command lists the previous runs, displaying their run ID, source name,
121121
start time, status, and source URN. This command allows you to filter results using the --urn option for URN-based
122122
filtering or the --source option to filter by source name (partial or complete matches are supported).
123123

124124
```shell
125125
# List all ingestion runs
126-
datahub ingest --list-source-runs
126+
datahub ingest list-source-runs
127127
# Filter runs by a source name containing "demo"
128-
datahub ingest --list-source-runs --source "demo"
128+
datahub ingest list-source-runs --source "demo"
129129
```
130130

131131
#### ingest --preview
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.linkedin.common.urn;
2+
3+
import com.linkedin.data.template.Custom;
4+
import com.linkedin.data.template.DirectCoercer;
5+
import com.linkedin.data.template.TemplateOutputCastException;
6+
import java.net.URISyntaxException;
7+
8+
public final class DataPlatformInstanceUrn extends Urn {
9+
10+
public static final String ENTITY_TYPE = "dataPlatformInstance";
11+
12+
private final DataPlatformUrn _platform;
13+
private final String _instanceId;
14+
15+
public DataPlatformInstanceUrn(DataPlatformUrn platform, String instanceId) {
16+
super(ENTITY_TYPE, TupleKey.create(platform, instanceId));
17+
this._platform = platform;
18+
this._instanceId = instanceId;
19+
}
20+
21+
public DataPlatformUrn getPlatformEntity() {
22+
return _platform;
23+
}
24+
25+
public String getInstance() {
26+
return _instanceId;
27+
}
28+
29+
public static DataPlatformInstanceUrn createFromString(String rawUrn) throws URISyntaxException {
30+
return createFromUrn(Urn.createFromString(rawUrn));
31+
}
32+
33+
public static DataPlatformInstanceUrn createFromUrn(Urn urn) throws URISyntaxException {
34+
if (!"li".equals(urn.getNamespace())) {
35+
throw new URISyntaxException(urn.toString(), "Urn namespace type should be 'li'.");
36+
} else if (!ENTITY_TYPE.equals(urn.getEntityType())) {
37+
throw new URISyntaxException(
38+
urn.toString(), "Urn entity type should be 'dataPlatformInstance'.");
39+
} else {
40+
TupleKey key = urn.getEntityKey();
41+
if (key.size() != 2) {
42+
throw new URISyntaxException(urn.toString(), "Invalid number of keys.");
43+
} else {
44+
try {
45+
return new DataPlatformInstanceUrn(
46+
(DataPlatformUrn) key.getAs(0, DataPlatformUrn.class),
47+
(String) key.getAs(1, String.class));
48+
} catch (Exception e) {
49+
throw new URISyntaxException(urn.toString(), "Invalid URN Parameter: '" + e.getMessage());
50+
}
51+
}
52+
}
53+
}
54+
55+
public static DataPlatformInstanceUrn deserialize(String rawUrn) throws URISyntaxException {
56+
return createFromString(rawUrn);
57+
}
58+
59+
static {
60+
Custom.initializeCustomClass(DataPlatformUrn.class);
61+
Custom.initializeCustomClass(DataPlatformInstanceUrn.class);
62+
Custom.registerCoercer(
63+
new DirectCoercer<DataPlatformInstanceUrn>() {
64+
public Object coerceInput(DataPlatformInstanceUrn object) throws ClassCastException {
65+
return object.toString();
66+
}
67+
68+
public DataPlatformInstanceUrn coerceOutput(Object object)
69+
throws TemplateOutputCastException {
70+
try {
71+
return DataPlatformInstanceUrn.createFromString((String) object);
72+
} catch (URISyntaxException e) {
73+
throw new TemplateOutputCastException("Invalid URN syntax: " + e.getMessage(), e);
74+
}
75+
}
76+
},
77+
DataPlatformInstanceUrn.class);
78+
}
79+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace com.linkedin.common
2+
3+
/**
4+
* Standardized dataset identifier.
5+
*/
6+
@java.class = "com.linkedin.common.urn.DataPlatformInstanceUrn"
7+
@validate.`com.linkedin.common.validator.TypedUrnValidator` = {
8+
"accessible" : true,
9+
"owningTeam" : "urn:li:internalTeam:datahub",
10+
"entityType" : "dataPlatformInstance",
11+
"constructable" : true,
12+
"namespace" : "li",
13+
"name" : "DataPlatformInstance",
14+
"doc" : "Standardized data platform instance identifier.",
15+
"owners" : [ "urn:li:corpuser:fbar", "urn:li:corpuser:bfoo" ],
16+
"fields" : [ {
17+
"type" : "com.linkedin.common.urn.DataPlatformUrn",
18+
"name" : "platform",
19+
"doc" : "Standardized platform urn."
20+
}, {
21+
"name" : "instance",
22+
"doc" : "Instance of the data platform (e.g. db instance)",
23+
"type" : "string",
24+
} ],
25+
"maxLength" : 100
26+
}
27+
typeref DataPlatformInstanceUrn = string

metadata-ingestion/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,15 @@ task lint(type: Exec, dependsOn: installDev) {
109109
commandLine 'bash', '-c',
110110
"source ${venv_name}/bin/activate && set -x && " +
111111
"black --check --diff src/ tests/ examples/ && " +
112-
"isort --check --diff src/ tests/ examples/ && " +
113-
"flake8 --count --statistics src/ tests/ examples/ && " +
112+
"ruff check src/ tests/ examples/ && " +
114113
"mypy --show-traceback --show-error-codes src/ tests/ examples/"
115114
}
115+
116116
task lintFix(type: Exec, dependsOn: installDev) {
117117
commandLine 'bash', '-c',
118118
"source ${venv_name}/bin/activate && set -x && " +
119119
"black src/ tests/ examples/ && " +
120-
"isort src/ tests/ examples/"
120+
"ruff check --fix src/ tests/ examples/"
121121
}
122122

123123
def pytest_default_env = "PYTHONDEVMODE=1"

metadata-ingestion/developing.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,12 @@ The architecture of this metadata ingestion framework is heavily inspired by [Ap
177177

178178
## Code style
179179

180-
We use black, isort, flake8, and mypy to ensure consistent code style and quality.
180+
We use black, ruff, and mypy to ensure consistent code style and quality.
181181

182182
```shell
183183
# Assumes: pip install -e '.[dev]' and venv is activated
184184
black src/ tests/
185-
isort src/ tests/
186-
flake8 src/ tests/
185+
ruff check src/ tests/
187186
mypy src/ tests/
188187
```
189188

0 commit comments

Comments
 (0)