Skip to content

Commit

Permalink
feat(*): Support setting owner type when assigning ownership (#4354)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjoyce0510 authored Mar 14, 2022
1 parent 23404f9 commit ecd263b
Show file tree
Hide file tree
Showing 19 changed files with 283 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.linkedin.datahub.graphql.exception.AuthorizationException;
import com.linkedin.datahub.graphql.generated.AddOwnerInput;
import com.linkedin.datahub.graphql.generated.OwnerEntityType;
import com.linkedin.datahub.graphql.generated.OwnershipType;
import com.linkedin.datahub.graphql.resolvers.mutate.util.OwnerUtils;
import com.linkedin.metadata.entity.EntityService;
import graphql.schema.DataFetcher;
Expand All @@ -30,6 +31,7 @@ public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throw

Urn ownerUrn = Urn.createFromString(input.getOwnerUrn());
OwnerEntityType ownerEntityType = input.getOwnerEntityType();
OwnershipType type = input.getType() == null ? OwnershipType.NONE : input.getType();
Urn targetUrn = Urn.createFromString(input.getResourceUrn());

if (!OwnerUtils.isAuthorizedToUpdateOwners(environment.getContext(), targetUrn)) {
Expand All @@ -50,6 +52,8 @@ public CompletableFuture<Boolean> get(DataFetchingEnvironment environment) throw
Urn actor = CorpuserUrn.createFromString(((QueryContext) environment.getContext()).getActorUrn());
OwnerUtils.addOwner(
ownerUrn,
// Assumption Alert: Assumes that GraphQL ownership type === GMS ownership type
com.linkedin.common.OwnershipType.valueOf(type.name()),
targetUrn,
actor,
_entityService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.linkedin.metadata.Constants;
import com.linkedin.metadata.authorization.PoliciesConfig;
import com.linkedin.metadata.entity.EntityService;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -34,6 +35,7 @@ private OwnerUtils() { }

public static void addOwner(
Urn ownerUrn,
OwnershipType type,
Urn resourceUrn,
Urn actor,
EntityService entityService
Expand All @@ -43,7 +45,7 @@ public static void addOwner(
Constants.OWNERSHIP_ASPECT_NAME,
entityService,
new Ownership());
addOwner(ownershipAspect, ownerUrn);
addOwner(ownershipAspect, ownerUrn, type);
persistAspect(resourceUrn, Constants.OWNERSHIP_ASPECT_NAME, ownershipAspect, actor, entityService);
}

Expand All @@ -63,23 +65,22 @@ public static void removeOwner(
persistAspect(resourceUrn, Constants.OWNERSHIP_ASPECT_NAME, ownershipAspect, actor, entityService);
}

private static void addOwner(Ownership ownershipAspect, Urn ownerUrn) {
private static void addOwner(Ownership ownershipAspect, Urn ownerUrn, OwnershipType type) {
if (!ownershipAspect.hasOwners()) {
ownershipAspect.setOwners(new OwnerArray());
}

OwnerArray ownerArray = ownershipAspect.getOwners();

// if owner exists, do not add it again
if (ownerArray.stream().anyMatch(association -> association.getOwner().equals(ownerUrn))) {
return;
}
final OwnerArray ownerArray = new OwnerArray(ownershipAspect.getOwners()
.stream()
.filter(owner -> !owner.getOwner().equals(ownerUrn))
.collect(Collectors.toList()));

Owner newOwner = new Owner();
newOwner.setType(OwnershipType.DATAOWNER);
newOwner.setType(type);
newOwner.setSource(new OwnershipSource().setType(OwnershipSourceType.MANUAL));
newOwner.setOwner(ownerUrn);
ownerArray.add(newOwner);
ownershipAspect.setOwners(ownerArray);
}

private static void removeOwner(Ownership ownership, Urn ownerUrn) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public Collection<MetadataChangeProposal> apply(
final Ownership ownership = new Ownership();
final Owner owner = new Owner();
owner.setOwner(actor);
owner.setType(OwnershipType.DATAOWNER);
owner.setType(OwnershipType.NONE);
owner.setSource(new OwnershipSource().setType(OwnershipSourceType.SERVICE));
ownership.setOwners(new OwnerArray(owner));
ownership.setLastModified(auditStamp);
Expand Down
51 changes: 41 additions & 10 deletions datahub-graphql-core/src/main/resources/entity.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2147,34 +2147,60 @@ Note that this field will soon become deprecated due to low usage
"""
enum OwnershipType {
"""
A person or group that is in charge of developing the code
A person or group who is responsible for technical aspects of the asset.
"""
TECHNICAL_OWNER

"""
DEVELOPER
A person or group who is responsible for logical, or business related, aspects of the asset.
"""
BUSINESS_OWNER

"""
A person or group that is owning the data
A steward, expert, or delegate responsible for the asset.
"""
DATAOWNER
DATA_STEWARD

"""
No specific type associated with the owner.
"""
NONE

"""
A person or group that owns the data.
Deprecated! This ownership type is no longer supported. Use TECHNICAL_OWNER instead.
"""
DATAOWNER @deprecated

"""
A person or group that is in charge of developing the code
Deprecated! This ownership type is no longer supported. Use TECHNICAL_OWNER instead.
"""
DEVELOPER @deprecated

"""
A person or a group that overseas the operation, eg a DBA or SRE
Deprecated! This ownership type is no longer supported. Use TECHNICAL_OWNER instead.
"""
DELEGATE
DELEGATE @deprecated

"""
A person, group, or service that produces or generates the data
Deprecated! This ownership type is no longer supported. Use TECHNICAL_OWNER instead.
"""
PRODUCER
PRODUCER @deprecated

"""
A person, group, or service that consumes the data
A person or a group that has direct business interest
Deprecated! Use BUSINESS_OWNER instead.
"""
CONSUMER
STAKEHOLDER @deprecated

"""
A person or a group that has direct business interest
A person, group, or service that consumes the data
Deprecated! This ownership type is no longer supported.
"""
STAKEHOLDER
CONSUMER @deprecated
}

"""
Expand Down Expand Up @@ -5105,6 +5131,11 @@ input AddOwnerInput {
"""
ownerEntityType: OwnerEntityType!

"""
The ownership type for the new owner. If none is provided, then a new NONE will be added.
"""
type: OwnershipType

"""
The urn of the resource or entity to attach or remove the owner from, for example a dataset urn
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
useGetDashboardQuery,
useUpdateDashboardMutation,
} from '../../../graphql/dashboard.generated';
import { Dashboard, EntityType, PlatformType, SearchResult } from '../../../types.generated';
import { Dashboard, EntityType, OwnershipType, PlatformType, SearchResult } from '../../../types.generated';
import { EntityAndType } from '../../lineage/types';
import { Entity, IconStyleType, PreviewType } from '../Entity';
import { EntityProfile } from '../shared/containers/profile/EntityProfile';
Expand Down Expand Up @@ -104,6 +104,9 @@ export class DashboardEntity implements Entity<Dashboard> {
},
{
component: SidebarOwnerSection,
properties: {
defaultOwnerType: OwnershipType.TechnicalOwner,
},
},
{
component: SidebarDomainSection,
Expand Down
5 changes: 4 additions & 1 deletion datahub-web-react/src/app/entity/dataFlow/DataFlowEntity.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { ShareAltOutlined } from '@ant-design/icons';
import { DataFlow, EntityType, PlatformType, SearchResult } from '../../../types.generated';
import { DataFlow, EntityType, OwnershipType, PlatformType, SearchResult } from '../../../types.generated';
import { Preview } from './preview/Preview';
import { Entity, IconStyleType, PreviewType } from '../Entity';
import { EntityProfile } from '../shared/containers/profile/EntityProfile';
Expand Down Expand Up @@ -89,6 +89,9 @@ export class DataFlowEntity implements Entity<DataFlow> {
},
{
component: SidebarOwnerSection,
properties: {
defaultOwnerType: OwnershipType.TechnicalOwner,
},
},
{
component: SidebarDomainSection,
Expand Down
5 changes: 4 additions & 1 deletion datahub-web-react/src/app/entity/dataJob/DataJobEntity.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import { ConsoleSqlOutlined } from '@ant-design/icons';
import { DataJob, EntityType, PlatformType, SearchResult } from '../../../types.generated';
import { DataJob, EntityType, OwnershipType, PlatformType, SearchResult } from '../../../types.generated';
import { Preview } from './preview/Preview';
import { Entity, IconStyleType, PreviewType } from '../Entity';
import { EntityProfile } from '../shared/containers/profile/EntityProfile';
Expand Down Expand Up @@ -101,6 +101,9 @@ export class DataJobEntity implements Entity<DataJob> {
},
{
component: SidebarOwnerSection,
properties: {
defaultOwnerType: OwnershipType.TechnicalOwner,
},
},
{
component: SidebarDomainSection,
Expand Down
5 changes: 4 additions & 1 deletion datahub-web-react/src/app/entity/dataset/DatasetEntity.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { DatabaseFilled, DatabaseOutlined } from '@ant-design/icons';
import { Typography } from 'antd';
import { Dataset, EntityType, SearchResult } from '../../../types.generated';
import { Dataset, EntityType, OwnershipType, SearchResult } from '../../../types.generated';
import { Entity, IconStyleType, PreviewType } from '../Entity';
import { Preview } from './preview/Preview';
import { FIELDS_TO_HIGHLIGHT } from './search/highlights';
Expand Down Expand Up @@ -179,6 +179,9 @@ export class DatasetEntity implements Entity<Dataset> {
},
{
component: SidebarOwnerSection,
properties: {
defaultOwnerType: OwnershipType.TechnicalOwner,
},
},
{
component: SidebarDomainSection,
Expand Down
3 changes: 3 additions & 0 deletions datahub-web-react/src/app/entity/domain/DomainEntity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ export class DomainEntity implements Entity<Domain> {
},
{
component: SidebarOwnerSection,
properties: {
hideOwnerType: true,
},
},
]}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export default function GroupOwnerSideBarSection({ urn, ownership, refetch }: Pr
</SectionWrapper>
<AddOwnerModal
urn={urn}
hideOwnerType
type={EntityType.CorpGroup}
visible={showAddModal}
refetch={refetch}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { message, Modal, Tag, Tooltip } from 'antd';
import { message, Modal, Popover, Tag, Typography } from 'antd';
import React from 'react';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
Expand All @@ -9,10 +9,12 @@ import { CustomAvatar } from '../../../../shared/avatar';
import { useEntityRegistry } from '../../../../useEntityRegistry';
import analytics, { EventType, EntityActionType } from '../../../../analytics';
import { useEntityData } from '../../EntityContext';
import { getDescriptionFromType, getNameFromType } from '../../containers/profile/sidebar/Ownership/ownershipUtils';

type Props = {
entityUrn: string;
owner: Owner;
hidePopOver?: boolean | undefined;
refetch?: () => Promise<any>;
};

Expand All @@ -24,7 +26,7 @@ const OwnerTag = styled(Tag)`
align-items: center;
`;

export const ExpandedOwner = ({ entityUrn, owner, refetch }: Props) => {
export const ExpandedOwner = ({ entityUrn, owner, hidePopOver, refetch }: Props) => {
const entityRegistry = useEntityRegistry();
const { entityType } = useEntityData();
const [removeOwnerMutation] = useRemoveOwnerMutation();
Expand Down Expand Up @@ -85,9 +87,18 @@ export const ExpandedOwner = ({ entityUrn, owner, refetch }: Props) => {
<OwnerTag onClose={onClose} closable>
<Link to={`/${entityRegistry.getPathName(owner.owner.type)}/${owner.owner.urn}`}>
<CustomAvatar name={name} photoUrl={pictureLink} useDefaultAvatar={false} />
<Tooltip placement="top" title={owner.type}>
{name}
</Tooltip>
{(hidePopOver && <>{name}</>) || (
<Popover
overlayStyle={{ maxWidth: 200 }}
placement="left"
title={<Typography.Text strong>{getNameFromType(owner.type)}</Typography.Text>}
content={
<Typography.Text type="secondary">{getDescriptionFromType(owner.type)}</Typography.Text>
}
>
{name}
</Popover>
)}
</Link>
</OwnerTag>
);
Expand Down
Loading

0 comments on commit ecd263b

Please sign in to comment.