diff --git a/openmetadata-service/pom.xml b/openmetadata-service/pom.xml index 4ab90944b5f..1214293bfc1 100644 --- a/openmetadata-service/pom.xml +++ b/openmetadata-service/pom.xml @@ -218,13 +218,6 @@ flyway-mysql - - - io.github.java-diff-utils - java-diff-utils - 4.12 - - software.amazon.awssdk @@ -412,6 +405,11 @@ unboundid-ldapsdk ${unboundsdk.version} + + org.bitbucket.cowwoc.diff-match-patch + diff-match-patch + ${diffMatch.version} + diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/events/ChangeEventHandler.java b/openmetadata-service/src/main/java/org/openmetadata/service/events/ChangeEventHandler.java index b52a6deca77..2f0f8444de0 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/events/ChangeEventHandler.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/events/ChangeEventHandler.java @@ -238,22 +238,21 @@ public class ChangeEventHandler implements EventHandler { } EntityInterface entityInterface = (EntityInterface) entity; + if (RestUtil.ENTITY_SOFT_DELETED.equals(changeType)) { + String entityType = Entity.getEntityTypeFromClass(entity.getClass()); + String message = String.format("Soft deleted **%s**: `%s`", entityType, entityInterface.getFullyQualifiedName()); + EntityLink about = new EntityLink(entityType, entityInterface.getFullyQualifiedName(), null, null, null); + Thread thread = getThread(about.getLinkString(), message, loggedInUserName); + return List.of(thread); + } if (RestUtil.ENTITY_DELETED.equals(changeType)) { String entityType = Entity.getEntityTypeFromClass(entity.getClass()); // In this case, the entity itself got deleted // for which there will be no change description. - String message = String.format("Deleted **%s**: `%s`", entityType, entityInterface.getFullyQualifiedName()); + String message = + String.format("Permanently Deleted **%s**: `%s`", entityType, entityInterface.getFullyQualifiedName()); EntityLink about = new EntityLink(entityType, entityInterface.getFullyQualifiedName(), null, null, null); - Thread thread = - new Thread() - .withId(UUID.randomUUID()) - .withThreadTs(System.currentTimeMillis()) - .withCreatedBy(entityInterface.getUpdatedBy()) - .withAbout(about.getLinkString()) - .withReactions(Collections.emptyList()) - .withUpdatedBy(entityInterface.getUpdatedBy()) - .withUpdatedAt(System.currentTimeMillis()) - .withMessage(message); + Thread thread = getThread(about.getLinkString(), message, loggedInUserName); return List.of(thread); } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/util/ChangeEventParser.java b/openmetadata-service/src/main/java/org/openmetadata/service/util/ChangeEventParser.java index f0891710125..aeebe11a003 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/util/ChangeEventParser.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/util/ChangeEventParser.java @@ -20,12 +20,11 @@ import static org.openmetadata.service.Entity.FIELD_OWNER; import static org.openmetadata.service.Entity.KPI; import static org.openmetadata.service.Entity.TEST_CASE; -import com.github.difflib.text.DiffRow; -import com.github.difflib.text.DiffRowGenerator; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -39,6 +38,7 @@ import javax.json.JsonValue; import javax.json.JsonValue.ValueType; import javax.json.stream.JsonParsingException; import org.apache.commons.lang.StringUtils; +import org.bitbucket.cowwoc.diffmatchpatch.DiffMatchPatch; import org.openmetadata.common.utils.CommonUtil; import org.openmetadata.schema.EntityInterface; import org.openmetadata.schema.dataInsight.kpi.Kpi; @@ -60,7 +60,7 @@ public final class ChangeEventParser { public static final String FEED_ADD_MARKER = ""; public static final String FEED_REMOVE_MARKER = ""; public static final String FEED_BOLD = "**%s**"; - public static final String SLACK_BOLD = "*%s* "; + public static final String SLACK_BOLD = "*%s*"; public static final String FEED_SPAN_ADD = ""; public static final String FEED_SPAN_REMOVE = ""; public static final String FEED_SPAN_CLOSE = ""; @@ -129,7 +129,7 @@ public final class ChangeEventParser { // TEAMS and FEED bold formatting is same return "** "; case SLACK: - return "* "; + return "*"; default: return "INVALID"; } @@ -157,7 +157,7 @@ public final class ChangeEventParser { // TEAMS and FEED bold formatting is same return "~~ "; case SLACK: - return "~ "; + return "~"; default: return "INVALID"; } @@ -405,7 +405,9 @@ public final class ChangeEventParser { message = String.format(("Followed " + getBold(publishTo) + " `%s`"), link.getEntityType(), link.getEntityFQN()); } else if (fieldValue != null && !fieldValue.isEmpty()) { - message = String.format(("Added " + getBold(publishTo) + ": `%s`"), updatedField, fieldValue); + message = + String.format( + ("Added " + getBold(publishTo) + ": " + getBold(publishTo)), updatedField, fieldValue.trim()); } break; case UPDATE: @@ -416,7 +418,8 @@ public final class ChangeEventParser { message = String.format("Unfollowed %s `%s`", link.getEntityType(), link.getEntityFQN()); } else { message = - String.format(("Deleted " + getBold(publishTo) + ": `%s`"), updatedField, getFieldValue(oldFieldValue)); + String.format( + ("Deleted " + getBold(publishTo) + ": `%s`"), updatedField, getFieldValue(oldFieldValue).trim()); } break; default: @@ -432,7 +435,7 @@ public final class ChangeEventParser { if (nullOrEmpty(diff)) { return StringUtils.EMPTY; } else { - String field = String.format("Updated %s: %s", getBold(publishTo), diff); + String field = String.format("Updated %s : %s", getBold(publishTo), diff); return String.format(field, updatedField); } } @@ -556,27 +559,23 @@ public final class ChangeEventParser { String addMarker = FEED_ADD_MARKER; String removeMarker = FEED_REMOVE_MARKER; - DiffRowGenerator generator = - DiffRowGenerator.create() - .showInlineDiffs(true) - .mergeOriginalRevised(true) - .inlineDiffByWord(true) - .oldTag(f -> removeMarker) // introduce a tag to mark removals - .newTag(f -> addMarker) // introduce a tag to mark new additions - .build(); - // compute the differences - List rows = generator.generateDiffRows(List.of(oldValue), List.of(newValue)); - - // merge rows by %n for new line - String diff = null; - for (DiffRow row : rows) { - if (diff == null) { - diff = row.getOldLine(); + DiffMatchPatch dmp = new DiffMatchPatch(); + LinkedList diffs = dmp.diffMain(oldValue, newValue); + dmp.diffCleanupSemantic(diffs); + StringBuilder outputStr = new StringBuilder(); + for (DiffMatchPatch.Diff d : diffs) { + if (DiffMatchPatch.Operation.EQUAL.equals(d.operation)) { + // merging equal values of both string .. + outputStr.append(d.text.trim()); + } else if (DiffMatchPatch.Operation.INSERT.equals(d.operation)) { + // merging added values with addMarker before and after of new values added.. + outputStr.append(addMarker).append(d.text.trim()).append(addMarker).append(" "); } else { - diff = String.format("%s%n%s", diff, row.getOldLine()); + // merging deleted values with removeMarker before and after of old value removed .. + outputStr.append(" ").append(removeMarker).append(d.text.trim()).append(removeMarker).append(" "); } } - + String diff = outputStr.toString().trim(); // The additions and removals will be wrapped by and tags // Replace them with html tags to render nicely in the UI // Example: This is a test sentenceline diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/ChangeEventParserResourceTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/ChangeEventParserResourceTest.java index 36e369c2d81..59fc6ef4ebc 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/resources/ChangeEventParserResourceTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/ChangeEventParserResourceTest.java @@ -103,7 +103,7 @@ class ChangeEventParserResourceTest extends OpenMetadataApplicationTest { ChangeEventParser.getFormattedMessages(ChangeEventParser.PUBLISH_TO.FEED, changeDescription, TABLE); assertEquals(1, messages.size()); - assertEquals("Added **owner**: `User One`", messages.values().iterator().next()); + assertEquals("Added **owner**: **User One**", messages.values().iterator().next()); } @Test @@ -117,7 +117,7 @@ class ChangeEventParserResourceTest extends OpenMetadataApplicationTest { assertEquals(1, messages.size()); assertEquals( - "Updated **description**: old" + "Updated **description** : old " + "new description", messages.values().iterator().next()); @@ -145,7 +145,7 @@ class ChangeEventParserResourceTest extends OpenMetadataApplicationTest { ChangeEventParser.getFormattedMessages(ChangeEventParser.PUBLISH_TO.SLACK, changeDescription, TABLE); assertEquals(1, messages.size()); - assertEquals("Updated *description* : ~old~ *new* description", messages.values().iterator().next()); + assertEquals("Updated *description* : ~old~ *new* description", messages.values().iterator().next()); // test if it updates correctly with one add and one delete change changeDescription = new ChangeDescription().withPreviousVersion(1.0); @@ -180,7 +180,7 @@ class ChangeEventParserResourceTest extends OpenMetadataApplicationTest { assertEquals(1, messages.size()); assertEquals( - "Updated **columns.lo_orderpriority**:
name: \"lo_order\"\"lo_orderpriority\"
displayName: \"lo_order\"\"lo_orderpriority\"
fullyQualifiedName: \"local_mysql.sample_db.lineorder.lo_order\"lo_orderpriority\"", + "Updated **columns.lo_orderpriority**:
name: \"lo_orderpriority \"
displayName: \"lo_orderpriority \"
fullyQualifiedName: \"local_mysql.sample_db.lineorder.lo_orderpriority \"", messages.values().iterator().next()); // Simulate a change of datatype change in column @@ -198,7 +198,7 @@ class ChangeEventParserResourceTest extends OpenMetadataApplicationTest { assertEquals(1, messages.size()); assertEquals( - "Updated **columns.lo_orderpriority**:
dataType: \"BLOB\"\"INT\"
dataTypeDisplay: \"blob\"\"int\"", + "Updated **columns.lo_orderpriority**:
dataType: \" BLOB INT \"
dataTypeDisplay: \" blob int \"", messages.values().iterator().next()); // Simulate multiple changes to columns @@ -216,7 +216,7 @@ class ChangeEventParserResourceTest extends OpenMetadataApplicationTest { assertEquals(1, messages.size()); assertEquals( - "Updated **columns**: lo_orderpriority, newColumn", + "Updated **columns** : lo_orderpriority, newColumn", messages.values().iterator().next()); } @@ -239,10 +239,10 @@ class ChangeEventParserResourceTest extends OpenMetadataApplicationTest { assertEquals(1, messages.size()); assertEquals( - "Updated *columns.lo_orderpriority* :\n" - + "name: ~\"lo_order\"~ *\"lo_orderpriority\"* \n" - + "displayName: ~\"lo_order\"~ *\"lo_orderpriority\"* \n" - + "fullyQualifiedName: \"local_mysql.sample_db.lineorder.~lo_order\"~ *lo_orderpriority\"* ", + "Updated *columns.lo_orderpriority*:\n" + + "name: \"lo_order*priority* \"\n" + + "displayName: \"lo_order*priority* \"\n" + + "fullyQualifiedName: \"local_mysql.sample_db.lineorder.lo_order*priority* \"", messages.values().iterator().next()); // Simulate a change of datatype change in column @@ -260,9 +260,9 @@ class ChangeEventParserResourceTest extends OpenMetadataApplicationTest { assertEquals(1, messages.size()); assertEquals( - "Updated *columns.lo_orderpriority* :\n" - + "dataType: ~\"BLOB\"~ *\"INT\"* \n" - + "dataTypeDisplay: ~\"blob\"~ *\"int\"* ", + "Updated *columns.lo_orderpriority*:\n" + + "dataType: \" ~BLOB~ *INT* \"\n" + + "dataTypeDisplay: \" ~blob~ *int* \"", messages.values().iterator().next()); // Simulate multiple changes to columns @@ -279,6 +279,6 @@ class ChangeEventParserResourceTest extends OpenMetadataApplicationTest { messages = ChangeEventParser.getFormattedMessages(ChangeEventParser.PUBLISH_TO.SLACK, changeDescription, TABLE); assertEquals(1, messages.size()); - assertEquals("Updated *columns* : lo_orderpriority*, newColumn* ", messages.values().iterator().next()); + assertEquals("Updated *columns* : lo_orderpriority*, newColumn*", messages.values().iterator().next()); } } diff --git a/pom.xml b/pom.xml index 2a35012320d..b654bcb96b7 100644 --- a/pom.xml +++ b/pom.xml @@ -78,6 +78,7 @@ 2.13.4 2.13.4.1 2.0.34 + 1.0 2.0.34 2.35 2.1.1