boolean isValid()

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;
    }