{"id":377083,"date":"2024-05-26T09:48:35","date_gmt":"2024-05-26T09:48:35","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=377083"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=377083","title":{"rendered":"<span>\u041a\u0430\u043a \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u043e\u0432 \u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u043e\u0432 \u0438 \u043d\u0435 \u0441\u0433\u043e\u0440\u0435\u0442\u044c? Spring Boot 3, Spring Kafka<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u0420\u0435\u0448\u0438\u043b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u043e\u0432 \u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u043e\u0432 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c Spring Boot \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u042f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u043b \u043a \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u043c\u0438 \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u043b \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u0438\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043c\u0435\u043d\u044f \u0438\u0441\u043a\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435 &#8212; \u0431\u043e\u043b\u0435\u0435 \u043b\u0443\u0447\u0448\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u0418 \u0432\u043e\u0442, \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0440\u0430\u0437 \u043f\u0440\u043e\u0448\u0435\u0440\u0441\u0442\u0438\u0432 \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u0439 \u043e\u043f\u044b\u0442 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u0430 (stackoverflow), \u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u043c\u0438\u043d\u0443\u0441\u043e\u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u0441 \u0432\u0430\u043c\u0438 \u043a\u0430\u043a \u044f \u043a \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u0435\u043b \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0434\u043b\u044f \u043c\u043e\u0438\u0445 \u043a\u0435\u0439\u0441\u043e\u0432 \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b (\u0438\u043b\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u0445\u0443\u0436\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e).<\/p>\n<p>\u0414\u0438\u0441\u043a\u043b\u0435\u0439\u043c\u0435\u0440. \u042f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438. \u0422\u043e \u0435\u0441\u0442\u044c \u044d\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0434\u043b\u044f unit-\u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 Spring \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043f\u043b\u044e\u0441\u0430\u043c\u0438 (\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043d\u0430 \u0431\u043e\u0435\u0432\u043e\u0435) \u0438 \u043c\u0438\u043d\u0443\u0441\u0430\u043c\u0438 (\u044d\u0442\u043e \u0414\u041e\u041b\u0413\u041e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0438 \u0414\u041e\u041b\u0413\u041e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f).<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 1. \u0410 \u0440\u0430\u0437\u0432\u0435 \u044d\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432\u043e\u043e\u0431\u0449\u0435?<\/strong><\/p>\n<p>\u041a\u043e\u0440\u043e\u0442\u043a\u043e: \u0434\u0430.<\/p>\n<p>\u041d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0435 \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430 \u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430 \u043d\u0443\u0436\u043d\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0430\u043c\u044b\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440? \u041d\u0443, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0443, \u0447\u0442\u043e \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">@Slf4j @Service @RequiredArgsConstructor public class UserConsumer {      private final UserService userService;     private final NotUserService notUserService;     private final UserHandler userHandler;     private final UserMapper userMapper;     private final List&lt;String> userCodes;      @KafkaListener(groupId = \"userConsumerGroupId\",             clientIdPrefix = \"UserConsumer\",             topics = {\"user-topic\"},             containerFactory = \"kafkaListenerContainerFactory\")     public void consume(UserInfoRecord userInfoRecord) {         log.info(\"\u0422\u0443\u0442 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438\");         log.info(\"C\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 \u0431\u0434?\");         log.info(\"\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438?\");         log.info(\"\u0412\u044b\u0437\u043e\u0432 \u043c\u0430\u043f\u043f\u0435\u0440\u043e\u0432?\");         log.info(\"\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 Kafka?\");     } } <\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 consume() \u043a\u0430\u043a \u0440\u0430\u0437 \u043c\u043e\u0436\u0435\u0442 \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430, \u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u0430\u0436\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430\u044f, \u043d\u043e \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443.<\/p>\n<p>\u0410 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440? \u041d\u0443, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">@Slf4j @Service @RequiredArgsConstructor public class UserProducer {      private final UserService userService;     \/** \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0435\u0440\u0441\u0438\u0441\u0442\u0438\u043d\u0433 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u0438\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 *\/     private final KafkaMessageService kafkaMessageService;     \/** \u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c - \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c KafkaProducer, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443 \u043d\u0430\u0441 \u043f\u043e \u0431\u041e\u043b\u044c\u0448\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441 AVRO *\/     private final KafkaProducer&lt;String, SpecificRecordBase> kafkaProducer;     \/** \u041d\u043e \u0435\u0441\u0442\u044c \u043c\u0435\u0441\u0442\u0430, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f JSON \u0432\u043c\u0435\u0441\u0442\u043e AVRO *\/     private final KafkaProducer&lt;String, String> kafkaJsonProducer;     private final ApplicationProperties applicationProperties;      public void sendUserInfoMessage(User user, Set&lt;Integer> managerIds) {       log.info(\"\u0422\u0443\u0442 \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438\");       log.info(\"\u041e\u0431\u044b\u0447\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0434\u0435\u0442 \u0441\u0431\u043e\u0440\u043a\u0430 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438.\")       log.info(\"\u041d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430.\");       var record = UserInfoRecord.newBuilder().build();       log.info(\"\u0422\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u0430\u043a \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0432 Kafka\");       log.info(\"\u0422\u0430\u043a \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f outbox-\u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430.\");       kafkaMessageService.persistMessageToSend(applicationProperties.userTopic(), record);     } }<\/code><\/pre>\n<p>\u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f outbox-pattern, \u0438 \u0442\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043b\u0430\u0434\u0435\u043c \u0432 \u0431\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u0434\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c.\u0418\u043b\u0438 \u043a\u043b\u0430\u0434\u0435\u043c \u0432 \u0411\u0414 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c. \u0418\u043b\u0438 \u043d\u0435 \u0432 \u0411\u0414 \u043a\u043b\u0430\u0434\u0435\u043c, \u0430 \u0435\u0449\u0435 \u043a\u0443\u0434\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c. \u0421\u0443\u0442\u0438 \u044d\u0442\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442 &#8212; \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u043b\u0438\u0431\u043e \u0432 \u0431\u0434, \u043b\u0438\u0431\u043e \u0441\u0440\u0430\u0437\u0443 \u0432 Kafka \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e KafkaProducer. \u041c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u043c \u0442\u0435\u0441\u0442\u0435 \u043b\u043e\u0433\u0438\u043a\u0443 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0435\u0440\u0441\u0438\u0441\u0442\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 &#8212; \u044d\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0432 \u0441\u0442\u0430\u0440\u0442\u0435\u0440\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Kafka. \u0410 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u0441\u0447\u0438\u0442\u0430\u0435\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0438 \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e. \u041d\u043e \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0414\u041e, \u0442\u043e \u0435\u0441\u0442\u044c \u043a\u0430\u043a \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043c\u043e\u0434\u0435\u043b\u044c, \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043b\u0438 \u043c\u044b \u043a\u043b\u0430\u0434\u0435\u043c \u043f\u043e\u043b\u044f, \u043d\u0435 \u0437\u0430\u0431\u044b\u043b\u0438 \u043b\u0438 \u043c\u044b \u0434\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u0432 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043b\u0438 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440 \u0440\u043e\u0441\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0431\u0443\u043a\u0432 \u0432 \u0435\u0433\u043e \u0424\u0418\u041e.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e: \u043b\u043e\u0433\u0438\u043a\u0430 \u0432 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430\u0445 \u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430\u0445 \u0442\u043e\u0436\u0435 \u043f\u0440\u043e\u0441\u0438\u0442\u0441\u044f \u0432 unit-\u0442\u0435\u0441\u0442\u044b, \u043a\u0430\u043a \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434.<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 1.5. \u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b<\/strong><\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043d\u0434 Kafka, \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u0442\u0435\u0441\u0442\u043e\u0432. \u041c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u044d\u0442\u043e \u043f\u043b\u043e\u0445\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u0443 \u0442\u0435\u0431\u044f \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0421\u044e\u0434\u0430 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043d\u0435\u0441\u0442\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f Kafka (\u0445\u043e\u0442\u044c \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440) \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0435-\u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0435 (Gitlab Runner \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435). \u0423\u0436\u0435 \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c \u0430\u0431\u0437\u0430\u0446\u0435\u043c \u0432\u044b\u0448\u0435, \u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0441\u043b\u0430\u0431\u043e\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0439.<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 2. &#171;\u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044c \u043b\u043e\u0433\u0438\u043a\u0443, \u0437\u0430\u0431\u0435\u0439 \u043d\u0430 \u043b\u043e\u0433\u0438&#187;<\/strong><\/p>\n<p>\u0414\u0430, \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u0442\u0430\u043f &#8212; \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u0440\u0438 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 Spring \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u0438\u0448\u0443\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a Kafka:<\/p>\n<pre><code>[org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] requestId: INFO  o.apache.kafka.clients.NetworkClient - [Consumer clientId=Consumer-0, groupId=app-group] Node -1 disconnected. [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] requestId: WARN  o.apache.kafka.clients.NetworkClient - [Consumer clientId=Consumer-0, groupId=app-group] Connection to node -1 (localhost\/127.0.0.1:3333) could not be established. Broker may not be available. [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] requestId: WARN  o.apache.kafka.clients.NetworkClient - [Consumer clientId=Consumer-0, groupId=app-group] Bootstrap broker localhost:3333 (id: -1 rack: null) disconnected<\/code><\/pre>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0438 \u044d\u0442\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u0430 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043f\u043e\u043c\u0435\u0448\u0430\u044e\u0442 \u0440\u0430\u0431\u043e\u0442\u0435 \u0432\u0441\u0435\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435. \u041d\u043e \u0435\u0441\u043b\u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u043e\u0432 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 5-10, \u0442\u043e \u0442\u0430\u043a\u0438\u0445 \u043b\u043e\u0433\u043e\u0432 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0449\u0443\u0442\u0438\u043c\u043e \u043c\u043d\u043e\u0433\u043e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u044b \u043e\u0431\u0449\u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043c\u0430 \u043b\u043e\u0433\u043e\u0432 \u043f\u0440\u0438 \u0442\u0435\u0441\u0442\u0430\u0445), \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u043b\u0438\u044f\u0442\u044c \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 3. &#171;\u0414\u0430 \u0437\u0430\u043c\u043e\u043a\u0430\u0439 \u0442\u044b \u0434\u0430 \u0438 \u0432\u0441\u0451..&#187;<\/strong> <\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0432\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0443\u0441\u043b\u044b\u0448\u0430\u043b \u0438\u043b\u0438 \u0443\u0432\u0438\u0434\u0435\u043b &#8212; \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043c\u043e\u043a\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u044b \u0438\/\u0438\u043b\u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u044b. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a (\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0435\u043a\u0438\u0439 BaseTest \u0434\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430):<\/p>\n<pre><code class=\"java\">@SpringJUnitConfig @SpringBootTest @EnableConfigurationProperties(ApplicationProperties.class) public abstract class BaseTest {      @MockBean(name = \"kafkaProducer\")     protected KafkaProducer kafkaProducer;     @MockBean     protected UserConsumer userConsumer;   }<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u043b\u043e\u0432\u0438\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u0430 \u043a Kafka, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u044b, \u043d\u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u044b \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430. \u0410 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043c\u043e\u043a\u0430\u043d\u044b.<\/p>\n<p>\u0418 \u043a\u0441\u0442\u0430\u0442\u0438, \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430 \u044d\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442! \u041c\u043e\u043a\u0430\u044f KafkaProducer &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u0431\u0438\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 Kafka, \u043c\u044b \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u0438\u043d \u043a\u043b\u0430\u0441\u0441\u0430-\u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0438 \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u043d\u0435\u0433\u043e \u0442\u0435\u0441\u0442:<\/p>\n<pre><code class=\"java\">class UserProducerTest extends BaseTest {      @Autowired     private UserProducer userProducer;      @Test     void testUserProducer() {       log.info(\"\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443\");       userProducer.produce();     }   }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u043a\u043e\u043d\u0441\u044e\u043c\u0435\u0440? \u041d\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">class UserConsumerTest extends BaseTest {      private final UserConsumer userConsumer = new UserConsumer(&lt;\u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438>);      @Test     void testUserProducer() {       log.info(\"\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443\");       userConsumer.consume();     }   }<\/code><\/pre>\n<p>\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432 UserConsumer \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b\/\u043a\u043b\u0430\u0441\u0441\u044b? \u0418\u0445 \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0442\u0443\u0442, \u043b\u0438\u0431\u043e \u0432\u0437\u044f\u0442\u044c \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0440\u0443\u0447\u043d\u0430\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e, \u0437\u0430\u043c\u043e\u043a\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440 &#8212; \u043e\u043a, \u0437\u0430\u043c\u043e\u043a\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440? \u0421\u043e\u043c\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u041e\u041a\u042d &#8212; \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e (\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 Spring, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435, \u043d\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0440\u0430\u0437\u043d\u044b\u0435). <\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 4. &#171;\u0414\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u044c\u043c\u0438 EmbeddedKafka, \u043e\u043d\u0430 \u0436\u0435 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u0430!&#187;<\/strong><\/p>\n<p>\u0414\u0430, \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 &#8212; \u043f\u043e\u0434\u043d\u044f\u0442\u044c EmbeddedKafka \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432. \u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e &#8212; \u0432\u0435\u0448\u0430\u0435\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e \u043d\u0430 \u0442\u0435\u0441\u0442:<\/p>\n<pre><code class=\"java\">@EmbeddedKafka(partitions = 1, brokerProperties = { \"listeners=PLAINTEXT:\/\/localhost:9092\", \"port=9092\" })<\/code><\/pre>\n<p>\u0418 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0432 maven (\u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435):<\/p>\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.springframework.kafka&lt;\/groupId>     &lt;artifactId>spring-kafka-test&lt;\/artifactId> &lt;\/dependency><\/code><\/pre>\n<p>\u041a\u0430\u043a\u0438\u0435 \u043f\u043b\u044e\u0441\u044b? \u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0443 \u043d\u0430\u0441 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0430\u044f embedded Kafka \u0432 \u0442\u0435\u0441\u0442\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u0444\u043b\u043e\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043c \u0432 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0438 \u0432 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0435.<\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0443\u0442: <a href=\"https:\/\/www.baeldung.com\/spring-boot-kafka-testing\">https:\/\/www.baeldung.com\/spring-boot-kafka-testing<\/a><\/p>\n<p>\u042f \u043b\u0438\u0448\u044c \u0441\u043a\u0430\u0436\u0443 \u043c\u0438\u043d\u0443\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0448\u0435\u043b: \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c spring-kafka-test \u0442\u044f\u043d\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0438\u0442\u0438\u0432\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043d\u0430 scala:<\/p>\n<ul>\n<li>\n<p>jackson-module-scala_2.13<\/p>\n<\/li>\n<li>\n<p>scala-collection-compat_2.13<\/p>\n<\/li>\n<li>\n<p>scala-java8-compat_2.13<\/p>\n<\/li>\n<li>\n<p>scala-library<\/p>\n<\/li>\n<li>\n<p>scala-logging_2.13<\/p>\n<\/li>\n<li>\n<p>scala-reflect<\/p>\n<\/li>\n<\/ul>\n<p>\u0418 \u0432 \u0446\u0435\u043b\u043e\u043c-\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e &#171;\u043d\u0443 \u0438 \u043b\u0430\u0434\u043d\u043e, \u043d\u0443 \u0438 \u043f\u0443\u0441\u043a\u0430\u0439, \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u0435\u0441\u0442\u0430\u0445&#187;. \u041d\u043e \u044d\u0442\u0438 \u043b\u0438\u0431\u044b \u0432\u043b\u0438\u044f\u044e\u0442 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430! \u042f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043b\u043e\u0432\u0438\u043b \u0442\u0430\u043a\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<pre><code class=\"java\">ClassCast class scala.collection.immutable.$colon$colon cannot be cast to class java.util.List (scala.collection.immutable.$colon$colon is in unnamed module of loader 'app'; java.util.List is in module java.base of loader 'bootstrap')<\/code><\/pre>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u043c\u044b \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438 \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043f\u0430\u043a\u0435\u0442 scala. \u041d\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"http:\/\/querydsl.com\/\">querydsl<\/a>. \u0418 \u043f\u0440\u0438 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 &#171;\u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0430&#187;. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u043b\u0435\u0433\u043a\u043e \u0447\u0438\u043d\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0447\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 maven-\u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u043d\u043e \u043a\u043e\u043f\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u043c \u043d\u0435 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c.<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 5. &#171;\u041d\u0443 \u0442\u043e\u0433\u0434\u0430 \u0442\u0435\u0431\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 testcontainers, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0439 \u043d\u0430 \u043d\u0435\u043c Kafka!&#187;<\/strong><\/p>\n<p>\u0418 \u043f\u0440\u0430\u0432\u0434\u0430, \u043f\u043e\u043c\u043e\u0436\u0435\u0442. \u0423 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 Spring Boot \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 testcontainers, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445.<\/p>\n<p>\u0410\u0445 \u0434\u0430, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u044f \u0432\u0441\u043a\u043e\u043b\u044c\u0437\u044c \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b, \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c AVRO \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043f\u043e Kafka. \u0422\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Schema Registry (SR). \u0410 \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u043d\u0443\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 SR. \u0422\u0443\u0442 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 &#8212; \u0437\u0430\u043c\u043e\u043a\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 WireMock, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c SR \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0442\u0435\u043d\u0434\u0430, \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043d\u0430 Gitlab Runner \u0438\u043b\u0438 \u0435\u0449\u0435 \u0433\u0434\u0435-\u0442\u043e. \u042f \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0434\u0432\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 &#8212; \u044d\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043b \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0443\u044e SR \u0447\u0435\u0440\u0435\u0437 wiremock &#8212; \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u043e, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0434\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u044d\u043c\u0443\u043b\u044f\u0446\u0438\u0438 \u043d\u043e\u0432\u044b\u0445 \u0441\u0445\u0435\u043c, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0435. \u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 SR \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438. \u041d\u043e \u0442\u0443\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0435\u0431\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0432 SR \u0434\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432. \u0410 \u0442\u0435\u0441\u0442\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u0433\u043e\u0432\u043e\u0440\u044f \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u044e\u0442\u0441\u044f \u0414\u041e \u0440\u0435\u043b\u0438\u0437\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043d\u0434.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c kafka-testcontainers \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445, \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043b\u0438\u0431\u0443 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430, \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u043c\u0438:<\/p>\n<pre><code class=\"xml\">&lt;dependencies>     &lt;dependency>         &lt;groupId>org.springframework.kafka&lt;\/groupId>         &lt;artifactId>spring-kafka&lt;\/artifactId>         &lt;scope>compile&lt;\/scope>     &lt;\/dependency>     &lt;!-- \u0422\u0443\u0442 \u0443 \u043d\u0430\u0441 \u043f\u0440\u043e\u0441\u0442\u043e \u043b\u0438\u0431\u0430 \u0441 \u043c\u043e\u0434\u0435\u043b\u044c\u043a\u0430\u043c\u0438 \u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c\u044e \u043d\u0430 AVRO -->     &lt;dependency>         &lt;groupId>ru.alfastrah&lt;\/groupId>         &lt;artifactId>avro-models&lt;\/artifactId>         &lt;scope>compile&lt;\/scope>     &lt;\/dependency>     &lt;dependency>         &lt;groupId>org.wiremock&lt;\/groupId>         &lt;artifactId>wiremock-standalone&lt;\/artifactId>         &lt;scope>compile&lt;\/scope>     &lt;\/dependency>     &lt;dependency>         &lt;groupId>org.testcontainers&lt;\/groupId>         &lt;artifactId>kafka&lt;\/artifactId>         &lt;scope>compile&lt;\/scope>     &lt;\/dependency>     &lt;dependency>         &lt;groupId>org.springframework.boot&lt;\/groupId>         &lt;artifactId>spring-boot-testcontainers&lt;\/artifactId>         &lt;scope>compile&lt;\/scope>     &lt;\/dependency>     &lt;dependency>         &lt;groupId>org.springframework.boot&lt;\/groupId>         &lt;artifactId>spring-boot-starter-test&lt;\/artifactId>         &lt;scope>compile&lt;\/scope>     &lt;\/dependency>      &lt;dependency>         &lt;groupId>org.springframework&lt;\/groupId>         &lt;artifactId>spring-web&lt;\/artifactId>         &lt;scope>test&lt;\/scope>     &lt;\/dependency> &lt;\/dependencies><\/code><\/pre>\n<p>\u041d\u0443 \u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u0432 \u043b\u0438\u0431\u0435 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"java\">@ImportTestcontainers public interface KafkaBaseTest {      Logger log = org.slf4j.LoggerFactory.getLogger(KafkaTestingClass.class);     \/** Kafka-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 *\/     KafkaContainer KAFKA_CONTAINER = new KafkaContainer(KAFKA_IMAGE_NAME);      \/** \u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0411\u0414 *\/     @DynamicPropertySource     static void kafkaProperties(DynamicPropertyRegistry registry) {         if (!KAFKA_CONTAINER.isRunning()) {             KAFKA_CONTAINER.start();             var servers = KAFKA_CONTAINER.getBootstrapServers();             log.info(\"Kafka-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 {} (\u0438 \u0430\u0434\u0440\u0435\u0441 \u043f\u043e\u043b\u043e\u0436\u0435\u043d \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e bootstrap-servers)\", servers);             registry.add(\"bootstrap-servers\", () -> servers);         }     } }<\/code><\/pre>\n<p>\u0412\u0441\u0435 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0435 kafka \u043d\u0430 testcontainers \u0442\u0430\u043a (implements KafkaBaseTest):<\/p>\n<pre><code class=\"java\">@SpringJUnitConfig @SpringBootTest @EnableConfigurationProperties(value = ApplicationProperties.class) public abstract class BaseTest implements KafkaBaseTest { }<\/code><\/pre>\n<p>\u041c\u0438\u043d\u0443\u0441\u044b:<\/p>\n<ul>\n<li>\n<p>\u0441\u0431\u043e\u0440\u043a\u0430 \u0441\u0442\u0430\u043b\u0430 \u0434\u043e\u043b\u044c\u0448\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 kafka;<\/p>\n<\/li>\n<li>\n<p>\u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u043e, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u043c \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e &#8212; \u043d\u0435 \u043b\u043e\u0433\u0438\u043a\u0443 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430 \u0438\u043b\u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430, \u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 kafka. \u042d\u0442\u043e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0442\u043e\u0436\u0435 \u0432\u0430\u0436\u043d\u043e, \u043d\u043e;<\/p>\n<\/li>\n<li>\n<p>\u043a\u043e\u0434 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u0441\u0442\u0430\u043b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u0438\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"java\">class UserProducerTest extends BaseTest {      @Autowired     private KafkaSettings kafkaSettings;     @Autowired     private ApplicationProperties appProperties;     @Autowired     private UserProducer userProducer;     @Autowired     private KafkaListenerContainerFactory kafkaListenerContainerFactory;     @Autowired     private KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry;      @Test     void KafkaProducerTest() {         var counter = new AtomicInteger(0);         new KafkaListenerCreator&lt;SomeEvent>(kafkaSettings.groupId(), kafkaListenerContainerFactory, kafkaListenerEndpointRegistry)                 .createAndRegisterListener(appProperties.topicName(), \"KafkaProducerServiceTestListener\", (record) -> {                     log.info(\"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435: {}\", record);                     if (\"UserProducerTest\".equals(record.getTestData())) {                         counter.getAndIncrement();                     }                 });         AtomicInteger iteration = new AtomicInteger(0);         Arrays.stream(EventType.values()).forEach(eventType -> {             var record = createNewRecord(iteration.getAndIncrement());             userProducer.send(record);         });         await().atMost(Duration.ofSeconds(6L)).untilAsserted(() -> {             assertEquals(EventType.values().length, iteration.get());             assertEquals(2, counter.get());         });     }   }<\/code><\/pre>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 6. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0432\u0441\u0451, \u0447\u0442\u043e \u0432\u044b\u0448\u0435, \u0442\u043e \u0447\u0442\u043e \u0436\u0435?<\/strong><\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0432\u044b\u0448\u0435, \u0432\u043e\u043f\u0440\u043e\u0441 \u0441 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0438 \u0431\u044b\u043b \u0432\u0441\u0435 \u0435\u0449\u0435 \u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0442. \u042f \u043e\u043a\u0443\u043d\u0443\u043b\u0441\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0440\u0430\u0437 \u0432 \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u0439 \u043e\u043f\u044b\u0442 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u0430 \u0438 \u043d\u0430\u0448\u0435\u043b \u0442\u0430\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0448\u0442\u0443\u043a\u0443, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e: \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 autoStartup \u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 @KafkaListener (\u0441\u0440\u0430\u0437\u0443 \u0441\u044e\u0434\u0430 \u044f \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u043d\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b).<\/p>\n<p>\u0418 \u0442\u043e\u0433\u0434\u0430 \u043c\u044b \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432\u044b\u0448\u0435 \u0438 \u043f\u0438\u0448\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"java\">\/\/ \u0412 \u0442\u0435\u0441\u0442\u0430\u0445 \u043c\u043e\u043a\u0430\u0435\u043c \u0431\u0438\u043d\u044b \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u043e\u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 Kafka public abstract class BaseTest {      @MockBean(name = \"kafkaProducer\")     protected KafkaProducer kafkaProducer;     @MockBean(name = \"kafkaJsonProducer\")     protected KafkaProducer kafkaJsonProducer; }<\/code><\/pre>\n<pre><code class=\"java\">@Slf4j @Service @RequiredArgsConstructor public class UserConsumer {      private final UserService userService;     private final NotUserService notUserService;     private final UserHandler userHandler;     private final UserMapper userMapper;     private final List&lt;String> userCodes;      @KafkaListener(       \/\/ \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0432\u043b\u0438\u044f\u0442\u044c \u043d\u0430 \u043d\u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e       autoStartup = \"${auto-startup:true}\",       groupId = \"userConsumerGroupId\",       clientIdPrefix = \"UserConsumer\",       topics = {\"user-topic\"},       containerFactory = \"kafkaListenerContainerFactory\")     public void consume(UserInfoRecord userInfoRecord) {         log.info(\"\u0422\u0443\u0442 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438\");         log.info(\"C\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 \u0431\u0434?\");         log.info(\"\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438?\");         log.info(\"\u0412\u044b\u0437\u043e\u0432 \u043c\u0430\u043f\u043f\u0435\u0440\u043e\u0432?\");         log.info(\"\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 Kafka?\");     } }<\/code><\/pre>\n<pre><code class=\"yaml\"># \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c application.yml \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u0432\u0442\u043e\u0437\u0430\u043f\u0443\u0441\u043a: auto-startup: false<\/code><\/pre>\n<p>\u0427\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432 \u0438\u0442\u043e\u0433\u0435: \u0431\u0438\u043d \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435, \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 \u043d\u0435 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a kafka. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0443 \u043d\u0430\u0441 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 &#171;\u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0437\u0430\u0434\u0430\u043b containerFactory&#187; &#8212; \u0441\u0432\u0430\u043b\u0438\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0438\u043b\u0438 \u043f\u0440\u0438 \u0442\u0435\u0441\u0442\u0430\u0445.<\/p>\n<p>\u0418 \u0442\u043e\u0433\u0434\u0430 \u0442\u0435\u0441\u0442 \u043d\u0430 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">class UserConsumerTest extends BaseTest {      \/\/ \u041f\u0440\u043e\u0441\u0442\u043e \u0431\u0435\u0440\u0435\u043c \u0431\u0438\u043d \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434 consume     @Autowired     private UserConsumer userConsumer;      @Test     @DataSet(value = \"userConsumer_initial.yml\")     @ExpectedDataSet(value = \"userConsumer_expected.yml\")     void testConsume() {         userConsumer.consume(buildMessage());     } }<\/code><\/pre>\n<p>\u0410 \u0432\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"java\">class UserProducerTest extends BaseTest {      @Autowired     private UserProducer userProducer;     @Autowired     private ApplicationProperties appProperties;      @Test     @DataSet(value = {\"UserProducerTest.yml\"})     void testPolicyPaymentProducer() {         getUsers().forEach(user -> userProducer.sendInfo(user));          verify(kafkaMessageService, times(4)).persistMessageToSend(eq(appProperties.topicName()), argThat((arg) -> {             var record = (UserRecord) arg;             assertEquals(expectedField1, record.getId());             assertEquals(expectedField2, record.getStatus());             assertEquals(expectedField3, record.getUid());             return record.getExpectedSomething() == null;         }));     } }<\/code><\/pre>\n<p>\u041f\u043e\u043a\u0430 \u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u043a\u0430\u043a \u043d\u0430 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u043c \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0438 \u0445\u043e\u0442\u0438\u043c &#8212; \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u043e\u0432 \u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u043e\u0432.<\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e, \u0447\u0442\u043e \u0434\u043e\u0447\u0438\u0442\u0430\u043b\u0438. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u043a\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0432\u044b?<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/816057\/\"> https:\/\/habr.com\/ru\/articles\/816057\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u0420\u0435\u0448\u0438\u043b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u043e\u0432 \u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u043e\u0432 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c Spring Boot \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u042f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u043b \u043a \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u043c\u0438 \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u043b \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u0438\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043c\u0435\u043d\u044f \u0438\u0441\u043a\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435 &#8212; \u0431\u043e\u043b\u0435\u0435 \u043b\u0443\u0447\u0448\u0435\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u0418 \u0432\u043e\u0442, \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0440\u0430\u0437 \u043f\u0440\u043e\u0448\u0435\u0440\u0441\u0442\u0438\u0432 \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u0439 \u043e\u043f\u044b\u0442 \u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u0442\u0432\u0430 (stackoverflow), \u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0448\u0435\u043b \u043c\u0438\u043d\u0443\u0441\u043e\u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u0441 \u0432\u0430\u043c\u0438 \u043a\u0430\u043a \u044f \u043a \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0448\u0435\u043b \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u0434\u043b\u044f \u043c\u043e\u0438\u0445 \u043a\u0435\u0439\u0441\u043e\u0432 \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b (\u0438\u043b\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u0445\u0443\u0436\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e).<\/p>\n<p>\u0414\u0438\u0441\u043a\u043b\u0435\u0439\u043c\u0435\u0440. \u042f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438. \u0422\u043e \u0435\u0441\u0442\u044c \u044d\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0434\u043b\u044f unit-\u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 Spring \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043f\u043b\u044e\u0441\u0430\u043c\u0438 (\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043d\u0430 \u0431\u043e\u0435\u0432\u043e\u0435) \u0438 \u043c\u0438\u043d\u0443\u0441\u0430\u043c\u0438 (\u044d\u0442\u043e \u0414\u041e\u041b\u0413\u041e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0438 \u0414\u041e\u041b\u0413\u041e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f).<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 1. \u0410 \u0440\u0430\u0437\u0432\u0435 \u044d\u0442\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432\u043e\u043e\u0431\u0449\u0435?<\/strong><\/p>\n<p>\u041a\u043e\u0440\u043e\u0442\u043a\u043e: \u0434\u0430.<\/p>\n<p>\u041d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0435 \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430 \u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430 \u043d\u0443\u0436\u043d\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0430\u043c\u044b\u0439 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440? \u041d\u0443, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0443, \u0447\u0442\u043e \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">@Slf4j @Service @RequiredArgsConstructor public class UserConsumer {      private final UserService userService;     private final NotUserService notUserService;     private final UserHandler userHandler;     private final UserMapper userMapper;     private final List&lt;String> userCodes;      @KafkaListener(groupId = \"userConsumerGroupId\",             clientIdPrefix = \"UserConsumer\",             topics = {\"user-topic\"},             containerFactory = \"kafkaListenerContainerFactory\")     public void consume(UserInfoRecord userInfoRecord) {         log.info(\"\u0422\u0443\u0442 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438\");         log.info(\"C\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 \u0431\u0434?\");         log.info(\"\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438?\");         log.info(\"\u0412\u044b\u0437\u043e\u0432 \u043c\u0430\u043f\u043f\u0435\u0440\u043e\u0432?\");         log.info(\"\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 Kafka?\");     } } <\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 consume() \u043a\u0430\u043a \u0440\u0430\u0437 \u043c\u043e\u0436\u0435\u0442 \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430, \u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u0430\u0436\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430\u044f, \u043d\u043e \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443.<\/p>\n<p>\u0410 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440? \u041d\u0443, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u043a\u0430\u043a-\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">@Slf4j @Service @RequiredArgsConstructor public class UserProducer {      private final UserService userService;     \/** \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u0435\u0440\u0441\u0438\u0441\u0442\u0438\u043d\u0433 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u0438\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 *\/     private final KafkaMessageService kafkaMessageService;     \/** \u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c - \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c KafkaProducer, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443 \u043d\u0430\u0441 \u043f\u043e \u0431\u041e\u043b\u044c\u0448\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441 AVRO *\/     private final KafkaProducer&lt;String, SpecificRecordBase> kafkaProducer;     \/** \u041d\u043e \u0435\u0441\u0442\u044c \u043c\u0435\u0441\u0442\u0430, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f JSON \u0432\u043c\u0435\u0441\u0442\u043e AVRO *\/     private final KafkaProducer&lt;String, String> kafkaJsonProducer;     private final ApplicationProperties applicationProperties;      public void sendUserInfoMessage(User user, Set&lt;Integer> managerIds) {       log.info(\"\u0422\u0443\u0442 \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438\");       log.info(\"\u041e\u0431\u044b\u0447\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0434\u0435\u0442 \u0441\u0431\u043e\u0440\u043a\u0430 \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438.\")       log.info(\"\u041d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430.\");       var record = UserInfoRecord.newBuilder().build();       log.info(\"\u0422\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u0430\u043a \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0432 Kafka\");       log.info(\"\u0422\u0430\u043a \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f outbox-\u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430.\");       kafkaMessageService.persistMessageToSend(applicationProperties.userTopic(), record);     } }<\/code><\/pre>\n<p>\u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f outbox-pattern, \u0438 \u0442\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043b\u0430\u0434\u0435\u043c \u0432 \u0431\u0434 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0430\u0434\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c.\u0418\u043b\u0438 \u043a\u043b\u0430\u0434\u0435\u043c \u0432 \u0411\u0414 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c. \u0418\u043b\u0438 \u043d\u0435 \u0432 \u0411\u0414 \u043a\u043b\u0430\u0434\u0435\u043c, \u0430 \u0435\u0449\u0435 \u043a\u0443\u0434\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c. \u0421\u0443\u0442\u0438 \u044d\u0442\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442 &#8212; \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u043b\u0438\u0431\u043e \u0432 \u0431\u0434, \u043b\u0438\u0431\u043e \u0441\u0440\u0430\u0437\u0443 \u0432 Kafka \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e KafkaProducer. \u041c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u043c \u0442\u0435\u0441\u0442\u0435 \u043b\u043e\u0433\u0438\u043a\u0443 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0435\u0440\u0441\u0438\u0441\u0442\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 &#8212; \u044d\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0432 \u0441\u0442\u0430\u0440\u0442\u0435\u0440\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Kafka. \u0410 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 \u0441\u0447\u0438\u0442\u0430\u0435\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0438 \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e. \u041d\u043e \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0414\u041e, \u0442\u043e \u0435\u0441\u0442\u044c \u043a\u0430\u043a \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043c\u043e\u0434\u0435\u043b\u044c, \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043b\u0438 \u043c\u044b \u043a\u043b\u0430\u0434\u0435\u043c \u043f\u043e\u043b\u044f, \u043d\u0435 \u0437\u0430\u0431\u044b\u043b\u0438 \u043b\u0438 \u043c\u044b \u0434\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u0432 \u043c\u043e\u0434\u0435\u043b\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043b\u0438 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440 \u0440\u043e\u0441\u0442\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0431\u0443\u043a\u0432 \u0432 \u0435\u0433\u043e \u0424\u0418\u041e.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e: \u043b\u043e\u0433\u0438\u043a\u0430 \u0432 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0430\u0445 \u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430\u0445 \u0442\u043e\u0436\u0435 \u043f\u0440\u043e\u0441\u0438\u0442\u0441\u044f \u0432 unit-\u0442\u0435\u0441\u0442\u044b, \u043a\u0430\u043a \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434.<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 1.5. \u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b<\/strong><\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0442\u0435\u043d\u0434 Kafka, \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u0442\u0435\u0441\u0442\u043e\u0432. \u041c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u044d\u0442\u043e \u043f\u043b\u043e\u0445\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u0443 \u0442\u0435\u0431\u044f \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043d\u0430 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0421\u044e\u0434\u0430 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043d\u0435\u0441\u0442\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f Kafka (\u0445\u043e\u0442\u044c \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440) \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0435-\u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0435 (Gitlab Runner \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435). \u0423\u0436\u0435 \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c \u0430\u0431\u0437\u0430\u0446\u0435\u043c \u0432\u044b\u0448\u0435, \u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0441\u043b\u0430\u0431\u043e\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u043e\u0439.<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 2. &#171;\u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044c \u043b\u043e\u0433\u0438\u043a\u0443, \u0437\u0430\u0431\u0435\u0439 \u043d\u0430 \u043b\u043e\u0433\u0438&#187;<\/strong><\/p>\n<p>\u0414\u0430, \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u0442\u0430\u043f &#8212; \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u0440\u0438 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 Spring \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u0438\u0448\u0443\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a Kafka:<\/p>\n<pre><code>[org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] requestId: INFO  o.apache.kafka.clients.NetworkClient - [Consumer clientId=Consumer-0, groupId=app-group] Node -1 disconnected. [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] requestId: WARN  o.apache.kafka.clients.NetworkClient - [Consumer clientId=Consumer-0, groupId=app-group] Connection to node -1 (localhost\/127.0.0.1:3333) could not be established. Broker may not be available. [org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1] requestId: WARN  o.apache.kafka.clients.NetworkClient - [Consumer clientId=Consumer-0, groupId=app-group] Bootstrap broker localhost:3333 (id: -1 rack: null) disconnected<\/code><\/pre>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0438 \u044d\u0442\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u0430 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043f\u043e\u043c\u0435\u0448\u0430\u044e\u0442 \u0440\u0430\u0431\u043e\u0442\u0435 \u0432\u0441\u0435\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435. \u041d\u043e \u0435\u0441\u043b\u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u043e\u0432 \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 5-10, \u0442\u043e \u0442\u0430\u043a\u0438\u0445 \u043b\u043e\u0433\u043e\u0432 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0449\u0443\u0442\u0438\u043c\u043e \u043c\u043d\u043e\u0433\u043e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u044b \u043e\u0431\u0449\u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043c\u0430 \u043b\u043e\u0433\u043e\u0432 \u043f\u0440\u0438 \u0442\u0435\u0441\u0442\u0430\u0445), \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432\u043b\u0438\u044f\u0442\u044c \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 3. &#171;\u0414\u0430 \u0437\u0430\u043c\u043e\u043a\u0430\u0439 \u0442\u044b \u0434\u0430 \u0438 \u0432\u0441\u0451..&#187;<\/strong> <\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0432\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0443\u0441\u043b\u044b\u0448\u0430\u043b \u0438\u043b\u0438 \u0443\u0432\u0438\u0434\u0435\u043b &#8212; \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043c\u043e\u043a\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u044b \u0438\/\u0438\u043b\u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u044b. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a (\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0435\u043a\u0438\u0439 BaseTest \u0434\u043b\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430):<\/p>\n<pre><code class=\"java\">@SpringJUnitConfig @SpringBootTest @EnableConfigurationProperties(ApplicationProperties.class) public abstract class BaseTest {      @MockBean(name = \"kafkaProducer\")     protected KafkaProducer kafkaProducer;     @MockBean     protected UserConsumer userConsumer;   }<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u043b\u043e\u0432\u0438\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u0430 \u043a Kafka, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0438 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u044b, \u043d\u0438 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u044b \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430. \u0410 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043c\u043e\u043a\u0430\u043d\u044b.<\/p>\n<p>\u0418 \u043a\u0441\u0442\u0430\u0442\u0438, \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430 \u044d\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442! \u041c\u043e\u043a\u0430\u044f KafkaProducer &#8212; \u0442\u043e \u0435\u0441\u0442\u044c \u0431\u0438\u043d \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 Kafka, \u043c\u044b \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0431\u0438\u043d \u043a\u043b\u0430\u0441\u0441\u0430-\u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0430 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0438 \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u043d\u0435\u0433\u043e \u0442\u0435\u0441\u0442:<\/p>\n<pre><code class=\"java\">class UserProducerTest extends BaseTest {      @Autowired     private UserProducer userProducer;      @Test     void testUserProducer() {       log.info(\"\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443\");       userProducer.produce();     }   }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u043a\u043e\u043d\u0441\u044e\u043c\u0435\u0440? \u041d\u0443, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">class UserConsumerTest extends BaseTest {      private final UserConsumer userConsumer = new UserConsumer(&lt;\u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438>);      @Test     void testUserProducer() {       log.info(\"\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443\");       userConsumer.consume();     }   }<\/code><\/pre>\n<p>\u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432 UserConsumer \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b\/\u043a\u043b\u0430\u0441\u0441\u044b? \u0418\u0445 \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0442\u0443\u0442, \u043b\u0438\u0431\u043e \u0432\u0437\u044f\u0442\u044c \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0440\u0443\u0447\u043d\u0430\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e, \u0437\u0430\u043c\u043e\u043a\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440 &#8212; \u043e\u043a, \u0437\u0430\u043c\u043e\u043a\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440? \u0421\u043e\u043c\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u041e\u041a\u042d &#8212; \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e (\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 Spring, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435, \u043d\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0440\u0430\u0437\u043d\u044b\u0435). <\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 4. &#171;\u0414\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u044c\u043c\u0438 EmbeddedKafka, \u043e\u043d\u0430 \u0436\u0435 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u0430!&#187;<\/strong><\/p>\n<p>\u0414\u0430, \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 &#8212; \u043f\u043e\u0434\u043d\u044f\u0442\u044c EmbeddedKafka \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432. \u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e &#8212; \u0432\u0435\u0448\u0430\u0435\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e \u043d\u0430 \u0442\u0435\u0441\u0442:<\/p>\n<pre><code class=\"java\">@EmbeddedKafka(partitions = 1, brokerProperties = { \"listeners=PLAINTEXT:\/\/localhost:9092\", \"port=9092\" })<\/code><\/pre>\n<p>\u0418 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0432 maven (\u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435):<\/p>\n<pre><code class=\"xml\">&lt;dependency>     &lt;groupId>org.springframework.kafka&lt;\/groupId>     &lt;artifactId>spring-kafka-test&lt;\/artifactId> &lt;\/dependency><\/code><\/pre>\n<p>\u041a\u0430\u043a\u0438\u0435 \u043f\u043b\u044e\u0441\u044b? \u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u0447\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0443 \u043d\u0430\u0441 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0430\u044f embedded Kafka \u0432 \u0442\u0435\u0441\u0442\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u0444\u043b\u043e\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043c \u0432 \u043a\u043e\u043d\u0441\u044c\u044e\u043c\u0435\u0440\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0438 \u0432 \u043f\u0440\u043e\u0434\u044e\u0441\u0435\u0440\u0435.<\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0443\u0442: <a href=\"https:\/\/www.baeldung.com\/spring-boot-kafka-testing\">https:\/\/www.baeldung.com\/spring-boot-kafka-testing<\/a><\/p>\n<p>\u042f \u043b\u0438\u0448\u044c \u0441\u043a\u0430\u0436\u0443 \u043c\u0438\u043d\u0443\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0448\u0435\u043b: \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c spring-kafka-test \u0442\u044f\u043d\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u0442\u0440\u0430\u043d\u0437\u0438\u0442\u0438\u0432\u043d\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043d\u0430 scala:<\/p>\n<ul>\n<li>\n<p>jackson-module-scala_2.13<\/p>\n<\/li>\n<li>\n<p>scala-collection-compat_2.13<\/p>\n<\/li>\n<li>\n<p>scala-java8-compat_2.13<\/p>\n<\/li>\n<li>\n<p>scala-library<\/p>\n<\/li>\n<li>\n<p>scala-logging_2.13<\/p>\n<\/li>\n<li>\n<p>scala-reflect<\/p>\n<\/li>\n<\/ul>\n<p>\u0418 \u0432 \u0446\u0435\u043b\u043e\u043c-\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e &#171;\u043d\u0443 \u0438 \u043b\u0430\u0434\u043d\u043e, \u043d\u0443 \u0438 \u043f\u0443\u0441\u043a\u0430\u0439, \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u0435\u0441\u0442\u0430\u0445&#187;. \u041d\u043e \u044d\u0442\u0438 \u043b\u0438\u0431\u044b \u0432\u043b\u0438\u044f\u044e\u0442 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u043e\u0434\u0430! \u042f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043b\u043e\u0432\u0438\u043b \u0442\u0430\u043a\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<pre><code class=\"java\">ClassCast class scala.collection.immutable.$colon$colon cannot be cast to class java.util.List (scala.collection.immutable.$colon$colon is in unnamed module of loader 'app'; java.util.List is in module java.base of loader 'bootstrap')<\/code><\/pre>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u043c\u044b \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0438 \u0432 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u043f\u0430\u043a\u0435\u0442 scala. \u041d\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"http:\/\/querydsl.com\/\">querydsl<\/a>. \u0418 \u043f\u0440\u0438 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 &#171;\u043f\u043e\u0434\u0441\u0442\u0430\u0432\u0430&#187;. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u044d\u0442\u043e \u043b\u0435\u0433\u043a\u043e \u0447\u0438\u043d\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0447\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 maven-\u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u043d\u043e \u043a\u043e\u043f\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u043c \u043d\u0435 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c.<\/p>\n<p><strong>\u0427\u0430\u0441\u0442\u044c 5. &#171;\u041d\u0443 \u0442\u043e\u0433\u0434\u0430 \u0442\u0435\u0431\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 testcontainers, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0439 \u043d\u0430 \u043d\u0435\u043c Kafka!&#187;<\/strong><\/p>\n<p>\u0418 \u043f\u0440\u0430\u0432\u0434\u0430, \u043f\u043e\u043c\u043e\u0436\u0435\u0442. \u0423 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 Spring Boot \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 testcontainers, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445.<\/p>\n<p>\u0410\u0445 \u0434\u0430, \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u044f \u0432\u0441\u043a\u043e\u043b\u044c\u0437\u044c \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b, \u0447\u0442\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c AVRO \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043f\u043e Kafka. \u0422\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Schema Registry (SR). \u0410 \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u043d\u0443\u0436\u043d\u043e<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-377083","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/377083","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=377083"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/377083\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=377083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=377083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=377083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}