diff --git a/ingestion/src/metadata/ingestion/ometa/mixins/user_mixin.py b/ingestion/src/metadata/ingestion/ometa/mixins/user_mixin.py new file mode 100644 index 00000000000..cac3195b76d --- /dev/null +++ b/ingestion/src/metadata/ingestion/ometa/mixins/user_mixin.py @@ -0,0 +1,47 @@ +# Copyright 2021 Collate +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Mixin class containing User specific methods + +To be used by OpenMetadata class +""" + +from metadata.generated.schema.entity.teams.user import User +from metadata.ingestion.ometa.client import REST +from metadata.ingestion.ometa.utils import ometa_logger + +logger = ometa_logger() + + +class OMetaUserMixin: + """ + OpenMetadata API methods related to user. + + To be inherited by OpenMetadata + """ + + client: REST + + def get_user_by_email(self, email: str) -> None: + """ + GET user entity by name + + :param email: User Email + """ + if email: + + name = email.split("@")[0] + users = self.es_search_from_fqn(entity_type=User, fqn_search_string=name) + if users: + for user in users: + if user.email.__root__ == email: + return user + return None diff --git a/ingestion/src/metadata/ingestion/ometa/ometa_api.py b/ingestion/src/metadata/ingestion/ometa/ometa_api.py index 01de3ea918c..4e652c4ba17 100644 --- a/ingestion/src/metadata/ingestion/ometa/ometa_api.py +++ b/ingestion/src/metadata/ingestion/ometa/ometa_api.py @@ -85,6 +85,7 @@ from metadata.ingestion.ometa.mixins.table_mixin import OMetaTableMixin from metadata.ingestion.ometa.mixins.tag_mixin import OMetaTagMixin from metadata.ingestion.ometa.mixins.tests_mixin import OMetaTestsMixin from metadata.ingestion.ometa.mixins.topic_mixin import OMetaTopicMixin +from metadata.ingestion.ometa.mixins.user_mixin import OMetaUserMixin from metadata.ingestion.ometa.mixins.version_mixin import OMetaVersionMixin from metadata.ingestion.ometa.provider_registry import ( InvalidAuthProviderException, @@ -155,6 +156,7 @@ class OpenMetadata( OMetaTestsMixin, DataInisghtMixin, OMetaIngestionPipelineMixin, + OMetaUserMixin, Generic[T, C], ): """ diff --git a/ingestion/src/metadata/ingestion/source/dashboard/dashboard_service.py b/ingestion/src/metadata/ingestion/source/dashboard/dashboard_service.py index 9f0503473e5..02a0ecc5510 100644 --- a/ingestion/src/metadata/ingestion/source/dashboard/dashboard_service.py +++ b/ingestion/src/metadata/ingestion/source/dashboard/dashboard_service.py @@ -20,7 +20,6 @@ from pydantic import BaseModel from metadata.generated.schema.api.data.createChart import CreateChartRequest from metadata.generated.schema.api.data.createDashboard import CreateDashboardRequest from metadata.generated.schema.api.lineage.addLineage import AddLineageRequest -from metadata.generated.schema.api.teams.createUser import CreateUserRequest from metadata.generated.schema.entity.data.chart import Chart from metadata.generated.schema.entity.data.dashboard import Dashboard from metadata.generated.schema.entity.data.table import Table @@ -107,12 +106,6 @@ class DashboardServiceTopology(ServiceTopology): cache_all=True, clear_cache=True, ), - NodeStage( - type_=CreateUserRequest, - context="owner", - processor="yield_owner", - nullable=True, - ), NodeStage( type_=Dashboard, context="dashboard", @@ -220,14 +213,6 @@ class DashboardServiceSource(TopologyRunnerMixin, Source, ABC): """ return # Dashboard does not support fetching tags except Tableau - def yield_owner( - self, *args, **kwargs # pylint: disable=W0613 - ) -> Optional[Iterable[CreateUserRequest]]: - """ - Method to fetch dashboard owner - """ - return # Dashboard does not support fetching owner details except Tableau - def yield_dashboard_usage( self, *args, **kwargs # pylint: disable=W0613 ) -> Optional[Iterable[DashboardUsage]]: diff --git a/ingestion/src/metadata/ingestion/source/dashboard/superset.py b/ingestion/src/metadata/ingestion/source/dashboard/superset.py index 20586a67227..effb9779049 100644 --- a/ingestion/src/metadata/ingestion/source/dashboard/superset.py +++ b/ingestion/src/metadata/ingestion/source/dashboard/superset.py @@ -149,6 +149,14 @@ class SupersetSource(DashboardServiceSource): """ return dashboard + def get_owner_details(self, dashboard_details: dict) -> EntityReference: + if dashboard_details.get("owners"): + owner = dashboard_details["owners"][0] + user = self.metadata.get_user_by_email(owner.get("email")) + if user: + return EntityReference(id=user.id.__root__, type="user") + return None + def yield_dashboard( self, dashboard_details: dict ) -> Iterable[CreateDashboardRequest]: @@ -160,6 +168,7 @@ class SupersetSource(DashboardServiceSource): displayName=dashboard_details["dashboard_title"], description="", dashboardUrl=dashboard_details["url"], + owner=self.get_owner_details(dashboard_details), charts=[ EntityReference(id=chart.id.__root__, type="chart") for chart in self.context.charts diff --git a/ingestion/src/metadata/ingestion/source/dashboard/tableau.py b/ingestion/src/metadata/ingestion/source/dashboard/tableau.py index 1dba041df36..1444310f7f3 100644 --- a/ingestion/src/metadata/ingestion/source/dashboard/tableau.py +++ b/ingestion/src/metadata/ingestion/source/dashboard/tableau.py @@ -26,7 +26,6 @@ from metadata.generated.schema.api.tags.createTag import CreateTagRequest from metadata.generated.schema.api.tags.createTagCategory import ( CreateTagCategoryRequest, ) -from metadata.generated.schema.api.teams.createUser import CreateUserRequest from metadata.generated.schema.entity.data.dashboard import ( Dashboard as LineageDashboard, ) @@ -168,9 +167,7 @@ class TableauSource(DashboardServiceSource): """ return dashboard - def yield_owner( # pylint: disable=arguments-differ - self, dashboard_details: dict - ) -> Optional[Iterable[CreateUserRequest]]: + def get_owner_details(self, dashboard_details: dict) -> EntityReference: """Get dashboard owner Args: @@ -179,11 +176,10 @@ class TableauSource(DashboardServiceSource): Optional[EntityReference] """ owner = self.owner[dashboard_details["owner"]["id"]] - name = owner.get("name") - display_name = owner.get("fullName") - email = owner.get("email") - if name and email: - yield CreateUserRequest(name=name, displayName=display_name, email=email) + user = self.metadata.get_user_by_email(owner.get("email")) + if user: + return EntityReference(id=user.id.__root__, type="user") + return None def yield_tag(self, _) -> OMetaTagAndCategory: # pylint: disable=arguments-differ """ @@ -231,7 +227,7 @@ class TableauSource(DashboardServiceSource): name=dashboard_details.get("id"), displayName=dashboard_details.get("name"), description="", - owner=self.context.owner, + owner=self.get_owner_details(dashboard_details), charts=[ EntityReference(id=chart.id.__root__, type="chart") for chart in self.context.charts