Toʻlovni tasdiqlash integratsiyasi hodisasi ishlov beruvchisini yaratish

Toʻlovni tasdiqlash integratsiyasi hodisasi ishlov beruvchisini yaratish

1. Kirish

Mikroservislar arxitekturasi (MSA) muhitida har bir domen xizmati mustaqil biznes mas’uliyatlari va ma’lumotlar bazasiga ega. Ushbu tizimdagi davomat va ta’til domeni (Timecard/Leave xizmatlari) ham o‘z hayotiy sikli orqali ishlaydi; biroq foydalanuvchilarning ta’til arizalari (LeavePlan) va maxsus ish arizalari kabi asosiy biznes jarayonlari korxona miqyosidagi umumiy domen — External Approval Service bilan yaqin integratsiyani talab qiladi. Mavjud jarayonda tasdiqlash holatlari xizmat ichida boshqarilar edi, ammo kompaniya miqyosidagi elektron tasdiqlashlarni standartlashtirish tashqi tasdiqlash xizmati bilan integratsiya pipeline'ini yaratishni talab qildi. Biroq MSA muhitida tashqi tasdiqlash tizimi bilan aloqa oddiy sinxron yondashuv orqali amalga oshirilsa, tasdiqlash serveridagi kechikishlar yoki nosozliklar ichki xizmatlarga tranzaksiyalar bloklanishi ko‘rinishida tarqalishi mumkin. Bundan tashqari, tasdiqlash liniyasidagi tasdiqlash (Approved), rad etish (Rejected) va qaytarib olish (Withdrawn) foydalanuvchi qoralama arizani yuborganidan keyin asinxron tarzda sodir bo‘lgani sababli, ikki xizmat o‘rtasida eventual konsistentlikni kafolatlaydigan arxitektura talab etildi. Ushbu maqolada timecard-facade'ning inbound qatlamida ApprovalStatusHandler yaratilgani hamda SubmitLeaveRequestTask va LeavePlanTask bilan birlashtirilib, MSA muhitida asinxron, hodisaga asoslangan tasdiqlash holatini sinxronlashtirish pipeline'i yakunlangani haqidagi amaliy joriy etish holati bayon qilinadi.

2. Texnologiyani tanlash asoslari

Tashqi tasdiqlash xizmati bilan integratsiya arxitekturasini loyihalashda hal qilinishi kerak bo‘lgan asosiy muammolar quyidagilardan iborat edi.

  1. Nosozliklarni izolyatsiya qilish va asinxron ajratish: Tashqi tasdiqlash tizimidagi trafikning keskin oshishi yoki texnik xizmat ko‘rsatish davomat xizmatining mavjudligiga ta’sir qilmasligi uchun tasdiqlash yakuni natijasini asinxron hodisa xabari sifatida qabul qiladigan tuzilmani joriy etdik.

  2. Tashqi identifikator (approvalId) asosida domenlarni bog‘lash: Tashqi tasdiqlash xizmati tomonidan yaratiladigan tasdiqlash hujjati identifikatori (approvalId) ichki ta’til arizasi entiteti (LeavePlan) bilan foreign key (Reference Key) shaklida bog‘landi. Shu orqali keyinchalik asinxron holat o‘zgarishi hodisalari qabul qilinganda maqsadli domenni aniq izlash imkoniyati yaratildi.

  3. Hodisa idempotentligi va holat o‘tishlarini tekshirish: Tarmoq orqali qayta yuborish sababli bir xil tasdiqlash yakuni hodisasi bir necha marta qabul qilingan taqdirda ham ichki ma’lumotlar buzilishining oldini olish uchun entitet darajasidagi idempotentlik himoyasini (State-based Guard) loyihalashtirdik.

Shu sababli tashqi xizmatdagi holat o‘zgarishlarini xavfsiz kuzatish va taqsimlangan muhitda ma’lumotlar yaxlitligini ta’minlash bilan birga, tizimlar o‘rtasidagi bog‘liqlikni kamaytiradigan yechim sifatida inbound hodisa handler'iga asoslangan holatni sinxronlashtirish pattern'ini joriy etdik.

3. Joriy etish jarayoni va muammolarni bartaraf etish

Ushbu bo‘limda loyihadagi amaliy tasdiqlash integratsiyasi pipeline'ining loyihalash tamoyillari asosida tashqi tasdiqlash xizmati ichki domen bilan qanday xavfsiz integratsiya qilingani, jumladan, muayyan kod bloklari batafsil tushuntiriladi.

3.1 Tasdiqlash xizmatiga yuborish so‘rovi va identifikatorni bog‘lash (SubmitLeaveRequestTask)

Foydalanuvchi ta’til arizasini yuborganida, SubmitLeaveRequestTask tashqi tasdiqlash hujjati identifikatori (approvalId) taqdim etilganini tekshiradi va boshlang‘ich holatni InApproval (tasdiqlash jarayonda) qiymatiga o‘rnatadi. Tekshiruvlarni (qolgan kunlar va ustma-ust tushadigan davrlarni tekshirish) bajargach, approvalId qiymatini LeavePlan entitetida saqlaydi. Shu tariqa keyinchalik asinxron tarzda keladigan tasdiqlash natijasi hodisalarini kuzata oladigan bir yo‘nalishli bog‘lash tuzilmasi yakunlanadi.

@Service
@RequiredArgsConstructor
public class SubmitLeaveRequestTask {

    private final LeavePlanLogic leavePlanLogic;
    private final LeavePermitLogic leavePermitLogic;

    public String submitLeaveRequest(String citizenId, LocalDate startDate, LocalDate endDate,
                                     LeaveType leaveType, double leaveDays, String approvalId) {

        LeavePermit leavePermit = getLeavePermit(citizenId, startDate.getYear());
        leavePermit.planLeave(leaveDays);
        leavePermitLogic.modifyLeavePermit(leavePermit);

        LeavePlanCdo leavePlanCdo = LeavePlanCdo.builder()
                .citizenId(citizenId)
                .leaveType(leaveType)
                .planStatus(StringUtils.hasText(approvalId) ? PlanStatus.InApproval : PlanStatus.Planned)
                .approvalId(approvalId)
                .build();

        return leavePlanLogic.registerLeavePlan(leavePlanCdo);
    }
}

3.2 Tasdiqlash holati hodisalarini qabul qilish va yo‘naltirish (ApprovalStatusHandler)

Tashqi elektron tasdiqlash tizimida tasdiqlash liniyasidagi yakuniy tasdiq, rad etish yoki yuborilgan qoralama arizani qaytarib olish kabi holat o‘zgarishi yuz berganda, hodisa payload'i inbound consumer kanali orqali kiradi. ApprovalStatusHandler tashqi tasdiqlash xizmatining hodisa spetsifikatsiyasini ichki domen yadrosidan ajratib turadigan adapter vazifasini bajaradi va qabul qilingan tasdiqlash holatiga (status) muvofiq ishlov berishni tegishli domen Task metodiga yo‘naltiradi.

@Component
@RequiredArgsConstructor
public class ApprovalStatusHandler {

    private final LeavePlanTask leavePlanTask;

    public void handleApprovalStatusChanged(ApprovalStatusEventPayload payload) {
        String approvalId = payload.getDocumentId();
        ApprovalStatus status = payload.getStatus();

        switch (status) {
            case Approved -> leavePlanTask.approveLeavePlanByApprovalId(approvalId, payload.getApproverId());
            case Rejected -> leavePlanTask.rejectLeavePlanByApprovalId(approvalId, payload.getRejectReason());
            case Cancel -> leavePlanTask.cancelLeavePlanByApprovalId(approvalId);
            default -> {
                log.info("Approval transient state received: {}", status);
            }
        }
    }
}

3.3 Domen idempotentligini tekshirish va holatni yangilash (LeavePlanTask)

LeavePlanTask tashqi tasdiqlash identifikatori (approvalId) asosida ichki domen entitetini izlaydi. U entitetning joriy holatini (PlanStatus.Approved) oldindan tekshirish orqali idempotentlik himoyasini (State-based Guard) amalga oshiradi. Shu bilan tarmoq orqali qayta urinishlar yoki xabarlarning takroran yetkazilishi sababli allaqachon yakunlangan tasdiqlash hodisasi yana qabul qilingan taqdirda ham tizim noto‘g‘ri ishlamasligi ta’minlanadi. Faqat yaroqli o‘tishlar holat o‘zgarishiga va tasdiqlash metama’lumotlarining saqlanishiga olib keladi; shundan so‘ng keyingi jarayonlarni xavfsiz ishga tushirish uchun tasdiqlash yakunlanganini bildiruvchi yakuniy domen hodisasi e’lon qilinadi.

@Component
@RequiredArgsConstructor
public class LeavePlanTask {

    private final LeavePlanStore leavePlanStore;
    private final EventPublisher eventPublisher;

    @Transactional
    public void approveLeavePlanByApprovalId(String approvalId, String approverId) {
        LeavePlan leavePlan = leavePlanStore.findByApprovalId(approvalId)
                .orElseThrow(() -> new NoSuchElementException("연동된 휴가 건이 없습니다: " + approvalId));

        if (leavePlan.getPlanStatus() == PlanStatus.Approved) {
            return;
        }

        leavePlan.setPlanStatus(PlanStatus.Approved);
        leavePlan.setApproverId(approverId);
        leavePlan.setApprovedTime(System.currentTimeMillis());
        leavePlanStore.update(leavePlan);

        eventPublisher.publish(new LeavePlanEvent(leavePlan.getId(),     leavePlan.getRequesterId(), PlanStatus.Approved));
    }
}

3.4 Muammolarni bartaraf etish: Tasdiqlash holati o‘zgarishlari va DB CHECK cheklovlari o‘rtasidagi nomuvofiqliklarni hal qilish

Tasdiqlash xizmatini integratsiya qilishning dastlabki bosqichlarida foydalanuvchi tasdiqlash so‘rovini yuborganidan keyin ichki domen holati o‘zgartirilayotganda DB darajasidagi CHECK (plan_status IN (...)) cheklovi buzilishi yuz berdi. Mavjud ichki state-machine sxemasida faqat xizmatning o‘z tasdiqlash jarayoniga asoslangan holat qiymatlari belgilangan edi, shu sababli tashqi tasdiqlash xizmati bilan integratsiya uchun qo‘shilgan batafsil hayotiy sikl holati (InApproval) mavjud emas edi. Ushbu muammoni hal qilish uchun ma’lumotlar bazasi cheklovlarini eng so‘nggi tasdiqlash hayotiy sikli bilan sinxronlashtiradigan Flyway migration skriptini qo‘lladik hamda runtime ma’lumotlar konsistentligini ta’minlash uchun LeavePlanTask'ga istisno holatida rollback himoyasini qo‘shdik.

4. Natijalar va erishilgan yutuqlar

Asinxron tasdiqlash integratsiyasi event-handler arxitekturasini kompaniyaning asosiy davomat va ta’til domenlariga qo‘llash quyidagi texnik yutuqlarni berdi.

  • MSA tizimlari o‘rtasidagi bog‘liqlikni kamaytirish va nosozliklarni izolyatsiya qilish: Tashqi elektron tasdiqlash xizmatidagi trafikning keskin oshishi yoki vaqtinchalik nosozliklar davomat xizmatining asosiy funksiyalariga tarqalmasligini ta’minlab, to‘liq nosozlik izolyatsiyasiga erishdik.

  • Taqsimlangan ma’lumotlar konsistentligini ta’minlash: Tashqi tasdiqlash identifikatoriga (approvalId) asoslangan idempotent handler dizayni orqali tasdiqlash hujjatlari va ichki domen ma’lumotlari o‘rtasidagi konsistentlikni ishonchli saqladik; bunda takroriy hodisalarga ishlov berish yoki tarmoq orqali qayta urinishlar sababli hodisalarning o‘tkazib yuborilishi yuz bermadi.

  • Standart integratsiya arxitekturasini shakllantirish: ApprovalStatusHandler'ni qatlamlarga ajratish va modullashtirish orqali tasdiqlash xizmati bilan integratsiyani talab qiladigan yangi domenlarga, masalan, maxsus ish va xizmat safarlariga kengayishda izchil qayta foydalanish mumkin bo‘lgan ichki standart integratsiya pattern'ini yaratdik.

5. Xulosa

Ushbu tasdiqlash integratsiyasi event handler'ini joriy etish MSA muhitida tashqi xizmatlar bilan aloqa qilishda domenlar o‘rtasidagi bog‘liqlikni kamaytiradigan va ma’lumotlar yaxlitligini ishonchli himoya qiladigan backend arxitekturasi dizaynining muhimligini anglash imkonini berdi.

Oddiy sinxron API chaqiruvlaridan voz kechib, asinxron hodisa handler'ini (ApprovalStatusHandler), shuningdek, entitet darajasidagi idempotent holat yangilash dizaynini joriy etish orqali tizimlar o‘rtasida ham nosozliklarni izolyatsiya qilishga, ham eventual konsistentlikka erisha oldik. Ushbu loyiha orqali shakllangan tashqi xizmatlar integratsiyasi pattern'lari va holatni sinxronlashtirish bo‘yicha tajribani ichki standart yo‘riqnomalarga aylantirishni rejalashtirmoqdamiz. Shu orqali kompaniyaning taqsimlangan tizimlari arxitekturasi barqarorligini keyingi bosqichga olib chiqishga hissa qo‘shamiz.

* Foydalanilgan manbalar

  • Enterprise Integration Patterns - Event-Driven Consumer & Message Dispatcher

  • Chris Richardson - Microservices Patterns (Saga and Asynchronous Messaging)

  • Spring Framework Official Documentation - Integration and Event Listeners

D.Hyeok

Site footer