mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-05 13:03:45 +00:00
fix: reverted deprecated fields on testSuite (#19284)
Added deprecated fields with a notice. This is to ensure migrations that use them do not break.
This commit is contained in:
parent
78e8d360a5
commit
7d05902945
@ -0,0 +1,76 @@
|
|||||||
|
package org.openmetadata.annotations;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.sun.codemodel.JAnnotationUse;
|
||||||
|
import com.sun.codemodel.JClass;
|
||||||
|
import com.sun.codemodel.JDefinedClass;
|
||||||
|
import com.sun.codemodel.JFieldVar;
|
||||||
|
import com.sun.codemodel.JMethod;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import org.jsonschema2pojo.AbstractAnnotator;
|
||||||
|
|
||||||
|
/** Add {@link Deprecated} annotation to generated Java classes */
|
||||||
|
public class DeprecatedAnnotator extends AbstractAnnotator {
|
||||||
|
|
||||||
|
/** Add {@link Deprecated} annotation to property fields */
|
||||||
|
@Override
|
||||||
|
public void propertyField(
|
||||||
|
JFieldVar field, JDefinedClass clazz, String propertyName, JsonNode propertyNode) {
|
||||||
|
super.propertyField(field, clazz, propertyName, propertyNode);
|
||||||
|
if (propertyNode.get("deprecated") != null && propertyNode.get("deprecated").asBoolean()) {
|
||||||
|
field.annotate(Deprecated.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add {@link Deprecated} annotation to getter methods */
|
||||||
|
@Override
|
||||||
|
public void propertyGetter(JMethod getter, JDefinedClass clazz, String propertyName) {
|
||||||
|
super.propertyGetter(getter, clazz, propertyName);
|
||||||
|
addDeprecatedAnnotationIfApplies(getter, propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Add {@link Deprecated} annotation to setter methods */
|
||||||
|
@Override
|
||||||
|
public void propertySetter(JMethod setter, JDefinedClass clazz, String propertyName) {
|
||||||
|
super.propertySetter(setter, clazz, propertyName);
|
||||||
|
addDeprecatedAnnotationIfApplies(setter, propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use reflection methods to access the {@link JDefinedClass} of the {@link JMethod} object. If
|
||||||
|
* the {@link JMethod} is pointing to a field annotated with {@link Deprecated} then annotates
|
||||||
|
* the {@link JMethod} object with {@link Deprecated}
|
||||||
|
*/
|
||||||
|
private void addDeprecatedAnnotationIfApplies(JMethod jMethod, String propertyName) {
|
||||||
|
try {
|
||||||
|
Field outerClassField = JMethod.class.getDeclaredField("outer");
|
||||||
|
outerClassField.setAccessible(true);
|
||||||
|
JDefinedClass outerClass = (JDefinedClass) outerClassField.get(jMethod);
|
||||||
|
|
||||||
|
TreeMap<String, JFieldVar> insensitiveFieldsMap =
|
||||||
|
new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
insensitiveFieldsMap.putAll(outerClass.fields());
|
||||||
|
|
||||||
|
if (insensitiveFieldsMap.containsKey(propertyName)
|
||||||
|
&& insensitiveFieldsMap.get(propertyName).annotations().stream()
|
||||||
|
.anyMatch(
|
||||||
|
annotation ->
|
||||||
|
Deprecated.class.getName().equals(getAnnotationClassName(annotation)))) {
|
||||||
|
jMethod.annotate(Deprecated.class);
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getAnnotationClassName(JAnnotationUse annotation) {
|
||||||
|
try {
|
||||||
|
Field clazzField = JAnnotationUse.class.getDeclaredField("clazz");
|
||||||
|
clazzField.setAccessible(true);
|
||||||
|
return ((JClass) clazzField.get(annotation)).fullName();
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,6 +19,10 @@ public class OpenMetadataAnnotator extends CompositeAnnotator {
|
|||||||
|
|
||||||
public OpenMetadataAnnotator() {
|
public OpenMetadataAnnotator() {
|
||||||
// we can add multiple annotators
|
// we can add multiple annotators
|
||||||
super(new ExposedAnnotator(), new MaskedAnnotator(), new PasswordAnnotator());
|
super(
|
||||||
|
new ExposedAnnotator(),
|
||||||
|
new MaskedAnnotator(),
|
||||||
|
new PasswordAnnotator(),
|
||||||
|
new DeprecatedAnnotator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,8 +25,9 @@ public class MigrationUtil {
|
|||||||
testSuiteRepository.listAll(
|
testSuiteRepository.listAll(
|
||||||
new EntityUtil.Fields(Set.of("id")), new ListFilter(Include.ALL));
|
new EntityUtil.Fields(Set.of("id")), new ListFilter(Include.ALL));
|
||||||
for (TestSuite suite : testSuites) {
|
for (TestSuite suite : testSuites) {
|
||||||
if (Boolean.TRUE.equals(suite.getBasic()) && suite.getBasicEntityReference() != null) {
|
if (Boolean.TRUE.equals(suite.getExecutable())
|
||||||
String tableFQN = suite.getBasicEntityReference().getFullyQualifiedName();
|
&& suite.getExecutableEntityReference() != null) {
|
||||||
|
String tableFQN = suite.getExecutableEntityReference().getFullyQualifiedName();
|
||||||
String suiteFQN = tableFQN + ".testSuite";
|
String suiteFQN = tableFQN + ".testSuite";
|
||||||
suite.setName(suiteFQN);
|
suite.setName(suiteFQN);
|
||||||
suite.setFullyQualifiedName(suiteFQN);
|
suite.setFullyQualifiedName(suiteFQN);
|
||||||
|
|||||||
@ -48,13 +48,13 @@ public class MigrationUtil {
|
|||||||
testSuiteRepository.listAll(
|
testSuiteRepository.listAll(
|
||||||
new EntityUtil.Fields(Set.of("id")), new ListFilter(Include.ALL));
|
new EntityUtil.Fields(Set.of("id")), new ListFilter(Include.ALL));
|
||||||
for (TestSuite suite : testSuites) {
|
for (TestSuite suite : testSuites) {
|
||||||
if (suite.getBasicEntityReference() != null
|
if (suite.getExecutableEntityReference() != null
|
||||||
&& (!suite.getBasic() || !suite.getFullyQualifiedName().contains("testSuite"))) {
|
&& (!suite.getExecutable() || !suite.getFullyQualifiedName().contains("testSuite"))) {
|
||||||
String tableFQN = suite.getBasicEntityReference().getFullyQualifiedName();
|
String tableFQN = suite.getExecutableEntityReference().getFullyQualifiedName();
|
||||||
String suiteFQN = tableFQN + ".testSuite";
|
String suiteFQN = tableFQN + ".testSuite";
|
||||||
suite.setName(suiteFQN);
|
suite.setName(suiteFQN);
|
||||||
suite.setFullyQualifiedName(suiteFQN);
|
suite.setFullyQualifiedName(suiteFQN);
|
||||||
suite.setBasic(true);
|
suite.setExecutable(true);
|
||||||
collectionDAO.testSuiteDAO().update(suite);
|
collectionDAO.testSuiteDAO().update(suite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ public class MigrationUtil {
|
|||||||
try {
|
try {
|
||||||
TestSuite existingTestSuite =
|
TestSuite existingTestSuite =
|
||||||
testSuiteRepository.getDao().findEntityById(existingTestSuiteRel.getId());
|
testSuiteRepository.getDao().findEntityById(existingTestSuiteRel.getId());
|
||||||
if (Boolean.TRUE.equals(existingTestSuite.getBasic())
|
if (Boolean.TRUE.equals(existingTestSuite.getExecutable())
|
||||||
&& existingTestSuite.getFullyQualifiedName().equals(executableTestSuiteFQN)) {
|
&& existingTestSuite.getFullyQualifiedName().equals(executableTestSuiteFQN)) {
|
||||||
// There is a native test suite associated with this testCase.
|
// There is a native test suite associated with this testCase.
|
||||||
relationWithExecutableTestSuiteExists = true;
|
relationWithExecutableTestSuiteExists = true;
|
||||||
@ -111,7 +111,7 @@ public class MigrationUtil {
|
|||||||
// check from table -> nativeTestSuite there should only one relation
|
// check from table -> nativeTestSuite there should only one relation
|
||||||
List<CollectionDAO.EntityRelationshipRecord> testSuiteRels =
|
List<CollectionDAO.EntityRelationshipRecord> testSuiteRels =
|
||||||
testSuiteRepository.findToRecords(
|
testSuiteRepository.findToRecords(
|
||||||
executableTestSuite.getBasicEntityReference().getId(),
|
executableTestSuite.getExecutableEntityReference().getId(),
|
||||||
TABLE,
|
TABLE,
|
||||||
Relationship.CONTAINS,
|
Relationship.CONTAINS,
|
||||||
TEST_SUITE);
|
TEST_SUITE);
|
||||||
@ -122,7 +122,7 @@ public class MigrationUtil {
|
|||||||
// if testsuite cannot be retrieved but the relation exists, then this is orphaned
|
// if testsuite cannot be retrieved but the relation exists, then this is orphaned
|
||||||
// relation, we will delete the relation
|
// relation, we will delete the relation
|
||||||
testSuiteRepository.deleteRelationship(
|
testSuiteRepository.deleteRelationship(
|
||||||
executableTestSuite.getBasicEntityReference().getId(),
|
executableTestSuite.getExecutableEntityReference().getId(),
|
||||||
TABLE,
|
TABLE,
|
||||||
testSuiteRel.getId(),
|
testSuiteRel.getId(),
|
||||||
TEST_SUITE,
|
TEST_SUITE,
|
||||||
@ -158,9 +158,9 @@ public class MigrationUtil {
|
|||||||
new CreateTestSuite()
|
new CreateTestSuite()
|
||||||
.withName(FullyQualifiedName.buildHash(executableTestSuiteFQN))
|
.withName(FullyQualifiedName.buildHash(executableTestSuiteFQN))
|
||||||
.withDisplayName(executableTestSuiteFQN)
|
.withDisplayName(executableTestSuiteFQN)
|
||||||
.withBasicEntityReference(entityLink.getEntityFQN()),
|
.withExecutableEntityReference(entityLink.getEntityFQN()),
|
||||||
"ingestion-bot")
|
"ingestion-bot")
|
||||||
.withBasic(true)
|
.withExecutable(true)
|
||||||
.withFullyQualifiedName(executableTestSuiteFQN);
|
.withFullyQualifiedName(executableTestSuiteFQN);
|
||||||
testSuiteRepository.prepareInternal(newExecutableTestSuite, false);
|
testSuiteRepository.prepareInternal(newExecutableTestSuite, false);
|
||||||
testSuiteRepository
|
testSuiteRepository
|
||||||
@ -169,7 +169,7 @@ public class MigrationUtil {
|
|||||||
"fqnHash", newExecutableTestSuite, newExecutableTestSuite.getFullyQualifiedName());
|
"fqnHash", newExecutableTestSuite, newExecutableTestSuite.getFullyQualifiedName());
|
||||||
// add relationship between executable TestSuite with Table
|
// add relationship between executable TestSuite with Table
|
||||||
testSuiteRepository.addRelationship(
|
testSuiteRepository.addRelationship(
|
||||||
newExecutableTestSuite.getBasicEntityReference().getId(),
|
newExecutableTestSuite.getExecutableEntityReference().getId(),
|
||||||
newExecutableTestSuite.getId(),
|
newExecutableTestSuite.getId(),
|
||||||
Entity.TABLE,
|
Entity.TABLE,
|
||||||
TEST_SUITE,
|
TEST_SUITE,
|
||||||
|
|||||||
@ -460,16 +460,17 @@ public class MigrationUtil {
|
|||||||
.withDescription(create.getDescription())
|
.withDescription(create.getDescription())
|
||||||
.withDisplayName(create.getDisplayName())
|
.withDisplayName(create.getDisplayName())
|
||||||
.withName(create.getName());
|
.withName(create.getName());
|
||||||
if (create.getBasicEntityReference() != null) {
|
if (create.getExecutableEntityReference() != null) {
|
||||||
Table table =
|
Table table =
|
||||||
Entity.getEntityByName(Entity.TABLE, create.getBasicEntityReference(), "", Include.ALL);
|
Entity.getEntityByName(
|
||||||
|
Entity.TABLE, create.getExecutableEntityReference(), "", Include.ALL);
|
||||||
EntityReference entityReference =
|
EntityReference entityReference =
|
||||||
new EntityReference()
|
new EntityReference()
|
||||||
.withId(table.getId())
|
.withId(table.getId())
|
||||||
.withFullyQualifiedName(table.getFullyQualifiedName())
|
.withFullyQualifiedName(table.getFullyQualifiedName())
|
||||||
.withName(table.getName())
|
.withName(table.getName())
|
||||||
.withType(Entity.TABLE);
|
.withType(Entity.TABLE);
|
||||||
testSuite.setBasicEntityReference(entityReference);
|
testSuite.setExecutableEntityReference(entityReference);
|
||||||
}
|
}
|
||||||
return testSuite;
|
return testSuite;
|
||||||
}
|
}
|
||||||
@ -516,9 +517,9 @@ public class MigrationUtil {
|
|||||||
new CreateTestSuite()
|
new CreateTestSuite()
|
||||||
.withName(FullyQualifiedName.buildHash(nativeTestSuiteFqn))
|
.withName(FullyQualifiedName.buildHash(nativeTestSuiteFqn))
|
||||||
.withDisplayName(nativeTestSuiteFqn)
|
.withDisplayName(nativeTestSuiteFqn)
|
||||||
.withBasicEntityReference(entityLink.getEntityFQN()),
|
.withExecutableEntityReference(entityLink.getEntityFQN()),
|
||||||
"ingestion-bot")
|
"ingestion-bot")
|
||||||
.withBasic(true)
|
.withExecutable(true)
|
||||||
.withFullyQualifiedName(nativeTestSuiteFqn);
|
.withFullyQualifiedName(nativeTestSuiteFqn);
|
||||||
testSuiteRepository.prepareInternal(newExecutableTestSuite, false);
|
testSuiteRepository.prepareInternal(newExecutableTestSuite, false);
|
||||||
try {
|
try {
|
||||||
@ -533,7 +534,7 @@ public class MigrationUtil {
|
|||||||
}
|
}
|
||||||
// add relationship between executable TestSuite with Table
|
// add relationship between executable TestSuite with Table
|
||||||
testSuiteRepository.addRelationship(
|
testSuiteRepository.addRelationship(
|
||||||
newExecutableTestSuite.getBasicEntityReference().getId(),
|
newExecutableTestSuite.getExecutableEntityReference().getId(),
|
||||||
newExecutableTestSuite.getId(),
|
newExecutableTestSuite.getId(),
|
||||||
Entity.TABLE,
|
Entity.TABLE,
|
||||||
TEST_SUITE,
|
TEST_SUITE,
|
||||||
@ -564,7 +565,7 @@ public class MigrationUtil {
|
|||||||
ListFilter filter = new ListFilter(Include.ALL);
|
ListFilter filter = new ListFilter(Include.ALL);
|
||||||
List<TestSuite> testSuites = testSuiteRepository.listAll(new Fields(Set.of("id")), filter);
|
List<TestSuite> testSuites = testSuiteRepository.listAll(new Fields(Set.of("id")), filter);
|
||||||
for (TestSuite testSuite : testSuites) {
|
for (TestSuite testSuite : testSuites) {
|
||||||
testSuite.setBasic(false);
|
testSuite.setExecutable(false);
|
||||||
List<CollectionDAO.EntityRelationshipRecord> ingestionPipelineRecords =
|
List<CollectionDAO.EntityRelationshipRecord> ingestionPipelineRecords =
|
||||||
collectionDAO
|
collectionDAO
|
||||||
.relationshipDAO()
|
.relationshipDAO()
|
||||||
|
|||||||
@ -106,16 +106,16 @@ public class MigrationUtilV111 {
|
|||||||
suite = JsonUtils.readValue(pgObject.getValue(), TestSuite.class);
|
suite = JsonUtils.readValue(pgObject.getValue(), TestSuite.class);
|
||||||
}
|
}
|
||||||
// Only Test Suite which are executable needs to be updated
|
// Only Test Suite which are executable needs to be updated
|
||||||
if (Boolean.TRUE.equals(suite.getBasic())) {
|
if (Boolean.TRUE.equals(suite.getExecutable())) {
|
||||||
if (suite.getBasicEntityReference() != null) {
|
if (suite.getExecutableEntityReference() != null) {
|
||||||
updateTestSuite(handle, suite, updateSql);
|
updateTestSuite(handle, suite, updateSql);
|
||||||
} else {
|
} else {
|
||||||
String entityName = StringUtils.replaceOnce(suite.getDisplayName(), ".testSuite", "");
|
String entityName = StringUtils.replaceOnce(suite.getDisplayName(), ".testSuite", "");
|
||||||
try {
|
try {
|
||||||
Table table = collectionDAO.tableDAO().findEntityByName(entityName, Include.ALL);
|
Table table = collectionDAO.tableDAO().findEntityByName(entityName, Include.ALL);
|
||||||
// Update Test Suite
|
// Update Test Suite
|
||||||
suite.setBasic(true);
|
suite.setExecutable(true);
|
||||||
suite.setBasicEntityReference(table.getEntityReference());
|
suite.setExecutableEntityReference(table.getEntityReference());
|
||||||
updateTestSuite(handle, suite, updateSql);
|
updateTestSuite(handle, suite, updateSql);
|
||||||
removeDuplicateTestCases(collectionDAO, handle, getSql);
|
removeDuplicateTestCases(collectionDAO, handle, getSql);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
@ -133,9 +133,9 @@ public class MigrationUtilV111 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void updateTestSuite(Handle handle, TestSuite suite, String updateSql) {
|
public static void updateTestSuite(Handle handle, TestSuite suite, String updateSql) {
|
||||||
if (suite.getBasicEntityReference() != null) {
|
if (suite.getExecutableEntityReference() != null) {
|
||||||
try {
|
try {
|
||||||
EntityReference executableEntityRef = suite.getBasicEntityReference();
|
EntityReference executableEntityRef = suite.getExecutableEntityReference();
|
||||||
// Run new Migrations
|
// Run new Migrations
|
||||||
suite.setName(String.format("%s.testSuite", executableEntityRef.getName()));
|
suite.setName(String.format("%s.testSuite", executableEntityRef.getName()));
|
||||||
suite.setFullyQualifiedName(
|
suite.setFullyQualifiedName(
|
||||||
|
|||||||
@ -37,6 +37,11 @@
|
|||||||
"description": "Entity reference the test suite needs to execute the test against. Only applicable if the test suite is basic.",
|
"description": "Entity reference the test suite needs to execute the test against. Only applicable if the test suite is basic.",
|
||||||
"$ref": "../../type/basic.json#/definitions/fullyQualifiedEntityName"
|
"$ref": "../../type/basic.json#/definitions/fullyQualifiedEntityName"
|
||||||
},
|
},
|
||||||
|
"executableEntityReference": {
|
||||||
|
"description": "DEPRECATED in 1.6.2: use 'basicEntityReference'",
|
||||||
|
"$ref": "../../type/basic.json#/definitions/fullyQualifiedEntityName",
|
||||||
|
"deprecated": true
|
||||||
|
},
|
||||||
"domain": {
|
"domain": {
|
||||||
"description": "Fully qualified name of the domain the Table belongs to.",
|
"description": "Fully qualified name of the domain the Table belongs to.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
|||||||
@ -125,10 +125,20 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
|
"executable": {
|
||||||
|
"description": "DEPRECATED in 1.6.2: Use 'basic'",
|
||||||
|
"type": "boolean",
|
||||||
|
"deprecated": true
|
||||||
|
},
|
||||||
"basicEntityReference": {
|
"basicEntityReference": {
|
||||||
"description": "Entity reference the test suite needs to execute the test against. Only applicable if the test suite is basic.",
|
"description": "Entity reference the test suite needs to execute the test against. Only applicable if the test suite is basic.",
|
||||||
"$ref": "../type/entityReference.json"
|
"$ref": "../type/entityReference.json"
|
||||||
},
|
},
|
||||||
|
"executableEntityReference": {
|
||||||
|
"description": "DEPRECATED in 1.6.2: Use 'basicEntityReference'.",
|
||||||
|
"$ref": "../type/entityReference.json",
|
||||||
|
"deprecated": true
|
||||||
|
},
|
||||||
"summary": {
|
"summary": {
|
||||||
"description": "Summary of the previous day test cases execution for this test suite.",
|
"description": "Summary of the previous day test cases execution for this test suite.",
|
||||||
"$ref": "./basic.json#/definitions/testSummary"
|
"$ref": "./basic.json#/definitions/testSummary"
|
||||||
|
|||||||
@ -31,6 +31,10 @@ export interface CreateTestSuite {
|
|||||||
* Fully qualified name of the domain the Table belongs to.
|
* Fully qualified name of the domain the Table belongs to.
|
||||||
*/
|
*/
|
||||||
domain?: string;
|
domain?: string;
|
||||||
|
/**
|
||||||
|
* DEPRECATED in 1.6.2: use 'basicEntityReference'
|
||||||
|
*/
|
||||||
|
executableEntityReference?: string;
|
||||||
/**
|
/**
|
||||||
* Name that identifies this test suite.
|
* Name that identifies this test suite.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -50,6 +50,14 @@ export interface TestSuite {
|
|||||||
* the table it belongs to.
|
* the table it belongs to.
|
||||||
*/
|
*/
|
||||||
domain?: EntityReference;
|
domain?: EntityReference;
|
||||||
|
/**
|
||||||
|
* DEPRECATED in 1.6.2: Use 'basic'
|
||||||
|
*/
|
||||||
|
executable?: boolean;
|
||||||
|
/**
|
||||||
|
* DEPRECATED in 1.6.2: Use 'basicEntityReference'.
|
||||||
|
*/
|
||||||
|
executableEntityReference?: EntityReference;
|
||||||
/**
|
/**
|
||||||
* FullyQualifiedName same as `name`.
|
* FullyQualifiedName same as `name`.
|
||||||
*/
|
*/
|
||||||
@ -127,6 +135,8 @@ export interface TestSuite {
|
|||||||
* Domain the test Suite belongs to. When not set, the test Suite inherits the domain from
|
* Domain the test Suite belongs to. When not set, the test Suite inherits the domain from
|
||||||
* the table it belongs to.
|
* the table it belongs to.
|
||||||
*
|
*
|
||||||
|
* DEPRECATED in 1.6.2: Use 'basicEntityReference'.
|
||||||
|
*
|
||||||
* Owners of this TestCase definition.
|
* Owners of this TestCase definition.
|
||||||
*
|
*
|
||||||
* This schema defines the EntityReferenceList type used for referencing an entity.
|
* This schema defines the EntityReferenceList type used for referencing an entity.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user