Integrációs minták Apache tevével

1. Áttekintés

Ez a cikk az Apache Camel által támogatott néhány alapvető vállalati integrációs mintát (EIP) ismerteti. Az integrációs minták segítséget nyújtanak a rendszerek integrálásának szabványosított módszereire.

Ha először át kell tekintenie az Apache Camel alapjait, feltétlenül látogassa meg ezt a cikket, hogy bővítse az alapokat.

2. Az EIP-kről

A vállalati integrációs minták olyan tervezési minták, amelyek célja az integrációs kihívások megoldásának biztosítása. A teve számos ilyen minta megvalósítását biztosítja. A támogatott minták teljes listájának megtekintéséhez látogassa meg ezt a linket.

Ebben a cikkben a Tartalom alapú útválasztó, az Üzenetfordító, a Multicast, a Splitter és a Dead Letter Channel integrációs mintáival foglalkozunk.

2. Tartalom alapú útválasztó

A Tartalomalapú útválasztó egy olyan útválasztó, amely egy üzenet fejlécének, a hasznos teher egy részének vagy alapvetően bárminek az üzenetcseréből származó, általunk tartalomnak tekintett üzenet alapján továbbítja az üzenetet a rendeltetési helyre.

Azzal kezdődik választás() DSL utasítás, amelyet egy vagy több követ mikor() DSL utasítások. Minden egyes mikor() állítmánykifejezést tartalmaz, amely kielégítés esetén magában foglalja a feldolgozott lépések végrehajtását.

Illusztráljuk ezt az EIP-t úgy, hogy meghatározunk egy útvonalat, amely egy mappa fájljait használja fel, és a fájlkiterjesztéstől függően két különböző mappába helyezi át őket. Útvonalunkra Spring XML fájlban hivatkozunk a Camel egyedi XML szintaxisával:

Az útvonal meghatározása a ContentBasedFileRouter osztály, ahol a fájlokat a forrásmappából két különböző célmappába továbbítják, a kiterjesztésüktől függően.

Alternatív megoldásként itt használhatnánk a Spring Java config megközelítést, a Spring XML fájl helyett. Ehhez hozzá kell adnunk egy további függőséget a projektünkhöz:

 org.apache.camel camel-spring-javaconfig 2.18.1 

A műtárgy legújabb verziója itt található.

Ezt követően ki kell terjesztenünk CamelConfiguration osztály és felülírja útvonalak () módszer, amely hivatkozni fog ContentBasedFileRouter:

A @Configuration public class ContentBasedFileRouterConfig kiterjeszti a CamelConfiguration {@Bean ContentBasedFileRouter getContentBasedFileRouter () {return new ContentBasedFileRouter (); } @Orride public List Routes () {return Arrays.asList (getContentBasedFileRouter ()); }}

A kiterjesztést a Simple Expression Language segítségével értékelik egyszerű() DSL utasítás, amelyet kifejezések és predikátumok értékelésére szántak:

public class ContentBasedFileRouter kiterjeszti a RouteBuilder {private static final String SOURCE_FOLDER = "src / test / source-folder"; privát statikus végső karakterlánc DESTINATION_FOLDER_TXT = "src / test / destination-folder-txt"; privát statikus végső karakterlánc DESTINATION_FOLDER_OTHER = "src / teszt / cél-mappa-egyéb"; A @Orride public void configure () a (z) (kivétel: "(file: //" + SOURCE_FOLDER + "? Delete = true") kivételt dobja. Choice () .when (simple ("$ {file: ext} == 'txt'" )) .to ("fájl: //" + DESTINATION_FOLDER_TXT) .egyébként () .to ("fájl: //" + DESTINATION_FOLDER_OTHER); }}

Itt emellett használjuk másképp() DSL utasítás az összes olyan üzenet továbbításához, amelyek nem felelnek meg a vele megadott predikátumoknak mikor() nyilatkozatok.

3. Üzenetfordító

Mivel minden rendszer a saját adatformátumát használja, gyakran meg kell fordítania egy másik rendszerről érkező üzenetet a célrendszer által támogatott adatformátumba.

Teve támogatja MessageTranslator útválasztó, amely lehetővé teszi számunkra az üzenetek átalakítását az útválasztási logika bármelyik egyedi processzorának használatával, egy speciális bab felhasználásával az átalakítás végrehajtásához, vagy átalakítás () DSL nyilatkozat.

Példa egyedi processzor használatára az előző cikkben található, ahol meghatároztunk egy processzort, amely időbélyeget készít az egyes bejövő fájlok fájlneveihez.

Bemutatjuk, hogyan kell használni az Üzenetfordítót átalakítás () nyilatkozat:

public class MessageTranslatorFileRouter kiterjeszti a RouteBuilder {private static final String SOURCE_FOLDER = "src / test / source-folder"; privát statikus végső karakterlánc DESTINATION_FOLDER = "src / test / destination-folder"; A @Orride public void configure () a (z) (kivétel: "(file: //" + SOURCE_FOLDER + "? Delete = true") .transform (body (). Append (header (Exchange.FILE_NAME)))). : // "+ DESTINATION_FOLDER); }}

Ebben a példában a fájlnevet a fájl tartalmához csatoljuk átalakítás () utasítás minden fájlhoz a forrás mappából, és az átalakított fájlok áthelyezése egy célmappába.

4. Multicast

A multicast lehetővé teszi számunkra, hogy irányítsa ugyanazt az üzenetet különböző végpontok halmazába, és más módon dolgozza fel őket.

Ez a használatával lehetséges multicast () DSL utasítás, majd a végpontok és a bennük lévő feldolgozási lépések felsorolásával.

Alapértelmezés szerint a különböző végpontokon történő feldolgozás nem párhuzamosan zajlik, de a használatával ez megváltoztatható párhuzamos feldolgozás() DSL nyilatkozat.

Camel alapértelmezés szerint a multicast után az utolsó választ használja kimenő üzenetként. Lehetséges azonban egy másik összesítési stratégia meghatározása, amelyet a multicast válaszok összegyűjtésére használnak.

Lássuk, hogyan néz ki a Multicast EIP egy példán. Fájlokat gyűjtünk a forrásmappából két különböző útvonalra, ahol átalakítjuk a tartalmukat, és elküldjük őket különböző célmappákba. Itt használjuk közvetlen: komponens, amely lehetővé teszi számunkra, hogy két útvonalat összekapcsoljunk:

public class MulticastFileRouter kiterjeszti a RouteBuilder {private static final String SOURCE_FOLDER = "src / test / source-folder"; privát statikus végső karakterlánc DESTINATION_FOLDER_WORLD = "src / test / destination-folder-world"; privát statikus végső karakterlánc DESTINATION_FOLDER_HELLO = "src / test / destination-folder-hello"; A @Orride public void configure () a (z) (kivétel: "(file: //" + SOURCE_FOLDER + "? Delete = true") .multicast () .to ("direct: append", "direct: prepend"). End ( ); from ("direct: append") .transform (body (). append ("World")) .to ("file: //" + DESTINATION_FOLDER_WORLD); from ("direct: prepend") .transform (body (). prepend ("Hello")) .to ("file: //" + DESTINATION_FOLDER_HELLO); }}

5. Hasító

A hasító lehetővé teszi számunkra, hogy ossza fel a bejövő üzenetet több darabra, és mindegyiket külön-külön dolgozza fel. Ez a használatával lehetséges hasított() DSL nyilatkozat.

A Multicasttal szemben a Splitter megváltoztatja a bejövő üzenetet, míg a Multicast a jelenlegi állapotában hagyja.

Ennek példaként való bemutatásához meghatározunk egy útvonalat, ahol a fájl minden sora fel van osztva, és átalakul egy különálló fájlba, majd egy másik célmappába kerül. Minden új fájlt a fájl tartalmával megegyező fájlnévvel hozunk létre:

a public class SplitterFileRouter kiterjeszti a RouteBuilder {private static final String SOURCE_FOLDER = "src / test / source-folder"; privát statikus végső karakterlánc DESTINATION_FOLDER = "src / test / destination-folder"; A @Orride public void configure () kivételt dob ​​a {from ("file: //" + SOURCE_FOLDER + "? Delete = true") .split (body (). ConvertToString (). Tokenize ("\ n")) .setHeader ( Exchange.FILE_NAME, body ()) .to ("file: //" + DESTINATION_FOLDER); }}

6. Dead Letter Channel

Gyakori, és számítani kell arra, hogy néha előfordulhatnak problémák, például az adatbázis holtpontjai, amelyek miatt az üzenet nem a várt módon kerül kézbesítésre. Bizonyos esetekben azonban bizonyos késéssel újrapróbálkozás segít, és egy üzenet feldolgozásra kerül.

A Dead Letter Channel lehetővé teszi számunkra, hogy ellenőrizzük, mi történik egy üzenettel, miután nem sikerült kézbesíteni. A Dead Letter Channel segítségével megadhatjuk, hogy a dobott Kivételt továbbítsuk-e a hívónak, és hova irányítsuk a meghibásodott Exchange-t.

Ha nem sikerül kézbesíteni az üzenetet, a Holt levél levélcsatorna (ha használják) az üzenetet a holt levél végpontjába helyezi.

Bemutassuk ezt egy példán, kivetve az útvonalat:

public class DeadLetterChannelFileRouter kiterjeszti a RouteBuilder {private static final String SOURCE_FOLDER = "src / test / source-folder"; A @Orride public void configure () dobja a {errorHandler (deadLetterChannel ("log: dead? Level = ERROR") kivételt .maximumRedeliveries (3) .redeliveryDelay (1000) .retryAttemptedLogLevel (LoggingLevel.ERROR)); from ("file: //" + SOURCE_FOLDER + "? delete = true") .process (exchange -> {dobjon új IllegalArgumentException ("dobott kivétel!");}); }}

Itt definiáltunk egy errorHandler amely naplózza a sikertelen szállításokat és meghatározza az újraszállítási stratégiát. A beállítással retryAttemptedLogLevel (), minden újraszállítási kísérletet a megadott naplózási szinttel naplózunk.

Annak érdekében, hogy ez teljesen működőképes legyen, be kell állítanunk egy naplózót is.

A teszt futtatása után a következő napló utasítások láthatók a konzolon:

ERROR DeadLetterChannel: 156 - A (MessageId: ID-ZAG0025-50922-1481340325657-0-1 az ExchangeId-n: ID-ZAG0025-50922-1481340325657-0-2) kézbesítése sikertelen. Szállítás kísérlete esetén: 0 fogva: java.lang.IllegalArgumentException: Kivételt dobtak! ERROR DeadLetterChannel: 156 - A (MessageId: ID-ZAG0025-50922-1481340325657-0-1 az ExchangeId-n: ID-ZAG0025-50922-1481340325657-0-2) kézbesítése sikertelen. Szállítás kísérlete esetén: 1 fogott: java.lang.IllegalArgumentException: Kivételt dobtak! ERROR DeadLetterChannel: 156 - A (MessageId: ID-ZAG0025-50922-1481340325657-0-1 az ExchangeId-n: ID-ZAG0025-50922-1481340325657-0-2) kézbesítése sikertelen. Szállítási kísérlet esetén: 2 elkapva: java.lang.IllegalArgumentException: Kivételt dobtak! ERROR DeadLetterChannel: 156 - A (MessageId: ID-ZAG0025-50922-1481340325657-0-1 az ExchangeId-n: ID-ZAG0025-50922-1481340325657-0-2) kézbesítése sikertelen. Szállítás kísérlete esetén: 3 fogott: java.lang.IllegalArgumentException: Kivételt dobtak! HIBA halott: 156 - Exchange [ExchangePattern: InOnly, BodyType: org.apache.camel.component.file.GenericFile, Body: [A törzs fájl alapú: GenericFile [File.txt]]]

Amint észreveheti, minden újraszállítási kísérlet naplózásra kerül, megjelenítve az Exchange szolgáltatást, amelynek kézbesítése nem volt sikeres.

7. Következtetés

Ebben a cikkben bemutattuk az Apache Camel segítségével történő integrációs minták bevezetését, és néhány példán bemutattuk őket.

Bemutattuk, hogyan kell használni ezeket az integrációs mintákat, és miért hasznosak az integrációs kihívások megoldásában.

A cikk kódja megtalálható a GitHubon.