Example #1
0
 def __init__(self, **kwargs):
     super().__init__(**kwargs)
     self._entity_manager = BusinessEntityManager()
     self._logger = logging.getLogger(__name__)
     self._validator = JsonSchemaValidator()
     self._permission_classes = (IsAuthenticated,)
     self._permission_manager = PermissionManager()
    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 #3
0
class DeleteBusinessEntityView(APIView):

    _entity_manager = None

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

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

        body = ViewUtils.extract_body(request)
        key = body[Constants.KEY]
        if not self._validator.business_entity_exist(business_entity):
            return ViewUtils.business_entity_not_exist_response(business_entity)
        if Constants.VERSION not in body:
            return self._delete_all_versions(business_entity, key)

        return self._delete_from_version(body, business_entity, key)

    def _delete_all_versions(self, business_entity, key) -> Response:
        number_of_deleted_objects = self._entity_manager.delete_by_key(business_entity, key)

        message = (
            Constants.DELETE_ALL_VERSIONS_MESSAGE
            if number_of_deleted_objects > 0
            else Constants.DELETE_ALL_VERSIONS_MESSAGE_NOT_FOUND
        )

        return ViewUtils.custom_response(message.format(key), status.HTTP_200_OK)

    def _delete_from_version(self, body, business_entity, key) -> Response:
        version = body[Constants.VERSION]
        if not self._validator.version_exist(version, business_entity):
            return ViewUtils.custom_response(Constants.VERSION_NOT_EXIST.format(version), status.HTTP_400_BAD_REQUEST)
        number_of_deleted_objects = self._entity_manager.delete(business_entity, key, version)

        message = (
            Constants.DELETE_FROM_VERSION_MESSAGE
            if number_of_deleted_objects > 0
            else Constants.DELETE_FROM_VERSION_MESSAGE_NOT_FOUND
        )

        return ViewUtils.custom_response(message.format(key, version), status.HTTP_200_OK)
Example #4
0
class Command(BaseCommand):

    help = "publish all data from a business entity to the business entity channel/topic"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._entity_manager = BusinessEntityManager()
        self._logger = logging.getLogger(__name__)
        self._chunk_size = settings.DEFAULT_CHUNK_SIZE
        self._message_service = MessagePublisher()

    def add_arguments(self, parser):
        parser.add_argument(Constants.BUSINESS_ENTITY, type=str)
        parser.add_argument(Constants.CHUNK_SIZE,
                            type=int,
                            nargs="?",
                            default=settings.DEFAULT_CHUNK_SIZE)

    def handle(self, *args, **kwargs):
        self._chunk_size = kwargs[Constants.CHUNK_SIZE]
        business_entity = kwargs[Constants.BUSINESS_ENTITY]
        queryset = self._entity_manager.find_all(business_entity)
        tags = [Constants.FULL_EXPORT]

        for business_entity in queryset.iterator(chunk_size=self._chunk_size):
            self._message_service.send_entity_update_message(
                business_entity, tags)

        self._message_service.shutdown()
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)
Example #6
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)
Example #7
0
class ReadOnlyAdmin(admin.ModelAdmin):
    fields = ("key", "version", "data_prettified", "created", "modified")
    list_display = ["key", "version"]
    search_fields = ["key", "version"]

    _entity_manager = BusinessEntityManager()

    def has_view_permission(self, request, obj=None):
        if super().has_view_permission(request, obj):
            return True

        return request.user.has_perm("herbie_core.view_business_entities")

    def has_add_permission(self, request, obj=None):
        return False

    def has_change_permission(self, request, obj=None):
        return False

    def delete_model(self, request, entity):
        self._entity_manager.delete_by_instance(entity)

    def delete_queryset(self, request, queryset):
        self._entity_manager.delete_by_queryset(queryset)

    def data_prettified(self, model):
        json_data = json.dumps(model.data, sort_keys=True, indent=2)
        return mark_safe('<pre id="json-renderer" class="json-document">' +
                         json_data + "</pre>")

    data_prettified.short_description = "data"

    class Media:
        js = (settings.JSON_VIEWER.get("JS_URL"),
              settings.HERBIE_ADMIN.get("JS_URL"))
        css = {
            "all": (settings.JSON_VIEWER.get("CSS_URL"),
                    settings.HERBIE_ADMIN.get("CSS_URL"))
        }
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()
Example #10
0
 def __init__(self, **kwargs):
     super().__init__(**kwargs)
     self._entity_manager = BusinessEntityManager()
     self._logger = logging.getLogger(__name__)
     self._chunk_size = settings.DEFAULT_CHUNK_SIZE
     self._message_service = MessagePublisher()
 def setUp(self):
     self._entity_manager = BusinessEntityManager()
class BusinessEntityManagerTestCase(TestCase):
    def setUp(self):
        self._entity_manager = BusinessEntityManager()

    @mock.patch.object(MessagePublisher, "send_entity_create_message")
    @mock.patch.object(ManagerTestEntity, "objects")
    @mock.patch.object(BusinessEntityUtils,
                       "get_entity_class",
                       return_value=ManagerTestEntity)
    def test_create(self, mock_entity_utils, mock_objects,
                    mock_send_entity_create_message):
        mock_objects.update_or_create.return_value = (entity, True)
        created = self._entity_manager.update_or_create(
            entity_name, key, version, test_user, data)

        self.assertTrue(created)
        mock_objects.update_or_create.assert_called_once()
        mock_send_entity_create_message.assert_called_once_with(entity)

    @mock.patch.object(MessagePublisher, "send_entity_update_message")
    @mock.patch.object(ManagerTestEntity, "objects")
    @mock.patch.object(BusinessEntityUtils,
                       "get_entity_class",
                       return_value=ManagerTestEntity)
    def test_update(self, mock_entity_utils, mock_objects,
                    mock_send_entity_update_message):
        mock_objects.update_or_create.return_value = (entity, False)
        created = self._entity_manager.update_or_create(
            entity_name, key, version, test_user, data)

        self.assertFalse(created)
        mock_objects.update_or_create.assert_called_once()
        mock_send_entity_update_message.assert_called_once_with(entity)

    @mock.patch.object(MessagePublisher, "send_entity_delete_message")
    @mock.patch.object(QuerySet, "delete")
    @mock.patch.object(QuerySet, "all")
    @mock.patch.object(BusinessEntityUtils,
                       "get_entity_class",
                       return_value=ManagerTestEntity)
    def test_delete(self, mock_entity_utils, mock_queryset_all,
                    mock_queryset_delete, mock_send_entity_delete_message):
        mock_queryset_all.return_value = [entity]
        mock_queryset_delete.return_value = (1, {})
        delete_count = self._entity_manager.delete(entity_name, key, version)

        self.assertEqual(1, delete_count)
        mock_send_entity_delete_message.assert_called_once_with(entity)

    @mock.patch.object(MessagePublisher, "send_entity_delete_message")
    @mock.patch.object(QuerySet, "delete")
    @mock.patch.object(QuerySet, "all")
    @mock.patch.object(BusinessEntityUtils,
                       "get_entity_class",
                       return_value=ManagerTestEntity)
    def test_delete_by_key(self, mock_entity_utils, mock_queryset_all,
                           mock_queryset_delete,
                           mock_send_entity_delete_message):
        mock_queryset_all.return_value = [entity, entity]
        mock_queryset_delete.return_value = (2, {})
        delete_count = self._entity_manager.delete_by_key(entity_name, key)

        self.assertEqual(2, delete_count)
        mock_send_entity_delete_message.assert_has_calls(
            [call(entity), call(entity)])

    @mock.patch.object(ManagerTestEntity, "objects")
    @mock.patch.object(BusinessEntityUtils,
                       "get_entity_class",
                       return_value=ManagerTestEntity)
    def test_find_by_key_and_version(self, mock_entity_utils, mock_objects):
        mock_objects.get.return_value = entity

        entity_data = self._entity_manager.find_by_key_and_version(
            entity_name, key, version)

        self.assertEqual(entity_data, entity)

    @mock.patch.object(ManagerTestEntity, "objects")
    @mock.patch.object(BusinessEntityUtils,
                       "get_entity_class",
                       return_value=ManagerTestEntity)
    def test_find_by_key_and_version_returns_none_when_not_found(
            self, mock_entity_utils, mock_objects):
        mock_objects.get.side_effect = ManagerTestEntity.DoesNotExist

        self.assertIsNone(
            self._entity_manager.find_by_key_and_version(
                entity_name, "random", version))