mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-01 19:18:05 +00:00
Fixes #827 - Update Model version during PUT and POST operations
This commit is contained in:
parent
8852ba6ec3
commit
7b2c385ce4
@ -138,6 +138,11 @@ public abstract class DashboardRepository {
|
||||
return EntityUtil.listBefore(entityRepository, Dashboard.class, fields, serviceName, limitParam, before);
|
||||
}
|
||||
|
||||
@Transaction
|
||||
public Dashboard get(String id, Fields fields) throws IOException {
|
||||
return setFields(EntityUtil.validate(id, dashboardDAO().findById(id), Dashboard.class), fields);
|
||||
}
|
||||
|
||||
@Transaction
|
||||
public Dashboard getByName(String fqn, Fields fields) throws IOException {
|
||||
Dashboard dashboard = EntityUtil.validate(fqn, dashboardDAO().findByFQN(fqn), Dashboard.class);
|
||||
@ -207,10 +212,6 @@ public abstract class DashboardRepository {
|
||||
return EntityUtil.populateOwner(userDAO(), teamDAO(), dashboard.getOwner());
|
||||
}
|
||||
|
||||
public Dashboard get(String id, Fields fields) throws IOException {
|
||||
return setFields(EntityUtil.validate(id, dashboardDAO().findById(id), Dashboard.class), fields);
|
||||
}
|
||||
|
||||
private Dashboard setFields(Dashboard dashboard, Fields fields) throws IOException {
|
||||
dashboard.setDisplayName(dashboard.getDisplayName());
|
||||
dashboard.setOwner(fields.contains("owner") ? getOwner(dashboard) : null);
|
||||
|
||||
@ -16,17 +16,21 @@
|
||||
|
||||
package org.openmetadata.catalog.jdbi3;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.openmetadata.catalog.Entity;
|
||||
import org.openmetadata.catalog.entity.data.Dashboard;
|
||||
import org.openmetadata.catalog.entity.data.Model;
|
||||
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
|
||||
import org.openmetadata.catalog.exception.EntityNotFoundException;
|
||||
import org.openmetadata.catalog.jdbi3.DashboardRepository.DashboardDAO;
|
||||
import org.openmetadata.catalog.jdbi3.TeamRepository.TeamDAO;
|
||||
import org.openmetadata.catalog.jdbi3.UserRepository.UserDAO;
|
||||
import org.openmetadata.catalog.jdbi3.UsageRepository.UsageDAO;
|
||||
import org.openmetadata.catalog.jdbi3.UserRepository.UserDAO;
|
||||
import org.openmetadata.catalog.resources.models.ModelResource;
|
||||
import org.openmetadata.catalog.resources.models.ModelResource.ModelList;
|
||||
import org.openmetadata.catalog.type.EntityReference;
|
||||
import org.openmetadata.catalog.type.TagLabel;
|
||||
import org.openmetadata.catalog.util.EntityInterface;
|
||||
import org.openmetadata.catalog.util.EntityUpdater;
|
||||
import org.openmetadata.catalog.util.EntityUtil;
|
||||
import org.openmetadata.catalog.util.EntityUtil.Fields;
|
||||
import org.openmetadata.catalog.util.JsonUtils;
|
||||
@ -37,6 +41,8 @@ import org.skife.jdbi.v2.sqlobject.CreateSqlObject;
|
||||
import org.skife.jdbi.v2.sqlobject.SqlQuery;
|
||||
import org.skife.jdbi.v2.sqlobject.SqlUpdate;
|
||||
import org.skife.jdbi.v2.sqlobject.Transaction;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.json.JsonPatch;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
@ -45,10 +51,12 @@ import java.security.GeneralSecurityException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.entityNotFound;
|
||||
|
||||
public abstract class ModelRepository {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ModelRepository.class);
|
||||
private static final Fields MODEL_UPDATE_FIELDS = new Fields(ModelResource.FIELD_LIST,
|
||||
"owner,dashboard,tags");
|
||||
private static final Fields MODEL_PATCH_FIELDS = new Fields(ModelResource.FIELD_LIST,
|
||||
@ -73,6 +81,9 @@ public abstract class ModelRepository {
|
||||
@CreateSqlObject
|
||||
abstract UsageDAO usageDAO();
|
||||
|
||||
@CreateSqlObject
|
||||
abstract DashboardDAO dashboardDAO();
|
||||
|
||||
@CreateSqlObject
|
||||
abstract TagRepository.TagDAO tagDAO();
|
||||
|
||||
@ -131,30 +142,20 @@ public abstract class ModelRepository {
|
||||
}
|
||||
|
||||
@Transaction
|
||||
public PutResponse<Model> createOrUpdate(Model updatedModel,
|
||||
EntityReference newOwner) throws IOException {
|
||||
String fqn = getFQN(updatedModel);
|
||||
Model storedModel = JsonUtils.readValue(modelDAO().findByFQN(fqn), Model.class);
|
||||
if (storedModel == null) {
|
||||
return new PutResponse<>(Status.CREATED, createInternal(updatedModel, newOwner));
|
||||
}
|
||||
// Update existing model
|
||||
EntityUtil.populateOwner(userDAO(), teamDAO(), newOwner); // Validate new owner
|
||||
if (storedModel.getDescription() == null || storedModel.getDescription().isEmpty()) {
|
||||
storedModel.withDescription(updatedModel.getDescription());
|
||||
}
|
||||
//update the display name from source
|
||||
if (updatedModel.getDisplayName() != null && !updatedModel.getDisplayName().isEmpty()) {
|
||||
storedModel.withDisplayName(updatedModel.getDisplayName());
|
||||
public PutResponse<Model> createOrUpdate(Model updated, EntityReference newOwner) throws IOException {
|
||||
String fqn = getFQN(updated);
|
||||
Model stored = JsonUtils.readValue(modelDAO().findByFQN(fqn), Model.class);
|
||||
if (stored == null) {
|
||||
return new PutResponse<>(Status.CREATED, createInternal(updated, newOwner));
|
||||
}
|
||||
setFields(stored, MODEL_UPDATE_FIELDS);
|
||||
updated.setId(stored.getId());
|
||||
validateRelationships(updated, newOwner);
|
||||
|
||||
modelDAO().update(storedModel.getId().toString(), JsonUtils.pojoToJson(storedModel));
|
||||
|
||||
// Update owner relationship
|
||||
setFields(storedModel, MODEL_UPDATE_FIELDS); // First get the ownership information
|
||||
updateOwner(storedModel, storedModel.getOwner(), newOwner);
|
||||
|
||||
return new PutResponse<>(Status.OK, storedModel);
|
||||
ModelUpdater modelUpdater = new ModelUpdater(stored, updated, false);
|
||||
modelUpdater.updateAll();
|
||||
modelUpdater.store();
|
||||
return new PutResponse<>(Status.OK, updated);
|
||||
}
|
||||
|
||||
@Transaction
|
||||
@ -202,6 +203,7 @@ public abstract class ModelRepository {
|
||||
private Model setFields(Model model, Fields fields) throws IOException {
|
||||
model.setDisplayName(model.getDisplayName());
|
||||
model.setOwner(fields.contains("owner") ? getOwner(model) : null);
|
||||
model.setDashboard(fields.contains("dashboard") ? getDashboard(model) : null);
|
||||
model.setFollowers(fields.contains("followers") ? getFollowers(model) : null);
|
||||
model.setTags(fields.contains("tags") ? getTags(model.getFullyQualifiedName()) : null);
|
||||
model.setUsageSummary(fields.contains("usageSummary") ? EntityUtil.getLatestUsage(usageDAO(),
|
||||
@ -216,35 +218,56 @@ public abstract class ModelRepository {
|
||||
|
||||
private Model createInternal(Model model, EntityReference owner)
|
||||
throws IOException {
|
||||
String fqn = model.getName();
|
||||
model.setFullyQualifiedName(fqn);
|
||||
|
||||
EntityUtil.populateOwner(userDAO(), teamDAO(), owner); // Validate owner
|
||||
|
||||
modelDAO().insert(JsonUtils.pojoToJson(model));
|
||||
validateRelationships(model, owner);
|
||||
storeModel(model, false);
|
||||
addRelationships(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
private void validateRelationships(Model model, EntityReference owner) throws IOException {
|
||||
model.setFullyQualifiedName(getFQN(model));
|
||||
EntityUtil.populateOwner(userDAO(), teamDAO(), owner); // Validate owner
|
||||
if (model.getDashboard() != null) {
|
||||
String dashboardId = model.getDashboard().getId().toString();
|
||||
model.setDashboard(EntityUtil.getEntityReference(
|
||||
EntityUtil.validate(dashboardId, dashboardDAO().findById(dashboardId), Dashboard.class)));
|
||||
}
|
||||
model.setTags(EntityUtil.addDerivedTags(tagDAO(), model.getTags()));
|
||||
}
|
||||
|
||||
private void addRelationships(Model model) throws IOException {
|
||||
setOwner(model, model.getOwner());
|
||||
setDashboard(model, model.getDashboard());
|
||||
applyTags(model);
|
||||
}
|
||||
|
||||
private void storeModel(Model model, boolean update) throws JsonProcessingException {
|
||||
// Relationships and fields such as href are derived and not stored as part of json
|
||||
EntityReference owner = model.getOwner();
|
||||
List<TagLabel> tags = model.getTags();
|
||||
EntityReference dashboard = model.getDashboard();
|
||||
|
||||
// Don't store owner, dashboard, href and tags as JSON. Build it on the fly based on relationships
|
||||
model.withOwner(null).withDashboard(null).withHref(null).withTags(null);
|
||||
|
||||
if (update) {
|
||||
modelDAO().update(model.getId().toString(), JsonUtils.pojoToJson(model));
|
||||
} else {
|
||||
modelDAO().insert(JsonUtils.pojoToJson(model));
|
||||
}
|
||||
|
||||
// Restore the relationships
|
||||
model.withOwner(owner).withDashboard(dashboard).withTags(tags);
|
||||
}
|
||||
|
||||
private void patch(Model original, Model updated) throws IOException {
|
||||
String modelId = original.getId().toString();
|
||||
if (!original.getId().equals(updated.getId())) {
|
||||
throw new IllegalArgumentException(CatalogExceptionMessage.readOnlyAttribute(Entity.MODEL, "id"));
|
||||
}
|
||||
if (!original.getName().equals(updated.getName())) {
|
||||
throw new IllegalArgumentException(CatalogExceptionMessage.readOnlyAttribute(Entity.MODEL, "name"));
|
||||
}
|
||||
// Validate new owner
|
||||
EntityReference newOwner = EntityUtil.populateOwner(userDAO(), teamDAO(), updated.getOwner());
|
||||
|
||||
// Remove previous tags. Merge tags from the update and the existing tags
|
||||
EntityUtil.removeTags(tagDAO(), original.getFullyQualifiedName());
|
||||
|
||||
updated.setHref(null);
|
||||
updated.setOwner(null);
|
||||
modelDAO().update(modelId, JsonUtils.pojoToJson(updated));
|
||||
updateOwner(updated, original.getOwner(), newOwner);
|
||||
applyTags(updated);
|
||||
// Patch can't make changes to following fields. Ignore the changes
|
||||
updated.withFullyQualifiedName(original.getFullyQualifiedName()).withName(original.getName())
|
||||
.withId(original.getId());
|
||||
validateRelationships(updated, updated.getOwner());
|
||||
ModelRepository.ModelUpdater modelUpdater = new ModelRepository.ModelUpdater(original, updated, true);
|
||||
modelUpdater.updateAll();
|
||||
modelUpdater.store();
|
||||
}
|
||||
|
||||
private EntityReference getOwner(Model model) throws IOException {
|
||||
@ -257,9 +280,30 @@ public abstract class ModelRepository {
|
||||
model.setOwner(owner);
|
||||
}
|
||||
|
||||
private void updateOwner(Model model, EntityReference origOwner, EntityReference newOwner) {
|
||||
EntityUtil.updateOwner(relationshipDAO(), origOwner, newOwner, model.getId(), Entity.MODEL);
|
||||
model.setOwner(newOwner);
|
||||
private EntityReference getDashboard(Model model) throws IOException {
|
||||
if (model != null) {
|
||||
List<EntityReference> ids = relationshipDAO().findTo(model.getId().toString(), Relationship.USES.ordinal());
|
||||
if (ids.size() > 1) {
|
||||
LOG.warn("Possible database issues - multiple dashboards {} found for model {}", ids, model.getId());
|
||||
}
|
||||
if (!ids.isEmpty()) {
|
||||
String dashboardId = ids.get(0).getId().toString();
|
||||
return EntityUtil.getEntityReference(EntityUtil.validate(dashboardId, dashboardDAO().findById(dashboardId),
|
||||
Dashboard.class));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setDashboard(Model model, EntityReference dashboard) {
|
||||
if (dashboard != null) {
|
||||
relationshipDAO().insert(model.getId().toString(), model.getDashboard().getId().toString(),
|
||||
Entity.MODEL, Entity.DASHBOARD, Relationship.USES.ordinal());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeDashboard(Model model) {
|
||||
relationshipDAO().deleteFrom(model.getId().toString(), Relationship.USES.ordinal(), Entity.DASHBOARD);
|
||||
}
|
||||
|
||||
private void applyTags(Model model) throws IOException {
|
||||
@ -268,13 +312,6 @@ public abstract class ModelRepository {
|
||||
model.setTags(getTags(model.getFullyQualifiedName())); // Update tag to handle additional derived tags
|
||||
}
|
||||
|
||||
private void addRelationships(Model model) throws IOException {
|
||||
// Add owner relationship
|
||||
EntityUtil.setOwner(relationshipDAO(), model.getId(), Entity.MODEL, model.getOwner());
|
||||
// Add tag to model relationship
|
||||
applyTags(model);
|
||||
}
|
||||
|
||||
private List<EntityReference> getFollowers(Model model) throws IOException {
|
||||
return model == null ? null : EntityUtil.getFollowers(model.getId(), relationshipDAO(), userDAO());
|
||||
}
|
||||
@ -319,4 +356,99 @@ public abstract class ModelRepository {
|
||||
@SqlUpdate("DELETE FROM model_entity WHERE id = :id")
|
||||
int delete(@Bind("id") String id);
|
||||
}
|
||||
|
||||
static class ModelEntityInterface implements EntityInterface {
|
||||
private final Model model;
|
||||
|
||||
ModelEntityInterface(Model Model) {
|
||||
this.model = Model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getId() {
|
||||
return model.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return model.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return model.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityReference getOwner() {
|
||||
return model.getOwner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullyQualifiedName() {
|
||||
return model.getFullyQualifiedName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TagLabel> getTags() {
|
||||
return model.getTags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDescription(String description) {
|
||||
model.setDescription(description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDisplayName(String displayName) {
|
||||
model.setDisplayName(displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTags(List<TagLabel> tags) {
|
||||
model.setTags(tags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles entity updated from PUT and POST operation.
|
||||
*/
|
||||
public class ModelUpdater extends EntityUpdater {
|
||||
final Model orig;
|
||||
final Model updated;
|
||||
|
||||
public ModelUpdater(Model orig, Model updated, boolean patchOperation) {
|
||||
super(new ModelRepository.ModelEntityInterface(orig), new ModelRepository.ModelEntityInterface(updated), patchOperation, relationshipDAO(),
|
||||
tagDAO());
|
||||
this.orig = orig;
|
||||
this.updated = updated;
|
||||
}
|
||||
|
||||
public void updateAll() throws IOException {
|
||||
super.updateAll();
|
||||
updateAlgorithm();
|
||||
updateDashboard();
|
||||
}
|
||||
|
||||
private void updateAlgorithm() {
|
||||
update("algorithm", orig.getAlgorithm(), updated.getAlgorithm());
|
||||
}
|
||||
|
||||
private void updateDashboard() {
|
||||
// Remove existing dashboards
|
||||
removeDashboard(orig);
|
||||
|
||||
EntityReference origOwner = orig.getDashboard();
|
||||
EntityReference updatedOwner = updated.getDashboard();
|
||||
if (update("owner", origOwner == null ? null : origOwner.getId(),
|
||||
updatedOwner == null ? null : updatedOwner.getId())) {
|
||||
setDashboard(updated, updated.getDashboard());
|
||||
}
|
||||
}
|
||||
|
||||
public void store() throws IOException {
|
||||
updated.setVersion(getNewVersion(orig.getVersion()));
|
||||
storeModel(updated, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@ public enum Relationship {
|
||||
|
||||
// {Dashboard|Pipeline|Query} --- uses ---> Table
|
||||
// {User} --- uses ---> {Table|Dashboard|Query}
|
||||
// {Model} --- uses ---> {Dashboard}
|
||||
USES("uses"),
|
||||
|
||||
// {User|Team|Org} --- owns ---> {Table|Dashboard|Query}
|
||||
|
||||
@ -336,7 +336,7 @@ public class DashboardResourceTest extends CatalogApplicationTest {
|
||||
Dashboard dashboard = createAndCheckDashboard(request, adminAuthHeaders());
|
||||
//Update the table as Owner
|
||||
updateAndCheckDashboard(dashboard, request.withDisplayName(test.getDisplayName()).withDescription(null),
|
||||
OK, authHeaders(USER1.getEmail()), NO_CHANGE);
|
||||
OK, authHeaders(USER1.getEmail()), MINOR_UPDATE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -524,7 +524,6 @@ public class TableResourceTest extends CatalogApplicationTest {
|
||||
updatedColumns.remove(1);
|
||||
table = updateAndCheckTable(table, request.withColumns(updatedColumns), OK, adminAuthHeaders(), MAJOR_UPDATE);
|
||||
assertEquals(1, table.getColumns().size());
|
||||
validateTags(columns.get(0), table.getColumns().get(0));
|
||||
|
||||
// Ensure tag usage counts are updated to reflect removal of column c2
|
||||
assertEquals(tagCategoryUsageCount + 2, getTagCategoryUsageCount("user", userAuthHeaders()));
|
||||
|
||||
@ -26,15 +26,15 @@ import org.openmetadata.catalog.Entity;
|
||||
import org.openmetadata.catalog.api.data.CreateModel;
|
||||
import org.openmetadata.catalog.api.services.CreateDashboardService;
|
||||
import org.openmetadata.catalog.api.services.CreateDashboardService.DashboardServiceType;
|
||||
import org.openmetadata.catalog.entity.data.Model;
|
||||
import org.openmetadata.catalog.entity.data.Dashboard;
|
||||
import org.openmetadata.catalog.entity.data.Model;
|
||||
import org.openmetadata.catalog.entity.services.DashboardService;
|
||||
import org.openmetadata.catalog.entity.teams.Team;
|
||||
import org.openmetadata.catalog.entity.teams.User;
|
||||
import org.openmetadata.catalog.exception.CatalogExceptionMessage;
|
||||
import org.openmetadata.catalog.resources.dashboards.DashboardResourceTest;
|
||||
import org.openmetadata.catalog.resources.models.ModelResource.ModelList;
|
||||
import org.openmetadata.catalog.resources.services.DashboardServiceResourceTest;
|
||||
import org.openmetadata.catalog.resources.dashboards.DashboardResourceTest;
|
||||
import org.openmetadata.catalog.resources.tags.TagResourceTest;
|
||||
import org.openmetadata.catalog.resources.teams.TeamResourceTest;
|
||||
import org.openmetadata.catalog.resources.teams.UserResourceTest;
|
||||
@ -43,6 +43,7 @@ import org.openmetadata.catalog.type.TagLabel;
|
||||
import org.openmetadata.catalog.util.EntityUtil;
|
||||
import org.openmetadata.catalog.util.JsonUtils;
|
||||
import org.openmetadata.catalog.util.TestUtils;
|
||||
import org.openmetadata.catalog.util.TestUtils.UpdateType;
|
||||
import org.openmetadata.common.utils.JsonSchemaUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -70,6 +71,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.entityNotFound;
|
||||
import static org.openmetadata.catalog.exception.CatalogExceptionMessage.readOnlyAttribute;
|
||||
import static org.openmetadata.catalog.util.TestUtils.UpdateType.MINOR_UPDATE;
|
||||
import static org.openmetadata.catalog.util.TestUtils.UpdateType.NO_CHANGE;
|
||||
import static org.openmetadata.catalog.util.TestUtils.adminAuthHeaders;
|
||||
import static org.openmetadata.catalog.util.TestUtils.assertEntityPagination;
|
||||
import static org.openmetadata.catalog.util.TestUtils.assertResponse;
|
||||
@ -279,52 +282,50 @@ public class ModelResourceTest extends CatalogApplicationTest {
|
||||
public void put_ModelUpdateWithNoChange_200(TestInfo test) throws HttpResponseException {
|
||||
// Create a Model with POST
|
||||
CreateModel request = create(test).withOwner(USER_OWNER1);
|
||||
createAndCheckModel(request, adminAuthHeaders());
|
||||
Model model = createAndCheckModel(request, adminAuthHeaders());
|
||||
|
||||
// Update Model two times successfully with PUT requests
|
||||
updateAndCheckModel(request, OK, adminAuthHeaders());
|
||||
updateAndCheckModel(request, OK, adminAuthHeaders());
|
||||
model = updateAndCheckModel(model, request, OK, adminAuthHeaders(), NO_CHANGE);
|
||||
updateAndCheckModel(model, request, OK, adminAuthHeaders(), NO_CHANGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void put_ModelCreate_200(TestInfo test) throws HttpResponseException {
|
||||
// Create a new Model with put
|
||||
// Create a new Model with PUT
|
||||
CreateModel request = create(test).withOwner(USER_OWNER1);
|
||||
updateAndCheckModel(request.withName(test.getDisplayName()).withDescription(null), CREATED, adminAuthHeaders());
|
||||
updateAndCheckModel(null, request.withName(test.getDisplayName()).withDescription(null), CREATED,
|
||||
adminAuthHeaders(), NO_CHANGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void put_ModelCreate_as_owner_200(TestInfo test) throws HttpResponseException {
|
||||
// Create a new Model with put
|
||||
CreateModel request = create(test).withOwner(USER_OWNER1);
|
||||
// Add Owner as admin
|
||||
createAndCheckModel(request, adminAuthHeaders());
|
||||
//Update the table as Owner
|
||||
updateAndCheckModel(request.withName(test.getDisplayName()).withDescription(null),
|
||||
CREATED, authHeaders(USER1.getEmail()));
|
||||
// Add model as admin
|
||||
Model model = createAndCheckModel(request, adminAuthHeaders());
|
||||
// Update the table as Owner
|
||||
updateAndCheckModel(model, request, OK, authHeaders(USER1.getEmail()), NO_CHANGE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void put_ModelNullDescriptionUpdate_200(TestInfo test) throws HttpResponseException {
|
||||
CreateModel request = create(test).withDescription(null);
|
||||
createAndCheckModel(request, adminAuthHeaders());
|
||||
Model model = createAndCheckModel(request, adminAuthHeaders());
|
||||
|
||||
// Update null description with a new description
|
||||
Model db = updateAndCheckModel(request.withDisplayName("model1").
|
||||
withDescription("newDescription"), OK, adminAuthHeaders());
|
||||
assertEquals("newDescription", db.getDescription());
|
||||
assertEquals("model1", db.getDisplayName());
|
||||
Model db = updateAndCheckModel(model, request.withDisplayName("model1").
|
||||
withDescription("newDescription"), OK, adminAuthHeaders(), MINOR_UPDATE);
|
||||
assertEquals("model1", db.getDisplayName()); // Move this check to validate method
|
||||
}
|
||||
|
||||
@Test
|
||||
public void put_ModelEmptyDescriptionUpdate_200(TestInfo test) throws HttpResponseException {
|
||||
// Create table with empty description
|
||||
CreateModel request = create(test).withDescription("");
|
||||
createAndCheckModel(request, adminAuthHeaders());
|
||||
Model model = createAndCheckModel(request, adminAuthHeaders());
|
||||
|
||||
// Update empty description with a new description
|
||||
Model db = updateAndCheckModel(request.withDescription("newDescription"), OK, adminAuthHeaders());
|
||||
assertEquals("newDescription", db.getDescription());
|
||||
updateAndCheckModel(model, request.withDescription("newDescription"), OK, adminAuthHeaders(), MINOR_UPDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -340,30 +341,28 @@ public class ModelResourceTest extends CatalogApplicationTest {
|
||||
@Test
|
||||
public void put_ModelUpdateOwner_200(TestInfo test) throws HttpResponseException {
|
||||
CreateModel request = create(test).withDescription("");
|
||||
createAndCheckModel(request, adminAuthHeaders());
|
||||
Model model = createAndCheckModel(request, adminAuthHeaders());
|
||||
|
||||
// Change ownership from USER_OWNER1 to TEAM_OWNER1
|
||||
updateAndCheckModel(request.withOwner(TEAM_OWNER1), OK, adminAuthHeaders());
|
||||
model = updateAndCheckModel(model, request.withOwner(TEAM_OWNER1), OK, adminAuthHeaders(), MINOR_UPDATE);
|
||||
|
||||
// Remove ownership
|
||||
Model db = updateAndCheckModel(request.withOwner(null), OK, adminAuthHeaders());
|
||||
assertNull(db.getOwner());
|
||||
model = updateAndCheckModel(model, request.withOwner(null), OK, adminAuthHeaders(), MINOR_UPDATE);
|
||||
assertNull(model.getOwner());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void put_ModelUpdateAlgorithm_200(TestInfo test) throws HttpResponseException {
|
||||
CreateModel request = create(test).withDescription("");
|
||||
createAndCheckModel(request, adminAuthHeaders());
|
||||
|
||||
updateAndCheckModel(request.withAlgorithm("SVM"), OK, adminAuthHeaders());
|
||||
Model model = createAndCheckModel(request, adminAuthHeaders());
|
||||
updateAndCheckModel(model, request.withAlgorithm("SVM"), OK, adminAuthHeaders(), MINOR_UPDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void put_ModelUpdateDashboard_200(TestInfo test) throws HttpResponseException {
|
||||
CreateModel request = create(test).withDescription("");
|
||||
createAndCheckModel(request, adminAuthHeaders());
|
||||
|
||||
updateAndCheckModel(request.withDashboard(DASHBOARD_REFERENCE), OK, adminAuthHeaders());
|
||||
Model model = createAndCheckModel(request, adminAuthHeaders());
|
||||
updateAndCheckModel(model, request.withDashboard(DASHBOARD_REFERENCE), OK, adminAuthHeaders(), MINOR_UPDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -401,52 +400,18 @@ public class ModelResourceTest extends CatalogApplicationTest {
|
||||
List<TagLabel> modelTags = singletonList(TIER_1);
|
||||
|
||||
// Add description, owner when previously they were null
|
||||
model = patchModelAttributesAndCheck(model, "description",
|
||||
TEAM_OWNER1, modelTags, adminAuthHeaders());
|
||||
model = patchModelAttributesAndCheck(model, "description", TEAM_OWNER1, modelTags,
|
||||
adminAuthHeaders(), MINOR_UPDATE);
|
||||
model.setOwner(TEAM_OWNER1); // Get rid of href and name returned in the response for owner
|
||||
modelTags = singletonList(USER_ADDRESS_TAG_LABEL);
|
||||
|
||||
// Replace description, tier, owner
|
||||
model = patchModelAttributesAndCheck(model, "description1",
|
||||
USER_OWNER1, modelTags, adminAuthHeaders());
|
||||
model = patchModelAttributesAndCheck(model, "description1", USER_OWNER1, modelTags,
|
||||
adminAuthHeaders(), MINOR_UPDATE);
|
||||
model.setOwner(USER_OWNER1); // Get rid of href and name returned in the response for owner
|
||||
|
||||
// Remove description, tier, owner
|
||||
patchModelAttributesAndCheck(model, null, null, modelTags, adminAuthHeaders());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patch_ModelIDChange_400(TestInfo test) throws HttpResponseException, JsonProcessingException {
|
||||
// Ensure Model ID can't be changed using patch
|
||||
Model model = createModel(create(test), adminAuthHeaders());
|
||||
UUID modelId = model.getId();
|
||||
String modelJson = JsonUtils.pojoToJson(model);
|
||||
model.setId(UUID.randomUUID());
|
||||
HttpResponseException exception = assertThrows(HttpResponseException.class, () ->
|
||||
patchModel(modelId, modelJson, model, adminAuthHeaders()));
|
||||
assertResponse(exception, BAD_REQUEST, readOnlyAttribute(Entity.MODEL, "id"));
|
||||
|
||||
// ID can't be deleted
|
||||
model.setId(null);
|
||||
exception = assertThrows(HttpResponseException.class, () ->
|
||||
patchModel(modelId, modelJson, model, adminAuthHeaders()));
|
||||
assertResponse(exception, BAD_REQUEST, readOnlyAttribute(Entity.MODEL, "id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patch_ModelNameChange_400(TestInfo test) throws HttpResponseException, JsonProcessingException {
|
||||
// Ensure Model name can't be changed using patch
|
||||
Model model = createModel(create(test), adminAuthHeaders());
|
||||
String modelJson = JsonUtils.pojoToJson(model);
|
||||
model.setName("newName");
|
||||
HttpResponseException exception = assertThrows(HttpResponseException.class, () ->
|
||||
patchModel(modelJson, model, adminAuthHeaders()));
|
||||
assertResponse(exception, BAD_REQUEST, readOnlyAttribute(Entity.MODEL, "name"));
|
||||
|
||||
// Name can't be removed
|
||||
model.setName(null);
|
||||
exception = assertThrows(HttpResponseException.class, () ->
|
||||
patchModel(modelJson, model, adminAuthHeaders()));
|
||||
assertResponse(exception, BAD_REQUEST, readOnlyAttribute(Entity.MODEL, "name"));
|
||||
patchModelAttributesAndCheck(model, null, null, modelTags, adminAuthHeaders(), MINOR_UPDATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -485,12 +450,17 @@ public class ModelResourceTest extends CatalogApplicationTest {
|
||||
return getAndValidate(model.getId(), create, authHeaders, updatedBy);
|
||||
}
|
||||
|
||||
public static Model updateAndCheckModel(CreateModel create,
|
||||
Status status,
|
||||
Map<String, String> authHeaders) throws HttpResponseException {
|
||||
public static Model updateAndCheckModel(Model before, CreateModel create, Status status,
|
||||
Map<String, String> authHeaders, UpdateType updateType)
|
||||
throws HttpResponseException {
|
||||
String updatedBy = TestUtils.getPrincipal(authHeaders);
|
||||
Model updatedModel = updateModel(create, status, authHeaders);
|
||||
validateModel(updatedModel, create.getDescription(), create.getOwner(), updatedBy);
|
||||
if (before == null) {
|
||||
assertEquals(0.1, updatedModel.getVersion()); // First version created
|
||||
} else {
|
||||
TestUtils.validateUpdate(before.getVersion(), updatedModel.getVersion(), updateType);
|
||||
}
|
||||
|
||||
return getAndValidate(updatedModel.getId(), create, authHeaders, updatedBy);
|
||||
}
|
||||
@ -529,8 +499,8 @@ public class ModelResourceTest extends CatalogApplicationTest {
|
||||
model = byName ? getModelByName(model.getFullyQualifiedName(), fields, adminAuthHeaders()) :
|
||||
getModel(model.getId(), fields, adminAuthHeaders());
|
||||
assertNotNull(model.getOwner());
|
||||
assertNotNull(model.getAlgorithm());
|
||||
assertNotNull(model.getDashboard());
|
||||
assertNotNull(model.getAlgorithm()); // Provided as default field
|
||||
assertNull(model.getDashboard());
|
||||
|
||||
// .../models?fields=owner,algorithm
|
||||
fields = "owner,algorithm";
|
||||
@ -538,7 +508,7 @@ public class ModelResourceTest extends CatalogApplicationTest {
|
||||
getModel(model.getId(), fields, adminAuthHeaders());
|
||||
assertNotNull(model.getOwner());
|
||||
assertNotNull(model.getAlgorithm());
|
||||
assertNotNull(model.getDashboard());
|
||||
assertNull(model.getDashboard());
|
||||
|
||||
// .../models?fields=owner,algorithm, dashboard
|
||||
fields = "owner,algorithm,dashboard";
|
||||
@ -548,7 +518,6 @@ public class ModelResourceTest extends CatalogApplicationTest {
|
||||
assertNotNull(model.getAlgorithm());
|
||||
assertNotNull(model.getDashboard());
|
||||
TestUtils.validateEntityReference(model.getDashboard());
|
||||
|
||||
}
|
||||
|
||||
private static Model validateModel(Model model, String expectedDisplayName,
|
||||
@ -595,48 +564,30 @@ public class ModelResourceTest extends CatalogApplicationTest {
|
||||
assertNotNull(model.getOwner().getHref());
|
||||
}
|
||||
|
||||
validateTags(expectedTags, model.getTags());
|
||||
TestUtils.validateTags(model.getFullyQualifiedName(), expectedTags, model.getTags());
|
||||
return model;
|
||||
}
|
||||
|
||||
private static void validateTags(List<TagLabel> expectedList, List<TagLabel> actualList)
|
||||
throws HttpResponseException {
|
||||
if (expectedList == null) {
|
||||
return;
|
||||
}
|
||||
// When tags from the expected list is added to an entity, the derived tags for those tags are automatically added
|
||||
// So add to the expectedList, the derived tags before validating the tags
|
||||
List<TagLabel> updatedExpectedList = new ArrayList<>(expectedList);
|
||||
for (TagLabel expected : expectedList) {
|
||||
List<TagLabel> derived = EntityUtil.getDerivedTags(expected, TagResourceTest.getTag(expected.getTagFQN(),
|
||||
adminAuthHeaders()));
|
||||
updatedExpectedList.addAll(derived);
|
||||
}
|
||||
updatedExpectedList = updatedExpectedList.stream().distinct().collect(Collectors.toList());
|
||||
|
||||
assertTrue(actualList.containsAll(updatedExpectedList));
|
||||
assertTrue(updatedExpectedList.containsAll(actualList));
|
||||
}
|
||||
|
||||
private Model patchModelAttributesAndCheck(Model model, String newDescription,
|
||||
EntityReference newOwner, List<TagLabel> tags,
|
||||
Map<String, String> authHeaders)
|
||||
private Model patchModelAttributesAndCheck(Model before, String newDescription, EntityReference newOwner,
|
||||
List<TagLabel> tags, Map<String, String> authHeaders,
|
||||
UpdateType updateType)
|
||||
throws JsonProcessingException, HttpResponseException {
|
||||
String updatedBy = TestUtils.getPrincipal(authHeaders);
|
||||
String modelJson = JsonUtils.pojoToJson(model);
|
||||
String modelJson = JsonUtils.pojoToJson(before);
|
||||
|
||||
// Update the table attributes
|
||||
model.setDescription(newDescription);
|
||||
model.setOwner(newOwner);
|
||||
model.setTags(tags);
|
||||
before.setDescription(newDescription);
|
||||
before.setOwner(newOwner);
|
||||
before.setTags(tags);
|
||||
|
||||
// Validate information returned in patch response has the updates
|
||||
Model updatedModel = patchModel(modelJson, model, authHeaders);
|
||||
validateModel(updatedModel, model.getDescription(), newOwner, tags, updatedBy);
|
||||
Model updatedModel = patchModel(modelJson, before, authHeaders);
|
||||
validateModel(updatedModel, before.getDescription(), newOwner, tags, updatedBy);
|
||||
TestUtils.validateUpdate(before.getVersion(), updatedModel.getVersion(), updateType);
|
||||
|
||||
// GET the table and Validate information returned
|
||||
Model getModel = getModel(model.getId(), "owner,tags", authHeaders);
|
||||
validateModel(getModel, model.getDescription(), newOwner, tags, updatedBy);
|
||||
Model getModel = getModel(before.getId(), "owner,tags", authHeaders);
|
||||
validateModel(getModel, before.getDescription(), newOwner, tags, updatedBy);
|
||||
return updatedModel;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user