From 57c22b5fbef6dff66a8f07427159664bd97773f0 Mon Sep 17 00:00:00 2001 From: IceS2 Date: Wed, 30 Oct 2024 11:40:39 +0100 Subject: [PATCH] Initial JSONSchema specification for Asset Certification (#18392) * Initial JSONSchema specification for Asset Certification * Add backend logic to updateCertification * Add Tests for Asset Certification * Update certification config and set defaults * Fix Checkstyle * Fix Tests * Fix checkstyle --- .../java/org/openmetadata/service/Entity.java | 1 + .../service/jdbi3/CollectionDAO.java | 3 + .../service/jdbi3/EntityRepository.java | 60 ++++++++++ .../service/jdbi3/SystemRepository.java | 11 ++ .../resources/settings/SettingsCache.java | 16 +++ .../json/data/tags/certification.json | 31 ++++++ .../service/resources/EntityResourceTest.java | 103 ++++++++++++++++++ .../openmetadata/schema/EntityInterface.java | 8 ++ .../assetCertificationSettings.json | 20 ++++ .../schema/entity/data/apiCollection.json | 3 + .../json/schema/entity/data/apiEndpoint.json | 3 + .../json/schema/entity/data/chart.json | 3 + .../json/schema/entity/data/container.json | 3 + .../json/schema/entity/data/dashboard.json | 3 + .../entity/data/dashboardDataModel.json | 3 + .../json/schema/entity/data/database.json | 3 + .../schema/entity/data/databaseSchema.json | 3 + .../json/schema/entity/data/metric.json | 3 + .../json/schema/entity/data/mlmodel.json | 3 + .../json/schema/entity/data/pipeline.json | 3 + .../json/schema/entity/data/searchIndex.json | 3 + .../schema/entity/data/storedProcedure.json | 3 + .../json/schema/entity/data/table.json | 3 + .../json/schema/entity/data/topic.json | 3 + .../json/schema/settings/settings.json | 6 +- .../json/schema/type/assetCertification.json | 22 ++++ 26 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 openmetadata-service/src/main/resources/json/data/tags/certification.json create mode 100644 openmetadata-spec/src/main/resources/json/schema/configuration/assetCertificationSettings.json create mode 100644 openmetadata-spec/src/main/resources/json/schema/type/assetCertification.json diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/Entity.java b/openmetadata-service/src/main/java/org/openmetadata/service/Entity.java index 6600a380fef..e9bf591be56 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/Entity.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/Entity.java @@ -122,6 +122,7 @@ public final class Entity { public static final String FIELD_STYLE = "style"; public static final String FIELD_LIFE_CYCLE = "lifeCycle"; + public static final String FIELD_CERTIFICATION = "certification"; public static final String FIELD_DISABLED = "disabled"; diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java index f6051c5010d..fb2eeefc008 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java @@ -65,6 +65,7 @@ import org.openmetadata.schema.auth.PasswordResetToken; import org.openmetadata.schema.auth.PersonalAccessToken; import org.openmetadata.schema.auth.RefreshToken; import org.openmetadata.schema.auth.TokenType; +import org.openmetadata.schema.configuration.AssetCertificationSettings; import org.openmetadata.schema.dataInsight.DataInsightChart; import org.openmetadata.schema.dataInsight.custom.DataInsightCustomChart; import org.openmetadata.schema.dataInsight.kpi.Kpi; @@ -4910,6 +4911,8 @@ public interface CollectionDAO { .readValue(json, String.class); case PROFILER_CONFIGURATION -> JsonUtils.readValue(json, ProfilerConfiguration.class); case SEARCH_SETTINGS -> JsonUtils.readValue(json, SearchSettings.class); + case ASSET_CERTIFICATION_SETTINGS -> JsonUtils.readValue( + json, AssetCertificationSettings.class); default -> throw new IllegalArgumentException("Invalid Settings Type " + configType); }; settings.setConfigValue(value); diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java index 4f6d9540a7a..3dceb1c75f1 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/EntityRepository.java @@ -29,6 +29,7 @@ import static org.openmetadata.schema.utils.EntityInterfaceUtil.quoteName; import static org.openmetadata.service.Entity.ADMIN_USER_NAME; import static org.openmetadata.service.Entity.DATA_PRODUCT; import static org.openmetadata.service.Entity.DOMAIN; +import static org.openmetadata.service.Entity.FIELD_CERTIFICATION; import static org.openmetadata.service.Entity.FIELD_CHILDREN; import static org.openmetadata.service.Entity.FIELD_DATA_PRODUCTS; import static org.openmetadata.service.Entity.FIELD_DELETED; @@ -78,8 +79,11 @@ import com.networknt.schema.JsonSchema; import com.networknt.schema.ValidationMessage; import java.io.IOException; import java.net.URI; +import java.time.Instant; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.Period; +import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.temporal.TemporalAccessor; @@ -121,12 +125,14 @@ import org.openmetadata.schema.api.VoteRequest; import org.openmetadata.schema.api.VoteRequest.VoteType; import org.openmetadata.schema.api.feed.ResolveTask; import org.openmetadata.schema.api.teams.CreateTeam; +import org.openmetadata.schema.configuration.AssetCertificationSettings; import org.openmetadata.schema.entity.data.Table; import org.openmetadata.schema.entity.feed.Suggestion; import org.openmetadata.schema.entity.teams.Team; import org.openmetadata.schema.entity.teams.User; import org.openmetadata.schema.system.EntityError; import org.openmetadata.schema.type.ApiStatus; +import org.openmetadata.schema.type.AssetCertification; import org.openmetadata.schema.type.ChangeDescription; import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.Column; @@ -235,6 +241,7 @@ public abstract class EntityRepository { @Getter protected final boolean supportsOwners; @Getter protected final boolean supportsStyle; @Getter protected final boolean supportsLifeCycle; + @Getter protected final boolean supportsCertification; protected final boolean supportsFollower; protected final boolean supportsExtension; protected final boolean supportsVotes; @@ -328,6 +335,11 @@ public abstract class EntityRepository { this.patchFields.addField(allowedFields, FIELD_LIFE_CYCLE); this.putFields.addField(allowedFields, FIELD_LIFE_CYCLE); } + this.supportsCertification = allowedFields.contains(FIELD_CERTIFICATION); + if (supportsCertification) { + this.patchFields.addField(allowedFields, FIELD_CERTIFICATION); + this.putFields.addField(allowedFields, FIELD_CERTIFICATION); + } Map, Fields>>> fieldSupportMap = new HashMap<>(); @@ -2627,6 +2639,7 @@ public abstract class EntityRepository { updateReviewers(); updateStyle(); updateLifeCycle(); + updateCertification(); entitySpecificUpdate(); } } @@ -2929,6 +2942,53 @@ public abstract class EntityRepository { recordChange(FIELD_LIFE_CYCLE, origLifeCycle, updatedLifeCycle, true); } + private void updateCertification() { + if (!supportsCertification) { + return; + } + AssetCertification origCertification = original.getCertification(); + AssetCertification updatedCertification = updated.getCertification(); + + if (origCertification == updatedCertification || updatedCertification == null) return; + + SystemRepository systemRepository = Entity.getSystemRepository(); + AssetCertificationSettings assetCertificationSettings = + systemRepository.getAssetCertificationSettings(); + + String certificationLabel = updatedCertification.getTagLabel().getTagFQN(); + + validateCertification(certificationLabel, assetCertificationSettings); + + long certificationDate = System.currentTimeMillis(); + updatedCertification.setAppliedDate(certificationDate); + + LocalDateTime nowDateTime = + LocalDateTime.ofInstant(Instant.ofEpochMilli(certificationDate), ZoneOffset.UTC); + Period datePeriod = Period.parse(assetCertificationSettings.getValidityPeriod()); + LocalDateTime targetDateTime = nowDateTime.plus(datePeriod); + updatedCertification.setExpiryDate(targetDateTime.toInstant(ZoneOffset.UTC).toEpochMilli()); + + recordChange(FIELD_CERTIFICATION, origCertification, updatedCertification, true); + } + + private void validateCertification( + String certificationLabel, AssetCertificationSettings assetCertificationSettings) { + if (Optional.ofNullable(assetCertificationSettings).isEmpty()) { + throw new IllegalArgumentException( + "Certification is not configured. Please configure the Classification used for Certification in the Settings."); + } else { + String allowedClassification = assetCertificationSettings.getAllowedClassification(); + String[] fqnParts = FullyQualifiedName.split(certificationLabel); + String parentFqn = FullyQualifiedName.getParentFQN(fqnParts); + if (!allowedClassification.equals(parentFqn)) { + throw new IllegalArgumentException( + String.format( + "Invalid Classification: %s is not valid for Certification.", + certificationLabel)); + } + } + } + public final boolean updateVersion(Double oldVersion) { Double newVersion = oldVersion; if (majorVersionChange) { diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/SystemRepository.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/SystemRepository.java index 9f710e6ef65..867b450f58a 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/SystemRepository.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/SystemRepository.java @@ -9,6 +9,7 @@ import com.slack.api.bolt.model.builtin.DefaultInstaller; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Optional; import javax.json.JsonPatch; import javax.json.JsonValue; import javax.ws.rs.core.Response; @@ -16,6 +17,7 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.jdbi.v3.sqlobject.transaction.Transaction; import org.openmetadata.api.configuration.UiThemePreference; +import org.openmetadata.schema.configuration.AssetCertificationSettings; import org.openmetadata.schema.email.SmtpSettings; import org.openmetadata.schema.entity.services.ingestionPipelines.PipelineServiceClientResponse; import org.openmetadata.schema.security.client.OpenMetadataJWTClientConfig; @@ -110,6 +112,15 @@ public class SystemRepository { return null; } + public AssetCertificationSettings getAssetCertificationSettings() { + Optional oAssetCertificationSettings = + Optional.ofNullable(getConfigWithKey(SettingsType.ASSET_CERTIFICATION_SETTINGS.value())); + + return oAssetCertificationSettings + .map(settings -> (AssetCertificationSettings) settings.getConfigValue()) + .orElse(null); + } + public Settings getEmailConfigInternal() { try { Settings setting = dao.getConfigWithKey(SettingsType.EMAIL_CONFIGURATION.value()); diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/settings/SettingsCache.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/settings/SettingsCache.java index f685c73b143..a0f50d5dfbb 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/settings/SettingsCache.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/settings/SettingsCache.java @@ -13,6 +13,7 @@ package org.openmetadata.service.resources.settings; +import static org.openmetadata.schema.settings.SettingsType.ASSET_CERTIFICATION_SETTINGS; import static org.openmetadata.schema.settings.SettingsType.CUSTOM_UI_THEME_PREFERENCE; import static org.openmetadata.schema.settings.SettingsType.EMAIL_CONFIGURATION; import static org.openmetadata.schema.settings.SettingsType.LOGIN_CONFIGURATION; @@ -30,6 +31,7 @@ import org.openmetadata.api.configuration.ThemeConfiguration; import org.openmetadata.api.configuration.UiThemePreference; import org.openmetadata.schema.api.configuration.LoginConfiguration; import org.openmetadata.schema.api.searcg.SearchSettings; +import org.openmetadata.schema.configuration.AssetCertificationSettings; import org.openmetadata.schema.email.SmtpSettings; import org.openmetadata.schema.settings.Settings; import org.openmetadata.schema.settings.SettingsType; @@ -124,6 +126,20 @@ public class SettingsCache { .withConfigValue(new SearchSettings().withEnableAccessControl(false)); systemRepository.createNewSetting(setting); } + + // Initialise Certification Settings + Settings certificationSettings = + systemRepository.getConfigWithKey(ASSET_CERTIFICATION_SETTINGS.toString()); + if (certificationSettings == null) { + Settings setting = + new Settings() + .withConfigType(ASSET_CERTIFICATION_SETTINGS) + .withConfigValue( + new AssetCertificationSettings() + .withAllowedClassification("Certification") + .withValidityPeriod("P30D")); + systemRepository.createNewSetting(setting); + } } public static T getSetting(SettingsType settingName, Class clazz) { diff --git a/openmetadata-service/src/main/resources/json/data/tags/certification.json b/openmetadata-service/src/main/resources/json/data/tags/certification.json new file mode 100644 index 00000000000..b74aac7681f --- /dev/null +++ b/openmetadata-service/src/main/resources/json/data/tags/certification.json @@ -0,0 +1,31 @@ +{ + "createClassification": { + "name": "Certification", + "description": "Certifying Data Asset will provide the users with a clear idea of how reliable a Data Asset is.", + "provider": "system", + "mutuallyExclusive": "true" + }, + "createTags": [ + { + "name": "Bronze", + "description": "Bronze certified Data Asset.", + "style": { + "color": "#CD7F32" + } + }, + { + "name": "Silver", + "description": "Silver certified Data Asset.", + "style": { + "color": "#C0C0C0" + } + }, + { + "name": "Gold", + "description": "Gold certified Data Asset.", + "style": { + "color": "#FFD700" + } + } + ] +} diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/EntityResourceTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/EntityResourceTest.java index ad387a12b48..2641ab72e4a 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/resources/EntityResourceTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/EntityResourceTest.java @@ -26,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import static org.openmetadata.common.utils.CommonUtil.listOf; import static org.openmetadata.common.utils.CommonUtil.listOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; @@ -128,6 +129,7 @@ import org.openmetadata.schema.api.feed.CreateThread; import org.openmetadata.schema.api.teams.CreateTeam; import org.openmetadata.schema.api.teams.CreateTeam.TeamType; import org.openmetadata.schema.api.tests.CreateTestSuite; +import org.openmetadata.schema.configuration.AssetCertificationSettings; import org.openmetadata.schema.dataInsight.DataInsightChart; import org.openmetadata.schema.dataInsight.type.KpiTarget; import org.openmetadata.schema.entities.docStore.Document; @@ -155,11 +157,14 @@ import org.openmetadata.schema.entity.teams.User; import org.openmetadata.schema.entity.type.Category; import org.openmetadata.schema.entity.type.CustomProperty; import org.openmetadata.schema.entity.type.Style; +import org.openmetadata.schema.settings.Settings; +import org.openmetadata.schema.settings.SettingsType; import org.openmetadata.schema.tests.TestDefinition; import org.openmetadata.schema.tests.TestSuite; import org.openmetadata.schema.type.AccessDetails; import org.openmetadata.schema.type.AnnouncementDetails; import org.openmetadata.schema.type.ApiStatus; +import org.openmetadata.schema.type.AssetCertification; import org.openmetadata.schema.type.ChangeDescription; import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.Column; @@ -178,6 +183,7 @@ import org.openmetadata.service.Entity; import org.openmetadata.service.OpenMetadataApplicationTest; import org.openmetadata.service.exception.CatalogExceptionMessage; import org.openmetadata.service.jdbi3.EntityRepository.EntityUpdater; +import org.openmetadata.service.jdbi3.SystemRepository; import org.openmetadata.service.resources.apis.APICollectionResourceTest; import org.openmetadata.service.resources.bots.BotResourceTest; import org.openmetadata.service.resources.databases.TableResourceTest; @@ -209,6 +215,7 @@ import org.openmetadata.service.resources.teams.*; import org.openmetadata.service.search.models.IndexMapping; import org.openmetadata.service.security.SecurityUtil; import org.openmetadata.service.util.EntityUtil; +import org.openmetadata.service.util.FullyQualifiedName; import org.openmetadata.service.util.JsonUtils; import org.openmetadata.service.util.ResultList; import org.openmetadata.service.util.TestUtils; @@ -247,6 +254,7 @@ public abstract class EntityResourceTest T withHref(URI href); @JsonIgnore diff --git a/openmetadata-spec/src/main/resources/json/schema/configuration/assetCertificationSettings.json b/openmetadata-spec/src/main/resources/json/schema/configuration/assetCertificationSettings.json new file mode 100644 index 00000000000..17e2cfba42b --- /dev/null +++ b/openmetadata-spec/src/main/resources/json/schema/configuration/assetCertificationSettings.json @@ -0,0 +1,20 @@ +{ + "$id": "https://open-metadata.org/schema/configuration/assetCertificationSettings.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AssetCertificationSettings", + "description": "This schema defines the Asset Certification Settings.", + "type": "object", + "javaType": "org.openmetadata.schema.configuration.AssetCertificationSettings", + "properties": { + "allowedClassification": { + "type": "string", + "description": "Classification that can be used for certifications." + }, + "validityPeriod": { + "type": "string", + "description": "ISO 8601 duration for the validity period." + } + }, + "required": ["allowedClassification", "validityPeriod"], + "additionalProperties": false +} \ No newline at end of file diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/apiCollection.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/apiCollection.json index f39bf6481ad..c23d64bc34e 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/apiCollection.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/apiCollection.json @@ -105,6 +105,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/apiEndpoint.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/apiEndpoint.json index dcbb280247f..481485d5d8c 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/apiEndpoint.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/apiEndpoint.json @@ -167,6 +167,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/chart.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/chart.json index 61f110da93b..425a3ae9b89 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/chart.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/chart.json @@ -155,6 +155,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/container.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/container.json index 3c29afe3119..b1ad94e9f58 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/container.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/container.json @@ -189,6 +189,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/dashboard.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/dashboard.json index fcc644b729a..9d1d0019ec9 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/dashboard.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/dashboard.json @@ -143,6 +143,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/dashboardDataModel.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/dashboardDataModel.json index eaa6aa0cbc4..1831dc3006c 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/dashboardDataModel.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/dashboardDataModel.json @@ -166,6 +166,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/database.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/database.json index 1cbea85c665..bcc0f601d07 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/database.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/database.json @@ -121,6 +121,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/databaseSchema.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/databaseSchema.json index 724bae7004f..ceb4c41b444 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/databaseSchema.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/databaseSchema.json @@ -117,6 +117,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/metric.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/metric.json index 59005273b0b..6840f192872 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/metric.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/metric.json @@ -195,6 +195,9 @@ "extension": { "description": "Entity extension data with custom attributes added to the entity.", "$ref": "../../type/basic.json#/definitions/entityExtension" + }, + "certification": { + "$ref": "../../type/assetCertification.json" } }, "required": ["id", "name"], diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/mlmodel.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/mlmodel.json index 1281b819f93..6d9621a28cd 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/mlmodel.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/mlmodel.json @@ -285,6 +285,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/pipeline.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/pipeline.json index 92fc0dd6433..72456dbe0fb 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/pipeline.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/pipeline.json @@ -271,6 +271,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/searchIndex.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/searchIndex.json index 8a3d1be2bae..06281115376 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/searchIndex.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/searchIndex.json @@ -248,6 +248,9 @@ "description": "Life Cycle of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/storedProcedure.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/storedProcedure.json index b4cdffbe623..70ef8b5f0f6 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/storedProcedure.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/storedProcedure.json @@ -158,6 +158,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/table.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/table.json index 3d20fcda1a3..9e8a93917df 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/table.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/table.json @@ -1121,6 +1121,9 @@ "description": "Life Cycle of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/topic.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/topic.json index c3381b0c23e..f153ce2dfc5 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/topic.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/topic.json @@ -174,6 +174,9 @@ "description": "Life Cycle properties of the entity", "$ref": "../../type/lifeCycle.json" }, + "certification": { + "$ref": "../../type/assetCertification.json" + }, "sourceHash": { "description": "Source hash of the entity", "type": "string", diff --git a/openmetadata-spec/src/main/resources/json/schema/settings/settings.json b/openmetadata-spec/src/main/resources/json/schema/settings/settings.json index a9e7f7e7f3c..b715a8d821d 100644 --- a/openmetadata-spec/src/main/resources/json/schema/settings/settings.json +++ b/openmetadata-spec/src/main/resources/json/schema/settings/settings.json @@ -30,7 +30,8 @@ "slackInstaller", "slackState", "profilerConfiguration", - "searchSettings" + "searchSettings", + "assetCertificationSettings" ] } }, @@ -76,6 +77,9 @@ }, { "$ref": "../configuration/searchSettings.json" + }, + { + "$ref": "../configuration/assetCertificationSettings.json" } ] } diff --git a/openmetadata-spec/src/main/resources/json/schema/type/assetCertification.json b/openmetadata-spec/src/main/resources/json/schema/type/assetCertification.json new file mode 100644 index 00000000000..a3502050375 --- /dev/null +++ b/openmetadata-spec/src/main/resources/json/schema/type/assetCertification.json @@ -0,0 +1,22 @@ +{ "$id": "https://open-metadata.org/schema/type/assetCertification.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AssetCertification", + "description": "Defines the Asset Certification schema.", + "javaType": "org.openmetadata.schema.type.AssetCertification", + "type": "object", + "properties": { + "tagLabel": { + "$ref": "./tagLabel.json" + }, + "appliedDate": { + "description": "The date when the certification was applied.", + "$ref": "basic.json#/definitions/timestamp" + }, + "expiryDate": { + "description": "The date when the certification expires.", + "$ref": "basic.json#/definitions/timestamp" + } + }, + "required": ["tagLabel", "appliedDate", "expiryDate"], + "additionalProperties": false +} \ No newline at end of file