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()
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)
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)
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 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()
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))