mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-13 00:22:23 +00:00
GEN-1434: Improvement : Show displayName for database and databaseSchema in explore tree (#17876)
* Show displayName for database and databaseSchema in explore tree * use display name for database and schema * add playwright * resync indexes of dataAssets based on database & databaseSchema displayName change --------- Co-authored-by: karanh37 <karanh37@gmail.com> Co-authored-by: Karan Hotchandani <33024356+karanh37@users.noreply.github.com>
This commit is contained in:
parent
d2bce8adf4
commit
a99fbb2eb6
@ -24,6 +24,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.csv.CSVPrinter;
|
||||
@ -105,6 +106,18 @@ public class DatabaseRepository extends EntityRepository<Database> {
|
||||
return Entity.getEntity(entity.getService(), fields, Include.ALL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityRelationshipReindex(Database original, Database updated) {
|
||||
super.entityRelationshipReindex(original, updated);
|
||||
|
||||
// Update search indexes of assets and entity on database displayName change
|
||||
if (!Objects.equals(original.getDisplayName(), updated.getDisplayName())) {
|
||||
searchRepository
|
||||
.getSearchClient()
|
||||
.reindexAcrossIndices("database.fullyQualifiedName", original.getEntityReference());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String exportToCsv(String name, String user) throws IOException {
|
||||
Database database = getByName(null, name, Fields.EMPTY_FIELDS); // Validate database name
|
||||
|
||||
@ -28,6 +28,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.csv.CSVPrinter;
|
||||
@ -179,6 +180,18 @@ public class DatabaseSchemaRepository extends EntityRepository<DatabaseSchema> {
|
||||
.withServiceType(database.getServiceType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityRelationshipReindex(DatabaseSchema original, DatabaseSchema updated) {
|
||||
super.entityRelationshipReindex(original, updated);
|
||||
|
||||
// Update search indexes of assets and entity on databaseSchema displayName change
|
||||
if (!Objects.equals(original.getDisplayName(), updated.getDisplayName())) {
|
||||
searchRepository
|
||||
.getSearchClient()
|
||||
.reindexAcrossIndices("databaseSchema.fullyQualifiedName", original.getEntityReference());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String exportToCsv(String name, String user) throws IOException {
|
||||
DatabaseSchema schema = getByName(null, name, Fields.EMPTY_FIELDS); // Validate database schema
|
||||
|
||||
@ -1311,6 +1311,14 @@ public class ElasticSearchClient implements SearchClient {
|
||||
AggregationBuilders.terms("databaseSchema.name.keyword")
|
||||
.field("databaseSchema.name.keyword")
|
||||
.size(MAX_AGGREGATE_SIZE));
|
||||
searchSourceBuilder.aggregation(
|
||||
AggregationBuilders.terms("database.displayName")
|
||||
.field("database.displayName")
|
||||
.size(MAX_AGGREGATE_SIZE));
|
||||
searchSourceBuilder.aggregation(
|
||||
AggregationBuilders.terms("databaseSchema.displayName")
|
||||
.field("databaseSchema.displayName")
|
||||
.size(MAX_AGGREGATE_SIZE));
|
||||
return addAggregation(searchSourceBuilder);
|
||||
}
|
||||
|
||||
|
||||
@ -1291,6 +1291,14 @@ public class OpenSearchClient implements SearchClient {
|
||||
AggregationBuilders.terms("databaseSchema.name.keyword")
|
||||
.field("databaseSchema.name.keyword")
|
||||
.size(MAX_AGGREGATE_SIZE));
|
||||
searchSourceBuilder.aggregation(
|
||||
AggregationBuilders.terms("database.displayName")
|
||||
.field("database.displayName")
|
||||
.size(MAX_AGGREGATE_SIZE));
|
||||
searchSourceBuilder.aggregation(
|
||||
AggregationBuilders.terms("databaseSchema.displayName")
|
||||
.field("databaseSchema.displayName")
|
||||
.size(MAX_AGGREGATE_SIZE));
|
||||
return addAggregation(searchSourceBuilder);
|
||||
}
|
||||
|
||||
|
||||
@ -403,6 +403,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
},
|
||||
|
||||
@ -308,6 +308,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer"
|
||||
|
||||
@ -189,6 +189,7 @@
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
@ -235,6 +236,7 @@
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
|
||||
@ -402,6 +402,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
},
|
||||
|
||||
@ -307,6 +307,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer"
|
||||
|
||||
@ -185,6 +185,7 @@
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
@ -231,6 +232,7 @@
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,6 +190,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
},
|
||||
@ -228,6 +238,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
},
|
||||
|
||||
@ -375,6 +375,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
},
|
||||
|
||||
@ -282,6 +282,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer"
|
||||
|
||||
@ -165,6 +165,7 @@
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
@ -211,6 +212,7 @@
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,6 +164,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
},
|
||||
@ -204,6 +214,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"displayName": {
|
||||
"type": "keyword",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"normalizer": "lowercase_normalizer",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"fullyQualifiedName": {
|
||||
"type": "text"
|
||||
},
|
||||
|
||||
@ -96,14 +96,8 @@ test.describe('Advanced Search', { tag: '@advanced-search' }, () => {
|
||||
tierTag2.responseData.fullyQualifiedName,
|
||||
],
|
||||
'service.displayName.keyword': [table1.service.name, table2.service.name],
|
||||
'database.displayName.keyword': [
|
||||
table1.database.name,
|
||||
table2.database.name,
|
||||
],
|
||||
'databaseSchema.displayName.keyword': [
|
||||
table1.schema.name,
|
||||
table2.schema.name,
|
||||
],
|
||||
'database.displayName': [table1.database.name, table2.database.name],
|
||||
'databaseSchema.displayName': [table1.schema.name, table2.schema.name],
|
||||
'columns.name.keyword': ['email', 'shop_id'],
|
||||
'displayName.keyword': [
|
||||
table1.entity.displayName,
|
||||
|
||||
@ -11,8 +11,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import test, { expect } from '@playwright/test';
|
||||
import { get } from 'lodash';
|
||||
import { SidebarItem } from '../../constant/sidebar';
|
||||
import { redirectToHomePage } from '../../utils/common';
|
||||
import { EntityTypeEndpoint } from '../../support/entity/Entity.interface';
|
||||
import { TableClass } from '../../support/entity/TableClass';
|
||||
import { getApiContext, redirectToHomePage } from '../../utils/common';
|
||||
import { updateDisplayNameForEntity } from '../../utils/entity';
|
||||
import { sidebarClick } from '../../utils/sidebar';
|
||||
|
||||
// use the admin user to login
|
||||
@ -107,4 +111,82 @@ test.describe('Explore Tree scenarios ', () => {
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test('Verify Database and Database schema after rename', async ({ page }) => {
|
||||
const { apiContext, afterAction } = await getApiContext(page);
|
||||
const table = new TableClass();
|
||||
await table.create(apiContext);
|
||||
await table.visitEntityPage(page);
|
||||
const schemaName = get(table.schemaResponseData, 'name', '');
|
||||
const dbName = get(table.databaseResponseData, 'name', '');
|
||||
const serviceName = get(table.serviceResponseData, 'name', '');
|
||||
const updatedSchemaName = `Test ${schemaName} updated`;
|
||||
const updatedDbName = `Test ${dbName} updated`;
|
||||
|
||||
const schemaRes = page.waitForResponse('/api/v1/databaseSchemas/name/*');
|
||||
await page.getByRole('link', { name: schemaName }).click();
|
||||
// Rename Schema Page
|
||||
await schemaRes;
|
||||
await updateDisplayNameForEntity(
|
||||
page,
|
||||
updatedSchemaName,
|
||||
EntityTypeEndpoint.DatabaseSchema
|
||||
);
|
||||
|
||||
const dbRes = page.waitForResponse('/api/v1/databases/name/*');
|
||||
await page.getByRole('link', { name: dbName }).click();
|
||||
// Rename Database Page
|
||||
await dbRes;
|
||||
await updateDisplayNameForEntity(
|
||||
page,
|
||||
updatedDbName,
|
||||
EntityTypeEndpoint.Database
|
||||
);
|
||||
|
||||
await sidebarClick(page, SidebarItem.EXPLORE);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const serviceNameRes = page.waitForResponse(
|
||||
'/api/v1/search/query?q=&index=database_search_index&from=0&size=0*mysql*'
|
||||
);
|
||||
await page
|
||||
.locator('div')
|
||||
.filter({ hasText: /^mysql$/ })
|
||||
.locator('svg')
|
||||
.first()
|
||||
.click();
|
||||
await serviceNameRes;
|
||||
|
||||
const databaseRes = page.waitForResponse(
|
||||
'/api/v1/search/query?q=&index=dataAsset*serviceType*'
|
||||
);
|
||||
|
||||
await page
|
||||
.locator('.ant-tree-treenode')
|
||||
.filter({ hasText: serviceName })
|
||||
.locator('.ant-tree-switcher svg')
|
||||
.click();
|
||||
await databaseRes;
|
||||
|
||||
await expect(
|
||||
page.getByTestId(`explore-tree-title-${updatedDbName}`)
|
||||
).toBeVisible();
|
||||
|
||||
const databaseSchemaRes = page.waitForResponse(
|
||||
'/api/v1/search/query?q=&index=dataAsset*database.displayName*'
|
||||
);
|
||||
|
||||
await page
|
||||
.locator('.ant-tree-treenode')
|
||||
.filter({ hasText: updatedDbName })
|
||||
.locator('.ant-tree-switcher svg')
|
||||
.click();
|
||||
await databaseSchemaRes;
|
||||
|
||||
await expect(
|
||||
page.getByTestId(`explore-tree-title-${updatedSchemaName}`)
|
||||
).toBeVisible();
|
||||
|
||||
await table.delete(apiContext);
|
||||
await afterAction();
|
||||
});
|
||||
});
|
||||
|
||||
@ -44,12 +44,12 @@ export const FIELDS: EntityFields[] = [
|
||||
},
|
||||
{
|
||||
id: 'Database',
|
||||
name: 'database.displayName.keyword',
|
||||
name: 'database.displayName',
|
||||
localSearch: false,
|
||||
},
|
||||
{
|
||||
id: 'Database Schema',
|
||||
name: 'databaseSchema.displayName.keyword',
|
||||
name: 'databaseSchema.displayName',
|
||||
localSearch: false,
|
||||
},
|
||||
{
|
||||
|
||||
@ -53,8 +53,8 @@ export enum EntityFields {
|
||||
TAG = 'tags.tagFQN',
|
||||
TIER = 'tier.tagFQN',
|
||||
SERVICE = 'service.displayName.keyword',
|
||||
DATABASE = 'database.name.keyword',
|
||||
DATABASE_SCHEMA = 'databaseSchema.name.keyword',
|
||||
DATABASE = 'database.displayName',
|
||||
DATABASE_SCHEMA = 'databaseSchema.displayName',
|
||||
COLUMN = 'columns.name.keyword',
|
||||
CHART = 'charts.displayName.keyword',
|
||||
TASK = 'tasks.displayName.keyword',
|
||||
|
||||
@ -139,7 +139,7 @@ class AdvancedSearchClassBase {
|
||||
* Fields specific to tables
|
||||
*/
|
||||
tableQueryBuilderFields: Fields = {
|
||||
'database.displayName.keyword': {
|
||||
[EntityFields.DATABASE]: {
|
||||
label: t('label.database'),
|
||||
type: 'select',
|
||||
mainWidgetProps: this.mainWidgetProps,
|
||||
@ -152,7 +152,7 @@ class AdvancedSearchClassBase {
|
||||
},
|
||||
},
|
||||
|
||||
'databaseSchema.displayName.keyword': {
|
||||
[EntityFields.DATABASE_SCHEMA]: {
|
||||
label: t('label.database-schema'),
|
||||
type: 'select',
|
||||
mainWidgetProps: this.mainWidgetProps,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user