Menggunakan mesin Spring state pada contoh protokol ROSEU
Artikel ini menjelaskan penggunaan mesin Spring state menggunakan contoh membangun koneksi sesuai dengan teknologi ROSEU. Koneksi dibuat antara dua operator EDO dalam mode point-to-point atau melalui pusat roaming. Ini menjelaskan cara mengelola negara, beralih negara dengan acara, dan melakukan tindakan yang ditentukan ketika mengubah negara. Jika tertarik, maka saya minta kucing.

Protokol ROSEU dijelaskan secara rinci di
sini .
Untuk sebuah artikel, kita hanya perlu mengetahui prinsip membangun koneksi antara dua klien EDI. Masing-masing dari mereka mengirim undangan untuk membuat koneksi. Jenis undangan adalah "Permintaan" atau "Istirahat".
Untuk membuat koneksi, kedua peserta dalam alur kerja harus mengirim undangan dari jenis "Permintaan". Setelah itu, koneksi dianggap terjalin.
Jika salah satu peserta mengirim undangan jenis "Break", maka koneksi terputus.
Dalam sistem kami, kami menetapkan tujuh status yang mungkin untuk peserta EDI.
- Koneksi gagal - NO_CONNECTION
- Klien kami telah mengirim undangan untuk roaming. Tapi kami belum mengirimkannya. Itu dibenarkan oleh asinkroni institusi aplikasi dan pengirimannya ke pusat roaming. - INVITATION_SAVED
- Koneksi berhasil dibuat - ARE_CONNECTED
- Koneksi terputus atas inisiatif salah satu peserta - CONNECTION_BROKEN
- Undangan eksternal datang, klien kami tidak mengirim apa pun sebelumnya - INVITATION_RECEIVED
- Undangan klien kami diterima oleh pusat roaming - INVITATION_SEND
- Kesalahan Koneksi - CONNECTION_ERROR
Kemungkinan acara:
- Klien kami mengirim undangan ke "Permintaan". - OUTCOME_INVITATION
- Klien kami mengirim undangan "Break" - OUTCOME_REJECT
- Klien eksternal mengirim undangan "Permintaan" - INCOME_INVITATION
- Klien eksternal mengirim undangan "Istirahat" - INCOME_REJECT
- Roaming Center berhasil menerima undangan - RC_SUCCESS
- Pusat roaming tidak menerima undangan - RC_ERROR
Tabel pengalihan status. Baris pertama adalah status awal. Kolom pertama adalah acara. Di persimpangan - status baru.

Peralihan status seperti itu dapat dikodekan melalui sakelar, jika, jika-lain. Tetapi melalui mesin negara, menurut saya, ini akan lebih nyaman.
Logikanya adalah sebagai berikut - jika seseorang terputus, maka siapa pun dapat membangun kembali. Jika terjadi kesalahan saat membuat koneksi, maka tidak ada lagi yang bisa dilakukan, koreksi manual dari masalah diperlukan.
Dokumentasi terperinci tentang mesin Spring state diambil
dari sini .
Kami akan menciptakan mobil melalui pembangun
StateMachineBuilder.Builder<ClientsState, ContractorEvent> builder = StateMachineBuilder.builder();
Selanjutnya, kami mengatur semua status yang mungkin. Status awal diatur ke status pelanggan saat ini.
builder.configureStates() .withStates() .initial(initialState) .states(EnumSet.allOf(ClientsState.class));
Kami mengkonfigurasi autostart mobil. Jika tidak, Anda harus memulai secara manual
builder.configureConfiguration() .withConfiguration() .autoStartup(true);
Selanjutnya, kami meresepkan tahapan.
sumber - status awal,
target - status akhir,
peristiwa - peristiwa di mana peralihan status terjadi,
tindakan - memperbarui status klien.
builder.configureTransitions() .withExternal() .source(NO_CONNECTION) .target(INVITATION_RECEIVED) .event(INCOME_INVITATION) .action(updateStateAction) .and() .withExternal() .source(NO_CONNECTION) .target(CONNECTION_BROKEN) .event(INCOME_REJECT) .action(updateStateAction)
Setelah membuat mesin status, kami meneruskan
acara ke inputnya. Tetapi kami dalam
aksi memerlukan informasi tambahan untuk memperbarui status pelanggan. Oleh karena itu, kami membungkus
acara dalam
pesan dan memasukkan data yang diperlukan di
header .
StateMachine<ClientsState, ContractorEvent> sm = builder.build(); Map<String, Object> clients = new HashMap<>(); clients.put("client1", "client11"); clients.put("client2", "client22"); MessageHeaders headers = new MessageHeaders(clients); Message<ContractorEvent> message = new GenericMessage<>(event, headers); sm.sendEvent(message); sm.stop();
Selanjutnya dalam
tindakan data ini diekstraksi dan digunakan.
@Service public class UpdateStateAction implements Action<ClientsState, ContractorEvent> { @Override public void execute(StateContext<ClientsState, ContractorEvent> context) { System.out.println("Source state: " + context.getSource()); System.out.println("Target state: " + context.getTarget()); System.out.println("Event: " + context.getEvent()); MessageHeaders headers = context.getMessageHeaders(); System.out.println(headers.get("client1")); System.out.println(headers.get("client2")); } }
Anda juga dapat menggunakan
penjaga untuk mencegah perubahan status, tetapi dalam kasus kami ini tidak perlu.
Pada dasarnya itu. Kode sumber untuk contoh dapat diambil dari
tautan .
Dalam artikel tersebut, kami memeriksa cara menggunakan mesin status pegas untuk menyandikan tabel transisi status.
Ini tidak semua kemampuannya, tetapi hanya yang paling dasar. Saya harap artikel ini bermanfaat dan mendorong Anda untuk menggunakan kerangka kerja ini.
Jika Anda memiliki pengalaman pribadi menggunakannya, selamat datang untuk berkomentar.
UPD
Selama penggunaan, fitur yang menarik terungkap - dalam kasus pengecualian dalam salah satu tindakan default, kesalahan tidak dilemparkan, tetapi hanya dicatat. Dalam hal ini, eksekusi seluruh mesin negara tidak berhenti. Dan bahkan metode hasStateMachineError mengembalikan false.
Sebagai keputusan, kami membuat AbstractAction di mana kami menangkap pengecualian dan memasukkannya ke dalam konteks mesin keadaan. Setelah itu, dalam kasus pengecualian, hasStateMachineError mengembalikan true dan kemudian kami memprosesnya lebih lanjut.
@Override public void execute(StateContext<StatesEnum, OperationsEnum> context) { try { prepareContext(context); executeInternal(context); } catch (Exception e) { logger.error(" state machine", e); context.getStateMachine().setStateMachineError(e); } }