def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self._entity_manager = BusinessEntityManager()
        self._permission_classes = (IsAuthenticated, )
        self._permission_manager = PermissionManager()
        self._validator = JsonSchemaValidator()
        self._schema_registry = SchemaRegistry()
Example #2
0
    def _save_json_schema(self, business_entity: str, version: str, data: str):
        schema = Schema.objects.filter(name=business_entity, version=version)

        reg = SchemaRegistry()
        reg.find_schema(business_entity, version)

        schema_data = json.loads(data) if data != "" else {}

        if not schema.exists():
            self._create_json_schema(business_entity=business_entity,
                                     version=version,
                                     data=schema_data)
        else:
            self._update_json_schema(schema=schema,
                                     business_entity=business_entity,
                                     version=version,
                                     data=schema_data)
Example #3
0
class JsonSchemaValidator:
    def __init__(self):
        self._schema_registry = SchemaRegistry()

    def validate_schema(self, schema: str, json_data: json) -> json:
        data_validated = Draft7Validator(schema, format_checker=draft7_format_checker)
        sorted_errors = sorted(data_validated.iter_errors(json_data), key=lambda e: e.path)

        errors = {}

        for error in sorted_errors:
            if error.validator == ValidatorResponseConstants.REQUIRED_KEY:
                error_property = re.search("'(.+?)'", error.message)
                if error_property:
                    errors[error_property.group(1)] = {
                        ValidatorResponseConstants.ERROR_MESSAGE: error.message,
                        ValidatorResponseConstants.VALIDATE_KEY: error.validator,
                    }
            elif error.validator == ValidatorResponseConstants.ADDITIONAL_PROPERTIES:
                errors[error.validator] = {
                    ValidatorResponseConstants.ERROR_MESSAGE: error.message,
                    ValidatorResponseConstants.VALIDATE_KEY: error.validator,
                }
            else:
                for error_property in error.path:
                    errors[error_property] = {
                        ValidatorResponseConstants.ERROR_MESSAGE: error.message,
                        ValidatorResponseConstants.VALIDATE_KEY: error.validator_value,
                    }

        return errors

    def business_entity_exist(self, business_entity: str) -> bool:
        business_entity_names = self._schema_registry.get_all_schema_names()

        return business_entity in business_entity_names

    def version_exist(self, version: str, business_entity: str) -> bool:
        versions = self._schema_registry.get_all_versions(business_entity)

        return version in versions
Example #4
0
class SaveBusinessEntityView(APIView):
    _entity_manager = None

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._entity_manager = BusinessEntityManager()
        self._logger = logging.getLogger(__name__)
        self._validator = JsonSchemaValidator()
        self._schema_registry = SchemaRegistry()
        self._permission_classes = (IsAuthenticated,)
        self._permission_manager = PermissionManager()

    def post(self, request: Request, business_entity: str) -> Response:
        if not self._validator.business_entity_exist(business_entity):
            return ViewUtils.business_entity_not_exist_response(business_entity)
        if not self._permission_manager.has_save_permission(business_entity, request):
            return ViewUtils.unauthorized_response()

        body = ViewUtils.extract_body(request)

        if Constants.VERSION not in body:
            return ViewUtils.custom_response(Constants.VERSION_MISSING, status.HTTP_400_BAD_REQUEST)

        version = body[Constants.VERSION]

        if not self._validator.version_exist(version=version, business_entity=business_entity):
            return ViewUtils.business_entity_version_not_exist_response(version)

        key = body[Constants.KEY]
        payload = body[Constants.PAYLOAD]

        schema = self._get_json_schema(business_entity=business_entity, version=version)

        error_messages = self._validator.validate_schema(schema, payload)

        if error_messages:
            return ViewUtils.custom_response(error_messages, status.HTTP_400_BAD_REQUEST)

        created = self._entity_manager.update_or_create(business_entity, key, version, request.user, payload)

        return self._create_response(created, key, version)

    def _create_response(self, created, key, version):
        if created:
            return ViewUtils.custom_response(Constants.SAVE_MESSAGE.format(key, version), status.HTTP_201_CREATED)

        return ViewUtils.custom_response(Constants.UPDATE_MESSAGE.format(key, version), status.HTTP_200_OK)

    def _get_json_schema(self, business_entity, version) -> json:
        return self._schema_registry.find_schema(business_entity, version)
class UpdateBusinessEntityView(APIView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self._entity_manager = BusinessEntityManager()
        self._permission_classes = (IsAuthenticated, )
        self._permission_manager = PermissionManager()
        self._validator = JsonSchemaValidator()
        self._schema_registry = SchemaRegistry()

    def patch(self, request: Request, business_entity: str, key: str,
              version: str):
        entity = self._entity_manager.find_by_key_and_version(
            business_entity, key, version)

        if entity is None:
            return ViewUtils.custom_response(
                f"Entity {business_entity} not found for Key: {key} / Version: {version}",
                status.HTTP_422_UNPROCESSABLE_ENTITY,
            )

        body = ViewUtils.extract_body(request)
        entity_dict = self._update_fields(entity, body)

        schema = self._get_json_schema(business_entity=business_entity,
                                       version=version)

        error_messages = self._validator.validate_schema(schema, entity_dict)

        if error_messages:
            return ViewUtils.custom_response(error_messages,
                                             status.HTTP_400_BAD_REQUEST)

        self._entity_manager.update_or_create(business_entity, key, version,
                                              request.user, entity_dict)

        return ViewUtils.custom_response(
            Constants.UPDATE_MESSAGE.format(key, version), status.HTTP_200_OK)

    def _update_fields(self, entity: AbstractBusinessEntity,
                       payload_data: dict):
        return {**entity.data, **payload_data}

    def _get_json_schema(self, business_entity, version) -> json:
        return self._schema_registry.find_schema(business_entity, version)
class SchemaVersionCompatibility:
    def __init__(self):
        self._schema_validator = JsonSchemaValidator()
        self._logger = logging.getLogger(__name__)
        self._mock_data_generator = SchemaMockDataGenerator()
        self._schema_registry = SchemaRegistry()

    def is_backwards_compatible(self, new_schema: dict, business_entity: str,
                                version: str):
        new_schema_mock_data = self._mock_data_generator.mock_data_from_schema(
            new_schema)
        current_schema_version = self._schema_registry.find_schema(
            business_entity=business_entity, version=version)

        errors = self._schema_validator.validate_schema(
            schema=current_schema_version, json_data=new_schema_mock_data)

        if errors:
            self._logger.info(f"Error validating new Schema: {errors}")
            return False

        return True
class GetBusinessEntityDataView(APIView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._entity_manager = BusinessEntityManager()
        self._schema_registry = SchemaRegistry()

    def get(self,
            request: Request,
            business_entity: str,
            key: str,
            version: str = None) -> Response:
        version = self._get_latest_version_when_none(business_entity, version)

        if version is None:
            return ViewUtils.custom_response(
                f"Schema {business_entity} not found",
                status.HTTP_422_UNPROCESSABLE_ENTITY)

        business_entity_data = self._entity_manager.find_by_key_and_version(
            business_entity, key, version)

        if business_entity_data is None:
            return ViewUtils.custom_response(
                f"Entity {business_entity} not found for Key: {key} / Version: {version}",
                status.HTTP_422_UNPROCESSABLE_ENTITY,
            )

        serializer = BusinessEntitySerializer(business_entity_data)

        return Response(serializer.data, status=status.HTTP_200_OK)

    def _get_latest_version_when_none(self,
                                      business_entity: str,
                                      version: str = None) -> Optional[str]:
        if version is not None:
            return version

        return self._schema_registry.get_schema_latest_version(business_entity)
 def __init__(self, **kwargs):
     super().__init__(**kwargs)
     self._entity_manager = BusinessEntityManager()
     self._schema_registry = SchemaRegistry()
 def __init__(self):
     self._schema_validator = JsonSchemaValidator()
     self._logger = logging.getLogger(__name__)
     self._mock_data_generator = SchemaMockDataGenerator()
     self._schema_registry = SchemaRegistry()
Example #10
0
 def __init__(self):
     self._schema_registry = SchemaRegistry()