Event filter restricted usageSummary, added for testCase(with default disabled) (#7107)

This commit is contained in:
mohitdeuex 2022-09-01 20:15:16 +05:30 committed by GitHub
parent f4c0d82882
commit 9e689f7f8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 484 additions and 176 deletions

View File

@ -22,6 +22,7 @@ import javax.ws.rs.core.Response;
import lombok.extern.slf4j.Slf4j;
import org.openmetadata.catalog.filter.FilterRegistry;
import org.openmetadata.catalog.filter.Filters;
import org.openmetadata.catalog.resources.settings.SettingsCache;
import org.openmetadata.catalog.settings.Settings;
import org.openmetadata.catalog.settings.SettingsType;
import org.openmetadata.catalog.util.FilterUtil;
@ -118,6 +119,7 @@ public class SettingsRepository {
.insertSettings(setting.getConfigType().toString(), JsonUtils.pojoToJson(setting.getConfigValue()));
if (setting.getConfigType().equals(ACTIVITY_FEED_FILTER_SETTING)) {
FilterRegistry.add(FilterUtil.getEventFilterFromSettings(setting));
SettingsCache.getInstance().putSettings(setting);
}
} catch (Exception ex) {
throw new RuntimeException(ex);

View File

@ -1,86 +0,0 @@
package org.openmetadata.catalog.kafka;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.util.Properties;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.CommonClientConfigs;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.config.SslConfigs;
import org.openmetadata.catalog.events.WebhookPublisher;
import org.openmetadata.catalog.jdbi3.CollectionDAO;
import org.openmetadata.catalog.resources.events.EventResource;
import org.openmetadata.catalog.type.ChangeEvent;
import org.openmetadata.catalog.type.Webhook;
import org.openmetadata.catalog.util.JsonUtils;
@Slf4j
public class KafkaWebhookEventPublisher extends WebhookPublisher {
protected final Webhook webhook;
private static KafkaProducer<String, String> producer;
Properties properties = new Properties();
public KafkaWebhookEventPublisher(Webhook webhook, CollectionDAO dao) {
super(webhook, dao);
this.webhook = webhook;
if (webhook.getKafkaProperties().getSecurityProtocol().equals(KafkaEventConfiguration.SecurityProtocol.SSL)) {
// configuration for SSL Encryption
if (webhook.getKafkaProperties().getSSLProtocol() != null
&& webhook.getKafkaProperties().getSSLTrustStoreLocation() != null
&& webhook.getKafkaProperties().getSSLTrustStorePassword() != null
&& webhook.getKafkaProperties().getSSLKeystoreLocation() != null
&& webhook.getKafkaProperties().getSSLKeystorePassword() != null
&& webhook.getKafkaProperties().getSSLKeyPassword() != null) {
properties.put(
CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, webhook.getKafkaProperties().getSecurityProtocol());
properties.put(SslConfigs.SSL_PROTOCOL_CONFIG, webhook.getKafkaProperties().getSSLProtocol());
properties.put(
SslConfigs.SSL_TRUSTSTORE_LOCATION_CONFIG, webhook.getKafkaProperties().getSSLTrustStoreLocation());
properties.put(
SslConfigs.SSL_TRUSTSTORE_PASSWORD_CONFIG, webhook.getKafkaProperties().getSSLTrustStorePassword());
// configuration for SSL Authentication
properties.put(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG, webhook.getKafkaProperties().getSSLKeystoreLocation());
properties.put(SslConfigs.SSL_KEYSTORE_PASSWORD_CONFIG, webhook.getKafkaProperties().getSSLKeystorePassword());
properties.put(SslConfigs.SSL_KEY_PASSWORD_CONFIG, webhook.getKafkaProperties().getSSLKeyPassword());
} else {
LOG.info("The SSL could not be configured as the required properties are not defined!");
}
}
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, webhook.getEndpoint().toString());
properties.put(ProducerConfig.ACKS_CONFIG, webhook.getKafkaProperties().getAcks());
properties.put(ProducerConfig.RETRIES_CONFIG, webhook.getKafkaProperties().getRetries());
properties.put(ProducerConfig.BATCH_SIZE_CONFIG, webhook.getBatchSize());
properties.put(ProducerConfig.LINGER_MS_CONFIG, webhook.getKafkaProperties().getLingerMS());
properties.put(ProducerConfig.BUFFER_MEMORY_CONFIG, webhook.getKafkaProperties().getBufferMemory());
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, webhook.getKafkaProperties().getKeySerializer());
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, webhook.getKafkaProperties().getValueSerializer());
producer = new KafkaProducer<>(properties);
}
@Override
public void onStart() {
LOG.info("Kafka Webhook Publisher Started");
}
@Override
public void onShutdown() {
producer.flush();
producer.close();
}
@Override
public void publish(EventResource.ChangeEventList events) throws JsonProcessingException {
if (webhook.getKafkaProperties().getTopics() != null) {
for (String topic : webhook.getKafkaProperties().getTopics()) {
for (ChangeEvent event : events.getData()) {
String eventJson = JsonUtils.pojoToJson(event);
producer.send(new ProducerRecord<>(topic, eventJson));
}
}
} else {
LOG.info("Topics are null");
}
}
}

View File

@ -358,8 +358,7 @@ public class WebhookResource extends EntityResource<Webhook, WebhookRepository>
.withTimeout(create.getTimeout())
.withEnabled(create.getEnabled())
.withSecretKey(create.getSecretKey())
.withKafkaProperties(create.getKafkaProperties())
.withStatus(Boolean.TRUE.equals(create.getEnabled()) ? Status.ACTIVE : Status.DISABLED)
.withWebhookType(WebhookType.fromValue(create.getWebhookType().value()));
.withWebhookType(create.getWebhookType() == null ? WebhookType.generic : create.getWebhookType());
}
}

View File

@ -61,6 +61,10 @@ public class SettingsCache {
}
}
public void putSettings(Settings setting) throws RuntimeException {
SETTINGS_CACHE.put(setting.getConfigType().toString(), setting);
}
public static void cleanUp() {
SETTINGS_CACHE.invalidateAll();
INITIALIZED = false;

View File

@ -401,7 +401,10 @@ public final class EntityUtil {
deleteFilter.ifPresent(
eventFilter ->
filters.add(
new Filters().withEventType(EventType.ENTITY_SOFT_DELETED).withFields(eventFilter.getFields())));
new Filters()
.withEventType(EventType.ENTITY_SOFT_DELETED)
.withInclude(eventFilter.getInclude())
.withExclude(eventFilter.getExclude())));
}
public static EntityReference copy(EntityReference from, EntityReference to) {

View File

@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.openmetadata.catalog.Entity;
import org.openmetadata.catalog.filter.EventFilter;
import org.openmetadata.catalog.filter.Filters;
import org.openmetadata.catalog.settings.Settings;
@ -36,6 +37,7 @@ import org.openmetadata.catalog.type.FieldChange;
public class FilterUtil {
private static final String TEST_CASE_RESULT = "testCaseResult";
private static final String WILDCARD_FILTER = "all";
public static boolean shouldProcessRequest(ChangeEvent changeEvent, Map<String, Map<EventType, Filters>> filtersMap) {
if (filtersMap != null && !filtersMap.isEmpty()) {
@ -44,20 +46,16 @@ public class FilterUtil {
Map<EventType, Filters> filtersOfEntity = filtersMap.get(entityType);
if (filtersOfEntity == null || filtersOfEntity.size() == 0) {
// check if we have all entities Filter
return handleWithWildCardFilter(filtersMap.get("all"), eventType, getUpdateField(changeEvent));
return handleWithWildCardFilter(filtersMap.get(WILDCARD_FILTER), eventType, getUpdateField(changeEvent));
} else {
Filters sf;
if ((sf = filtersOfEntity.get(eventType)) == null) {
return false;
} else {
if (sf.getFields().contains("all")) {
return true;
if (entityType.equals(Entity.TEST_CASE)) {
return handleTestCaseFilter(changeEvent, sf);
} else {
if (entityType.equals("testCase")) {
return handleTestCaseFilter(changeEvent, sf);
} else {
return checkIfFilterContainField(sf, getUpdateField(changeEvent));
}
return checkIfFilterContainField(sf, getUpdateField(changeEvent));
}
}
}
@ -68,15 +66,18 @@ public class FilterUtil {
private static boolean handleTestCaseFilter(ChangeEvent changeEvent, Filters sf) {
List<FieldChange> fieldChanges = getAllFieldChange(changeEvent);
for (FieldChange fieldChange : fieldChanges) {
if (fieldChange.getName().equals(TEST_CASE_RESULT)) {
if (fieldChange.getName().equals(TEST_CASE_RESULT) && fieldChange.getNewValue() != null) {
TestCaseResult testCaseResult = (TestCaseResult) fieldChange.getNewValue();
TestCaseStatus status = testCaseResult.getTestCaseStatus();
if (sf.getFields().contains(TEST_CASE_RESULT + status.toString())) {
String statusField = TEST_CASE_RESULT + status.toString();
if (sf.getInclude().contains(statusField)) {
return true;
} else if (sf.getExclude().contains(statusField)) {
return false;
}
}
}
return checkIfFilterContainField(sf, getUpdateField(changeEvent));
return sf.getInclude().contains(WILDCARD_FILTER);
}
public static boolean handleWithWildCardFilter(
@ -84,8 +85,7 @@ public class FilterUtil {
if (wildCardFilter != null && !wildCardFilter.isEmpty()) {
// check if we have all entities Filter
Filters f = wildCardFilter.get(type);
boolean allFieldCheck = checkIfFilterContainField(f, updatedField);
return f != null && (f.getFields().contains("all") || allFieldCheck);
return checkIfFilterContainField(f, updatedField);
}
return false;
}
@ -93,10 +93,14 @@ public class FilterUtil {
public static boolean checkIfFilterContainField(Filters f, List<String> updatedField) {
if (f != null) {
for (String changed : updatedField) {
if (f.getFields().contains(changed)) {
// field is present in excluded
if (f.getExclude().contains(changed)) {
return false;
} else if (f.getInclude().contains(changed)) {
return true;
}
}
return f.getInclude().contains(WILDCARD_FILTER);
}
return false;
}
@ -111,12 +115,13 @@ public class FilterUtil {
}
public static List<FieldChange> getAllFieldChange(ChangeEvent changeEvent) {
ChangeDescription description = changeEvent.getChangeDescription();
List<FieldChange> allFieldChange = new ArrayList<>();
allFieldChange.addAll(description.getFieldsAdded());
allFieldChange.addAll(description.getFieldsUpdated());
allFieldChange.addAll(description.getFieldsDeleted());
ChangeDescription description = changeEvent.getChangeDescription();
if (description != null) {
allFieldChange.addAll(description.getFieldsAdded());
allFieldChange.addAll(description.getFieldsUpdated());
allFieldChange.addAll(description.getFieldsDeleted());
}
return allFieldChange;
}

View File

@ -7,27 +7,210 @@
"filters": [
{
"eventType": "entityCreated",
"fields": [
"include": [
"all"
]
],
"exclude": []
},
{
"eventType": "entityUpdated",
"fields": [
"include": [
"all"
]
],
"exclude": ["usageSummary"]
},
{
"eventType": "entityDeleted",
"fields": [
"include": [
"all"
]
],
"exclude": []
},
{
"eventType": "entitySoftDeleted",
"fields": [
"include": [
"all"
]
],
"exclude": []
}
]
},
{
"entityType": "table",
"filters": [
{
"eventType": "entityCreated",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entityUpdated",
"include": [
"description",
"owner",
"tags",
"followers"
],
"exclude": []
},
{
"eventType": "entityDeleted",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entitySoftDeleted",
"include": [
"all"
],
"exclude": []
}
]
},
{
"entityType": "dashboard",
"filters": [
{
"eventType": "entityCreated",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entityUpdated",
"include": [
"description",
"owner",
"tags",
"followers"
],
"exclude": []
},
{
"eventType": "entityDeleted",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entitySoftDeleted",
"include": [
"all"
],
"exclude": []
}
]
},
{
"entityType": "pipeline",
"filters": [
{
"eventType": "entityCreated",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entityUpdated",
"include": [
"description",
"owner",
"tags",
"followers"
],
"exclude": []
},
{
"eventType": "entityDeleted",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entitySoftDeleted",
"include": [
"all"
],
"exclude": []
}
]
},
{
"entityType": "mlmodel",
"filters": [
{
"eventType": "entityCreated",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entityUpdated",
"include": [
"description",
"owner",
"tags",
"followers"
],
"exclude": []
},
{
"eventType": "entityDeleted",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entitySoftDeleted",
"include": [
"all"
],
"exclude": []
}
]
},
{
"entityType": "testCase",
"filters": [
{
"eventType": "entityCreated",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entityUpdated",
"include": [
"testCaseResultSuccess",
"testCaseResultFailed",
"testCaseResultAborted"
],
"exclude": []
},
{
"eventType": "entityDeleted",
"include": [
"all"
],
"exclude": []
},
{
"eventType": "entitySoftDeleted",
"include": [
"all"
],
"exclude": []
}
]
}

View File

@ -51,12 +51,8 @@
"description": "Secret set by the webhook client used for computing HMAC SHA256 signature of webhook payload and sent in `X-OM-Signature` header in POST requests to publish the events.",
"type": "string"
},
"kafkaProperties": {
"description": "Properties of Kafka Producer",
"$ref": "../../configuration/kafkaEventConfiguration.json"
},
"webhookType": {
"description": "Type of webhook slack,generic,kafka etc",
"description": "Type of webhook slack,generic,msteams etc",
"$ref": "../../entity/events/webhook.json#/definitions/webhookType"
}
},

View File

@ -8,7 +8,7 @@
"javaInterfaces": ["org.openmetadata.catalog.EntityInterface"],
"definitions": {
"webhookType": {
"description": "Type of webhook slack, generic, kafka, etc.",
"description": "Type of webhook slack, generic, msteams, etc.",
"type": "string",
"javaType": "org.openmetadata.catalog.type.WebhookType",
"default": "generic",
@ -44,7 +44,7 @@
"type": "string"
},
"webhookType": {
"description": "Type of webhook slack, generic, kafka, etc.",
"description": "Type of webhook slack, generic, msteams, etc.",
"$ref": "#/definitions/webhookType"
},
"description": {
@ -68,10 +68,6 @@
"type": "integer",
"default": 10
},
"kafkaProperties": {
"description": "Properties of Kafka Producer",
"$ref": "../../configuration/kafkaEventConfiguration.json"
},
"timeout": {
"description": "Connection timeout in seconds. (Default 10s).",
"type": "integer",

View File

@ -17,6 +17,140 @@
"entityDeleted"
]
},
"entityTypes": {
"javaType": "org.openmetadata.catalog.filter.EntityTypes",
"description": "Type of event.",
"type": "string",
"enum": [
"All",
"Chart",
"Dashboard",
"Database",
"Database Schema",
"Glossary",
"Glossary Term",
"Location",
"Metrics",
"Ml Model",
"Pipeline",
"Report",
"Table",
"Topic",
"Test Case"
],
"javaEnums": [
{
"name": "all"
},
{
"name": "chart"
},
{
"name": "dashboard"
},
{
"name": "database"
},
{
"name": "databaseSchema"
},
{
"name": "glossary"
},
{
"name": "glossaryTerm"
},
{
"name": "location"
},
{
"name": "metrics"
},
{
"name": "mlmodel"
},
{
"name": "pipeline"
},
{
"name": "report"
},
{
"name": "table"
},
{
"name": "topic"
},
{
"name": "testCase"
}
]
},
"fieldTypes": {
"javaType": "org.openmetadata.catalog.filter.FieldType",
"description": "Type of event.",
"type": "string",
"enum": [
"All",
"Display Name",
"Description",
"Owner",
"Location",
"Tags",
"Usage Summary",
"Followers",
"Sample Data",
"Synonyms",
"Glossary",
"Test Case Result Success",
"Test Case Result Failed",
"Test Case Result Aborted"
],
"javaEnums": [
{
"name": "all"
},
{
"name": "displayName"
},
{
"name": "description"
},
{
"name": "owner"
},
{
"name": "location"
},
{
"name": "tags"
},
{
"name": "usageSummary"
},
{
"name": "followers"
},
{
"name": "sampleData"
},
{
"name": "synonyms"
},
{
"name": "glossary"
},
{
"name": "testCaseResultSuccess"
},
{
"name": "testCaseResultFailure"
},
{
"name": "testCaseResultAborted"
}
]
},
"filters": {
"type": "object",
"javaType": "org.openmetadata.catalog.filter.Filters",
@ -25,14 +159,23 @@
"description": "Event type that is being requested.",
"$ref": "#/definitions/eventType"
},
"fields": {
"description": "Field on which to apply the filter on",
"include": {
"description": "Field which are allowed to pass",
"type": "array",
"items": {
"type": "string"
},
"default": ["all"],
"uniqueItems": true
},
"exclude": {
"description": "Field which are not allowed to pass",
"type": "array",
"items": {
"type": "string"
},
"default": [],
"uniqueItems": true
}
},
"required": ["eventType"],

View File

@ -22,7 +22,6 @@ import static org.openmetadata.catalog.util.EntityUtil.fieldDeleted;
import static org.openmetadata.catalog.util.EntityUtil.fieldUpdated;
import static org.openmetadata.catalog.util.TestUtils.ADMIN_AUTH_HEADERS;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import java.io.IOException;
import java.net.URI;
@ -65,16 +64,14 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook, CreateWebho
allEntityFilter.setEntityType("all");
allEntityFilter.setFilters(
List.of(
new Filters().withEventType(EventType.ENTITY_CREATED).withFields(allFilter),
new Filters().withEventType(EventType.ENTITY_UPDATED).withFields(allFilter),
new Filters().withEventType(EventType.ENTITY_DELETED).withFields(allFilter),
new Filters().withEventType(EventType.ENTITY_SOFT_DELETED).withFields(allFilter)));
new Filters().withEventType(EventType.ENTITY_CREATED).withInclude(allFilter).withExclude(new HashSet<>()),
new Filters().withEventType(EventType.ENTITY_UPDATED).withInclude(allFilter).withExclude(new HashSet<>()),
new Filters().withEventType(EventType.ENTITY_DELETED).withInclude(allFilter).withExclude(new HashSet<>()),
new Filters()
.withEventType(EventType.ENTITY_SOFT_DELETED)
.withInclude(allFilter)
.withExclude(new HashSet<>())));
ALL_EVENTS_FILTER.add(allEntityFilter);
try {
System.out.println(JsonUtils.pojoToJson(ALL_EVENTS_FILTER));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public WebhookResourceTest() {
@ -189,9 +186,12 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook, CreateWebho
Set<String> allFilter = new HashSet<>();
allFilter.add("all");
Filters createFilter = new Filters().withEventType(EventType.ENTITY_CREATED).withFields(allFilter);
Filters updateFilter = new Filters().withEventType(EventType.ENTITY_UPDATED).withFields(allFilter);
Filters deleteFilter = new Filters().withEventType(EventType.ENTITY_DELETED).withFields(allFilter);
Filters createFilter =
new Filters().withEventType(EventType.ENTITY_CREATED).withInclude(allFilter).withExclude(new HashSet<>());
Filters updateFilter =
new Filters().withEventType(EventType.ENTITY_UPDATED).withInclude(allFilter).withExclude(new HashSet<>());
Filters deleteFilter =
new Filters().withEventType(EventType.ENTITY_DELETED).withInclude(allFilter).withExclude(new HashSet<>());
EventFilter f1 = new EventFilter().withEntityType("all").withFilters(List.of(createFilter));
EventFilter f2 =
@ -300,16 +300,18 @@ public class WebhookResourceTest extends EntityResourceTest<Webhook, CreateWebho
String name = EventType.ENTITY_CREATED + ":" + entity;
String uri = baseUri + "/" + EventType.ENTITY_CREATED + "/" + entity;
Set<String> allFiler = new HashSet<>();
allFiler.add("all");
Filters createFilter = new Filters().withEventType(EventType.ENTITY_CREATED).withFields(allFiler);
Set<String> allFilter = new HashSet<>();
allFilter.add("all");
Filters createFilter =
new Filters().withEventType(EventType.ENTITY_CREATED).withInclude(allFilter).withExclude(new HashSet<>());
EventFilter f1 = new EventFilter().withEntityType(entity).withFilters(List.of(createFilter));
createWebhook(name, uri, List.of(f1));
// Create webhook with endpoint api/v1/test/webhook/entityUpdated/<entity> to receive entityUpdated events
name = EventType.ENTITY_UPDATED + ":" + entity;
uri = baseUri + "/" + EventType.ENTITY_UPDATED + "/" + entity;
Filters updateFilter = new Filters().withEventType(EventType.ENTITY_UPDATED).withFields(allFiler);
Filters updateFilter =
new Filters().withEventType(EventType.ENTITY_UPDATED).withInclude(allFilter).withExclude(new HashSet<>());
EventFilter f2 = new EventFilter().withEntityType(entity).withFilters(List.of(updateFilter));
createWebhook(name, uri, List.of(f2));

View File

@ -90,19 +90,23 @@ const mockData = {
filters: [
{
eventType: 'entityCreated',
fields: ['all'],
include: ['all'],
exclude: [],
},
{
eventType: 'entityUpdated',
fields: ['all'],
include: ['all'],
exclude: [],
},
{
eventType: 'entityDeleted',
fields: ['all'],
include: ['all'],
exclude: [],
},
{
eventType: 'entitySoftDeleted',
fields: ['all'],
include: ['all'],
exclude: [],
},
],
},

View File

@ -38,8 +38,8 @@ const EventFilterSelect = ({
metric === EventType.EntityUpdated
? Object.values(EventUpdateTypes).map((updateType) => ({
title: startCase(updateType),
value: updateType,
key: updateType,
value: `${EventType.EntityUpdated}-${updateType}`,
key: `${EventType.EntityUpdated}-${updateType}`,
}))
: undefined,
})),

View File

@ -34,19 +34,23 @@ export const EVENT_FILTERS_DEFAULT_VALUE = {
filters: [
{
eventType: 'entityCreated',
fields: ['all'],
include: ['all'],
exclude: [],
},
{
eventType: 'entityUpdated',
fields: ['all'],
include: ['all'],
exclude: [],
},
{
eventType: 'entityDeleted',
fields: ['all'],
include: ['all'],
exclude: [],
},
{
eventType: 'entitySoftDeleted',
fields: ['all'],
include: ['all'],
exclude: [],
},
],
} as EventFilter;

View File

@ -3,19 +3,23 @@ import { Filters } from '../../generated/settings/settings';
export const formData = [
{
eventType: 'entityCreated',
fields: [],
include: [],
exclude: [],
},
{
eventType: 'entityUpdated',
fields: [],
include: [],
exclude: [],
},
{
eventType: 'entitySoftDeleted',
fields: [],
include: [],
exclude: [],
},
{
eventType: 'entityDeleted',
fields: [],
include: [],
exclude: [],
},
] as Filters[];
@ -25,4 +29,5 @@ export const ActivityFeedEntity = {
dashboard: 'Dashboard',
pipeline: 'Pipeline',
mlmodel: 'ML Model',
testCase: 'Test Case',
} as Record<string, string>;

View File

@ -93,13 +93,13 @@ const ActivityFeedSettingsPage: React.FC = () => {
};
const generateTreeData = (entityType: string, data?: Filters[]) => {
return data?.map(({ eventType, fields }) => {
return data?.map(({ eventType, include }) => {
const key = `${entityType}-${eventType}` as string;
return {
key: key,
title: startCase(eventType),
data: fields,
data: include,
children:
eventType === 'entityUpdated'
? [
@ -133,13 +133,13 @@ const ActivityFeedSettingsPage: React.FC = () => {
filters &&
filters.map((obj) => {
if (
obj?.fields &&
obj.fields.length === 1 &&
obj.fields[0] === 'all'
obj.include &&
obj.include.length === 1 &&
obj.include[0] === 'all'
) {
checkedArray.push(`${entityType}-${obj.eventType}`);
} else {
obj?.fields?.forEach((entityUpdated) => {
obj?.include?.forEach((entityUpdated) => {
const name = `${entityType}-${obj.eventType}-${entityUpdated}`;
checkedArray.push(name);
});

View File

@ -1,5 +1,8 @@
import { isEmpty, isUndefined } from 'lodash';
import { Filters } from '../../generated/settings/settings';
import { getDiffArray } from '../../utils/CommonUtils';
const entityUpdatedFields = ['description', 'owner', 'tags', 'followers'];
export const getPayloadFromSelected = (
selectedOptions: Record<string, string[]>,
@ -25,7 +28,8 @@ export const getPayloadFromSelected = (
...valueAcc,
{
eventType: selected[1],
fields: ['all'],
include: ['all'],
exclude: [],
},
];
} else {
@ -39,11 +43,14 @@ export const getPayloadFromSelected = (
resultArr.push(...arr[0]);
if (!isUndefined(nonUpdatedFields) && !isEmpty(nonUpdatedFields)) {
const selectedUpdatedData = nonUpdatedFields.filter(
(name) => !isUndefined(name) || (!isEmpty(name) && name)
);
resultArr.push({
eventType: 'entityUpdated',
fields: nonUpdatedFields.filter(
(name) => !isUndefined(name) || (!isEmpty(name) && name)
),
include: selectedUpdatedData,
exclude: getDiffArray(entityUpdatedFields, selectedUpdatedData),
});
}

View File

@ -14,7 +14,15 @@
import { Popover } from 'antd';
import { AxiosError } from 'axios';
import classNames from 'classnames';
import { capitalize, isEmpty, isNil, isNull, isUndefined } from 'lodash';
import {
capitalize,
differenceWith,
isEmpty,
isEqual,
isNil,
isNull,
isUndefined,
} from 'lodash';
import {
EntityFieldThreadCount,
ExtraInfo,
@ -879,3 +887,10 @@ export const getIngestionStatuses = (ingestion: IngestionPipeline) => {
);
});
};
export const getDiffArray = (
compareWith: string[],
toCompare: string[]
): string[] => {
return differenceWith(compareWith, toCompare, isEqual);
};

View File

@ -1,11 +1,15 @@
import { Store } from 'antd/lib/form/interface';
import { isEqual } from 'lodash';
import { isEqual, isUndefined } from 'lodash';
import {
EVENT_FILTERS_DEFAULT_VALUE,
EVENT_FILTER_FORM_INITIAL_VALUE,
} from '../components/AddWebhook/WebhookConstants';
import { TERM_ALL } from '../constants/constants';
import { EventFilter, Filters } from '../generated/entity/events/webhook';
import {
EventFilter,
EventType,
Filters,
} from '../generated/entity/events/webhook';
export const getEventFilters = (data: Store): EventFilter[] => {
if (isEqual(data, EVENT_FILTER_FORM_INITIAL_VALUE)) {
@ -18,17 +22,39 @@ export const getEventFilters = (data: Store): EventFilter[] => {
}
if (value) {
const selectedFilter = data[`${key}-tree`] as string[];
const entityUpdatedFields = selectedFilter
?.map((filter) =>
filter.includes(`${EventType.EntityUpdated}-`)
? filter.split('-')[1]
: undefined
)
.filter((filter) => filter);
const eventFilters = [
...selectedFilter.filter(
(filter) => !filter.includes(`${EventType.EntityUpdated}-`)
),
entityUpdatedFields ? EventType.EntityUpdated : undefined,
];
const includeData = (entityUpdatedFields as string[]).filter(
(entityUpdatedField) => !isUndefined(entityUpdatedField)
);
return [
...acc,
{
entityType: key,
filters:
selectedFilter[0] === TERM_ALL
eventFilters[0] === TERM_ALL
? EVENT_FILTERS_DEFAULT_VALUE.filters
: (selectedFilter.map((filter) => ({
: (eventFilters.map((filter) => ({
eventType: filter,
fields: [TERM_ALL],
include:
filter === EventType.EntityUpdated
? includeData
: [TERM_ALL],
exclude: [],
})) as Filters[]),
},
];