@mondart/nestjs-common-module 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +25 -0
- package/.github/workflows/npm-publish.yml +34 -0
- package/.prettierrc +4 -0
- package/common/caching/caching.module.ts +28 -0
- package/common/caching/caching.service.ts +34 -0
- package/common/caching/index.ts +2 -0
- package/common/constants/index.ts +1 -0
- package/common/constants/validation-constraints.const.ts +14 -0
- package/common/controllers/core-crud.controller.ts +106 -0
- package/common/controllers/index.ts +1 -0
- package/common/decorators/entity-order.decorator.ts +19 -0
- package/common/decorators/index.ts +2 -0
- package/common/decorators/swagger-api-response.decorator.ts +30 -0
- package/common/decorators/validations/default/array-max-size.decorator.ts +9 -0
- package/common/decorators/validations/default/array-min-size.decorator.ts +9 -0
- package/common/decorators/validations/default/array-not-empty.decorator.ts +7 -0
- package/common/decorators/validations/default/index.ts +20 -0
- package/common/decorators/validations/default/is-array.decorator.ts +7 -0
- package/common/decorators/validations/default/is-boolean.decorator.ts +10 -0
- package/common/decorators/validations/default/is-date.decorator.ts +10 -0
- package/common/decorators/validations/default/is-enum.decorator.ts +9 -0
- package/common/decorators/validations/default/is-int.decorator.ts +10 -0
- package/common/decorators/validations/default/is-not-empty-object.decorator.ts +15 -0
- package/common/decorators/validations/default/is-not-empty.decorator.ts +7 -0
- package/common/decorators/validations/default/is-number-string.decorator.ts +12 -0
- package/common/decorators/validations/default/is-object.decorator.ts +7 -0
- package/common/decorators/validations/default/is-positive.decorator.ts +10 -0
- package/common/decorators/validations/default/is-string.decorator.ts +8 -0
- package/common/decorators/validations/default/is-uuid.decorator.ts +7 -0
- package/common/decorators/validations/default/matches.decorator.ts +13 -0
- package/common/decorators/validations/default/max-length.decorator.ts +9 -0
- package/common/decorators/validations/default/max.decorator.ts +13 -0
- package/common/decorators/validations/default/min-length.decorator.ts +9 -0
- package/common/decorators/validations/default/min.decorator.ts +13 -0
- package/common/decorators/validations/index.ts +3 -0
- package/common/decorators/validations/is-id.decorator.ts +20 -0
- package/common/decorators/validations/is-not-empty-string.decorator.ts +14 -0
- package/common/dto/index.ts +2 -0
- package/common/dto/request/base-request.dto.ts +11 -0
- package/common/dto/request/event.dto.ts +25 -0
- package/common/dto/request/id.dto.ts +10 -0
- package/common/dto/request/ids.dto.ts +13 -0
- package/common/dto/request/index.ts +4 -0
- package/common/dto/response/base-response-with-action-dates.dto.ts +19 -0
- package/common/dto/response/base-response.dto.ts +10 -0
- package/common/dto/response/error-response.dto.ts +22 -0
- package/common/dto/response/index.ts +5 -0
- package/common/dto/response/kafka-success-response.dto.ts +56 -0
- package/common/dto/response/success-response.dto.ts +32 -0
- package/common/dto/response/validation.dto.ts +80 -0
- package/common/entities/action-dates.entity.ts +30 -0
- package/common/entities/base.entity.ts +7 -0
- package/common/entities/index.ts +2 -0
- package/common/entities/parent.entity.ts +35 -0
- package/common/enums/environments.enum.ts +6 -0
- package/common/enums/index.ts +2 -0
- package/common/enums/shared-messages.enum.ts +40 -0
- package/common/filters/http-exception.filter.ts +74 -0
- package/common/filters/index.ts +1 -0
- package/common/filters/rpc-exception.filter.ts +40 -0
- package/common/helper/get-env.helper.ts +3 -0
- package/common/helper/get-env.ts +3 -0
- package/common/helper/index.ts +2 -0
- package/common/helper/message-formatter.helper.ts +30 -0
- package/common/helper/multi-inheritance.helper.ts +12 -0
- package/common/helper/multi-inheritance.util.ts +12 -0
- package/common/index.ts +14 -0
- package/common/interface/core-crud-service.option.ts +8 -0
- package/common/interface/custom-validation-arguments.interface.ts +20 -0
- package/common/interface/index.ts +2 -0
- package/common/interface/kafka-success-response.interfase.ts +9 -0
- package/common/interface/pagination-query.ts +39 -0
- package/common/lib/index.ts +1 -0
- package/common/lib/kafka/constant/consumer.const.ts +13 -0
- package/common/lib/kafka/constant/kafka.const.ts +9 -0
- package/common/lib/kafka/index.ts +5 -0
- package/common/lib/kafka/kafka-admin.service.ts +51 -0
- package/common/lib/kafka/kafka-consumer.service.ts +59 -0
- package/common/lib/kafka/kafka-instance.const.ts +9 -0
- package/common/lib/kafka/kafka-logger.ts +25 -0
- package/common/lib/kafka/kafka-producer.service.ts +97 -0
- package/common/lib/kafka/kafka.interface.ts +22 -0
- package/common/lib/kafka/kafka.module.ts +80 -0
- package/common/lib/kafka/kafka.provider.ts +10 -0
- package/common/lib/kafka/kafka.service.ts +224 -0
- package/common/services/core-crud.service.ts +457 -0
- package/common/services/index.ts +1 -0
- package/common/strategy/index.ts +1 -0
- package/common/strategy/type-orm-naming.strategy.ts +17 -0
- package/common/validators/does-exist.validator.ts +42 -0
- package/common/validators/env.validator.ts +28 -0
- package/common/validators/index.ts +4 -0
- package/common/validators/is-unique.validator.ts +70 -0
- package/common/validators/validation-options.ts +38 -0
- package/dist/caching/caching.module.d.ts +2 -0
- package/dist/caching/caching.module.js +41 -0
- package/dist/caching/caching.module.js.map +1 -0
- package/dist/caching/caching.service.d.ts +9 -0
- package/dist/caching/caching.service.js +45 -0
- package/dist/caching/caching.service.js.map +1 -0
- package/dist/caching/index.d.ts +2 -0
- package/dist/caching/index.js +19 -0
- package/dist/caching/index.js.map +1 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +18 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/validation-constraints.const.d.ts +14 -0
- package/dist/constants/validation-constraints.const.js +19 -0
- package/dist/constants/validation-constraints.const.js.map +1 -0
- package/dist/controllers/core-crud.controller.d.ts +19 -0
- package/dist/controllers/core-crud.controller.js +72 -0
- package/dist/controllers/core-crud.controller.js.map +1 -0
- package/dist/controllers/index.d.ts +1 -0
- package/dist/controllers/index.js +18 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/decorators/entity-order.decorator.d.ts +2 -0
- package/dist/decorators/entity-order.decorator.js +18 -0
- package/dist/decorators/entity-order.decorator.js.map +1 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +19 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/swagger-api-response.decorator.d.ts +5 -0
- package/dist/decorators/swagger-api-response.decorator.js +25 -0
- package/dist/decorators/swagger-api-response.decorator.js.map +1 -0
- package/dist/decorators/validations/default/array-max-size.decorator.d.ts +1 -0
- package/dist/decorators/validations/default/array-max-size.decorator.js +12 -0
- package/dist/decorators/validations/default/array-max-size.decorator.js.map +1 -0
- package/dist/decorators/validations/default/array-min-size.decorator.d.ts +1 -0
- package/dist/decorators/validations/default/array-min-size.decorator.js +12 -0
- package/dist/decorators/validations/default/array-min-size.decorator.js.map +1 -0
- package/dist/decorators/validations/default/array-not-empty.decorator.d.ts +1 -0
- package/dist/decorators/validations/default/array-not-empty.decorator.js +10 -0
- package/dist/decorators/validations/default/array-not-empty.decorator.js.map +1 -0
- package/dist/decorators/validations/default/index.d.ts +20 -0
- package/dist/decorators/validations/default/index.js +37 -0
- package/dist/decorators/validations/default/index.js.map +1 -0
- package/dist/decorators/validations/default/is-array.decorator.d.ts +1 -0
- package/dist/decorators/validations/default/is-array.decorator.js +10 -0
- package/dist/decorators/validations/default/is-array.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-boolean.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/is-boolean.decorator.js +10 -0
- package/dist/decorators/validations/default/is-boolean.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-date.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/is-date.decorator.js +10 -0
- package/dist/decorators/validations/default/is-date.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-enum.decorator.d.ts +1 -0
- package/dist/decorators/validations/default/is-enum.decorator.js +12 -0
- package/dist/decorators/validations/default/is-enum.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-int.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/is-int.decorator.js +10 -0
- package/dist/decorators/validations/default/is-int.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-not-empty-object.decorator.d.ts +5 -0
- package/dist/decorators/validations/default/is-not-empty-object.decorator.js +13 -0
- package/dist/decorators/validations/default/is-not-empty-object.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-not-empty.decorator.d.ts +1 -0
- package/dist/decorators/validations/default/is-not-empty.decorator.js +10 -0
- package/dist/decorators/validations/default/is-not-empty.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-number-string.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/is-number-string.decorator.js +10 -0
- package/dist/decorators/validations/default/is-number-string.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-object.decorator.d.ts +2 -0
- package/dist/decorators/validations/default/is-object.decorator.js +10 -0
- package/dist/decorators/validations/default/is-object.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-positive.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/is-positive.decorator.js +10 -0
- package/dist/decorators/validations/default/is-positive.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-string.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/is-string.decorator.js +11 -0
- package/dist/decorators/validations/default/is-string.decorator.js.map +1 -0
- package/dist/decorators/validations/default/is-uuid.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/is-uuid.decorator.js +10 -0
- package/dist/decorators/validations/default/is-uuid.decorator.js.map +1 -0
- package/dist/decorators/validations/default/matches.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/matches.decorator.js +10 -0
- package/dist/decorators/validations/default/matches.decorator.js.map +1 -0
- package/dist/decorators/validations/default/max-length.decorator.d.ts +1 -0
- package/dist/decorators/validations/default/max-length.decorator.js +12 -0
- package/dist/decorators/validations/default/max-length.decorator.js.map +1 -0
- package/dist/decorators/validations/default/max.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/max.decorator.js +10 -0
- package/dist/decorators/validations/default/max.decorator.js.map +1 -0
- package/dist/decorators/validations/default/min-length.decorator.d.ts +1 -0
- package/dist/decorators/validations/default/min-length.decorator.js +12 -0
- package/dist/decorators/validations/default/min-length.decorator.js.map +1 -0
- package/dist/decorators/validations/default/min.decorator.d.ts +3 -0
- package/dist/decorators/validations/default/min.decorator.js +10 -0
- package/dist/decorators/validations/default/min.decorator.js.map +1 -0
- package/dist/decorators/validations/index.d.ts +3 -0
- package/dist/decorators/validations/index.js +20 -0
- package/dist/decorators/validations/index.js.map +1 -0
- package/dist/decorators/validations/is-id.decorator.d.ts +4 -0
- package/dist/decorators/validations/is-id.decorator.js +21 -0
- package/dist/decorators/validations/is-id.decorator.js.map +1 -0
- package/dist/decorators/validations/is-not-empty-string.decorator.d.ts +4 -0
- package/dist/decorators/validations/is-not-empty-string.decorator.js +15 -0
- package/dist/decorators/validations/is-not-empty-string.decorator.js.map +1 -0
- package/dist/dto/index.d.ts +2 -0
- package/dist/dto/index.js +19 -0
- package/dist/dto/index.js.map +1 -0
- package/dist/dto/request/base-request.dto.d.ts +4 -0
- package/dist/dto/request/base-request.dto.js +24 -0
- package/dist/dto/request/base-request.dto.js.map +1 -0
- package/dist/dto/request/event.dto.d.ts +8 -0
- package/dist/dto/request/event.dto.js +45 -0
- package/dist/dto/request/event.dto.js.map +1 -0
- package/dist/dto/request/id.dto.d.ts +3 -0
- package/dist/dto/request/id.dto.js +25 -0
- package/dist/dto/request/id.dto.js.map +1 -0
- package/dist/dto/request/ids.dto.d.ts +3 -0
- package/dist/dto/request/ids.dto.js +28 -0
- package/dist/dto/request/ids.dto.js.map +1 -0
- package/dist/dto/request/index.d.ts +4 -0
- package/dist/dto/request/index.js +21 -0
- package/dist/dto/request/index.js.map +1 -0
- package/dist/dto/response/base-response-with-action-dates.dto.d.ts +7 -0
- package/dist/dto/response/base-response-with-action-dates.dto.js +36 -0
- package/dist/dto/response/base-response-with-action-dates.dto.js.map +1 -0
- package/dist/dto/response/base-response.dto.d.ts +4 -0
- package/dist/dto/response/base-response.dto.js +24 -0
- package/dist/dto/response/base-response.dto.js.map +1 -0
- package/dist/dto/response/error-response.dto.d.ts +8 -0
- package/dist/dto/response/error-response.dto.js +38 -0
- package/dist/dto/response/error-response.dto.js.map +1 -0
- package/dist/dto/response/index.d.ts +5 -0
- package/dist/dto/response/index.js +22 -0
- package/dist/dto/response/index.js.map +1 -0
- package/dist/dto/response/kafka-success-response.dto.d.ts +14 -0
- package/dist/dto/response/kafka-success-response.dto.js +66 -0
- package/dist/dto/response/kafka-success-response.dto.js.map +1 -0
- package/dist/dto/response/success-response.dto.d.ts +9 -0
- package/dist/dto/response/success-response.dto.js +44 -0
- package/dist/dto/response/success-response.dto.js.map +1 -0
- package/dist/dto/response/validation.dto.d.ts +25 -0
- package/dist/dto/response/validation.dto.js +84 -0
- package/dist/dto/response/validation.dto.js.map +1 -0
- package/dist/entities/action-dates.entity.d.ts +8 -0
- package/dist/entities/action-dates.entity.js +43 -0
- package/dist/entities/action-dates.entity.js.map +1 -0
- package/dist/entities/base.entity.d.ts +4 -0
- package/dist/entities/base.entity.js +22 -0
- package/dist/entities/base.entity.js.map +1 -0
- package/dist/entities/index.d.ts +2 -0
- package/dist/entities/index.js +19 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/entities/parent.entity.d.ts +8 -0
- package/dist/entities/parent.entity.js +45 -0
- package/dist/entities/parent.entity.js.map +1 -0
- package/dist/enums/environments.enum.d.ts +6 -0
- package/dist/enums/environments.enum.js +11 -0
- package/dist/enums/environments.enum.js.map +1 -0
- package/dist/enums/index.d.ts +2 -0
- package/dist/enums/index.js +19 -0
- package/dist/enums/index.js.map +1 -0
- package/dist/enums/shared-messages.enum.d.ts +25 -0
- package/dist/enums/shared-messages.enum.js +30 -0
- package/dist/enums/shared-messages.enum.js.map +1 -0
- package/dist/filters/http-exception.filter.d.ts +8 -0
- package/dist/filters/http-exception.filter.js +65 -0
- package/dist/filters/http-exception.filter.js.map +1 -0
- package/dist/filters/index.d.ts +1 -0
- package/dist/filters/index.js +18 -0
- package/dist/filters/index.js.map +1 -0
- package/dist/filters/rpc-exception.filter.d.ts +5 -0
- package/dist/filters/rpc-exception.filter.js +21 -0
- package/dist/filters/rpc-exception.filter.js.map +1 -0
- package/dist/helper/get-env.d.ts +1 -0
- package/dist/helper/get-env.helper.d.ts +1 -0
- package/dist/helper/get-env.helper.js +7 -0
- package/dist/helper/get-env.helper.js.map +1 -0
- package/dist/helper/get-env.js +7 -0
- package/dist/helper/get-env.js.map +1 -0
- package/dist/helper/index.d.ts +2 -0
- package/dist/helper/index.js +19 -0
- package/dist/helper/index.js.map +1 -0
- package/dist/helper/message-formatter.helper.d.ts +3 -0
- package/dist/helper/message-formatter.helper.js +27 -0
- package/dist/helper/message-formatter.helper.js.map +1 -0
- package/dist/helper/multi-inheritance.helper.d.ts +1 -0
- package/dist/helper/multi-inheritance.helper.js +13 -0
- package/dist/helper/multi-inheritance.helper.js.map +1 -0
- package/dist/helper/multi-inheritance.util.d.ts +1 -0
- package/dist/helper/multi-inheritance.util.js +13 -0
- package/dist/helper/multi-inheritance.util.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/interface/core-crud-service.option.d.ts +7 -0
- package/dist/interface/core-crud-service.option.js +10 -0
- package/dist/interface/core-crud-service.option.js.map +1 -0
- package/dist/interface/custom-validation-arguments.interface.d.ts +14 -0
- package/dist/interface/custom-validation-arguments.interface.js +3 -0
- package/dist/interface/custom-validation-arguments.interface.js.map +1 -0
- package/dist/interface/index.d.ts +2 -0
- package/dist/interface/index.js +19 -0
- package/dist/interface/index.js.map +1 -0
- package/dist/interface/kafka-success-response.interfase.d.ts +9 -0
- package/dist/interface/kafka-success-response.interfase.js +3 -0
- package/dist/interface/kafka-success-response.interfase.js.map +1 -0
- package/dist/interface/pagination-query.d.ts +13 -0
- package/dist/interface/pagination-query.js +55 -0
- package/dist/interface/pagination-query.js.map +1 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +18 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/kafka/constant/consumer.const.d.ts +12 -0
- package/dist/lib/kafka/constant/consumer.const.js +18 -0
- package/dist/lib/kafka/constant/consumer.const.js.map +1 -0
- package/dist/lib/kafka/constant/kafka.const.d.ts +9 -0
- package/dist/lib/kafka/constant/kafka.const.js +14 -0
- package/dist/lib/kafka/constant/kafka.const.js.map +1 -0
- package/dist/lib/kafka/index.d.ts +4 -0
- package/dist/lib/kafka/index.js +8 -0
- package/dist/lib/kafka/index.js.map +1 -0
- package/dist/lib/kafka/kafka-admin.service.d.ts +7 -0
- package/dist/lib/kafka/kafka-admin.service.js +47 -0
- package/dist/lib/kafka/kafka-admin.service.js.map +1 -0
- package/dist/lib/kafka/kafka-consumer.service.d.ts +9 -0
- package/dist/lib/kafka/kafka-consumer.service.js +50 -0
- package/dist/lib/kafka/kafka-consumer.service.js.map +1 -0
- package/dist/lib/kafka/kafka-instance.const.d.ts +2 -0
- package/dist/lib/kafka/kafka-instance.const.js +12 -0
- package/dist/lib/kafka/kafka-instance.const.js.map +1 -0
- package/dist/lib/kafka/kafka-logger.d.ts +2 -0
- package/dist/lib/kafka/kafka-logger.js +22 -0
- package/dist/lib/kafka/kafka-logger.js.map +1 -0
- package/dist/lib/kafka/kafka-producer.service.d.ts +10 -0
- package/dist/lib/kafka/kafka-producer.service.js +76 -0
- package/dist/lib/kafka/kafka-producer.service.js.map +1 -0
- package/dist/lib/kafka/kafka.interface.d.ts +15 -0
- package/dist/lib/kafka/kafka.interface.js +5 -0
- package/dist/lib/kafka/kafka.interface.js.map +1 -0
- package/dist/lib/kafka/kafka.module.d.ts +10 -0
- package/dist/lib/kafka/kafka.module.js +77 -0
- package/dist/lib/kafka/kafka.module.js.map +1 -0
- package/dist/lib/kafka/kafka.provider.d.ts +7 -0
- package/dist/lib/kafka/kafka.provider.js +12 -0
- package/dist/lib/kafka/kafka.provider.js.map +1 -0
- package/dist/lib/kafka/kafka.service.d.ts +38 -0
- package/dist/lib/kafka/kafka.service.js +124 -0
- package/dist/lib/kafka/kafka.service.js.map +1 -0
- package/dist/services/core-crud.service.d.ts +31 -0
- package/dist/services/core-crud.service.js +318 -0
- package/dist/services/core-crud.service.js.map +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +18 -0
- package/dist/services/index.js.map +1 -0
- package/dist/strategy/index.d.ts +1 -0
- package/dist/strategy/index.js +18 -0
- package/dist/strategy/index.js.map +1 -0
- package/dist/strategy/type-orm-naming.strategy.d.ts +4 -0
- package/dist/strategy/type-orm-naming.strategy.js +12 -0
- package/dist/strategy/type-orm-naming.strategy.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/validators/does-exist.validator.d.ts +8 -0
- package/dist/validators/does-exist.validator.js +48 -0
- package/dist/validators/does-exist.validator.js.map +1 -0
- package/dist/validators/env.validator.d.ts +2 -0
- package/dist/validators/env.validator.js +27 -0
- package/dist/validators/env.validator.js.map +1 -0
- package/dist/validators/index.d.ts +4 -0
- package/dist/validators/index.js +21 -0
- package/dist/validators/index.js.map +1 -0
- package/dist/validators/is-unique.validator.d.ts +7 -0
- package/dist/validators/is-unique.validator.js +58 -0
- package/dist/validators/is-unique.validator.js.map +1 -0
- package/dist/validators/validation-options.d.ts +3 -0
- package/dist/validators/validation-options.js +28 -0
- package/dist/validators/validation-options.js.map +1 -0
- package/nest-cli.json +8 -0
- package/package.json +81 -0
- package/tsconfig.build.json +4 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { IsNumber, IsOptional } from 'class-validator';
|
|
2
|
+
import { IsString } from '../decorators/validations/default';
|
|
3
|
+
import { Transform } from 'class-transformer';
|
|
4
|
+
import { PaginateQuery } from 'nestjs-paginate';
|
|
5
|
+
|
|
6
|
+
export class PaginationQueryCustom implements PaginateQuery {
|
|
7
|
+
@IsNumber()
|
|
8
|
+
@IsOptional()
|
|
9
|
+
@Transform(({ value }) => (value ? parseInt(value, 10) : undefined))
|
|
10
|
+
page?: number;
|
|
11
|
+
|
|
12
|
+
@IsNumber()
|
|
13
|
+
@IsOptional()
|
|
14
|
+
@Transform(({ value }) => (value ? parseInt(value, 10) : undefined))
|
|
15
|
+
limit?: number;
|
|
16
|
+
|
|
17
|
+
@IsString({ each: true })
|
|
18
|
+
sortBy?: [string, string][];
|
|
19
|
+
|
|
20
|
+
@IsString({ each: true })
|
|
21
|
+
@IsOptional()
|
|
22
|
+
searchBy?: string[];
|
|
23
|
+
|
|
24
|
+
@IsString({ each: true })
|
|
25
|
+
@IsOptional()
|
|
26
|
+
search?: string;
|
|
27
|
+
|
|
28
|
+
@IsString({ each: true })
|
|
29
|
+
@IsOptional()
|
|
30
|
+
select?: string[];
|
|
31
|
+
|
|
32
|
+
@IsString()
|
|
33
|
+
@IsOptional()
|
|
34
|
+
path: string;
|
|
35
|
+
|
|
36
|
+
filter?: {
|
|
37
|
+
[column: string]: string | string[];
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './kafka';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Admin } from 'kafkajs';
|
|
2
|
+
import { Logger } from '@nestjs/common';
|
|
3
|
+
import { kafka } from './kafka-instance.const';
|
|
4
|
+
|
|
5
|
+
export default class KafkaAdminService {
|
|
6
|
+
private kafkaAdmin: Admin;
|
|
7
|
+
|
|
8
|
+
public constructor(clientId: string, brokers: string[]) {
|
|
9
|
+
this.kafkaAdmin = this.createKafkaAdmin(clientId, brokers);
|
|
10
|
+
|
|
11
|
+
const errorTypes = ['unhandledRejection', 'uncaughtException'];
|
|
12
|
+
const signalTraps = ['SIGTERM', 'SIGINT', 'SIGUSR2'];
|
|
13
|
+
|
|
14
|
+
errorTypes.forEach((type) => {
|
|
15
|
+
process.on(type, async (e) => {
|
|
16
|
+
try {
|
|
17
|
+
Logger.log(`process.on ${type}`);
|
|
18
|
+
Logger.error(e);
|
|
19
|
+
await this.shutdown();
|
|
20
|
+
process.exit(0);
|
|
21
|
+
} catch (_) {
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
signalTraps.forEach((type) => {
|
|
28
|
+
process.once(type, async () => {
|
|
29
|
+
try {
|
|
30
|
+
await this.shutdown();
|
|
31
|
+
} finally {
|
|
32
|
+
process.kill(process.pid, type);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async getTopics() {
|
|
39
|
+
let topics = await this.kafkaAdmin.listTopics();
|
|
40
|
+
topics = topics.filter((topic) => topic.slice(0, 1) !== '_');
|
|
41
|
+
return topics;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private async shutdown(): Promise<void> {
|
|
45
|
+
await this.kafkaAdmin.disconnect();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private createKafkaAdmin(clientId, brokers): Admin {
|
|
49
|
+
return kafka(clientId, brokers).admin();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Consumer } from 'kafkajs';
|
|
2
|
+
import { Logger } from '@nestjs/common';
|
|
3
|
+
import { kafka } from './kafka-instance.const';
|
|
4
|
+
|
|
5
|
+
export default class KafkaConsumerService {
|
|
6
|
+
private kafkaConsumer: Consumer;
|
|
7
|
+
|
|
8
|
+
public constructor(clientId, brokers, groupId) {
|
|
9
|
+
this.kafkaConsumer = this.createKafkaConsumer(clientId, brokers, groupId);
|
|
10
|
+
|
|
11
|
+
const errorTypes = ['unhandledRejection', 'uncaughtException'];
|
|
12
|
+
const signalTraps = ['SIGTERM', 'SIGINT', 'SIGUSR2'];
|
|
13
|
+
|
|
14
|
+
errorTypes.forEach((type) => {
|
|
15
|
+
process.on(type, async (e) => {
|
|
16
|
+
try {
|
|
17
|
+
Logger.log(`process.on ${type}`);
|
|
18
|
+
Logger.error(e);
|
|
19
|
+
await this.shutdown();
|
|
20
|
+
process.exit(0);
|
|
21
|
+
} catch (_) {
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
signalTraps.forEach((type) => {
|
|
28
|
+
process.once(type, async () => {
|
|
29
|
+
try {
|
|
30
|
+
await this.shutdown();
|
|
31
|
+
} finally {
|
|
32
|
+
process.kill(process.pid, type);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public async connectConsumer(): Promise<Consumer> {
|
|
39
|
+
await this.kafkaConsumer.connect();
|
|
40
|
+
return this.kafkaConsumer;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public async healthCheck() {
|
|
44
|
+
const describe = await this.kafkaConsumer.describeGroup();
|
|
45
|
+
return describe.state;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public async shutdown(): Promise<void> {
|
|
49
|
+
await this.kafkaConsumer.disconnect();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private createKafkaConsumer(
|
|
53
|
+
clientId,
|
|
54
|
+
brokers,
|
|
55
|
+
groupId = 'consumer-group',
|
|
56
|
+
): Consumer {
|
|
57
|
+
return kafka(clientId, brokers).consumer({ groupId });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Logger } from '@nestjs/common';
|
|
2
|
+
import { logLevel, LogEntry, logCreator } from 'kafkajs';
|
|
3
|
+
|
|
4
|
+
export // This function returns a LogCreator that is compatible with KafkaJS requirements
|
|
5
|
+
const createKafkaLoggerAdapter: logCreator = () => {
|
|
6
|
+
const nestLogger = new Logger('KafkaJS', { timestamp: true });
|
|
7
|
+
// Converts KafkaJS log levels to appropriate NestJS log methods
|
|
8
|
+
const logMethodMap = {
|
|
9
|
+
[logLevel.ERROR]: 'error',
|
|
10
|
+
[logLevel.WARN]: 'warn',
|
|
11
|
+
[logLevel.INFO]: 'log',
|
|
12
|
+
[logLevel.DEBUG]: 'debug',
|
|
13
|
+
[logLevel.NOTHING]: 'verbose', // Adjust according to your preference
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return ({ namespace, level, label, log }: LogEntry) => {
|
|
17
|
+
const { message, ...extra } = log;
|
|
18
|
+
const method = logMethodMap[level] || 'log';
|
|
19
|
+
|
|
20
|
+
nestLogger[method](
|
|
21
|
+
`${label} [${namespace}] ${message}`,
|
|
22
|
+
JSON.stringify(extra),
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Message, Producer, ProducerBatch, TopicMessages } from 'kafkajs';
|
|
2
|
+
import { Logger } from '@nestjs/common';
|
|
3
|
+
import { kafka } from './kafka-instance.const';
|
|
4
|
+
|
|
5
|
+
export default class KafkaProducerService {
|
|
6
|
+
private producer: Producer;
|
|
7
|
+
|
|
8
|
+
constructor(clientId: string, brokers: string[]) {
|
|
9
|
+
this.producer = this.createProducer(clientId, brokers);
|
|
10
|
+
this.setupGracefulShutdown();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
private setupGracefulShutdown(): void {
|
|
14
|
+
const errorTypes = ['unhandledRejection', 'uncaughtException'];
|
|
15
|
+
const signalTraps = ['SIGTERM', 'SIGINT', 'SIGUSR2'];
|
|
16
|
+
|
|
17
|
+
errorTypes.forEach((type) => {
|
|
18
|
+
process.on(type, async (e) => {
|
|
19
|
+
try {
|
|
20
|
+
Logger.log(`process.on ${type}`);
|
|
21
|
+
Logger.error(e);
|
|
22
|
+
await this.shutdown();
|
|
23
|
+
process.exit(0);
|
|
24
|
+
} catch (_) {
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
signalTraps.forEach((type) => {
|
|
31
|
+
process.once(type, async () => {
|
|
32
|
+
try {
|
|
33
|
+
await this.shutdown();
|
|
34
|
+
} finally {
|
|
35
|
+
process.kill(process.pid, type);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public async start() {
|
|
42
|
+
await this.producer.connect();
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public async shutdown(): Promise<void> {
|
|
47
|
+
await this.producer.disconnect();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public async sendBatch(
|
|
51
|
+
topic: string,
|
|
52
|
+
messages: Array<object>,
|
|
53
|
+
): Promise<void> {
|
|
54
|
+
const kafkaMessages: Array<Message> = messages.map((message) => {
|
|
55
|
+
return {
|
|
56
|
+
value: JSON.stringify(message),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const topicMessages: TopicMessages = {
|
|
61
|
+
topic,
|
|
62
|
+
messages: kafkaMessages,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const batch: ProducerBatch = {
|
|
66
|
+
topicMessages: [topicMessages],
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
await this.producer.sendBatch(batch);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async sendEvent(
|
|
73
|
+
topic: string,
|
|
74
|
+
message: unknown,
|
|
75
|
+
partition: number = undefined,
|
|
76
|
+
) {
|
|
77
|
+
const producer: Producer = this.producer;
|
|
78
|
+
|
|
79
|
+
const kafkaMessage: Message = {
|
|
80
|
+
value: typeof message == 'string' ? message : JSON.stringify(message),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// If partition is specified, set it in the send method
|
|
84
|
+
kafkaMessage.partition = partition;
|
|
85
|
+
|
|
86
|
+
const sendOptions: { topic: string; messages: Message[] } = {
|
|
87
|
+
topic,
|
|
88
|
+
messages: [kafkaMessage],
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
await producer.send(sendOptions);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private createProducer(clientId: string, brokers: string[]): Producer {
|
|
95
|
+
return kafka(clientId, brokers).producer();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ModuleMetadata, Type } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
export const KAFKA_MODULE_OPTIONS = 'KAFKA_MODULE_OPTIONS';
|
|
4
|
+
|
|
5
|
+
export interface KafkaModuleOptions {
|
|
6
|
+
clientId: string;
|
|
7
|
+
brokers: string[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface KafkaModuleFactory {
|
|
11
|
+
createModuleOptions: () => Promise<KafkaModuleOptions> | KafkaModuleOptions;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface KafkaModuleAsyncOptions
|
|
15
|
+
extends Pick<ModuleMetadata, 'imports'> {
|
|
16
|
+
inject?: any[];
|
|
17
|
+
useClass?: Type<KafkaModuleFactory>;
|
|
18
|
+
useExisting?: Type<KafkaModuleFactory>;
|
|
19
|
+
useFactory?: (
|
|
20
|
+
...args: any[]
|
|
21
|
+
) => Promise<KafkaModuleOptions> | KafkaModuleOptions;
|
|
22
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { DynamicModule, Global, Module, Provider } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
KAFKA_MODULE_OPTIONS,
|
|
5
|
+
KafkaModuleAsyncOptions,
|
|
6
|
+
KafkaModuleFactory,
|
|
7
|
+
KafkaModuleOptions,
|
|
8
|
+
} from './kafka.interface';
|
|
9
|
+
import { KafkaService } from './index';
|
|
10
|
+
|
|
11
|
+
@Global()
|
|
12
|
+
@Module({})
|
|
13
|
+
export class KafkaModule {
|
|
14
|
+
static forRoot(options: KafkaModuleOptions): DynamicModule {
|
|
15
|
+
return {
|
|
16
|
+
module: KafkaModule,
|
|
17
|
+
providers: [
|
|
18
|
+
{
|
|
19
|
+
provide: KAFKA_MODULE_OPTIONS,
|
|
20
|
+
useValue: options,
|
|
21
|
+
},
|
|
22
|
+
KafkaService,
|
|
23
|
+
],
|
|
24
|
+
exports: [KafkaService],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static forRootAsync(options: KafkaModuleAsyncOptions): DynamicModule {
|
|
29
|
+
return {
|
|
30
|
+
module: KafkaModule,
|
|
31
|
+
imports: [...options.imports],
|
|
32
|
+
providers: [...this.createAsyncProviders(options), KafkaService],
|
|
33
|
+
exports: [...this.createAsyncProviders(options), KafkaService],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private static createAsyncProviders(
|
|
38
|
+
options: KafkaModuleAsyncOptions,
|
|
39
|
+
): Provider[] {
|
|
40
|
+
if (options.useExisting || options.useFactory) {
|
|
41
|
+
return [this.createAsyncOptionsProvider(options)];
|
|
42
|
+
}
|
|
43
|
+
return [
|
|
44
|
+
this.createAsyncOptionsProvider(options),
|
|
45
|
+
{
|
|
46
|
+
provide: options.useClass,
|
|
47
|
+
useClass: options.useClass,
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private static createProviders(options: KafkaModuleOptions): Provider[] {
|
|
53
|
+
return [this.createOptionsProvider(options)];
|
|
54
|
+
}
|
|
55
|
+
private static createAsyncOptionsProvider(
|
|
56
|
+
options: KafkaModuleAsyncOptions,
|
|
57
|
+
): Provider {
|
|
58
|
+
if (options.useFactory) {
|
|
59
|
+
return {
|
|
60
|
+
provide: KAFKA_MODULE_OPTIONS,
|
|
61
|
+
useFactory: options.useFactory,
|
|
62
|
+
inject: options.inject || [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
provide: KAFKA_MODULE_OPTIONS,
|
|
67
|
+
useFactory: async (optionsFactory: KafkaModuleFactory) =>
|
|
68
|
+
await optionsFactory.createModuleOptions(),
|
|
69
|
+
inject: [options.useExisting || options.useClass],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
73
|
+
private static createOptionsProvider(options: KafkaModuleOptions): Provider {
|
|
74
|
+
return {
|
|
75
|
+
provide: KAFKA_MODULE_OPTIONS,
|
|
76
|
+
useFactory: async (optionsFactory: KafkaModuleFactory) =>
|
|
77
|
+
await optionsFactory.createModuleOptions(),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { KafkaService } from './kafka.service';
|
|
2
|
+
import { KafkaModuleOptions } from './kafka.interface';
|
|
3
|
+
|
|
4
|
+
export const KafkaProviders = [
|
|
5
|
+
{
|
|
6
|
+
provide: 'KAFKA_MODEL',
|
|
7
|
+
useFactory: (options: KafkaModuleOptions) => new KafkaService(options),
|
|
8
|
+
inject: ['DATABASE_CONNECTION'],
|
|
9
|
+
},
|
|
10
|
+
];
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { Inject, Injectable, Logger } from '@nestjs/common';
|
|
2
|
+
import { Consumer } from 'kafkajs';
|
|
3
|
+
import KafkaConsumerService from './kafka-consumer.service';
|
|
4
|
+
import { KAFKA_MODULE_OPTIONS, KafkaModuleOptions } from './kafka.interface';
|
|
5
|
+
import { env } from '../../helper/get-env.helper';
|
|
6
|
+
import { KafkaHealthState } from './constant/kafka.const';
|
|
7
|
+
import KafkaAdminService from './kafka-admin.service';
|
|
8
|
+
import KafkaProducerService from './kafka-producer.service';
|
|
9
|
+
|
|
10
|
+
@Injectable()
|
|
11
|
+
export class KafkaService {
|
|
12
|
+
private static instance: KafkaService;
|
|
13
|
+
private consumers: { [groupId: string]: KafkaConsumerService };
|
|
14
|
+
private consumersInstance: { [groupId: string]: Consumer };
|
|
15
|
+
private producerInstance: KafkaProducerService;
|
|
16
|
+
private adminInstance: KafkaAdminService;
|
|
17
|
+
public topics: { [groupId: string]: string[] };
|
|
18
|
+
public groupIds: { [item: string]: string };
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
@Inject(KAFKA_MODULE_OPTIONS)
|
|
22
|
+
private kafkaModuleOptions: KafkaModuleOptions,
|
|
23
|
+
) {
|
|
24
|
+
this.adminInstance = new KafkaAdminService(
|
|
25
|
+
this.kafkaModuleOptions.clientId,
|
|
26
|
+
this.kafkaModuleOptions.brokers,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Kafka Admin
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Getting available topics using Kafka admin instance
|
|
34
|
+
*/
|
|
35
|
+
async getAvailableTopics() {
|
|
36
|
+
return await this.adminInstance.getTopics();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Kafka Producer
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Make Producer instance and starting a Kafka producer service
|
|
43
|
+
*/
|
|
44
|
+
async startProducer() {
|
|
45
|
+
this.producerInstance = new KafkaProducerService(
|
|
46
|
+
this.kafkaModuleOptions.clientId,
|
|
47
|
+
this.kafkaModuleOptions.brokers,
|
|
48
|
+
);
|
|
49
|
+
await this.producerInstance.start();
|
|
50
|
+
Logger.log('Producer is Connected', 'KafkaProducer');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Stopping Producer instance of Kafka producer service
|
|
55
|
+
*/
|
|
56
|
+
async stopProducer() {
|
|
57
|
+
await this.producerInstance.shutdown();
|
|
58
|
+
Logger.log('Producer is Disconnected', 'KafkaProducer');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* sending an event using Kafka producer
|
|
63
|
+
* @param topic
|
|
64
|
+
* @param message
|
|
65
|
+
* @param partition
|
|
66
|
+
*/
|
|
67
|
+
async sendProducerEvent(
|
|
68
|
+
topic: string,
|
|
69
|
+
message: unknown,
|
|
70
|
+
partition: number = undefined,
|
|
71
|
+
) {
|
|
72
|
+
await this.producerInstance.sendEvent(topic, message, partition);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Kafka Consumer
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* This function sets up multiple Kafka consumers based on the provided information,
|
|
79
|
+
* initializing group IDs, topics, and consumer instances for each group.
|
|
80
|
+
*/
|
|
81
|
+
async setBulkConsumer(
|
|
82
|
+
consumersInfo: {
|
|
83
|
+
groupIdKey: string;
|
|
84
|
+
topics: string[];
|
|
85
|
+
groupIdDefaultValue?: string;
|
|
86
|
+
}[],
|
|
87
|
+
) {
|
|
88
|
+
await Promise.all(
|
|
89
|
+
consumersInfo.map((item) => {
|
|
90
|
+
this.groupIds = {
|
|
91
|
+
...this.groupIds,
|
|
92
|
+
[item.groupIdKey]: env(item.groupIdKey, item?.groupIdDefaultValue),
|
|
93
|
+
};
|
|
94
|
+
this.topics = {
|
|
95
|
+
...this.topics,
|
|
96
|
+
[this.groupIds[item.groupIdKey]]: item?.topics,
|
|
97
|
+
};
|
|
98
|
+
this.consumers = {
|
|
99
|
+
...this.consumers,
|
|
100
|
+
[this.groupIds[item.groupIdKey]]: new KafkaConsumerService(
|
|
101
|
+
this.kafkaModuleOptions.clientId,
|
|
102
|
+
this.kafkaModuleOptions.brokers,
|
|
103
|
+
this.groupIds[item.groupIdKey],
|
|
104
|
+
),
|
|
105
|
+
};
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* method setConsumer which sets up a Kafka consumer with the provided:
|
|
112
|
+
* groupIdKey, topics, and optional groupIdDefaultValue value.
|
|
113
|
+
* @param consumersInfo
|
|
114
|
+
*/
|
|
115
|
+
async setConsumer(consumersInfo: {
|
|
116
|
+
groupIdKey: string;
|
|
117
|
+
topics: string[];
|
|
118
|
+
groupIdDefaultValue?: string;
|
|
119
|
+
}) {
|
|
120
|
+
this.groupIds = {
|
|
121
|
+
...this.groupIds,
|
|
122
|
+
[consumersInfo.groupIdKey]: env(
|
|
123
|
+
consumersInfo.groupIdKey,
|
|
124
|
+
consumersInfo?.groupIdDefaultValue,
|
|
125
|
+
),
|
|
126
|
+
};
|
|
127
|
+
this.topics = {
|
|
128
|
+
...this.topics,
|
|
129
|
+
[this.groupIds[consumersInfo.groupIdKey]]: consumersInfo?.topics,
|
|
130
|
+
};
|
|
131
|
+
this.consumers = {
|
|
132
|
+
...this.consumers,
|
|
133
|
+
[this.groupIds[consumersInfo.groupIdKey]]: new KafkaConsumerService(
|
|
134
|
+
this.kafkaModuleOptions.clientId,
|
|
135
|
+
this.kafkaModuleOptions.brokers,
|
|
136
|
+
this.groupIds[consumersInfo.groupIdKey],
|
|
137
|
+
),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Asynchronously starts all consumers, subscribes them to respective topics.
|
|
143
|
+
*/
|
|
144
|
+
async startAllConsumers() {
|
|
145
|
+
const consumerKeys = Object.keys(this.consumers);
|
|
146
|
+
for await (const key of consumerKeys) {
|
|
147
|
+
this.consumersInstance = {
|
|
148
|
+
...this.consumersInstance,
|
|
149
|
+
[key]: await this.consumers[key].connectConsumer(),
|
|
150
|
+
};
|
|
151
|
+
await this.consumersInstance[key].subscribe({ topics: this.topics[key] });
|
|
152
|
+
}
|
|
153
|
+
Logger.log(
|
|
154
|
+
`Consumer is Connected. consumer-list: ${consumerKeys.join(', ')}`,
|
|
155
|
+
'KafkaConsumer',
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Stops all consumers by asynchronously shutting them down.
|
|
161
|
+
*/
|
|
162
|
+
async stopAllConsumers() {
|
|
163
|
+
return await Promise.all(
|
|
164
|
+
Object.keys(this.consumers).map(async (key) => {
|
|
165
|
+
await this.consumers[key].shutdown();
|
|
166
|
+
}),
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Method to start a consumer by group ID asynchronously.
|
|
172
|
+
* @param groupId
|
|
173
|
+
* @param fromBeginning
|
|
174
|
+
*/
|
|
175
|
+
async startConsumerByGroupId(
|
|
176
|
+
groupId: string,
|
|
177
|
+
fromBeginning: boolean = false,
|
|
178
|
+
) {
|
|
179
|
+
// Start the consumer for the given group ID and store the instance
|
|
180
|
+
this.consumersInstance = {
|
|
181
|
+
...this.consumersInstance,
|
|
182
|
+
[groupId]: await this.consumers[groupId].connectConsumer(),
|
|
183
|
+
};
|
|
184
|
+
await this.consumersInstance[groupId].subscribe({
|
|
185
|
+
fromBeginning,
|
|
186
|
+
topics: this.topics[groupId],
|
|
187
|
+
});
|
|
188
|
+
Logger.log(`\"${groupId}\" is Connected.`, 'KafkaConsumer');
|
|
189
|
+
// Return the consumer instance
|
|
190
|
+
return this.consumersInstance[groupId];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Method to stop a consumer by group ID.
|
|
195
|
+
*/
|
|
196
|
+
async stopConsumerByGroupId(groupId: string) {
|
|
197
|
+
return await this.consumers[groupId].shutdown();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* This method performs a health check on a specific Kafka consumer group and determines its state.
|
|
202
|
+
* It checks the Kafka state and whether any topics are paused in the consumer group.
|
|
203
|
+
* Returns the KafkaHealthState based on the conditions met.
|
|
204
|
+
*/
|
|
205
|
+
async healthCheck(groupId: string) {
|
|
206
|
+
const kafkaState =
|
|
207
|
+
(await this.consumers?.[groupId].healthCheck()) ?? KafkaHealthState.Dead;
|
|
208
|
+
if (kafkaState === KafkaHealthState.Stable) {
|
|
209
|
+
const paused = this.consumersInstance[groupId].paused();
|
|
210
|
+
const isPaused = paused.filter(
|
|
211
|
+
(item) => item.topic === this.topics[groupId][0],
|
|
212
|
+
);
|
|
213
|
+
if (isPaused.length !== 0) return KafkaHealthState.Pause;
|
|
214
|
+
}
|
|
215
|
+
return KafkaHealthState[kafkaState];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Retrieves a consumer instance by group ID.
|
|
220
|
+
*/
|
|
221
|
+
getConsumerInstanceByGroupId(groupId: string) {
|
|
222
|
+
return this.consumersInstance[groupId];
|
|
223
|
+
}
|
|
224
|
+
}
|