in agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceValidator.java [104:371]
boolean isValid(RangerService service, Action action, List<ValidationFailureDetails> failures) {
LOG.debug("==> RangerServiceValidator.isValid({})", service);
if (!(action == Action.CREATE || action == Action.UPDATE)) {
throw new IllegalArgumentException("isValid(RangerService, ...) is only supported for CREATE/UPDATE");
}
boolean valid = true;
if (service == null) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_NULL_SERVICE_OBJECT;
failures.add(new ValidationFailureDetailsBuilder()
.field("service")
.isMissing()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage())
.build());
valid = false;
} else {
Long id = service.getId();
if (action == Action.UPDATE) { // id is ignored for CREATE
if (id == null) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_EMPTY_SERVICE_ID;
failures.add(new ValidationFailureDetailsBuilder()
.field("id")
.isMissing()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage())
.build());
valid = false;
} else if (getService(id) == null) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_INVALID_SERVICE_ID;
failures.add(new ValidationFailureDetailsBuilder()
.field("id")
.isSemanticallyIncorrect()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(id))
.build());
valid = false;
}
}
String name = service.getName();
boolean nameSpecified = StringUtils.isNotBlank(name);
RangerServiceDef serviceDef = null;
if (!nameSpecified) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_INVALID_SERVICE_NAME;
failures.add(new ValidationFailureDetailsBuilder()
.field("name")
.isMissing()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(name))
.build());
valid = false;
} else {
Pattern serviceNameRegex = SERVICE_NAME_VALIDATION_REGEX;
if (action == Action.UPDATE) {
RangerService rangerService = getService(service.getId());
if (rangerService != null && StringUtils.isNotBlank(rangerService.getName()) && rangerService.getName().contains(" ")) {
//RANGER-2808 Support for space in services created with space in earlier version
serviceNameRegex = LEGACY_SERVICE_NAME_VALIDATION_REGEX;
}
}
if (!isValidString(serviceNameRegex, name)) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_SPECIAL_CHARACTERS_SERVICE_NAME;
failures.add(new ValidationFailureDetailsBuilder()
.field("name")
.isSemanticallyIncorrect()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(name))
.build());
valid = false;
} else {
RangerService otherService = getService(name);
if (otherService != null && action == Action.CREATE) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_SERVICE_NAME_CONFICT;
failures.add(new ValidationFailureDetailsBuilder()
.field("name")
.isSemanticallyIncorrect()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(name))
.build());
valid = false;
} else if (otherService != null && otherService.getId() != null && !otherService.getId().equals(id)) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_ID_NAME_CONFLICT;
failures.add(new ValidationFailureDetailsBuilder()
.field("id/name")
.isSemanticallyIncorrect()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(name, otherService.getId()))
.build());
valid = false;
}
}
}
// Display name
String displayName = service.getDisplayName();
if (!isValidString(SERVICE_DISPLAY_NAME_VALIDATION_REGEX, displayName)) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_SPECIAL_CHARACTERS_SERVICE_DISPLAY_NAME;
failures.add(new ValidationFailureDetailsBuilder()
.field("displayName")
.isSemanticallyIncorrect()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(displayName))
.build());
valid = false;
} else {
RangerService otherService = getServiceByDisplayName(displayName);
if (otherService != null && action == Action.CREATE) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_SERVICE_DISPLAY_NAME_CONFICT;
failures.add(new ValidationFailureDetailsBuilder()
.field("displayName")
.isSemanticallyIncorrect()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(displayName, otherService.getName()))
.build());
valid = false;
} else if (otherService != null && otherService.getId() != null && !otherService.getId().equals(id)) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_SERVICE_DISPLAY_NAME_CONFICT;
failures.add(new ValidationFailureDetailsBuilder()
.field("id/displayName")
.isSemanticallyIncorrect()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(displayName, otherService.getName()))
.build());
valid = false;
}
}
String type = service.getType();
boolean typeSpecified = StringUtils.isNotBlank(type);
if (!typeSpecified) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_MISSING_SERVICE_DEF;
failures.add(new ValidationFailureDetailsBuilder()
.field("type")
.isMissing()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(type))
.build());
valid = false;
} else {
serviceDef = getServiceDef(type);
if (serviceDef == null) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_INVALID_SERVICE_DEF;
failures.add(new ValidationFailureDetailsBuilder()
.field("type")
.isSemanticallyIncorrect()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(type))
.build());
valid = false;
}
}
if (nameSpecified && serviceDef != null) {
// check if required parameters were specified
Set<String> reqiredParameters = getRequiredParameters(serviceDef);
Set<String> inputParameters = getServiceConfigParameters(service);
Set<String> missingParameters = Sets.difference(reqiredParameters, inputParameters);
if (!missingParameters.isEmpty()) {
ValidationErrorCode error = ValidationErrorCode.SERVICE_VALIDATION_ERR_REQUIRED_PARM_MISSING;
failures.add(new ValidationFailureDetailsBuilder()
.field("configuration")
.subField(missingParameters.iterator().next()) // we return any one parameter!
.isMissing()
.errorCode(error.getErrorCode())
.becauseOf(error.getMessage(missingParameters))
.build());
valid = false;
}
}
String tagServiceName = service.getTagService();
if (StringUtils.isNotBlank(tagServiceName) && StringUtils.equals(type, EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME)) {
failures.add(new ValidationFailureDetailsBuilder()
.field("tag_service")
.isSemanticallyIncorrect()
.becauseOf("tag service cannot be part of a tag service")
.build());
valid = false;
}
if (StringUtils.isNotBlank(tagServiceName) && StringUtils.equals(type, EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_GDS_NAME)) {
failures.add(new ValidationFailureDetailsBuilder()
.field("tag_service")
.isSemanticallyIncorrect()
.becauseOf("gds service cannot be linked to a tag service")
.build());
valid = false;
}
boolean needToEnsureServiceType = false;
if (action == Action.UPDATE) {
RangerService otherService = getService(name);
String otherTagServiceName = otherService == null ? null : otherService.getTagService();
if (StringUtils.isNotBlank(tagServiceName)) {
if (!StringUtils.equals(tagServiceName, otherTagServiceName)) {
needToEnsureServiceType = true;
}
}
} else { // action == Action.CREATE
if (StringUtils.isNotBlank(tagServiceName)) {
needToEnsureServiceType = true;
}
}
if (needToEnsureServiceType) {
RangerService maybeTagService = getService(tagServiceName);
if (maybeTagService == null || !StringUtils.equals(maybeTagService.getType(), EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_TAG_NAME)) {
failures.add(new ValidationFailureDetailsBuilder()
.field("tag_service")
.isSemanticallyIncorrect()
.becauseOf("tag service name does not refer to existing tag service:" + tagServiceName)
.build());
valid = false;
}
}
}
LOG.debug("<== RangerServiceValidator.isValid({}): {}", service, valid);
return valid;
}