Feature: Reverse Metadata Ingestion (#19723)

This commit is contained in:
Keshav Mohta 2025-02-25 18:41:08 +05:30 committed by GitHub
parent a0e91f3dea
commit df193bd0c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 657 additions and 54 deletions

View File

@ -16,7 +16,7 @@ import os
import yaml
from metadata.automations.runner import execute
from metadata.automations.execute_runner import execute
from metadata.generated.schema.entity.automations.workflow import (
Workflow as AutomationWorkflow,
)

View File

@ -0,0 +1,49 @@
# 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.
"""
Run the Automation Workflow
"""
from functools import singledispatch
from typing import Any
from metadata.generated.schema.entity.automations.workflow import (
Workflow as AutomationWorkflow,
)
from metadata.ingestion.ometa.ometa_api import OpenMetadata
@singledispatch
def run_workflow(request: Any, *_, **__) -> Any:
"""
Main entrypoint to execute the automation workflow
"""
raise NotImplementedError(f"Workflow runner not implemented for {type(request)}")
def execute(encrypted_automation_workflow: AutomationWorkflow) -> Any:
"""
Execute the automation workflow.
The implementation depends on the request body type
"""
# Import all the functions defined for run_workflow
import metadata.automations.extended_runner # pylint: disable=import-outside-toplevel
import metadata.automations.runner # pylint: disable=import-outside-toplevel
# This will already instantiate the Secrets Manager
metadata = OpenMetadata(
config=encrypted_automation_workflow.openMetadataServerConnection
)
automation_workflow = metadata.get_by_name(
entity=AutomationWorkflow, fqn=encrypted_automation_workflow.name.root
)
return run_workflow(automation_workflow.request, automation_workflow, metadata)

View File

@ -0,0 +1,13 @@
# 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.
"""
Run the Automation Workflow for extended runners
"""

View File

@ -9,11 +9,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Run the Automation Workflow
Run the Automation Workflow for OpenMetadata
"""
from functools import singledispatch
from typing import Any
from metadata.automations.execute_runner import run_workflow
from metadata.generated.schema.entity.automations.testServiceConnection import (
TestServiceConnectionRequest,
)
@ -28,32 +27,6 @@ from metadata.ingestion.source.connections import get_connection, get_test_conne
from metadata.utils.ssl_manager import SSLManager, check_ssl_and_init
def execute(encrypted_automation_workflow: AutomationWorkflow) -> Any:
"""
Execute the automation workflow.
The implementation depends on the request body type
"""
# This will already instantiate the Secrets Manager
metadata = OpenMetadata(
config=encrypted_automation_workflow.openMetadataServerConnection
)
automation_workflow = metadata.get_by_name(
entity=AutomationWorkflow, fqn=encrypted_automation_workflow.name.root
)
return run_workflow(automation_workflow.request, automation_workflow, metadata)
@singledispatch
def run_workflow(request: Any, *_, **__) -> Any:
"""
Main entrypoint to execute the automation workflow
"""
raise NotImplementedError(f"Workflow runner not implemented for {type(request)}")
@run_workflow.register
def _(
request: TestServiceConnectionRequest,

View File

@ -29,6 +29,9 @@ from metadata.generated.schema.entity.domains.domain import Domain
from metadata.generated.schema.entity.services.connections.testConnectionResult import (
TestConnectionResult,
)
from metadata.generated.schema.entity.services.ingestionPipelines.reverseIngestionResponse import (
ReverseIngestionResponse,
)
from metadata.generated.schema.tests.testCase import TestCase, TestCaseParameterValue
from metadata.generated.schema.type.basic import EntityLink, Markdown
from metadata.generated.schema.type.entityReference import EntityReference
@ -488,7 +491,7 @@ class OMetaPatchMixin(OMetaPatchMixinBase):
def patch_automation_workflow_response(
self,
automation_workflow: AutomationWorkflow,
test_connection_result: TestConnectionResult,
result: Union[TestConnectionResult, ReverseIngestionResponse],
workflow_status: WorkflowStatus,
) -> None:
"""
@ -496,14 +499,21 @@ class OMetaPatchMixin(OMetaPatchMixinBase):
"""
result_data: Dict = {
PatchField.PATH: PatchPath.RESPONSE,
PatchField.VALUE: test_connection_result.model_dump(),
PatchField.VALUE: result.model_dump(),
PatchField.OPERATION: PatchOperation.ADD,
}
# for deserializing into json convert enum object to string
result_data[PatchField.VALUE]["status"] = result_data[PatchField.VALUE][
"status"
].value
if isinstance(result, TestConnectionResult):
result_data[PatchField.VALUE]["status"] = result_data[PatchField.VALUE][
"status"
].value
else:
# Convert UUID in string
data = result_data[PatchField.VALUE]
data["serviceId"] = str(data["serviceId"])
for operation_result in data["results"]:
operation_result["id"] = str(operation_result["id"])
status_data: Dict = {
PatchField.PATH: PatchPath.STATUS,

View File

@ -12,8 +12,9 @@
"""
Source connection helper
"""
import re
import traceback
from typing import Any
from typing import Any, List, Tuple
from pydantic import BaseModel
from sqlalchemy import inspect
@ -142,3 +143,10 @@ def get_foreign_keys(
f"Error while fetching foreign key constraint error for table [{schema}.{table_name}]: {exc}"
)
return []
def parse_bigqeury_labels(labels: str) -> List[Tuple[str, str]]:
"""
This function is used to parse BigQuery label string into a list of tuples.
"""
return re.findall(r'STRUCT\("([^"]+)",\s*"([^"]+)"\)', labels)

View File

@ -12,6 +12,8 @@
"""
MySQL SQLAlchemy Helper Methods
"""
# pylint: disable=protected-access,too-many-branches,too-many-statements,too-many-locals
from sqlalchemy import util
from sqlalchemy.dialects.mysql.enumerated import ENUM, SET
@ -136,9 +138,9 @@ def parse_column(self, line, state):
raw_type = get_display_datatype(
col_type=type_,
char_len=type_instance.length if hasattr(type_instance, "length") else None,
precision=type_instance.precision
if hasattr(type_instance, "precision")
else None,
precision=(
type_instance.precision if hasattr(type_instance, "precision") else None
),
scale=type_instance.scale if hasattr(type_instance, "scale") else None,
)

View File

@ -16,6 +16,7 @@ from functools import partial
from typing import Optional
from databricks.sdk import WorkspaceClient
from sqlalchemy.engine import Engine
from metadata.generated.schema.entity.automations.workflow import (
Workflow as AutomationWorkflow,
@ -26,6 +27,11 @@ from metadata.generated.schema.entity.services.connections.database.unityCatalog
from metadata.generated.schema.entity.services.connections.testConnectionResult import (
TestConnectionResult,
)
from metadata.ingestion.connections.builders import (
create_generic_db_connection,
get_connection_args_common,
init_empty_connection_arguments,
)
from metadata.ingestion.connections.test_connections import test_connection_steps
from metadata.ingestion.ometa.ometa_api import OpenMetadata
from metadata.ingestion.source.database.unitycatalog.client import UnityCatalogClient
@ -53,6 +59,23 @@ def get_connection(connection: UnityCatalogConnection) -> WorkspaceClient:
)
def get_sqlalchemy_connection(connection: UnityCatalogConnection) -> Engine:
"""
Create sqlalchemy connection
"""
if connection.httpPath:
if not connection.connectionArguments:
connection.connectionArguments = init_empty_connection_arguments()
connection.connectionArguments.root["http_path"] = connection.httpPath
return create_generic_db_connection(
connection=connection,
get_connection_url_fn=get_connection_url,
get_connection_args_fn=get_connection_args_common,
)
def test_connection(
metadata: OpenMetadata,
connection: WorkspaceClient,

View File

@ -60,6 +60,7 @@ class Loggers(Enum):
TEST_SUITE = "TestSuite"
QUERY_RUNNER = "QueryRunner"
APP = "App"
REVERSE_INGESTION = "ReverseIngestion"
@DynamicClassAttribute
def value(self):
@ -143,6 +144,14 @@ def ingestion_logger():
return logging.getLogger(Loggers.INGESTION.value)
def reverse_ingestion_logger():
"""
Method to get the REVERSE INGESTION logger
"""
return logging.getLogger(Loggers.REVERSE_INGESTION.value)
def utils_logger():
"""
Method to get the UTILS logger

View File

@ -19,7 +19,7 @@ from openmetadata_managed_apis.api.response import ApiResponse
from openmetadata_managed_apis.utils.logger import routes_logger
from pydantic import ValidationError
from metadata.automations.runner import execute
from metadata.automations.execute_runner import execute
from metadata.ingestion.api.parser import parse_automation_workflow_gracefully
from metadata.utils.secrets.secrets_manager_factory import SecretsManagerFactory

View File

@ -16,6 +16,7 @@ package org.openmetadata.service.secrets.converter;
import java.util.List;
import org.openmetadata.schema.entity.automations.TestServiceConnectionRequest;
import org.openmetadata.schema.entity.automations.Workflow;
import org.openmetadata.schema.metadataIngestion.ReverseIngestionPipeline;
import org.openmetadata.schema.services.connections.metadata.OpenMetadataConnection;
import org.openmetadata.service.util.JsonUtils;
@ -30,7 +31,9 @@ public class WorkflowClassConverter extends ClassConverter {
public Object convert(Object object) {
Workflow workflow = (Workflow) JsonUtils.convertValue(object, this.clazz);
tryToConvertOrFail(workflow.getRequest(), List.of(TestServiceConnectionRequest.class))
tryToConvertOrFail(
workflow.getRequest(),
List.of(TestServiceConnectionRequest.class, ReverseIngestionPipeline.class))
.ifPresent(workflow::setRequest);
if (workflow.getOpenMetadataServerConnection() != null) {

View File

@ -5,7 +5,9 @@
"description": "A unit of work that will be triggered as an API call to the OpenMetadata server.",
"type": "object",
"javaType": "org.openmetadata.schema.entity.automations.CreateWorkflow",
"javaInterfaces": ["org.openmetadata.schema.CreateEntity"],
"javaInterfaces": [
"org.openmetadata.schema.CreateEntity"
],
"properties": {
"name": {
"description": "Name of the workflow.",
@ -28,6 +30,9 @@
"oneOf": [
{
"$ref": "../../entity/automations/testServiceConnection.json"
},
{
"$ref": "../../metadataIngestion/reverseIngestionPipeline.json"
}
]
},
@ -41,6 +46,9 @@
"oneOf": [
{
"$ref": "../../entity/services/connections/testConnectionResult.json"
},
{
"$ref": "../../entity/services/ingestionPipelines/reverseIngestionResponse.json"
}
]
},
@ -49,11 +57,15 @@
"$ref": "../../type/entityReferenceList.json",
"default": null
},
"domain" : {
"domain": {
"description": "Fully qualified name of the domain the Table belongs to.",
"type": "string"
}
},
"additionalProperties": false,
"required": ["name", "workflowType", "request"]
}
"required": [
"name",
"workflowType",
"request"
]
}

View File

@ -5,21 +5,29 @@
"description": "A unit of work that will be triggered as an API call to the OpenMetadata server.",
"type": "object",
"javaType": "org.openmetadata.schema.entity.automations.Workflow",
"javaInterfaces": ["org.openmetadata.schema.EntityInterface"],
"javaInterfaces": [
"org.openmetadata.schema.EntityInterface"
],
"definitions": {
"workflowType": {
"javaType": "org.openmetadata.schema.entity.automations.WorkflowType",
"description": "This enum defines the type for which this workflow applies to.",
"type": "string",
"enum": [
"TEST_CONNECTION"
"TEST_CONNECTION",
"REVERSE_INGESTION"
]
},
"workflowStatus": {
"javaType": "org.openmetadata.schema.entity.automations.WorkflowStatus",
"description": "Enum defining possible Workflow status",
"type": "string",
"enum": ["Pending", "Successful", "Failed", "Running"]
"enum": [
"Pending",
"Successful",
"Failed",
"Running"
]
}
},
"properties": {
@ -57,6 +65,9 @@
"oneOf": [
{
"$ref": "testServiceConnection.json"
},
{
"$ref": "../../metadataIngestion/reverseIngestionPipeline.json"
}
]
},
@ -65,6 +76,9 @@
"oneOf": [
{
"$ref": "../services/connections/testConnectionResult.json"
},
{
"$ref": "../services/ingestionPipelines/reverseIngestionResponse.json"
}
]
},
@ -105,15 +119,20 @@
"type": "boolean",
"default": false
},
"domain" : {
"domain": {
"description": "Domain the asset belongs to. When not set, the asset inherits the domain from the parent it belongs to.",
"$ref": "../../type/entityReference.json"
},
"dataProducts" : {
"dataProducts": {
"description": "List of data products this entity is part of.",
"$ref" : "../../type/entityReferenceList.json"
"$ref": "../../type/entityReferenceList.json"
}
},
"additionalProperties": false,
"required": ["id", "name", "workflowType", "request"]
}
"required": [
"id",
"name",
"workflowType",
"request"
]
}

View File

@ -0,0 +1,58 @@
{
"$id": "https://open-metadata.org/schema/entity/applications/reverseMetadata/reverseIngestionResponse.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ReverseIngestionResponse",
"javaType": "org.openmetadata.schema.entity.services.ingestionPipelines.ReverseIngestionResponse",
"description": "Apply a set of operations on a service",
"type": "object",
"definitions": {
"reverseIngestionOperationResult": {
"javaType": "org.openmetadata.schema.entity.services.ingestionPipelines.reverseIngestionOperationResult",
"type": "object",
"properties": {
"id": {
"description": "The id of the operation",
"$ref": "../../../type/basic.json#/definitions/uuid"
},
"success": {
"description": "Whether the specific operation was successful",
"type": "boolean"
},
"message": {
"description": "Error message in case of failure",
"type": "string"
}
},
"required": [
"id",
"success"
]
}
},
"properties": {
"serviceId": {
"description": "The id of the service to be modified",
"$ref": "../../../type/basic.json#/definitions/uuid"
},
"success": {
"description": "Whether the workflow was successful. Failure indicates a critical failure such as connection issues.",
"type": "boolean"
},
"message": {
"description": "Error message in case of failure",
"type": "string"
},
"results": {
"description": "List of operations to be performed on the service",
"type": "array",
"items": {
"$ref": "#/definitions/reverseIngestionOperationResult"
}
}
},
"additionalProperties": false,
"required": [
"serviceId",
"results"
]
}

View File

@ -0,0 +1,90 @@
{
"$id": "https://open-metadata.org/schema/entity/applications/metadataIngestion/reverseIngestionPipeline.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "reverseIngestionPipeline",
"javaType": "org.openmetadata.schema.metadataIngestion.ReverseIngestionPipeline",
"description": "Apply a set of operations on a service",
"type": "object",
"definitions": {
"reverseIngestionType": {
"description": "Reverse Ingestion Config Pipeline type",
"type": "string",
"enum": [
"ReverseIngestion"
],
"default": "ReverseIngestion"
},
"operation": {
"description": "Operation to be performed on the entity",
"type": "object",
"properties": {
"id": {
"description": "The id of the operation",
"$ref": "../type/basic.json#/definitions/uuid"
},
"entityLink": {
"description": "Entity to be modified",
"$ref": "../type/basic.json#/definitions/entityLink"
},
"type": {
"description": "Type of operation to perform",
"type": "string",
"javaType": "org.openmetadata.schema.metadataIngestion.reverseIngestionOperationType",
"enum": [
"UPDATE_DESCRIPTION",
"UPDATE_OWNER",
"UPDATE_TAGS"
]
},
"SQLTemplate": {
"description": "Templated SQL command to be used for the operation. Context parameters will be populated based on the event type.",
"type": "string"
},
"parameters": {
"description": "The configuration for the operation to be applied",
"oneOf": [
{
"$ref": "./reverseingestionconfig/descriptionConfig.json"
},
{
"$ref": "./reverseingestionconfig/ownerConfig.json"
},
{
"$ref": "./reverseingestionconfig/tagsConfig.json"
}
]
}
},
"required": [
"id",
"entity",
"type",
"parameters"
],
"additionalProperties": false
}
},
"properties": {
"type": {
"description": "Pipeline type",
"$ref": "#/definitions/reverseIngestionType",
"default": "ReverseIngestion"
},
"serviceId": {
"description": "The id of the database service to be modified",
"$ref": "../type/basic.json#/definitions/uuid"
},
"operations": {
"description": "List of operations to be performed on the service",
"type": "array",
"items": {
"$ref": "#/definitions/operation"
}
}
},
"additionalProperties": false,
"required": [
"serviceId",
"operations"
]
}

View File

@ -0,0 +1,19 @@
{
"$id": "https://open-metadata.org/schema/metadataIngestion/reverseingestionconfig/descriptionConfig.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Reverse Ingestion Description Config",
"type": "object",
"description": "Configuration for updating descriptions",
"javaType": "org.openmetadata.schema.metadataIngestion.reverseingestionconfig.descriptionConfig",
"properties": {
"previousDescription": {
"description": "Previous description of the service",
"type": "string"
},
"newDescription": {
"description": "New description of the service",
"type": "string"
}
},
"additionalProperties": false
}

View File

@ -0,0 +1,19 @@
{
"$id": "https://open-metadata.org/schema/metadataIngestion/reverseingestionconfig/ownerConfig.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Reverse Ingestion Owner Config",
"type": "object",
"description": "Configuration for updating owners",
"javaType": "org.openmetadata.schema.metadataIngestion.reverseingestionconfig.ownerConfig",
"properties": {
"removedOwners": {
"description": "Removed owners from the entity",
"$ref": "../../type/entityReferenceList.json"
},
"addedOwners": {
"description": "Added owners to be applied",
"$ref": "../../type/entityReferenceList.json"
}
},
"additionalProperties": false
}

View File

@ -0,0 +1,25 @@
{
"$id": "https://open-metadata.org/schema/metadataIngestion/reverseingestionconfig/tagsConfig.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Reverse Ingestion Tags Config",
"type": "object",
"description": "Configuration for updating tags",
"javaType": "org.openmetadata.schema.metadataIngestion.reverseingestionconfig.tagsConfig",
"properties": {
"removedTags": {
"description": "Removed tags of the entity",
"type": "array",
"items": {
"$ref": "../../type/tagLabel.json"
}
},
"addedTags": {
"description": "Added tags to be applied",
"type": "array",
"items": {
"$ref": "../../type/tagLabel.json"
}
}
},
"additionalProperties": false
}

View File

@ -62,6 +62,9 @@
},
{
"$ref": "apiServiceMetadataPipeline.json"
},
{
"$ref": "reverseIngestionPipeline.json"
}
]
}
@ -238,4 +241,4 @@
}
],
"additionalProperties": false
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright 2025 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.
*/
/**
* Apply a set of operations on a service
*/
export interface ReverseIngestionResponse {
/**
* Error message in case of failure
*/
message?: string;
/**
* List of operations to be performed on the service
*/
results: ReverseIngestionOperationResult[];
/**
* The id of the service to be modified
*/
serviceId: string;
/**
* Whether the workflow was successful. Failure indicates a critical failure such as
* connection issues.
*/
success?: boolean;
}
export interface ReverseIngestionOperationResult {
/**
* The id of the operation
*/
id: string;
/**
* Error message in case of failure
*/
message?: string;
/**
* Whether the specific operation was successful
*/
success: boolean;
[property: string]: any;
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2025 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.
*/
/**
* Configuration for updating descriptions
*/
export interface DescriptionConfig {
/**
* New description of the service
*/
newDescription?: string;
/**
* Previous description of the service
*/
previousDescription?: string;
}

View File

@ -0,0 +1,81 @@
/*
* Copyright 2025 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.
*/
/**
* Configuration for updating owners
*/
export interface OwnerConfig {
/**
* Added owners to be applied
*/
addedOwners?: EntityReference[];
/**
* Removed owners from the entity
*/
removedOwners?: EntityReference[];
}
/**
* Added owners to be applied
*
* This schema defines the EntityReferenceList type used for referencing an entity.
* EntityReference is used for capturing relationships from one entity to another. For
* example, a table has an attribute called database of type EntityReference that captures
* the relationship of a table `belongs to a` database.
*
* This schema defines the EntityReference type used for referencing an entity.
* EntityReference is used for capturing relationships from one entity to another. For
* example, a table has an attribute called database of type EntityReference that captures
* the relationship of a table `belongs to a` database.
*/
export interface EntityReference {
/**
* If true the entity referred to has been soft-deleted.
*/
deleted?: boolean;
/**
* Optional description of entity.
*/
description?: string;
/**
* Display Name that identifies this entity.
*/
displayName?: string;
/**
* Fully qualified name of the entity instance. For entities such as tables, databases
* fullyQualifiedName is returned in this field. For entities that don't have name hierarchy
* such as `user` and `team` this will be same as the `name` field.
*/
fullyQualifiedName?: string;
/**
* Link to the entity resource.
*/
href?: string;
/**
* Unique identifier that identifies an entity instance.
*/
id: string;
/**
* If true the relationship indicated by this entity reference is inherited from the parent
* entity.
*/
inherited?: boolean;
/**
* Name of the entity instance.
*/
name?: string;
/**
* Entity type/class name - Examples: `database`, `table`, `metrics`, `databaseService`,
* `dashboardService`...
*/
type: string;
}

View File

@ -0,0 +1,112 @@
/*
* Copyright 2025 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.
*/
/**
* Configuration for updating tags
*/
export interface TagsConfig {
/**
* Added tags to be applied
*/
addedTags?: TagLabel[];
/**
* Removed tags of the entity
*/
removedTags?: TagLabel[];
}
/**
* This schema defines the type for labeling an entity with a Tag.
*/
export interface TagLabel {
/**
* Description for the tag label.
*/
description?: string;
/**
* Display Name that identifies this tag.
*/
displayName?: string;
/**
* Link to the tag resource.
*/
href?: string;
/**
* Label type describes how a tag label was applied. 'Manual' indicates the tag label was
* applied by a person. 'Derived' indicates a tag label was derived using the associated tag
* relationship (see Classification.json for more details). 'Propagated` indicates a tag
* label was propagated from upstream based on lineage. 'Automated' is used when a tool was
* used to determine the tag label.
*/
labelType: LabelType;
/**
* Name of the tag or glossary term.
*/
name?: string;
/**
* Label is from Tags or Glossary.
*/
source: TagSource;
/**
* 'Suggested' state is used when a tag label is suggested by users or tools. Owner of the
* entity must confirm the suggested labels before it is marked as 'Confirmed'.
*/
state: State;
style?: Style;
tagFQN: string;
}
/**
* Label type describes how a tag label was applied. 'Manual' indicates the tag label was
* applied by a person. 'Derived' indicates a tag label was derived using the associated tag
* relationship (see Classification.json for more details). 'Propagated` indicates a tag
* label was propagated from upstream based on lineage. 'Automated' is used when a tool was
* used to determine the tag label.
*/
export enum LabelType {
Automated = "Automated",
Derived = "Derived",
Manual = "Manual",
Propagated = "Propagated",
}
/**
* Label is from Tags or Glossary.
*/
export enum TagSource {
Classification = "Classification",
Glossary = "Glossary",
}
/**
* 'Suggested' state is used when a tag label is suggested by users or tools. Owner of the
* entity must confirm the suggested labels before it is marked as 'Confirmed'.
*/
export enum State {
Confirmed = "Confirmed",
Suggested = "Suggested",
}
/**
* UI Style is used to associate a color code and/or icon to entity to customize the look of
* that entity in UI.
*/
export interface Style {
/**
* Hex Color Code to mark an entity such as GlossaryTerm, Tag, Domain or Data Product.
*/
color?: string;
/**
* An icon to associate with GlossaryTerm, Tag, Domain or Data Product.
*/
iconURL?: string;
}