Tvorba vlastního adaptéru pro vstup do ArcGIS GeoEvent Serveru
ArcGIS GeoEvent Server umožňuje zpracovávat datové proudy v reálném čase a zpřístupňovat je pro ostatní součásti systému ArcGIS. Tento technicky podrobný článek se zabývá tvorbou vlastního modulu pro příjem datového proudu.
Data o událostech, jako jsou například pozice a stav pohybujících se objektů, stav automatických lokalizovaných čidel nebo lokalizované události na sociálních sítích, může ArcGIS GeoEvent Server dále filtrovat, transformovat a vyhodnocovat. V průběhu zpracování mohou vznikat i nové události, jako je například upozornění při překročení kritické rychlosti pohybujícího se objektu, vstupu objektu do zakázané zóny, přiblížení se dvou objektů, překročení hodnot nějakého kritického atributu objektu apod. ArcGIS GeoEvent Server nakonec proudy získaných a zpracovaných událostí předá do systému ArcGIS (například pro vrstvu dat měnících se v reálném čase Stream layer) či do jiných IT systémů (pro záznam událostí do databází, notifikaci osob apod.).
Co je to konektor?
Pro připojení výše uvedených proudů dat (ať vstupních či výstupních) používá ArcGIS GeoEvent Server konektory. Vstupní (input) konektor načítá (transportuje) proud dat a transformuje (adaptuje) ho do událostí (objektů) GeoEventu, naopak výstupní (output) konektor provádí překlad GeoEventu do patřičného formátu a publikaci dat ze serveru „ven“.
U input konektoru načítání provádí jeho transportní vrstva (Transport) a překlad adaptační vrstva (Adapter). Input konektor je tedy defacto konkrétní kombinací transportní a adaptační vrstvy, obdobně je tomu pak i u output konektoru.
Co je to přesně ten adapter?
Adapter je překladatel načteného proudu bytů (které poskytuje vrstva Transport v podobě objektu ByteBuffer což je pole bytů) do objektů GeoEventu popisujících nějakou konkrétní událost. Každý druh události může vyžadovat různě definovaný objekt, a proto adaptér na základě definice, která je jeho součástí, vytvoří nový objekt, ten naplní daty (třeba již nějak upravenými a filtrovanými) a předá jej k dalšímu zpracování v GeoEvent Serveru.
Tvorba vlastního adaptéru
I když Esri nabízí celou škálu input a output transporterů a adaptérů, které lze vhodnou kombinací a parametrizováním sestavit do funkčního vstupu pro mnoho datových zdrojů i pro výstupy do různých systémů, celou realitu real-time dat jimi samozřejmě pokrýt nelze. Proto můžeme potřebovat vytvořit vlastní adaptér či transporter.
Úpravu ArcGIS GeoEvent Serveru provádíme programováním odvozených tříd v jazyce Java a základní logika jednoduchého adaptéru musí řešit dvě základní věci:
- Definovat, jak mají v adaptéru vznikající geoeventy (objekty typu GeoEvent) vypadat. Tedy popsat, jaké všechny atributy, jakých datových typů a kardinalit a v jaké vnitřní struktuře má vznikající objekt obsahovat (případně zde lze dále i definovat, jaké má mít adaptér nastavitelné parametry ovlivňující jeho další chování). Toto lze provést v třídě odvozené z třídy AdapterDefinitionBase.
- Se znalostí načítaného vstupního formátu dat přeložit potřebné informace z transportní vrstvy předávaných objektů ByteBuffer (pole bytů obsahující načtená data) do vytvářených GeoEvent objektů. Tato část logiky se programuje v potomku třídy InboundAdapterBase.
V základě jde tedy u jednoduchého adaptéru o doprogramování Java balíčku obsahujícího tři rozšiřující potomky tříd AdapterDefinitionBase a InboundAdapterBase. (Třetí třídy AdapterServiceBase si nyní nebudeme u jednoduchého adaptéru všímat.)
Instalace GeoEvent Serveru obsahuje již ve své adresářové struktuře adresář c:\Program Files\ArcGIS\Server\GeoEvent\sdk, kde lze najít kromě potřebného API a užitečné dokumentace GeoEvent Developer Guide.pdf a api/index.html i adresář samples, ve kterém lze nalézt řadu ukázkových projeků pro adaptéry i transportery (adresářů obsahujících projektový pom.xml). Tvorbu vlastního adaptéru je vhodné postavit přímo na těchto šablonách.
Nejprve si celý adresář sdk zkopírujme na počítač, kde budeme adaptér vyvíjet (nebo alespoň needitovat originální ukázky). V případě, že na počítači je nainstalován Java SE Development Kit (JDK) správné verze (verzi lze zjistit v GeoEvent Developer Guide.pdf) a že námi používané Java IDE podporuje práci s projekty Maven (u starších verzí je někdy třeba doinstalovat plugin), můžeme začít a vybraný projekt Maven do IDE naimportovat.
Jako první je vhodné ve vlastnostech projektu změnit název skupiny (groupId), název artefaktu (artifactId) a název projektu (ukázka z projektu v NetBeans IDE)...
... a ujistit se, že projekt bude kompilován ve správném JDK (viz dokumentace v adresáři sdk).
Nyní přistupme k samotné tvorbě, respektive programování tříd vytvářeného balíčku.
Definice nové GeoEventDefinition v potomku třídy AdapterDefinitionBase
V případě, že ve vytvářeném adaptéru nelze použít již existující definici (v Javě objekt GeoEventDefinition), je potřeba ji v konstruktoru potomka třídy AdapterDefinitionBase vytvořit, tedy nastavit zde krom jména samotného objektu i jména a strukturu atributů, jejich datových typů, kardinalit a označení atributů geometrie a atributu pro tracking. (Přiřadit atributům tagy.) Mimo to je vhodné zároveň v kódu definici přiřadit konkrétní GUID, aby v případě, že se server restartuje a balíček znovu načte, nedošlo k tvorbě nové definice s novým (a jiným) GUID, než pomocí kterého je referencována z existujících adaptérů. Tyto adaptéry bez vazby na definici by pak nemohly objekt GeoEventu vytvořit.
V případě, že chování adaptéru chceme také parametrizovat, je v konstruktoru potomka třídy AdapterDefinitionBase možné definovat také jaké parametry má adaptér mít a nastavit jim případně výchozí hodnoty.
Definice v potomku třídy InboundAdapterBase
Vlastní logiku adaptéru řešící převod do GeoEvent objektů programujeme v potomku třídy InboundAdapterBase. V případě, že adaptér potřebuje pracovat s parametry ovlivňujícími samotný proces převodu a tvorby událostí, je nejprve potřeba v překrytí metody afterPropertiesSet (překrytí pomocí anotace @Override) tyto parametry načíst pomocí funkcí getProperty(jmeno_parametru).getValue() a přetypovat získaný objekt s hodnotou parametru na správný datový typ a přiřadit ho lokální proměnné, se kterou pak hodláme v kódu dál pracovat.
Po získání všech potřebných proměnných z parametrů lze přistoupit již k opravdovému jádru adaptéru, tedy ke získání potřebných informací z objektu ByteBuffer, k tvorbě GeoEvent objektů a jejich předání k dalšímu zpracování v GeoEvent Serveru.
Pokud víme, že z jednoho přicházejícího objektu ByteBuffer bude ve výsledku pouze jeden objekt GeoEvent (čili jedna událost), lze překrýt pomocí klauzule @Override jednodušší metodu adapt, kterou bude proces GES spouštět pro každý objekt ByteBuffer, a která musí na výstupu odevzdat objekt typu GeoEvent:
@Override
protected GeoEvent adapt(ByteBuffer buffer, String channelId) { … return geoevent}
V asi častějším případě, kdy je počet událostí pro jeden obdržený objekt ByteBuffer větší než 1, je potřeba obsloužit pomocí překrytí metodu receive, která nic nevrací, ale zato ve svém těle může opakovaně volat metodu geoEventListener.receive(), pomocí které postupně předá hotové události dalším procesům GES.
@Override
public void receive(ByteBuffer buffer, String channelId) { … geoEventListener.receive(geoevent) …}
Výsledný zkompilovaný adaptér (soubor JAR) se pak do GeoEvent Serveru instaluje buď nahráním do deploy adresáře (c:\Program Files\ArcGIS\Server\GeoEvent\deploy\), případně výběrem souboru v GeoEvent Manageru (components – adapters – tlačítko Add Local Adapter).
Po instalaci archivu JAR s adaptérem již můžeme v GeoEvent Manageru nalézt jak námi výše vytvořenou GeoEvent definici…
… tak při tvorbě input konektoru samotný adaptér (i s jemu specifickými námi definovanými parametry).
Případné logování chyb, debug a záznam nastalých situací lze v kódu adaptéru provést přes metody objektu com.esri.ges.framework.i18n.BundleLogger (lze jej nalézt v ukázkách), logy lze nalézt v adresáři <ArcGIS_Server_Installation>\GeoEvent\data\log.