Zobrazují se příspěvky se štítkemwmq. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemwmq. Zobrazit všechny příspěvky

13. března 2012

WebSphere MQ, interakce s Javou

Pokud se chceme k WebShere MQ (WMQ) připojit z Javy, máme k dispozici dvě možnosti - buď použít WMQ třídy pro Javu, nebo je možné komunikovat pomocí Java Message Service (JMS). Obě možnosti mají svoje pro a proti, takže krátké shrnutí v pár bodech:

  • WMQ třídy pro Javu:
    • zapouzdřují Message Queue Interface (MQI),
    • poskytují plnou sadu funkčností WMQ,
    • je to proprietární řešení, ale jednodušší k používání, než JMS.
  • (WMQ třídy pro) JMS:
    • Java "industry standard" pro messaging,
    • je součástí Java EE specifikace (a tedy součástí většiny (Java) aplikačních serverů),
    • umožňuje spravovat administrované objekty (connection factory, fronty ad.) v centrální repository.
Společná konfigurace
Ať už použijeme jeden, nebo druhý způsob, v obou případech je potřeba mít vytvořené některé objekty. Všechny použité typy objektů jsem popisoval již v minulém zápisu. Jedinou informací navíc je, že vytvořený kanál musí být typu server-connection.


WMQ třídy pro Javu
Třídy pro Javu jsou poměrně přímočaré - stačí, pokud člověk rozumí hierarchii a funkci základních objektů ve WMQ:

  1. Vytvoří se instance Queue Manageru.
  2. Z něj se získá instace Queue, s parametrem daného typu otevření (procházení, vstup, výstup atd.).
  3. Vytvoří se Message a nastaví se jí nějaká data.
  4. Zpráva se vloží do (nebo načte z) fronty.
  5. Zavřou se zdroje.
package com.adastracorp.jprase.wmq.java;

import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;


public class JavaProvider {

    private static final String QM_NAME = "QM_JAVA";
    private static final String HOSTNAME =
                                        "192.168.6.128";
    private static final String CHANNEL =
                                        "JAVA.CHANNEL";
    private static final int PORT = 5557;
    private static final String QUEUE = "JPRASE";

    private static void init() {
        MQEnvironment.hostname = HOSTNAME;
        MQEnvironment.channel = CHANNEL;
        MQEnvironment.port = PORT;
    }

    public static void main(String[] args)
                                    throws Exception  {
        init();

        MQQueueManager queueManager =
                            new MQQueueManager(QM_NAME);
        MQQueue queue = queueManager
                        .accessQueue(QUEUE,
                                     CMQC.MQOO_OUTPUT |
                                     CMQC.MQOO_INQUIRE);

        MQMessage message = new MQMessage();
        message.writeUTF("Hello, WMQ!");

        queue.put(message);

        queue.close();
        queueManager.disconnect();
    }
}

WMQ třídy pro JMS
U JMS je trochu více konfigurace - je potřeba vytvořit Initial Context a do něj vložit Connection Factory a Destination. Destination je mapovaná na (existující) frontu a queue managera. WMQ v současné verzi (7.0.1.2) poskytuje pro JNDI dvě implementace (ale je možné použít i jiné, např. JNDI na WebSphere AS):

  • LDAP server (com.sun.jndi.ldap.com.sun.jndi.fscontext.RefFSContextFactory),
  • File system (com.sun.jndi.fscontext.RefFSContextFactory).


Výsledná konfigurace vypadá takto:


Kód samotný je pak klasické JMS:
  1. Vytvoření InitialContext.
  2. Vyhledání ConnectionFactory.
  3. Vytvoření Connection.
  4. Vytvoření Session.
  5. Vytvoření Destination.
  6. Vytvoření MessageProducer/MessageConsumer.
  7. Vytvoření Message (pro producenta).
  8. Odeslání (příjem) Message.
  9. Zavření zdrojů.
package com.adastracorp.jprase.wmq.jms;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;

public class JmsProvider {

    private static final String CONTEXT_FACTORY =
           "com.sun.jndi.fscontext.RefFSContextFactory";
    private static final String PROVIDER_URL =
           "file:///jms";

    private static Context getContext()
                                throws NamingException {
        Properties env = new Properties();
        env.put(Context.INITIAL_CONTEXT_FACTORY,
                CONTEXT_FACTORY);
        env.put(Context.PROVIDER_URL, PROVIDER_URL);

        return new InitialContext(env);
    }

    public static void main(String[] args)
                                    throws Exception {
        Context context = getContext();

        ConnectionFactory factory = (ConnectionFactory)
                        context.lookup("jmsConnFact");
        Connection connection = factory
                        .createConnection();
        Session session = connection
                    .createSession(false,
                             Session.AUTO_ACKNOWLEDGE);
        Destination destination = session
                        .createQueue("JPRASE");
        MessageProducer producer = session
                        .createProducer(destination);
        producer.setDeliveryMode(
                        DeliveryMode.NON_PERSISTENT);
        TextMessage message = session
                        .createTextMessage(
                                    "Hello, JMS!");
        producer.send(message);

        producer.close();
        session.close();
        connection.close();
    }
}

9. března 2012

WebSphere MQ, vzdálené posílání zpráv

Chystám teď do firmy takovou kumulovanou prezentaci o Enterprise Integration Patterns (EIP), WebSphere MQ (WMQ) a WebSphere Message Brokeru (WMB), tak bych se chtěl postupně podělit o pár konceptů. První z nich je koncept remote messaging na WMQ.

Následující příklad předpokládá již hotovou instalaci WMQ a je zaměřen na komunikaci dvou instancí WMQ - jedna je na lokálním a jedna na vzdáleném prostředí. Pro vyzkoušení, nebo prezentaci je možné použít i jenom jedinou, lokální instanci. Nejdřív si na úvod definujeme základní komponenty, které bude potřeba vytvořit, a které spolu budou komunikovat:

Queue Manager
Správce front vlastní a spravuje fronty, kanály a další objekty. Je to první WMQ objekt, který je nutné na čisté instalaci vytvořit. Správce umožňuje další objekty vytvářet, konfigurovat, spouštět, vypínat atd. Pro přístup k frontám a zprávám poskytuje queue manager dvě rozhraní (API):


Queue
Datová struktura pro ukládání zpráv. V našem příkladu budeme používat čtyři typy front:

  • Local queue - lokální fronta pro ukládání zpráv.
  • Remote queue - definice fronty, která je vlastněná jiným queue managerem.
  • Transmission queue - (lokální fronta,) dočasné úložiště zpráv určených pro vzdáleného queue managera.
  • Dead-letter queue - lokální fronta určená pro nedoručitelné zprávy.

Message Channel
Poskytuje jednosměrnou komunikační cestu pro přenos zpráv z jednoho queue manageru na druhý. Skládá se ze tří částí:
  • odesílající Message Channel Agent (MCA),
  • přijímající MCA,
  • komunikační spojení.
Na odesílajícím konci je vyžadována transmission queue.

Architektura vzdáleného posílání zpráv
Barevně jsou vyznačeny nově vytvářené objekty. V případě, že existuje pouze jedna (lokální) instance WMQ, je možné oba queue managery vytvořit lokálně. Obecný postup vytvoření objektů je následující:

  1. Vytvoření queue managera.
  2. Vytvoření dead-letter queue.
  3. Vytvoření local (remote) queue.
  4. Vytvoření transmission queue.
  5. Vytvoření message channelu.
  6. (Spuštění sender message channelu.)

Jelikož nejde o tutoriál, nebudu popisovat vytvoření jednotlivých objektů - to je dobře popsáno v dokumentaci. Pouze bych zde zmínil, že všechny uvedené objekty lze vytvořit dvěma způsoby - buď pomocí grafického rozhraní MQ Explorer (velice snadné), nebo pomocí MQ Script Commands (MQSC).

Výsledná architektura vypadá takto:


V uvedeném příkladu se zprávy vkládají do fronty SENDER a jsou přenášeno do fronty RECEIVER. Testovací zprávy je možné jednoduše do front vkládat, procházet a mazat pomocí již zmiňovaného MQ Exploreru (opět viz dokumentace). Pokud chcete zaměstnat i dead-letter queue, vložte zprávu do transmission queue QM_JPRASE, objeví se ve frontě DLQ na správci QM_REMOTE (transmission queue vyžaduje speciální hlavičku, která při běžném vložení zprávy do fronty není vyplněná).

A k čemu je to vůbec dobré, posílat zprávu z jednoho queue managera na jiný? Jenom čistě pro posílání zpráv to samozřejmě smysl nemá - na to by stačily fronty definované v rámci jednoho queue managera, ke kterým by se připojovali komunikující konzumenti a provideři.

Smysl to začíná dávat v momentě, pokud potřebuje komunikovat více queue managarů, např. z důvodů high availability, škálovatelnosti apod.

10. října 2011

Enterprise integrace, messaging

Dostal jsem se jako teamleader na integrační projekt, založený na proprietárním řešení/technologii. To proprietární (o kterém nechci psát) je nicméně postaveno nad WebSphere Message Brokerem (WMB). Právě kvůli WMB, jsem se pustil do čtení výborné knížky Enterprise Integration Patterns (EIP). A jelikož je pro mne jak WMB, tak EIP nové, rozhodl jsem se o tom napsat (v rámci studia) pár článečků. Takže...


Základní koncepty messagingu

WMB je, jak napovídá název, založený na messagingu, takže se prvně podíváme, co to ten messaging je a na čem jsou postaveny jeho základy (inspirováno a citováno z EIP). Vezměme si následující obrázek, který obsahuje všechny základní koncepty messagingu:


  • Messages (zprávy). Kolem zpráv se to celé točí. Zprávy jsou atomickým paketem dat, která jsou přenášeny z jednoho systému do druhého. Každá zpráva se skládá z hlavičky a z těla (nic překvapivého). Zprávy mají často hierarchickou podobu (např. XML, nebo struktura Java objektů).
  • Channels (kanály). Virtuální "trubky", kterými tečou zprávy. Kanály jsou jednosměrný - jedna aplikace do kanálu zapisuje a druhá z něj čte.
  • Endpoints (koncové body). Rozhraní pro připojení aplikace k messagingovému systému. Umožňuje aplikaci posílat a přijímat zprávy. Instance endpointu je svázána s konkrétním kanálem - z toho vyplývá, že může zprávy buď přijímat, nebo odesílat (ne obojí najednou).
  • Routing (směrování). Pokud máme hodně aplikací a kanálů, může být tok zprávy velmi komplikovaný. Namísto aby se o její trasu musel starat odesílatel, pošle ji do message routeru, který se postará o navigaci zprávy skrze topologii kanálů tak, aby dorazila k příjemci (známe z TCP/IP).
  • Pipes and Filters (trubky a filtry). Pokud potřebujeme se zprávou během jejího toku nějak pracovat, je vhodné ji přes několik kanálů prohnat potřebnými škatulkami - princip, který dobře znají uživatelé Unixu (ls -l /dev/ | grep sd[a-f] | wc -l), nebo električtí kytaristé (kytara - ladička - overdrive - chorus - kombo).
  • Transformation (transformace). To jsou ty krabičky. Potřebuju konvertovat data z jednoho formátu do jiného? Potřebuju zprávu něčím obohatit? Potřebuju změnit transportní protokol? Použiju odpovídající transformaci/krabičku.
Jak je vidět z uvedeného přehledu základních principů, jde o v podstatě triviální koncepty. Přínosem výše uvedené EIP knížky je, že jednak tyto principy probírá do hloubky a v různých variantách, jednak je uvádí komplexně (můžou být věci, které člověku na první, druhý, třetí pohled nedojdou) a jednak je kombinuje do důmyslných a praxí ověřených řešní (přeci jenom, jsou to vzory).