mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-01 19:18:05 +00:00
This commit is contained in:
parent
00934279c6
commit
0d119de96e
@ -53,6 +53,7 @@ import org.openmetadata.service.jdbi3.EntityRepository;
|
||||
import org.openmetadata.service.util.EntityUtil;
|
||||
import org.openmetadata.service.util.JsonUtils;
|
||||
import org.openmetadata.service.util.RestUtil.PutResponse;
|
||||
import org.openmetadata.service.util.ValidatorUtil;
|
||||
|
||||
/**
|
||||
* EntityCsv provides export and import capabilities for an entity. Each entity must implement the abstract methods to
|
||||
@ -345,6 +346,12 @@ public abstract class EntityCsv<T extends EntityInterface> {
|
||||
if (Boolean.FALSE.equals(importResult.getDryRun())) {
|
||||
try {
|
||||
repository.prepareInternal(entity);
|
||||
String violations = ValidatorUtil.validate(entity);
|
||||
if (violations != null) {
|
||||
// JSON schema based validation failed for the entity
|
||||
importFailure(resultsPrinter, violations, csvRecord);
|
||||
return;
|
||||
}
|
||||
PutResponse<T> response = repository.createOrUpdate(null, entity);
|
||||
responseStatus = response.getStatus();
|
||||
} catch (Exception ex) {
|
||||
|
||||
@ -1017,7 +1017,7 @@ public class UserResource extends EntityResource<User, UserRepository> {
|
||||
try {
|
||||
decodedBytes = Base64.getDecoder().decode(loginRequest.getPassword());
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalArgumentException("Password need to be encoded in Base-64.");
|
||||
throw new IllegalArgumentException("Password needs to be encoded in Base-64.");
|
||||
}
|
||||
loginRequest.withPassword(new String(decodedBytes));
|
||||
return Response.status(Response.Status.OK).entity(authHandler.loginUser(loginRequest)).build();
|
||||
|
||||
@ -66,8 +66,6 @@ public final class EntityUtil {
|
||||
//
|
||||
// Comparators used for sorting list based on the given type
|
||||
//
|
||||
|
||||
// Note ordering is same as server side ordering by ID as string to ensure PATCH operations work
|
||||
public static final Comparator<EntityReference> compareEntityReference =
|
||||
Comparator.comparing(EntityReference::getName);
|
||||
public static final Comparator<EntityVersionPair> compareVersion =
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package org.openmetadata.service.util;
|
||||
|
||||
import io.dropwizard.jersey.validation.DropwizardConfiguredValidator;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.ValidatorFactory;
|
||||
|
||||
public class ValidatorUtil {
|
||||
public static final javax.validation.Validator VALIDATOR;
|
||||
|
||||
static {
|
||||
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||
VALIDATOR = new DropwizardConfiguredValidator(factory.getValidator());
|
||||
}
|
||||
|
||||
private ValidatorUtil() {
|
||||
// Private constructor for a utility class
|
||||
}
|
||||
|
||||
public static <T> String validate(T entity) {
|
||||
Set<ConstraintViolation<T>> violations = VALIDATOR.validate(entity);
|
||||
String ret =
|
||||
violations.isEmpty()
|
||||
? null
|
||||
: Arrays.toString(
|
||||
violations.stream().map(v -> String.format("%s %s", v.getPropertyPath(), v.getMessage())).toArray());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -335,13 +335,21 @@ public class GlossaryResourceTest extends EntityResourceTest<Glossary, CreateGlo
|
||||
String glossaryName = "invalidCsv";
|
||||
createEntity(createRequest(glossaryName), ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Create glossaryTerm with invalid parent
|
||||
// Create glossaryTerm with invalid name (due to ::)
|
||||
String resultsHeader = recordToString(EntityCsv.getResultHeaders(GlossaryCsv.HEADERS));
|
||||
String record = "invalidParent,g1,dsp1,dsc1,h1;h2;h3,,term1;http://term1,Tier.Tier1,,,";
|
||||
String record = ",g::1,dsp1,dsc1,,,,,,,";
|
||||
String csv = createCsv(GlossaryCsv.HEADERS, listOf(record), null);
|
||||
CsvImportResult result = importCsv(glossaryName, csv, false);
|
||||
assertSummary(result, CsvImportResult.Status.FAILURE, 2, 1, 1);
|
||||
String[] expectedRows = {resultsHeader, getFailedRecord(record, entityNotFound(0, "invalidParent"))};
|
||||
String[] expectedRows = {resultsHeader, getFailedRecord(record, "[name must match \"\"^(?U)[\\w'\\- .&()]+$\"\"]")};
|
||||
assertRows(result, expectedRows);
|
||||
|
||||
// Create glossaryTerm with invalid parent
|
||||
record = "invalidParent,g1,dsp1,dsc1,h1;h2;h3,,term1;http://term1,Tier.Tier1,,,";
|
||||
csv = createCsv(GlossaryCsv.HEADERS, listOf(record), null);
|
||||
result = importCsv(glossaryName, csv, false);
|
||||
assertSummary(result, CsvImportResult.Status.FAILURE, 2, 1, 1);
|
||||
expectedRows = new String[] {resultsHeader, getFailedRecord(record, entityNotFound(0, "invalidParent"))};
|
||||
assertRows(result, expectedRows);
|
||||
|
||||
// Create glossaryTerm with invalid tags field
|
||||
|
||||
@ -963,13 +963,22 @@ public class UserResourceTest extends EntityResourceTest<User, CreateUser> {
|
||||
// Headers - name,displayName,description,email,timezone,isAdmin,teams,roles
|
||||
Team team = TEAM_TEST.createEntity(TEAM_TEST.createRequest("team-invalidCsv"), ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Invalid team
|
||||
// Invalid user name with "::"
|
||||
String resultsHeader = recordToString(EntityCsv.getResultHeaders(UserCsv.HEADERS));
|
||||
String record = "user,,,user@domain.com,,,invalidTeam,";
|
||||
String record = "invalid::User,,,user@domain.com,,,team-invalidCsv,";
|
||||
String csv = createCsv(UserCsv.HEADERS, listOf(record), null);
|
||||
CsvImportResult result = importCsv(team.getName(), csv, false);
|
||||
assertSummary(result, CsvImportResult.Status.FAILURE, 2, 1, 1);
|
||||
String[] expectedRows = {resultsHeader, getFailedRecord(record, EntityCsv.entityNotFound(6, "invalidTeam"))};
|
||||
String[] expectedRows = {resultsHeader, getFailedRecord(record, "[name must match \"\"^(?U)[\\w\\-.]+$\"\"]")};
|
||||
assertRows(result, expectedRows);
|
||||
|
||||
// Invalid team
|
||||
resultsHeader = recordToString(EntityCsv.getResultHeaders(UserCsv.HEADERS));
|
||||
record = "user,,,user@domain.com,,,invalidTeam,";
|
||||
csv = createCsv(UserCsv.HEADERS, listOf(record), null);
|
||||
result = importCsv(team.getName(), csv, false);
|
||||
assertSummary(result, CsvImportResult.Status.FAILURE, 2, 1, 1);
|
||||
expectedRows = new String[] {resultsHeader, getFailedRecord(record, EntityCsv.entityNotFound(6, "invalidTeam"))};
|
||||
assertRows(result, expectedRows);
|
||||
|
||||
// Invalid roles
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package org.openmetadata.service.util;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openmetadata.schema.entity.data.Glossary;
|
||||
|
||||
class ValidatorUtilTest {
|
||||
@Test
|
||||
void testValidator() {
|
||||
// Required parameters name, description, and id missing
|
||||
Glossary glossary = new Glossary().withName("name").withDescription("description");
|
||||
assertEquals("[id must not be null]", ValidatorUtil.validate(glossary));
|
||||
|
||||
glossary.withId(UUID.randomUUID()).withName(null);
|
||||
assertEquals("[name must not be null]", ValidatorUtil.validate(glossary));
|
||||
|
||||
glossary.withName("name").withDescription(null);
|
||||
assertEquals("[description must not be null]", ValidatorUtil.validate(glossary));
|
||||
|
||||
// Invalid name
|
||||
glossary.withName("invalid::Name").withDescription("description");
|
||||
assertEquals("[name must match \"^(?U)[\\w'\\- .&()]+$\"]", ValidatorUtil.validate(glossary));
|
||||
|
||||
// No error
|
||||
glossary.withName("validName").withId(UUID.randomUUID()).withDescription("description");
|
||||
assertNull(ValidatorUtil.validate(glossary));
|
||||
}
|
||||
}
|
||||
@ -42,6 +42,6 @@
|
||||
"default": null
|
||||
}
|
||||
},
|
||||
"required": ["id", "name", "description", "domain","href"],
|
||||
"required": ["id", "name", "description", "domain"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
||||
@ -45,6 +45,6 @@
|
||||
"default": null
|
||||
}
|
||||
},
|
||||
"required": ["id", "name", "description", "domainType","href"],
|
||||
"required": ["id", "name", "description", "domainType"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
||||
@ -61,6 +61,6 @@
|
||||
"$ref": "../../type/entityHistory.json#/definitions/changeDescription"
|
||||
}
|
||||
},
|
||||
"required": ["id", "name", "description", "domain", "href"],
|
||||
"required": ["id", "name", "description", "domain"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
||||
@ -80,6 +80,6 @@
|
||||
"$ref": "../../type/entityHistory.json#/definitions/changeDescription"
|
||||
}
|
||||
},
|
||||
"required": ["id", "name", "description", "domainType, ","href"],
|
||||
"required": ["id", "name", "description", "domainType"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
||||
@ -129,6 +129,6 @@
|
||||
"$ref": "../../type/entityReference.json"
|
||||
}
|
||||
},
|
||||
"required": ["id", "name", "href"],
|
||||
"required": ["id", "name"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
||||
@ -139,5 +139,5 @@
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "name", "email", "href"]
|
||||
"required": ["id", "name", "email"]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user