mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-01 19:18:05 +00:00
Merge branch '1.5.5' of github.com:open-metadata/OpenMetadata into 1.5.5
This commit is contained in:
commit
c75378f8e8
@ -45,7 +45,7 @@ VERSIONS = {
|
||||
"sqlalchemy-databricks": "sqlalchemy-databricks~=0.1",
|
||||
"databricks-sdk": "databricks-sdk>=0.18.0,<0.20.0",
|
||||
"trino": "trino[sqlalchemy]",
|
||||
"spacy": "spacy~=3.7",
|
||||
"spacy": "spacy<3.8",
|
||||
"looker-sdk": "looker-sdk>=22.20.0",
|
||||
"lkml": "lkml~=1.3",
|
||||
"tableau": "tableau-api-lib~=0.1",
|
||||
|
||||
@ -7,6 +7,7 @@ source:
|
||||
username: username
|
||||
password: password
|
||||
securityToken: securityToken
|
||||
organizationId: organizationId
|
||||
sobjectName: sobjectName
|
||||
# sslConfig:
|
||||
# caCertificate: |
|
||||
|
||||
@ -15,7 +15,6 @@ Source connection handler
|
||||
from typing import Optional
|
||||
|
||||
from simple_salesforce.api import Salesforce
|
||||
from sqlalchemy.engine import Engine
|
||||
|
||||
from metadata.generated.schema.entity.automations.workflow import (
|
||||
Workflow as AutomationWorkflow,
|
||||
@ -27,14 +26,17 @@ from metadata.ingestion.connections.test_connections import test_connection_step
|
||||
from metadata.ingestion.ometa.ometa_api import OpenMetadata
|
||||
|
||||
|
||||
def get_connection(connection: SalesforceConnection) -> Engine:
|
||||
def get_connection(connection: SalesforceConnection) -> Salesforce:
|
||||
"""
|
||||
Create connection
|
||||
"""
|
||||
return Salesforce(
|
||||
username=connection.username,
|
||||
password=connection.password.get_secret_value(),
|
||||
security_token=connection.securityToken.get_secret_value(),
|
||||
security_token=connection.securityToken.get_secret_value()
|
||||
if connection.securityToken
|
||||
else "",
|
||||
organizationId=connection.organizationId if connection.organizationId else "",
|
||||
domain=connection.salesforceDomain,
|
||||
version=connection.salesforceApiVersion,
|
||||
**connection.connectionArguments.root if connection.connectionArguments else {},
|
||||
|
||||
@ -49,6 +49,13 @@ These are the permissions you will require to fetch the metadata from Salesforce
|
||||
- **Username**: Username to connect to the Salesforce. This user should have the access as defined in requirements.
|
||||
- **Password**: Password to connect to Salesforce.
|
||||
- **Security Token**: Salesforce Security Token is required to access the metadata through APIs. You can checkout [this doc](https://help.salesforce.com/s/articleView?id=sf.user_security_token.htm&type=5) on how to get the security token.
|
||||
- **Organization ID**: Salesforce Organization ID is the unique identifier for your Salesforce identity. You can check out [this doc](https://help.salesforce.com/s/articleView?id=000385215&type=1) on how to get the your Salesforce Organization ID.
|
||||
{% note %}
|
||||
**Note**: You need to provide `15` digit organization id in this section. for e.g. `00DIB000004nDEq`, which you can find by following the steps mentioned in above doc (`Salesforce dashboard->Setup->Company Profile->Company Information->Salesforce.com Organization Id`).
|
||||
{% /note %}
|
||||
{% note %}
|
||||
**Note**: If you want to access salesforce metadata without token(only by using organization id), you will need to setup your ip in trusted ip ranges. You can go (`Salesforce dashboard->Setup->Security->Network Access->Trusted IP Ranges`) to configure this. You can check [here](https://help.salesforce.com/s/articleView?id=sf.security_networkaccess.htm&type=5) to configure your ip in trusted ip ranges.
|
||||
{% /note %}
|
||||
- **Salesforce Object Name**: Specify the Salesforce Object Name in case you want to ingest a specific object. If left blank, we will ingest all the Objects.
|
||||
- **Salesforce API Version**: Follow the steps mentioned [here](https://help.salesforce.com/s/articleView?id=000386929&type=1) to get the API version. Enter the numerical value in the field, For example `42.0`.
|
||||
- **Salesforce Domain**: When connecting to Salesforce, you can specify the domain to use for accessing the platform. The common domains include `login` and `test`, and you can also utilize Salesforce My Domain.
|
||||
|
||||
@ -83,18 +83,30 @@ This is a sample config for Salesforce:
|
||||
|
||||
{% codeInfo srNumber=5 %}
|
||||
|
||||
**sobjectName**: Specify the Salesforce Object Name in case you want to ingest a specific object. If left blank, we will ingest all the Objects.
|
||||
**Organization ID**: Salesforce Organization ID is the unique identifier for your Salesforce identity. You can check out [this doc](https://help.salesforce.com/s/articleView?id=000385215&type=1) on how to get the your Salesforce Organization ID.
|
||||
{% note %}
|
||||
**Note**: You need to provide `15` digit organization id in this section. for e.g. `00DIB000004nDEq`, which you can find by following the steps mentioned in above doc (`Salesforce dashboard->Setup->Company Profile->Company Information->Salesforce.com Organization Id`).
|
||||
{% /note %}
|
||||
{% note %}
|
||||
**Note**: If you want to access salesforce metadata without token(only by using organization id), you will need to setup your ip in trusted ip ranges. You can go (`Salesforce dashboard->Setup->Security->Network Access->Trusted IP Ranges`) to configure this. You can check [here](https://help.salesforce.com/s/articleView?id=sf.security_networkaccess.htm&type=5) to configure your ip in trusted ip ranges.
|
||||
{% /note %}
|
||||
|
||||
{% /codeInfo %}
|
||||
|
||||
{% codeInfo srNumber=6 %}
|
||||
|
||||
**salesforceApiVersion**: Follow the steps mentioned [here](https://help.salesforce.com/s/articleView?id=000386929&type=1) to get the API version. Enter the numerical value in the field, For example `42.0`.
|
||||
**sobjectName**: Specify the Salesforce Object Name in case you want to ingest a specific object. If left blank, we will ingest all the Objects.
|
||||
|
||||
{% /codeInfo %}
|
||||
|
||||
{% codeInfo srNumber=7 %}
|
||||
|
||||
**salesforceApiVersion**: Follow the steps mentioned [here](https://help.salesforce.com/s/articleView?id=000386929&type=1) to get the API version. Enter the numerical value in the field, For example `42.0`.
|
||||
|
||||
{% /codeInfo %}
|
||||
|
||||
{% codeInfo srNumber=8 %}
|
||||
|
||||
**salesforceDomain**: When connecting to Salesforce, you can specify the domain to use for accessing the platform. The common domains include `login` and `test`, and you can also utilize Salesforce My Domain.
|
||||
By default, the domain `login` is used for accessing Salesforce.
|
||||
|
||||
@ -108,13 +120,13 @@ By default, the domain `login` is used for accessing Salesforce.
|
||||
|
||||
#### Advanced Configuration
|
||||
|
||||
{% codeInfo srNumber=8 %}
|
||||
{% codeInfo srNumber=9 %}
|
||||
|
||||
**Connection Options (Optional)**: Enter the details for any additional connection options that can be sent to database during the connection. These details must be added as Key-Value pairs.
|
||||
|
||||
{% /codeInfo %}
|
||||
|
||||
{% codeInfo srNumber=9 %}
|
||||
{% codeInfo srNumber=10 %}
|
||||
|
||||
**Connection Arguments (Optional)**: Enter the details for any additional connection arguments such as security or protocol configs that can be sent to database during the connection. These details must be added as Key-Value pairs.
|
||||
|
||||
@ -144,19 +156,22 @@ source:
|
||||
securityToken: securityToken
|
||||
```
|
||||
```yaml {% srNumber=5 %}
|
||||
sobjectName: sobjectName
|
||||
organizationId: organizationId
|
||||
```
|
||||
```yaml {% srNumber=6 %}
|
||||
salesforceApiVersion: 42.0
|
||||
sobjectName: sobjectName
|
||||
```
|
||||
```yaml {% srNumber=7 %}
|
||||
salesforceDomain: login
|
||||
salesforceApiVersion: 42.0
|
||||
```
|
||||
```yaml {% srNumber=8 %}
|
||||
salesforceDomain: login
|
||||
```
|
||||
```yaml {% srNumber=9 %}
|
||||
# connectionOptions:
|
||||
# key: value
|
||||
```
|
||||
```yaml {% srNumber=9 %}
|
||||
```yaml {% srNumber=10 %}
|
||||
# connectionArguments:
|
||||
# key: value
|
||||
```
|
||||
|
||||
@ -13,6 +13,7 @@ slug: /main-concepts/metadata-standard/schemas/entity/services/connections/datab
|
||||
- **`username`** *(string)*: Username to connect to the Salesforce. This user should have privileges to read all the metadata in Redshift.
|
||||
- **`password`** *(string)*: Password to connect to the Salesforce.
|
||||
- **`securityToken`** *(string)*: Salesforce Security Token.
|
||||
- **`organizationId`** *(string)*: Salesforce Organization ID.
|
||||
- **`sobjectName`** *(string)*: Salesforce Object Name.
|
||||
- **`databaseName`** *(string)*: Optional name to give to the database in OpenMetadata. If left blank, we will use default as the database name.
|
||||
- **`salesforceApiVersion`** *(string)*: API version of the Salesforce instance. Default: `42.0`.
|
||||
|
||||
@ -49,6 +49,13 @@ These are the permissions you will require to fetch the metadata from Salesforce
|
||||
- **Username**: Username to connect to the Salesforce. This user should have the access as defined in requirements.
|
||||
- **Password**: Password to connect to Salesforce.
|
||||
- **Security Token**: Salesforce Security Token is required to access the metadata through APIs. You can checkout [this doc](https://help.salesforce.com/s/articleView?id=sf.user_security_token.htm&type=5) on how to get the security token.
|
||||
- **Organization ID**: Salesforce Organization ID is the unique identifier for your Salesforce identity. You can check out [this doc](https://help.salesforce.com/s/articleView?id=000385215&type=1) on how to get the your Salesforce Organization ID.
|
||||
{% note %}
|
||||
**Note**: You need to provide `15` digit organization id in this section. for e.g. `00DIB000004nDEq`, which you can find by following the steps mentioned in above doc (`Salesforce dashboard->Setup->Company Profile->Company Information->Salesforce.com Organization Id`).
|
||||
{% /note %}
|
||||
{% note %}
|
||||
**Note**: If you want to access salesforce metadata without token(only by using organization id), you will need to setup your ip in trusted ip ranges. You can go (`Salesforce dashboard->Setup->Security->Network Access->Trusted IP Ranges`) to configure this. You can check [here](https://help.salesforce.com/s/articleView?id=sf.security_networkaccess.htm&type=5) to configure your ip in trusted ip ranges.
|
||||
{% /note %}
|
||||
- **Salesforce Object Name**: Specify the Salesforce Object Name in case you want to ingest a specific object. If left blank, we will ingest all the Objects.
|
||||
- **Salesforce API Version**: Follow the steps mentioned [here](https://help.salesforce.com/s/articleView?id=000386929&type=1) to get the API version. Enter the numerical value in the field, For example `42.0`.
|
||||
- **Salesforce Domain**: When connecting to Salesforce, you can specify the domain to use for accessing the platform. The common domains include `login` and `test`, and you can also utilize Salesforce My Domain.
|
||||
|
||||
@ -83,17 +83,28 @@ This is a sample config for Salesforce:
|
||||
|
||||
{% codeInfo srNumber=5 %}
|
||||
|
||||
**Organization ID**: Salesforce Organization ID is the unique identifier for your Salesforce identity. You can check out [this doc](https://help.salesforce.com/s/articleView?id=000385215&type=1) on how to get the your Salesforce Organization ID.
|
||||
{% note %}
|
||||
**Note**: You need to provide `15` digit organization id in this section. for e.g. `00DIB000004nDEq`, which you can find by following the steps mentioned in above doc (`Salesforce dashboard->Setup->Company Profile->Company Information->Salesforce.com Organization Id`).
|
||||
{% /note %}
|
||||
{% note %}
|
||||
**Note**: If you want to access salesforce metadata without token(only by using organization id), you will need to setup your ip in trusted ip ranges. You can go (`Salesforce dashboard->Setup->Security->Network Access->Trusted IP Ranges`) to configure this. You can check [here](https://help.salesforce.com/s/articleView?id=sf.security_networkaccess.htm&type=5) to configure your ip in trusted ip ranges.
|
||||
{% /note %}
|
||||
{% /codeInfo %}
|
||||
|
||||
{% codeInfo srNumber=6 %}
|
||||
|
||||
**sobjectName**: Specify the Salesforce Object Name in case you want to ingest a specific object. If left blank, we will ingest all the Objects.
|
||||
|
||||
{% /codeInfo %}
|
||||
|
||||
{% codeInfo srNumber=6 %}
|
||||
{% codeInfo srNumber=7 %}
|
||||
|
||||
**salesforceApiVersion**: Follow the steps mentioned [here](https://help.salesforce.com/s/articleView?id=000386929&type=1) to get the API version. Enter the numerical value in the field, For example `42.0`.
|
||||
|
||||
{% /codeInfo %}
|
||||
|
||||
{% codeInfo srNumber=7 %}
|
||||
{% codeInfo srNumber=8 %}
|
||||
|
||||
**salesforceDomain**: When connecting to Salesforce, you can specify the domain to use for accessing the platform. The common domains include `login` and `test`, and you can also utilize Salesforce My Domain.
|
||||
By default, the domain `login` is used for accessing Salesforce.
|
||||
@ -108,13 +119,13 @@ By default, the domain `login` is used for accessing Salesforce.
|
||||
|
||||
#### Advanced Configuration
|
||||
|
||||
{% codeInfo srNumber=8 %}
|
||||
{% codeInfo srNumber=9 %}
|
||||
|
||||
**Connection Options (Optional)**: Enter the details for any additional connection options that can be sent to database during the connection. These details must be added as Key-Value pairs.
|
||||
|
||||
{% /codeInfo %}
|
||||
|
||||
{% codeInfo srNumber=9 %}
|
||||
{% codeInfo srNumber=10 %}
|
||||
|
||||
**Connection Arguments (Optional)**: Enter the details for any additional connection arguments such as security or protocol configs that can be sent to database during the connection. These details must be added as Key-Value pairs.
|
||||
|
||||
@ -144,19 +155,22 @@ source:
|
||||
securityToken: securityToken
|
||||
```
|
||||
```yaml {% srNumber=5 %}
|
||||
sobjectName: sobjectName
|
||||
organizationId: organizationId
|
||||
```
|
||||
```yaml {% srNumber=6 %}
|
||||
salesforceApiVersion: 42.0
|
||||
sobjectName: sobjectName
|
||||
```
|
||||
```yaml {% srNumber=7 %}
|
||||
salesforceDomain: login
|
||||
salesforceApiVersion: 42.0
|
||||
```
|
||||
```yaml {% srNumber=8 %}
|
||||
salesforceDomain: login
|
||||
```
|
||||
```yaml {% srNumber=9 %}
|
||||
# connectionOptions:
|
||||
# key: value
|
||||
```
|
||||
```yaml {% srNumber=9 %}
|
||||
```yaml {% srNumber=10 %}
|
||||
# connectionArguments:
|
||||
# key: value
|
||||
```
|
||||
|
||||
@ -13,6 +13,7 @@ slug: /main-concepts/metadata-standard/schemas/entity/services/connections/datab
|
||||
- **`username`** *(string)*: Username to connect to the Salesforce. This user should have privileges to read all the metadata in Redshift.
|
||||
- **`password`** *(string)*: Password to connect to the Salesforce.
|
||||
- **`securityToken`** *(string)*: Salesforce Security Token.
|
||||
- **`organizationId`** *(string)*: Salesforce Organization ID.
|
||||
- **`sobjectName`** *(string)*: Salesforce Object Name.
|
||||
- **`databaseName`** *(string)*: Optional name to give to the database in OpenMetadata. If left blank, we will use default as the database name.
|
||||
- **`salesforceApiVersion`** *(string)*: API version of the Salesforce instance. Default: `42.0`.
|
||||
|
||||
@ -37,6 +37,11 @@
|
||||
"type": "string",
|
||||
"format": "password"
|
||||
},
|
||||
"organizationId": {
|
||||
"title": "Salesforce Organization ID",
|
||||
"description": "Salesforce Organization ID is the unique identifier for your Salesforce identity",
|
||||
"type": "string"
|
||||
},
|
||||
"sobjectName": {
|
||||
"title": "Object Name",
|
||||
"description": "Salesforce Object Name.",
|
||||
|
||||
@ -275,6 +275,8 @@ test.describe('Observability Alert Flow', () => {
|
||||
test(`${sourceDisplayName} alert`, async ({ page }) => {
|
||||
const ALERT_NAME = generateAlertName();
|
||||
|
||||
test.slow(true);
|
||||
|
||||
await test.step('Create alert', async () => {
|
||||
await inputBasicAlertInformation({
|
||||
page,
|
||||
|
||||
@ -70,68 +70,66 @@ test.afterAll('Cleanup', async ({ browser }) => {
|
||||
for (const EntityClass of entities) {
|
||||
const defaultEntity = new EntityClass();
|
||||
|
||||
test.fixme(
|
||||
`Lineage creation from ${defaultEntity.getType()} entity`,
|
||||
async ({ browser }) => {
|
||||
test.slow(true);
|
||||
test(`Lineage creation from ${defaultEntity.getType()} entity`, async ({
|
||||
browser,
|
||||
}) => {
|
||||
test.slow(true);
|
||||
|
||||
const { page } = await createNewPage(browser);
|
||||
const { currentEntity, entities, cleanup } =
|
||||
await setupEntitiesForLineage(page, defaultEntity);
|
||||
const { page } = await createNewPage(browser);
|
||||
const { currentEntity, entities, cleanup } = await setupEntitiesForLineage(
|
||||
page,
|
||||
defaultEntity
|
||||
);
|
||||
|
||||
await test.step('Should create lineage for the entity', async () => {
|
||||
await redirectToHomePage(page);
|
||||
await currentEntity.visitEntityPage(page);
|
||||
await visitLineageTab(page);
|
||||
await verifyColumnLayerInactive(page);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
await performZoomOut(page);
|
||||
for (const entity of entities) {
|
||||
await connectEdgeBetweenNodes(page, currentEntity, entity);
|
||||
}
|
||||
await test.step('Should create lineage for the entity', async () => {
|
||||
await redirectToHomePage(page);
|
||||
await currentEntity.visitEntityPage(page);
|
||||
await visitLineageTab(page);
|
||||
await verifyColumnLayerInactive(page);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
await performZoomOut(page);
|
||||
for (const entity of entities) {
|
||||
await connectEdgeBetweenNodes(page, currentEntity, entity);
|
||||
}
|
||||
|
||||
await redirectToHomePage(page);
|
||||
await currentEntity.visitEntityPage(page);
|
||||
await visitLineageTab(page);
|
||||
await page
|
||||
.locator('.react-flow__controls-fitview')
|
||||
.dispatchEvent('click');
|
||||
await redirectToHomePage(page);
|
||||
await currentEntity.visitEntityPage(page);
|
||||
await visitLineageTab(page);
|
||||
await page
|
||||
.locator('.react-flow__controls-fitview')
|
||||
.dispatchEvent('click');
|
||||
|
||||
for (const entity of entities) {
|
||||
await verifyNodePresent(page, entity);
|
||||
}
|
||||
});
|
||||
for (const entity of entities) {
|
||||
await verifyNodePresent(page, entity);
|
||||
}
|
||||
});
|
||||
|
||||
await test.step('Should create pipeline between entities', async () => {
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
await performZoomOut(page);
|
||||
await test.step('Should create pipeline between entities', async () => {
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
await performZoomOut(page);
|
||||
|
||||
for (const entity of entities) {
|
||||
await applyPipelineFromModal(page, currentEntity, entity, pipeline);
|
||||
}
|
||||
});
|
||||
for (const entity of entities) {
|
||||
await applyPipelineFromModal(page, currentEntity, entity, pipeline);
|
||||
}
|
||||
});
|
||||
|
||||
await test.step(
|
||||
'Remove lineage between nodes for the entity',
|
||||
async () => {
|
||||
await redirectToHomePage(page);
|
||||
await currentEntity.visitEntityPage(page);
|
||||
await visitLineageTab(page);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
await performZoomOut(page);
|
||||
await test.step('Remove lineage between nodes for the entity', async () => {
|
||||
await redirectToHomePage(page);
|
||||
await currentEntity.visitEntityPage(page);
|
||||
await visitLineageTab(page);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
await performZoomOut(page);
|
||||
|
||||
for (const entity of entities) {
|
||||
await deleteEdge(page, currentEntity, entity);
|
||||
}
|
||||
}
|
||||
);
|
||||
for (const entity of entities) {
|
||||
await deleteEdge(page, currentEntity, entity);
|
||||
}
|
||||
});
|
||||
|
||||
await cleanup();
|
||||
}
|
||||
);
|
||||
await cleanup();
|
||||
});
|
||||
}
|
||||
|
||||
test.fixme('Verify column lineage between tables', async ({ browser }) => {
|
||||
test('Verify column lineage between tables', async ({ browser }) => {
|
||||
const { page } = await createNewPage(browser);
|
||||
const { apiContext, afterAction } = await getApiContext(page);
|
||||
const table1 = new TableClass();
|
||||
@ -169,117 +167,112 @@ test.fixme('Verify column lineage between tables', async ({ browser }) => {
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test.fixme(
|
||||
'Verify column lineage between table and topic',
|
||||
async ({ browser }) => {
|
||||
const { page } = await createNewPage(browser);
|
||||
const { apiContext, afterAction } = await getApiContext(page);
|
||||
const table = new TableClass();
|
||||
const topic = new TopicClass();
|
||||
await table.create(apiContext);
|
||||
await topic.create(apiContext);
|
||||
test('Verify column lineage between table and topic', async ({ browser }) => {
|
||||
const { page } = await createNewPage(browser);
|
||||
const { apiContext, afterAction } = await getApiContext(page);
|
||||
const table = new TableClass();
|
||||
const topic = new TopicClass();
|
||||
await table.create(apiContext);
|
||||
await topic.create(apiContext);
|
||||
|
||||
const sourceTableFqn = get(table, 'entityResponseData.fullyQualifiedName');
|
||||
const sourceCol = `${sourceTableFqn}.${get(
|
||||
table,
|
||||
'entityResponseData.columns[0].name'
|
||||
)}`;
|
||||
const targetCol = get(
|
||||
topic,
|
||||
'entityResponseData.messageSchema.schemaFields[0].children[0].fullyQualifiedName'
|
||||
);
|
||||
const sourceTableFqn = get(table, 'entityResponseData.fullyQualifiedName');
|
||||
const sourceCol = `${sourceTableFqn}.${get(
|
||||
table,
|
||||
'entityResponseData.columns[0].name'
|
||||
)}`;
|
||||
const targetCol = get(
|
||||
topic,
|
||||
'entityResponseData.messageSchema.schemaFields[0].children[0].fullyQualifiedName'
|
||||
);
|
||||
|
||||
await addPipelineBetweenNodes(page, table, topic);
|
||||
await activateColumnLayer(page);
|
||||
await addPipelineBetweenNodes(page, table, topic);
|
||||
await activateColumnLayer(page);
|
||||
|
||||
// Add column lineage
|
||||
await addColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
// Add column lineage
|
||||
await addColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
|
||||
await removeColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
await removeColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
|
||||
await deleteNode(page, topic);
|
||||
await table.delete(apiContext);
|
||||
await topic.delete(apiContext);
|
||||
await deleteNode(page, topic);
|
||||
await table.delete(apiContext);
|
||||
await topic.delete(apiContext);
|
||||
|
||||
await afterAction();
|
||||
}
|
||||
);
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test.fixme(
|
||||
'Verify column lineage between topic and api endpoint',
|
||||
async ({ browser }) => {
|
||||
const { page } = await createNewPage(browser);
|
||||
const { apiContext, afterAction } = await getApiContext(page);
|
||||
const topic = new TopicClass();
|
||||
const apiEndpoint = new ApiEndpointClass();
|
||||
test('Verify column lineage between topic and api endpoint', async ({
|
||||
browser,
|
||||
}) => {
|
||||
const { page } = await createNewPage(browser);
|
||||
const { apiContext, afterAction } = await getApiContext(page);
|
||||
const topic = new TopicClass();
|
||||
const apiEndpoint = new ApiEndpointClass();
|
||||
|
||||
await topic.create(apiContext);
|
||||
await apiEndpoint.create(apiContext);
|
||||
await topic.create(apiContext);
|
||||
await apiEndpoint.create(apiContext);
|
||||
|
||||
const sourceCol = get(
|
||||
topic,
|
||||
'entityResponseData.messageSchema.schemaFields[0].children[0].fullyQualifiedName'
|
||||
);
|
||||
const sourceCol = get(
|
||||
topic,
|
||||
'entityResponseData.messageSchema.schemaFields[0].children[0].fullyQualifiedName'
|
||||
);
|
||||
|
||||
const targetCol = get(
|
||||
apiEndpoint,
|
||||
'entityResponseData.responseSchema.schemaFields[0].children[1].fullyQualifiedName'
|
||||
);
|
||||
const targetCol = get(
|
||||
apiEndpoint,
|
||||
'entityResponseData.responseSchema.schemaFields[0].children[1].fullyQualifiedName'
|
||||
);
|
||||
|
||||
await addPipelineBetweenNodes(page, topic, apiEndpoint);
|
||||
await activateColumnLayer(page);
|
||||
await addPipelineBetweenNodes(page, topic, apiEndpoint);
|
||||
await activateColumnLayer(page);
|
||||
|
||||
// Add column lineage
|
||||
await addColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
// Add column lineage
|
||||
await addColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
|
||||
await removeColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
await removeColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
|
||||
await deleteNode(page, apiEndpoint);
|
||||
await topic.delete(apiContext);
|
||||
await apiEndpoint.delete(apiContext);
|
||||
await deleteNode(page, apiEndpoint);
|
||||
await topic.delete(apiContext);
|
||||
await apiEndpoint.delete(apiContext);
|
||||
|
||||
await afterAction();
|
||||
}
|
||||
);
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test.fixme(
|
||||
'Verify column lineage between table and api endpoint',
|
||||
async ({ browser }) => {
|
||||
const { page } = await createNewPage(browser);
|
||||
const { apiContext, afterAction } = await getApiContext(page);
|
||||
const table = new TableClass();
|
||||
const apiEndpoint = new ApiEndpointClass();
|
||||
await table.create(apiContext);
|
||||
await apiEndpoint.create(apiContext);
|
||||
test('Verify column lineage between table and api endpoint', async ({
|
||||
browser,
|
||||
}) => {
|
||||
const { page } = await createNewPage(browser);
|
||||
const { apiContext, afterAction } = await getApiContext(page);
|
||||
const table = new TableClass();
|
||||
const apiEndpoint = new ApiEndpointClass();
|
||||
await table.create(apiContext);
|
||||
await apiEndpoint.create(apiContext);
|
||||
|
||||
const sourceTableFqn = get(table, 'entityResponseData.fullyQualifiedName');
|
||||
const sourceCol = `${sourceTableFqn}.${get(
|
||||
table,
|
||||
'entityResponseData.columns[0].name'
|
||||
)}`;
|
||||
const targetCol = get(
|
||||
apiEndpoint,
|
||||
'entityResponseData.responseSchema.schemaFields[0].children[0].fullyQualifiedName'
|
||||
);
|
||||
const sourceTableFqn = get(table, 'entityResponseData.fullyQualifiedName');
|
||||
const sourceCol = `${sourceTableFqn}.${get(
|
||||
table,
|
||||
'entityResponseData.columns[0].name'
|
||||
)}`;
|
||||
const targetCol = get(
|
||||
apiEndpoint,
|
||||
'entityResponseData.responseSchema.schemaFields[0].children[0].fullyQualifiedName'
|
||||
);
|
||||
|
||||
await addPipelineBetweenNodes(page, table, apiEndpoint);
|
||||
await activateColumnLayer(page);
|
||||
await addPipelineBetweenNodes(page, table, apiEndpoint);
|
||||
await activateColumnLayer(page);
|
||||
|
||||
// Add column lineage
|
||||
await addColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
// Add column lineage
|
||||
await addColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
|
||||
await removeColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
await removeColumnLineage(page, sourceCol, targetCol);
|
||||
await page.click('[data-testid="edit-lineage"]');
|
||||
|
||||
await deleteNode(page, apiEndpoint);
|
||||
await table.delete(apiContext);
|
||||
await apiEndpoint.delete(apiContext);
|
||||
await deleteNode(page, apiEndpoint);
|
||||
await table.delete(apiContext);
|
||||
await apiEndpoint.delete(apiContext);
|
||||
|
||||
await afterAction();
|
||||
}
|
||||
);
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
@ -348,6 +348,11 @@ export const assignTag = async (
|
||||
await searchTags;
|
||||
await page.getByTestId(`tag-${tag}`).click();
|
||||
|
||||
await page.waitForSelector(
|
||||
'.ant-select-dropdown [data-testid="saveAssociatedTag"]',
|
||||
{ state: 'visible' }
|
||||
);
|
||||
|
||||
await expect(page.getByTestId('saveAssociatedTag')).toBeEnabled();
|
||||
|
||||
await page.getByTestId('saveAssociatedTag').click();
|
||||
@ -393,6 +398,11 @@ export const assignTagToChildren = async ({
|
||||
(response) => response.request().method() === 'PATCH'
|
||||
);
|
||||
|
||||
await page.waitForSelector(
|
||||
'.ant-select-dropdown [data-testid="saveAssociatedTag"]',
|
||||
{ state: 'visible' }
|
||||
);
|
||||
|
||||
await expect(page.getByTestId('saveAssociatedTag')).toBeEnabled();
|
||||
|
||||
await page.getByTestId('saveAssociatedTag').click();
|
||||
@ -425,6 +435,11 @@ export const removeTag = async (page: Page, tags: string[]) => {
|
||||
(response) => response.request().method() === 'PATCH'
|
||||
);
|
||||
|
||||
await page.waitForSelector(
|
||||
'.ant-select-dropdown [data-testid="saveAssociatedTag"]',
|
||||
{ state: 'visible' }
|
||||
);
|
||||
|
||||
await expect(page.getByTestId('saveAssociatedTag')).toBeEnabled();
|
||||
|
||||
await page.getByTestId('saveAssociatedTag').click();
|
||||
@ -467,6 +482,11 @@ export const removeTagsFromChildren = async ({
|
||||
(response) => response.request().method() === 'PATCH'
|
||||
);
|
||||
|
||||
await page.waitForSelector(
|
||||
'.ant-select-dropdown [data-testid="saveAssociatedTag"]',
|
||||
{ state: 'visible' }
|
||||
);
|
||||
|
||||
await expect(page.getByTestId('saveAssociatedTag')).toBeEnabled();
|
||||
|
||||
await page.getByTestId('saveAssociatedTag').click();
|
||||
@ -507,6 +527,11 @@ export const assignGlossaryTerm = async (
|
||||
await searchGlossaryTerm;
|
||||
await page.getByTestId(`tag-${glossaryTerm.fullyQualifiedName}`).click();
|
||||
|
||||
await page.waitForSelector(
|
||||
'.ant-select-dropdown [data-testid="saveAssociatedTag"]',
|
||||
{ state: 'visible' }
|
||||
);
|
||||
|
||||
await expect(page.getByTestId('saveAssociatedTag')).toBeEnabled();
|
||||
|
||||
await page.getByTestId('saveAssociatedTag').click();
|
||||
@ -549,6 +574,11 @@ export const assignGlossaryTermToChildren = async ({
|
||||
(response) => response.request().method() === 'PATCH'
|
||||
);
|
||||
|
||||
await page.waitForSelector(
|
||||
'.ant-select-dropdown [data-testid="saveAssociatedTag"]',
|
||||
{ state: 'visible' }
|
||||
);
|
||||
|
||||
await expect(page.getByTestId('saveAssociatedTag')).toBeEnabled();
|
||||
|
||||
await page.getByTestId('saveAssociatedTag').click();
|
||||
@ -585,6 +615,11 @@ export const removeGlossaryTerm = async (
|
||||
(response) => response.request().method() === 'PATCH'
|
||||
);
|
||||
|
||||
await page.waitForSelector(
|
||||
'.ant-select-dropdown [data-testid="saveAssociatedTag"]',
|
||||
{ state: 'visible' }
|
||||
);
|
||||
|
||||
await expect(page.getByTestId('saveAssociatedTag')).toBeEnabled();
|
||||
|
||||
await page.getByTestId('saveAssociatedTag').click();
|
||||
@ -628,6 +663,11 @@ export const removeGlossaryTermFromChildren = async ({
|
||||
(response) => response.request().method() === 'PATCH'
|
||||
);
|
||||
|
||||
await page.waitForSelector(
|
||||
'.ant-select-dropdown [data-testid="saveAssociatedTag"]',
|
||||
{ state: 'visible' }
|
||||
);
|
||||
|
||||
await expect(page.getByTestId('saveAssociatedTag')).toBeEnabled();
|
||||
|
||||
await page.getByTestId('saveAssociatedTag').click();
|
||||
|
||||
@ -867,7 +867,7 @@ export const createDescriptionTaskForGlossary = async (
|
||||
await assigneeField.click();
|
||||
|
||||
const userSearchResponse = page.waitForResponse(
|
||||
`/api/v1/search/query?q=*${value.assignee}**&index=user_search_index%2Cteam_search_index`
|
||||
`/api/v1/search/suggest?q=${value.assignee}&index=user_search_index%2Cteam_search_index`
|
||||
);
|
||||
await assigneeField.fill(value.assignee);
|
||||
await userSearchResponse;
|
||||
@ -922,7 +922,7 @@ export const createTagTaskForGlossary = async (
|
||||
);
|
||||
await assigneeField.click();
|
||||
const userSearchResponse = page.waitForResponse(
|
||||
`/api/v1/search/query?q=*${value.assignee}**&index=user_search_index%2Cteam_search_index`
|
||||
`/api/v1/search/suggest?q=${value.assignee}&index=user_search_index%2Cteam_search_index`
|
||||
);
|
||||
await assigneeField.fill(value.assignee);
|
||||
await userSearchResponse;
|
||||
|
||||
@ -32,6 +32,16 @@ $$section
|
||||
Salesforce Security Token is required to access the metadata through APIs. You can check out [this doc](https://help.salesforce.com/s/articleView?id=sf.user_security_token.htm&type=5) on how to get the security token.
|
||||
$$
|
||||
|
||||
$$section
|
||||
### Organization ID $(id="organizationId")
|
||||
|
||||
Salesforce Organization ID is the unique identifier for your Salesforce identity. You can check out [this doc](https://help.salesforce.com/s/articleView?id=000385215&type=1) on how to get the your Salesforce Organization ID.
|
||||
|
||||
**Note**: You need to provide `15` digit organization id in this section. for e.g. `00DIB000004nDEq`, which you can find by following the steps mentioned in above doc (`Salesforce dashboard->Setup->Company Profile->Company Information->Salesforce.com Organization Id`).
|
||||
|
||||
**Note**: If you want to access salesforce metadata without token(only by using organization id), you will need to setup your ip in trusted ip ranges. You can go (`Salesforce dashboard->Setup->Security->Network Access->Trusted IP Ranges`) to configure this. You can check [here](https://help.salesforce.com/s/articleView?id=sf.security_networkaccess.htm&type=5) to configure your ip in trusted ip ranges.
|
||||
$$
|
||||
|
||||
$$section
|
||||
### Object Name $(id="sobjectName")
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user