OSGi neboli Open Service Gateway

OSGi neboli Open Service Gateway initiative je specifikace dynamického modulárního systému pro programovací jazyk Java. V tomto článku si povíme něco o historii OSGi, ukážeme si jednoduchou aplikaci napsanou pomocí OSGi a podíváme se na přidávání a odebírání modulů z aplikace.

Historie

Práce na OSGi specifikaci začala v roce 1999. Původně byla cílena na síťová zařízení a vestavěné systémy a zde se také prosadila a začala využívat. V roce 2003 se vývojářský tým platformy Eclipse rozhodl vyměnit proprietární modulární systém za vlastní implementaci OSGi s názvem Equinox. Dnes už většina aplikačních serverů podporuje nebo plánuje podporu OSGi. OSGi se tak na poli enterprise aplikací stává alternativou k zatím rozšířenější Javě EE. K dalším populárním implementacím OSGi kromě Equinoxu patří také Apache Felix nebo Knopflerfish.

Využití

Hlavní výhoda OSGi při jeho použití k vývoji aplikace je právě modulárnost. Umožňuje nám to za běhu naší aplikace přidávat a odebírat její součásti. Zlepšuje se nám tak udržovatelnost aplikace, například můžeme aktualizovat jednu část aplikace, aniž bychom museli zbylé komponenty této aplikace odpojit z provozu. Mezi další výhody patří také možnost mít zavedeno více verzí jednoho modulu. Pokud máme dvě části aplikace, které závisí na různých verzích jedné knihovny, OSGi nám umožní běh obou verzí zároveň. Každé komponentě bude umožněn přístup pouze ke správné verzi této knihovny.

Dále se budeme věnovat ukázce základní práce s OSGi. Pro demonstraci budeme používat právě výše zmíněný Equinox, který je dodávaný v jednom balíku spolu s Eclipse IDE. Stáhnout si ho můžete třeba z oficiálních stránek. Pro vytvoření nového OSGi modulu si vytvoříme tzv. Plug-In Project.

Bundle

V OSGi se každý jednotlivý modul aplikace označuje jako tzv. bundle, což je obyčejný jar archiv s přidaným hlavičkovým souborem MANIFEST.MF. Při práci s moduly používáme právě tento soubor a nadefinujeme si zde, jaké balíčky importujeme a exportujeme.

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloService
Bundle-SymbolicName: com.bcvsolutions.sample.HelloService
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.bcvsolutions.sample.service.impl.HelloServiceActivator
Bundle-Vendor: BCVSOLUTIONS
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: org.osgi.framework;version="1.3.0"
Export-Package: com.bcvsolutions.javaworld.sample.service

Tento soubor obsahuje několik důležitých hlaviček. Mezi pro nás nejdůležitější patří Bundle-Activator, Import-Package a Export-Package. Bundle-Activator označuje tzv. activator třídu. Ta definuje dvě základní metody každého OSGi bundlu start a stop. Tyto metody spouští a ukončují náš bundle. Import-Package nám definuje balíčky, které náš bundle potřebuje. Pokud není bundle obsahující daný balíček přítomný v OSGi kontejneru, není možné náš bundle spustit. Export-Package nám zase definuje balíčky, které dáváme k dispozici jiným bundlům.

Activator třída pak může vypadat například takto.

package com.bcvsolutions.sample.helloservice;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator {

	public void start(BundleContext context) throws Exception {
		System.out.println("Hello World!!");
	}
	
	public void stop(BundleContext context) throws Exception {
		System.out.println("Goodbye World!!");
	}

}

OSGi kontejner zavolá metodu start při spouštění bundlu. BundleContext je objekt umožnující interakci s frameworkem. Metoda stop je volaná při ukončování bundlu, je vhodné v této metodě provést čistící operace např. odpojení od databáze.

Správa bundlů

Ke správě bundlů v kontejneru nám dobře poslouží OSGi konzole. Můžeme v ní instalovat a odinstalovat bundle, spustit a zastavit bundle nebo si třeba zobrazit všechny bundly dostupné v kontejneru.

osgi> ss
"Framework is launched."


id	State       Bundle
0	ACTIVE      org.eclipse.osgi_3.10.1.v20140909-1633
	            Fragments=603
...
841	RESOLVED    com.bcvsolutions.sample.HelloWorld_1.0.0.qualifier
843	ACTIVE      com.bcvsolutions.sample.HelloService_1.0.0.qualifier

Po vypsání bundlů příkazem ss můžeme vidět dva námi připravené bundly. HelloService je bundle, který exportuje jednu ze svých služeb (viz MANIFEST.MF výše). Zároveň vidíme, že je ve stavu active, což znamená, že je spuštěný v kontejneru. Druhý bundle HelloWorld, který má importovaný balíček z bundlu HelloService, je ve stavu resolved, což značí, že je připraven na spuštění a má vyřešeny veškeré závislosti. Nyní ho můžeme spustit příkazem start.

osgi> start 841
Hello World!!
Inside HelloServiceImple.sayHello()
Say Hello
osgi> stop 841
Goodbye World!!

Vidíme, že balíček byl spuštěn a také, že využívá jedné ze služeb balíčku HelloService. Nakonec jsme bundle zase ukončili příkazem stop.

Životní cyklus bundlu

Životní cyklus OSGi bundlu

Balíček po dobu své funkce projde několika stavy. Po instalaci do frameworku se dostává do stavu installed. Jakmile jsou uspokojeny jeho závislosti přechází do stavu resolved a čeká na spuštění. Při spouštění se dostává do fáze starting, z níž po navrácení metody start přejde do stavu active. Během ukončování je ve stavu stopping a po návratu metody stop se balíček opět navrátí do stavu resolved. Po odinstalaci balíčku se dostává do stavu uninstalled.

Závěr

V tomto příspěvku jsme si ukázali základní práci s OSGi bundly, exportování a importování jednotlivých modulů a základ správy osgi bundlů pomocí konzole.
V případě dotazů mě neváhejte kontaktovat na miroslav.staffa@bcvsolutions.eu.

Jak zrychlit načítání dat z personálního systému VEMA?

Pří správě uživatelských účtů Identity Managerem je vždy jeden, nebo více systémů, autoritativní zdroj informací o uživatelích. Údaje o uživatelích jsou v pravidelných intervalech načítány a dále se propagují do dalších systémů. Jelikož počet takových uživatelů může být velký, tak je neefektivní je načítat všechny, protože u většiny uživatelů nedojde k žádné změně. Ideální řešení je takové, že Identity Manager načítá z autoritativního systému pouze ty uživatelské záznamy, které byly od posledně modifikovány. To však lze pouze v případě, že daný systém u záznamů uživatele ukládá čas poslední modifikace. Personální systém Vema, který je u našeho zákazníka pro CzechIdM autoritou pro identity, neposkytuje pouze změnové záznamy. Proto jsme si museli poradit sami a to jednoduše. V databázi Oracle, kam se provádí z personalistiky full-export, jsme zajistili evidenci změn a tyto změny poskytujeme do CzechIdM. Tím bylo možné rapidně zrychlit načítání autoritativních dat. Proces, který dříve trval až 13 hodin, byl nahrazen procesem, který trvá řádově minuty! Pojďme se na to podívat blíže.

Počáteční stav

Zdrojem autoritativních dat je personální systém Vema. Z personálního systému se provádí každý den full-export do Oracle DB, ze které si je mohou načítat externí aplikace. Export probíhá tak, že se nejprve smažou všechna data včetně samotných databázových tabulek, opět se vytvoří databázové tabulky a následně se do nich vloží aktuální data personálního systému. CzechIdM načítá data o uživatelích právě z exportní Oracle databáze. Na základě načtených dat inicializuje personální procesy a propaguje změny na další napojené systémy. Například při nástupu nového zaměstnance CzechIdM načte jeho popisné údaje z Oracle databáze, založí mu identitu v CzechIdM a na základě jeho funkčního zařazení mu přidělí role, dle kterých se pro něho automaticky vytvoří účty na dalších systémech zákazníka (založí se mu email, účet v docházkovém systému atd.). S tím, jak se rapidně navyšujel počet načítaných uživatelů a počet napojených koncových systémů, tak se samozřejmě prodlužuje i samotný proces rekonciliace. Bylo tedy potřeba od něho upustit a přejít k synchronizaci. Problémem však bylo, že personální systém neexportuje s uživatelskými daty informace o času jejich poslední modifikace. Dříve, než se podíváme, jak jsme daný problém vyřešili, tak si pro jistotu vysvětlíme co znamenají výše uvedené pojmy rekonciliace a synchronizace. :-)

Synchronizace vs rekonciliace

Pojem rekonciliace v původním významu označuje proces usmíření, uvedení věcí do souladu. Tato definice poměrně přesně popisuje rekonciliaci i z pohledu Identity Managementu. Při rekonciliaci se prochází všechny uživatelské účty na koncovém systému a na základě definovaných akcí se aktualizují identity uživatelů v Identity Manageru. V našem konkrétním případě, kde koncovým systémem je personalistika, se na základě načtených dat aktualizují identity uživatelů, případně se vytváří identity nové pro nově evidované zaměstnance. Jelikož je personální systém v tomto případě systémem autoritativním, tak se popisné atributy automaticky propagují do koncových systémů, na kterých mají uživatelé založeny účty. Zde lze vidět analogii k původnímu významu slova rekonciliace. Identity manager uvede do souladu atributy uživatele na jeho účtech na koncových systémech s atributy, jenž jsou uvedeny dle personálního systému. Synchronizace, na rozdíl od rekonciliace, neprochází všechny uživatelské účty na koncovém systému. Místo toho si zjistí, které účty byly modifikovány od poslední synchronizace a dále pracuje pouze s nimi. V našem případě, kde mluvíme o napojování personálního systému, je hlavní výhodou synchronizace vůči rekonciliaci doba jejího běhu. V personálním systému je evidováno tisíce uživatelů, ale denně se jich aktualizuje pouze několik desítek, maximálně stovek. Doba běhu synchronizace je tedy řádově nižší než u rekonciliace.

Implementace synchronizace

Vraťme se však od strohé teorie k řešení našeho problému. Chceme nahradit proces rekonciliace personálního systému synchronizací. Data načítáme z přechodové Oracle databáze prostřednictvím databázových view, jenž pro nás integrují data z vícero tabulek. A co je hlavní, tak v datech není uvedeno, kdy byl daný záznam naposledy modifikován! První, co potřebujeme, je evidovat u všech tabulek obsahujících záznamy uživatelů informaci, kdy byl daný záznam aktualizován. Jelikož se tabulky při exportu z personálního systému mažou, tak si vytvoříme jejich kopie, které budou navíc obsahovat sloupec s informacemi o poslední modifikaci daného řádku (sloupec „modif_time“). Dále je potřeba realizovat to, že při exportu dat z personalistiky do databáze se nám budou aktualizovat data v našich tabulkách – „kopiích“ s tím, že se nám případně aktualizuje sloupec „modif_time“, pokud se daný řádek v „kopii“ liší od aktuálně exportovaného. Použití databázových triggerů není úplně šťastné, když se databázové tabulky při exportu mažou. Rozhodli jsme se tedy pro implementaci databázové procedury, která se bude volat vždy po skončení exportu. Ve výpisu níže je uvedena část této procedury, která se týká jedné z exportních tabulek, tabulky VEMA_UZIVATEL. Příkazem MERGE vložíme do naší „kopie“ (tabulka CZECHIDM_UZIVATELE) záznamy pro nové uživatele a aktualizujeme atributy u záznamů, které se liší mezi tabulkami VEMA_UZIVATEL a CZECHIDM_UZIVATELE. Zároveň u příslušných záznamů aktualizujeme atribut „modif_time“ v tabulce CZECHIDM_UZIVATELE. Následně zavoláním příkazu DELETE smažeme v tabulce CZECHIDM_UZIVATELE ty záznamy, které se již nevyskytují v tabulce VEMA_UZIVATEL. Obdobně je to realizováno i u ostatních exportních tabulek, které se týkají uživatelů a jejich atributů.

 /* Uzivatel */
 MERGE INTO VEMAEXPORT.CZECHIDM_UZIVATELE IDM
 USING (
 SELECT VEMA.JMENOZD, VEMA.PRIJMZD, VEMA.TITULYP, VEMA.TITULYZ, VEMA.OSCIS, VEMA.IDCIS, VEMA.LOKALITA FROM VEMAEXPORT.VEMA_UZIVATEL VEMA
 LEFT JOIN VEMAEXPORT.CZECHIDM_UZIVATELE IDM
 ON (VEMA.OSCIS = IDM.OSCIS)
 WHERE
 (IDM.OSCIS IS NULL) OR 
 (VEMA.JMENOZD || VEMA.PRIJMZD || VEMA.TITULYP || VEMA.TITULYZ || VEMA.OSCIS || VEMA.IDCIS || VEMA.LOKALITA) <> 
 (IDM.JMENOZD || IDM.PRIJMZD || IDM.TITULYP || IDM.TITULYZ || IDM.OSCIS || IDM.IDCIS || IDM.LOKALITA)) VEMA
 ON (VEMA.OSCIS = IDM.OSCIS)
 WHEN MATCHED THEN 
 UPDATE SET 
 IDM.JMENOZD=VEMA.JMENOZD, 
 IDM.PRIJMZD=VEMA.PRIJMZD, 
 IDM.TITULYP=VEMA.TITULYP, 
 IDM.TITULYZ=VEMA.TITULYZ, 
 IDM.IDCIS=VEMA.IDCIS, 
 IDM.LOKALITA=VEMA.LOKALITA, 
 IDM.MODIF_TIME=sysdate 
 WHEN NOT MATCHED THEN
 INSERT (OSCIS, JMENOZD, PRIJMZD, TITULYP, TITULYZ, IDCIS, LOKALITA, MODIF_TIME)
 VALUES (VEMA.OSCIS, VEMA.JMENOZD, VEMA.PRIJMZD, VEMA.TITULYP, VEMA.TITULYZ, VEMA.IDCIS, VEMA.LOKALITA, sysdate); 

 /* Smazeme data, co byla smazana ve VEMA_* tabulce */
 DELETE FROM VEMAEXPORT.CZECHIDM_UZIVATELE WHERE (OSCIS) IN (
 (SELECT OSCIS FROM VEMAEXPORT.CZECHIDM_UZIVATELE WHERE (JMENOZD, PRIJMZD, TITULYP, TITULYZ, OSCIS, IDCIS, LOKALITA)
 NOT IN
 (SELECT JMENOZD, PRIJMZD, TITULYP, TITULYZ, OSCIS, IDCIS, LOKALITA FROM VEMAEXPORT.VEMA_UZIVATEL))
 );

Nakonec upravíme naše databázová view, aby se data načítala z našich „kopií“ místo původních exportních tabulek a aby navracela u každého uživatele timestamp poslední modifikace přes všechny tabulky, které drží informace o uživateli. Příklad takového view je ve výpisu níže.

CREATE OR REPLACE FORCE VIEW "VEMAEXPORT"."CZECHIDM_UZIVATEL_VIEW" ("JMENO", "PRIJMENI", "TITULY_P", "TITULY_Z", "OSCIS", "IDCIS", "LOKALITA", "BUDOVA", "KANCELAR", "PSC", "LOGIN", "EMAIL", "TELEFON", "TELEFON_WEB", "MOBIL", "MODIF_TIME") AS 
 select distinct
 U.JMENOZD, 
 U.PRIJMZD, 
 U.TITULYP,
 U.TITULYZ,
 U.OSCIS,
 U.IDCIS,
 U.LOKALITA,
 (select L.ULICEN || ' ' || L.CP || ', ' || L.POSTA from CZECHIDM_LOKALITA L where L.LOKALITA=U.LOKALITA),
 (select L.NAZEV from CZECHIDM_LOKALITA L where L.LOKALITA=U.LOKALITA),
 (select L.PSC from CZECHIDM_LOKALITA L where L.LOKALITA=U.LOKALITA),
 (select C.KOD from CZECHIDM_SPOJENI C where (C.OSCIS=U.OSCIS and C.CISSP=1 and C.TYPSP='login')),
 (select C.KOD from CZECHIDM_SPOJENI C where (C.OSCIS=U.OSCIS and C.CISSP=2 and C.TYPSP='e-mail')),
 (select C.KOD from CZECHIDM_SPOJENI C where (C.OSCIS=U.OSCIS and C.CISSP=3 and C.TYPSP='telefon')),
 (select C.KOD from CZECHIDM_SPOJENI C where (C.OSCIS=U.OSCIS and C.CISSP=4 and C.TYPSP='telefonweb')),
 (select C.KOD from CZECHIDM_SPOJENI C where (C.OSCIS=U.OSCIS and C.CISSP=6 and C.TYPSP='mobil')),
 (select MAX(MODIF_TIME) from (
 SELECT U1.OSCIS AS OSCIS, L1.MODIF_TIME FROM CZECHIDM_UZIVATELE U1 LEFT JOIN CZECHIDM_LOKALITA L1 ON U1.LOKALITA=L1.LOKALITA
 UNION
 SELECT U1.OSCIS AS OSCIS, U1.MODIF_TIME AS MODIF_UZIVATEL FROM CZECHIDM_UZIVATELE U1
 UNION
 SELECT V.OSCIS AS OSCIS, V.MODIF_TIME AS MODIF_VYNETI FROM CZECHIDM_VYNETI V
 UNION
 SELECT Z.OSCIS AS OSCIS, Z.MODIF_TIME AS MODIF_VYNETI FROM CZECHIDM_ZASTUP Z
 UNION
 SELECT S.OSCIS AS OSCIS, S.MODIF_TIME AS MODIF_VYNETI FROM CZECHIDM_SPOJENI S
 UNION
 SELECT PS.OSCIS AS OSCIS, PS.MODIF_TIME AS MODIF_VYNETI FROM CZECHIDM_PRAC_SMLOUVY PS
 UNION
 SELECT PZ.OSCIS AS OSCIS, PZ.MODIF_TIME AS MODIF_VYNETI FROM CZECHIDM_PRAC_ZARAZENI PZ
 ) WHERE OSCIS=U.OSCIS)
 from CZECHIDM_UZIVATELE U;

Tímto máme realizovány všechny požadavky na straně databáze. Nyní již zbývá pouze nakonfigurovat synchronizaci personálního systému v CzechIdM a vypnout zdlouhavou rekonciliaci. :-) Jak toho docílit je hezky popsáno v příspěvku První krůčky s CzechIdM  Kapitola 3: Nastavení synchronizace a rekonciliace systému jednoho z kolegů.

Výsledek

A jaký je výsledek? Proces rekonciliace, který v tomto konkrétním případě trval několik hodin, byl nahrazen synchronizací, jenž běží většinou několik málo minut.

Závěr

V tomto příspěvku jsme si popsali rozdíly mezi synchronizací a rekonciliaci koncového systému. Dále jsme si na praktickém příkladu ukázali, jak je možné implementovat synchronizaci nad systémem, který na první pohled synchronizaci neumožňuje. Pokud byste měli nějaké dotazy, tak mne neváhejte kontaktovat na jaromir.mlejnek@bcvsolutions.eu.

Novinky v Javě 8

V první čtvrtině letošního roku vydal Oracle novou verzi Javy a to konkrétně ve verzi 8. Podle slov samotných vývojářů se jedná o největší novinku od vydání Javy. Je to pravda? Pojďme se podívat na jednotlivé novinky. Nová verze Javy přinesla velké množství více či méně zajímavých novinek. My se spolu podíváme na ty nejzajímavější. Konkrétně se podíváme na témata:

  • internet věcí
  • nové API pro datum a čas
  • projekt Nashorn
  • LAMBDA výrazy
  • stream API
  • novinky v zabezpečení

Internet věcí

Tak se na to vrhneme. Jednou z největších novinek je podle Oraclu rozšíření Internetu věcí. V praxi jde o to, že Java nyní podporuje nejrůznější senzory, jež mohou být umístěny například v hodinkách, chytrých náramcích, nebo v jiné nositelné i nenositelné elektronice. To přináší větší robustnost našeho kódu a možnosti používat funkce platformy Java SE 8. Představme si, že vyvíjíme aplikaci pro chytré domácnosti. S novou Javou 8 můžeme pohodlněji pracovat se všemi čidly, které budou v chytré domácnosti potřeba. Dalším příkladem mohou být aplikace, které pracují například s chytrým náramkem a na základě dat získaných z čidel tohoto náramku nám aplikace vypočítavá odhadovaný zdravotní stav.

API pro datum a čas

Další novinku, kterou určitě uvítá každý, kdo pracuje s časovými entitami, je nové API pro datum a čas. Jedná se o package java.time. Pro ty z Vás, kteří uvidíte podobnost s balíčkem JodaTime, máte pravdu. Nejedná se o žádnou kopii tohoto balíčku, ale při vytváření java.time se vývojáři nechali balíčkem JodaTime zřejmě trochu inspirovat a to není vůbec na škodu. Nový balíček podporuje reprezentaci časových údajů například i s časovou zónou, nebo si můžeme vybrat, zda-li chceme pracovat pouze s časem bez data, nebo naopak s datem bez času a podobně. Při vývoji tohoto balíčku se zřejmě nahlíželo na to, aby se s entitami dalo pracovat co nejvíce jako v reálném životě.

Clock clock;
clock = Clock.systemDefaultZone();
System.out.printf("časová zóna: " + clock + "\n");

Nejvíce vítanou novinkou tohoto balíčku je to, že všechny třídy jsou immutable a thread safe. To je vítaná novinka, protože s nimi můžeme pracovat ve více vláknech současně a zároveň se nemusíme starat o synchronizaci. Další věcí, která se mi líbila, je možnost „podvrhnout“ komponentě určitý čas při testování. Doteď pokud jsme nepoužívali JodaTime, museli jsme měnit systémový čas, a to není úplně nejelegantnější řešení. V java.time můžeme komponentě „nainjektovat“ čas, který potřebujeme, a tím například otestovat synchronizaci. V neposlední řadě bych rád také vyzdvihl nové možnosti používat periody. Ačkoliv se to může zdát jako zanedbatelná novinka, určitě nám to ulehčí vývoj aplikací.

LocalDate today = LocalDate.now();
LocalDate bigThing = LocalDate.of(2014, Month.SEPTEMBER, 18);
Period p = Period.between(bigThing, today);
        
long pocet = ChronoUnit.DAYS.between(today,birthday);
        
System.out.println("Do našeho workshopu zbývá už jen " + pocet + " dnů!!");

Projekt Nashorn

Projekt Nashorn je nový JavaScriptový engine, který běží přímo v JVM a umožňuje používat JavaScript v našich Java aplikacích. Tuto možnost nám nabízela už i Mozilla Rhino, ale Nashorn vylepšuje hlavně rychlost provádění JavaScriptového kódu a tím může naše aplikace používat jak prvky Javy, tak prvky JavaScriptu a na výkonu to nebude znát. To je zapříčiněno tím, že celý JavaScriptový kód se překompiluje do bytecode, který interpreter následně vykonává.

Funkcionální programování

Do Javy také dorazilo funkcionální programování v podobě LAMBDA výrazů. Lambda výraz je v podstatě funkce nebo zřetězení funkcí, která pro některé nebo všechny kombinace vstupních hodnot určuje výstupní hodnotu.

Lambda výrazy můžeme použít dvojím způsobem. Buďto použijeme lambda výraz anonymně, nebo za použití funkčního rozhraní můžeme předat lambda výraz například jako parametr metodě. V ukázce vidíme anonymní použití.

Collection<String> name = Arrays.asList("John", "Mary", "Anna");
        name.stream()
                .filter(a -> a.length() < 5)
                .sorted()
                .forEach(a -> System.out.println(a)
);

Stream API

Tak nyní už víme, co to je Lambda a můžeme se podívat na nějaké praktické použití. Nejvíce se používají právě ve Stream API, které se často používá s kolekcemi a na nich si ukážeme i základní práci. Každé kolekci nově přibyla metoda stream, která nám vrací funkcionální pohled. Práce s tímto streamem je podobná s prací v bashi. Používá se tam něco jako pipelina. Tedy máme kolekci, vytvoříme na ní stream a na něj aplikujeme nějakou operaci. Například nějaký filter nebo mapu. Každá tato funkce nám vrátí zase stream a na něj můžeme aplikovat zase jiný filter a podobně. Tyto operace s původní kolekcí nic nedělají, jen změním pohled na stream a nakonec, když už máme provedené všechny „lazy“ operace, tedy ty, co jen mění pohled, použijeme terminal operaci, která upraví stream zase na kolekci. Například použijeme metodu toArray(). Nyní si celý postup ukážeme na příkladu.

List<String> cislaSlovne = Arrays.asList("100", "200", "300", "400");
 int cisla[] = cislaSlovne
 .stream()
 .map(Integer::parseInt)
 .filter(num -> num < 200)
 .toArray();


 

Nejdříve jsme si vytvořili list Stringů, který jsme naplnili čísly. Dále jsme si na našem listu zavolali metodu stream(). Metoda stream() nám vrátila pohled na náš list, který jsme dále upravovali. Abychom mohli s hodnotami v pohledu pracovat jako s čísly, přemapujeme si jednotlivé hodnoty na integery. Posledním krokem jsme si vyfiltrovali všechna čísla, která jsou větší než 200.

Novinky v zabezpečení

Nová Java přináší také novinky v oblasti zabezpečení. Nově přináší nativní podporu TLS. Transport Layer Security neboli TLS jsou protokoly, které umožňují zabezpečenou komunikaci na internetu. TLS zabezpečuje komunikaci proti odposlouchávání nebo falšování zpráv, a to pomocí autentizace pro koncový bod. Jedná se tedy o to, že koncový bod, tedy webová aplikace jako například webový prohlížeč, není autentizován, ale server, se kterým komunikuje, autentizován je, takže prohlížeč vždy ví, s kým komunikuje.

Další novinku ocení všichni ti, kdo plánují svoje data šifrovat. Java 8 přináší totiž nativní podporu NSA Suite B Cryptographic Algorithms, což je balíček algoritmů, které pomáhají uchránit data při transportu přes nezabezpečený internet proti útokům hrubou silou. Tyto algoritmy jsou velmi silné a jejich prolomení je v podstatě nemožné. Další silné algoritmy od NSA jsou obsaženy v balíčku suite A, ten je ale přísně tajný a používá ho USA ve státní správě a o algoritmech v tomto balíčku se neví v podstatě nic. V suitě B jsou obsaženy například algoritmy pro šifrování, které používají klíče s délkou 128 nebo 256 bitů. Dále je obsažen algoritmus pro podporu digitálního podpisu (Elliptic Curve Digital Signature Algorithm (ECDSA). Tento algoritmus používá k zabezpečení eliptických křivek o velikosti 256 a 384 bitů.

Závěr

V tomto článku jsme si shrnuli nejvýraznější novinky v novém vydání Javy. Jedná se určitě o krok správným směrem, který nám přináší nové možnosti, jak rozšířit možnosti vývoje nových druhů aplikací. Ať už se chystáte vytvářet aplikaci, co bude číst data z čidla srdečního tepu, nebo jen chcete efektivněji selektovat hodnoty v kolekci, Java 8 Vám práci ulehčí.

Archiv v CzechIdM

Potřebovali jste si někdy něco zazálohovat? Případně potřebovali jste si udržovat změny ohledně nějakého objektu v průběhu času? Jestli ano, nyní je to v CzechIdM možné. V CzechIdM vznikl nový modul — archiv, který zvládá tyto úkony a ne jenom to. Vše o principu a správném použití archivu si můžete přečíst právě v tomto článku.

Funkčnost a GUI Archivu

Mezi primární funkci archivu patří samozřejmě archivování různých objektů. Také je možné jej prohledávat na základě zvolených kritérií či exportovat vybraná data do csv souboru. Tyto funkce jsou snadno přístupné administrátorovi přímo z administrátorského rozhranní CzechIdM pod záložkou uživatelé a podzáložkou archiv. Takto vypadá hlavní stránka archivu:

archiveMain

V hlavičce stránky je možné definovat kritéria, podle kterých si přejeme vyhledávat archivované objekty. Mezi možnosti patří hledání podle názvu, datum archivace, typu, či hodnoty atributu. Strukturu samotných objektů vysvětlím dále v článku. Po vyhledání se zobrazí seznam objektů odpovídajících výše uvedeným kritériím. V případě, že bychom si chtěli vyhledané objekty vyexportovat a dále s nimi pracovat, stačí pouze kliknout na tlačítko export a jen si uložit výsledný soubor.

archiveExport

Volání metod archivu z Java kódu

Nyní se zaměřím více na technickou stránku věci, aneb jak je možné obsluhovat archiv přes java kód. Pro obsluhu archivu vznikly nové statické metody na třídě data, které je možné volat kdekoliv z kódu. Protože automaticky se v CzechIdM nic nearchivuje, je nutné tuto akci vždy vyvolat explicitně. Například můžeme upravit workflow smazání uživatele, kde před samotným vykonáním smazání tohoto uživatele zaarchivujeme.

Archivování

Archivované objekty sice musí splňovat předepsanou strukturu vyžadovanou archivem, ale de facto je možné archivovat jakýkoliv serializovatelný objekt. Pro zaarchivování objektu musíme předat archivu meta informace jako jsou jméno a typ objektu a dále seznam jeho atributů, které si přejeme uložit. Každý ukládaný atribut se skládá ze jména a serializovatelné hodnoty. Při ukládání se tato hodnota uloží i v podobě řetězce z důvodů vyhledávání. Přesně s těmito atributy zavoláme metodu Data.archive a CzechIdM se postará o zbytek.

Vyhledávání v archivu

Pro prohledávání archivem používáme metodu Data.archiveSearch, které předáme kritéria vyhledávání. Ta nám vrátí iterátor, přes který můžeme procházet archivovanými objekty. Z důvodu rychlosti a optimalizace vrací iterátor pouze základní meta informace o archivovaném objektu, pro vytáhnutí celého objektu včetně jeho atributů musíme zavolat metodu Data.archiveGetElement, které předáme ID daného objektu. Zde je krátká ukázka jak definovat kritéria, které vyhledají objekt typu „IDENTITY“, zaarchivovaný před týdnem mající atribut manager nastavený na „Doe“:

Criteria criteria = new eu.bcvsolutions.idm.data.dto.Criteria();
criteria.add("type", "IDENTITY", Relation.EQ);
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DAY_OF_YEAR, -7);
criteria.add("archiveDate", cal.getTime(), Relation.GT);
criteria.createAlias("attributes", "attrs");
criteria.add("attrs.attrName", "manager", Relation.EQ);
criteria.add("attrs.attrValueAsString", "Doe", Relation.EQ);

Export

Export z archivu funguje podobně jako prohledávání. Na vstupu se mu předají kritéria a on vyexportuje všechny objekty odpovídající těmto kritériím do csv souboru. Ovšem protože každý objekt může mít k sobě napárovaný neomezený počet atributů a nás může zajímat pouze nějaká jejich podmnožina, je možné specifikovat pouze ty atributy, které se mají k daným objektům vyexportovat. Tyto atributy definujeme v mapě, které funkci exportu předáme. Jako klíče jsou názvy atributů, které chceme vyexportovat. Můžeme definovat i jejich hodnoty, které slouží pro přejmenování sloupce pro účely exportu. V případě, že chceme vyexportovat všechny atributy, předáme místo mapy null. Zde je názorná ukázka, jak vyexportovat všechny objekty archivu a k nim pouze atributy „MANAGER“ a „ROLES“ u kterých budeme ale chtít, aby se v exportu objevily jako „manažer“ a „role“.

Criteria criteria = new eu.bcvsolutions.idm.data.dto.Criteria();
Map<String> attributes = new HashMap<String>();
attributes.put("MANAGER", "manažer");
attributes.put("ROLES", "role");
File file = Data.archiveExport(criteria, attributes, "archiv_export");

Závěr

Po přečtení tohoto článku by jste měli být schopni sami umět ovládat archiv přes Java kód. Kdyby jste měli nějaké dotazy ohledně archivu či potřebovali poradit, kontaktujte mě přes filip.mestanek@bcvsolutions.eu.

Vypisujeme témata pro bakalářské a diplomové práce

Již několik let vypisujeme témata a vedeme bakalářské a diplomové práce. Zadání vytváříme na základě reálné potřeby pro skutečné zákazníky. Výsledek Vaší práce bude někdo používat a to v podstatě ihned. Proto hledáme šikovné lidi, kteří se nebojí udělat pořádnou práci a mají zájem se trochu zviditelnit.

Na čem budete pracovat?

CzechIdM Identity Management – nástroj pro centralizaci a automatizaci správy uživatelských identit (účtů, skupin atd.) v celé síti, a to bez výrazných zásahů do fungování stávajících systémů. CzechIdM je SW kompletně naprogramovaný v jazyce Java, konkrétně na platformě J2EE. Více zde: http://www.czechidm.com

Co budeš používat?

  • Java EE
  • JBoss AS
  • JBoss jBPM
  • Hibernate, Java persistent API (JPA)
  • Java Server Faces, Richfaces framework
  • EJB3
  • Connector Framework

Koho hledáme?

Obecně hledáme toho, kdo chce něco smysluplného vytvořit. Chceme toho, kdo dokončí co začal a chce se svou prací dlouhodobě chlubit. Pokud máte zájem vytvořit kvalitní práci, která nebude do šuplíku, a která bude přínosem, kontaktujte nás.

Ukázka témat

  1. Vytvoření konektoru na připojení Office365.
  2. Vytvoření automatické testovací platformy a automatických testů na GUI.
  3. Vytvoření nového uživatelského rozhraní CzechIdM.
  4. Realizace databázového migrátoru.

Kontakt

Kontaktuj mne na mailu lukas.cirkva@bcvsolutions.eu. Následovat bude osobní schůzka, kde si popovídáme a nabídneme několik témat a pokud si plácneme, domluvíme další kroky.

První krůčky s CzechIdM Kapitola 3: Nastavení synchronizace a rekonciliace systému

czechidm

V minulém díle jsme si ukázali, jak vytvořit koncový systém pro CzechIdM, a jak s jeho pomocí spojit CzechIdM s databázovou tabulkou. Dnes si ukážeme, jak sesynchronizovat účty v koncovém systému s identitami v CzechIdM. Také nastavíme rekonciliaci. Rozdíl mezi těmito dvěma slovy není veliký, protože obě operace se starají o stejnou činnost, jen v jiném rozsahu. V obou situacích sjednocujeme (synchronizujeme) stav účtů na koncovém systému a informace, které o nich máme v CzechIdM. A právě takovou operaci si dnes ukážeme. Ale nejdříve si vysvětlíme, co se vlastně při synchronizaci nebo při rekonciliaci děje.

Co to je synchronizace a rekonciliace

Jak jsme si již řekli o odstavec výše, cílem obou operací je synchronizovat data na koncovém systému a v CzechIdM. To se hodí provést v různých situacích. Buď jde o koncový systém, který jsme nově napojili na CzechIdM, a chceme účty na tomto systému připárovat k identitám v CzechIdM. Nebo jde o autoritativní koncový systém, kde pravidelně vznikají, aktualizují se nebo zanikají účty, a při každé takové změně chceme náležitě vytvořit, upravit či smazat příslušnou identitu v CzechIdM. Případně jde prostě o systém, kde z nějakého důvodu nesouhlasí stav účtů s tím, co je evidováno v CzechIdM, a to chceme opravit.

Zatímco při synchronizaci se zpracovávají jen ty účty na koncovém systému, které se od poslední synchronizace změnily nebo nově vytvořily, při rekonciliaci se zkontrolují úplně všechny účty. Samozřejmě nemusíme každých deset minut spouštět vybranou operaci ručně. Stačí jednou nastavit, kdy se má synchronizace či rekonciliace spustit a jak často se má opakovat.

Tím ale možnosti nastavení nekončí. Při obou operacích si můžeme vybrat, co se stane, nastane-li nějaká z modelových situací. Například představme si situaci, kdy vznikne nový účet na koncovém systému. Pomocí synchronizace můžeme nastavit, jaká operace se má provést. Můžeme si vybrat, co se stane jako výkonná akce a co jako informativní akce. Tak například jako výkonnou akci můžeme nastavit vytvoření nové identity, a jako informativní odeslání e-mailu na námi zadanou adresu. Samozřejmě pokud si nechceme zahlcovat schránku, CzechIdM nám může zaslat zprávu pouze v případě, kdy dojde k nějaké chybě, a nebo nám nemusí zasílat zprávy vůbec. Představivosti se meze nekladou.

Zasílání zpráv není rozhodně jedinou věcí, kterou CzechIdM umí. Můžeme si například nastavit hromadnou akci, která se spustí po zpracování všech účtů synchronizací/rekonciliací. Buďto můžeme opět odesílat zprávy, nebo si můžeme vybrat nějaké workflow či pravidlo, které se vykoná.

Důležitá věc, kterou musíme každé synchronizaci/rekonciliaci nastavit, je korelace. Korelace je podmínka, podle které CzechIdM přiřazuje jednotlivým identitám odpovídající účty. Například pokud jsme si v minulém dílu nastavili login jako jedinečný identifikátor účtu na koncovém systému, zde ho můžeme použít v nastavení synchronizace/rekonciliace: na základě rovnosti loginu koncového účtu a názvu identity v CzechIdM se účet této identitě přiřadí.

Zde jsou vyjmenované jednotlivé možnosti, které při synchronizaci či rekonciliaci mohou nastat:

  • ASSIGNED – účet je již přiřazen konkrétní identitě
  • MATCHED – účet a identita si odpovídají na základě korelace, ale účet ještě není připárován k identitě
  • MISSING_IDENTITY – existuje účet na koncovém systému, ale v CzechIdM neexistuje odpovídající identita
  • MISSING_ACCOUNT – existuje identita, která by měla na základě role mít účet na koncovém systému, ale nemá jej. Tento stav může nastat pouze u rekonciliace.

Tak nyní bychom měli mít alespoň základní informace o tom, co se vlastně při synchronizaci a rekonciliaci děje, a pojďme přejít na jejich nastavení.

 

Nastavení rekonciliace/synchronizace

Jako první krok si ukážeme, jak namapovat atributy.

Namapování atributů je potřebné v případě, kdy se během synchronizace/rekonciliace mají nastavovat hodnoty atributů identity v CzechIdM. Využijeme to tedy především u autoritativních koncových systémů. Například nastavíme, že do atributu „email“ u identity v CzechIdM se bude propagovat hodnota atributu „email“ koncového účtu. Pro rekonciliace běžných koncových systémů obvykle stačí nastavit mapování atributu „roles“, tj. jak se mají aktualizovat role identity v CzechIdM.

Přejdeme tedy na:

SystémyMapování atributů

1

vyplníme atributy identity a Uložíme výsledek.

2

Nyní přejdeme k nastavení samotné rekonciliace. Nastavení synchronizace je úplně stejné, proto si zde ukážeme pouze nastavení rekonciliace. Přejdeme na:

Systémy → Systémy → Nastavit rekonciliaci

1

u systému SystemTest1.

Zde nastavíme jednotlivé výkonné a informativní akce pro všechny stavy rekonciliace. 

42

a následně klikneme na Uložit.

Zobrazení výsledku rekonciliace/synchronizace

Zde si ukážeme, jak si zobrazit informace o probíhající rekonciliaci.

3

Přejdeme na:

Systémy → Systémy → Zobrazit informace o rekonciliaci (SystemTest1)

4

Zde jsou uvedeny informace o probíhající rekonciliaci, případně o posledním průběhu. Po prvním provedení se nelekejte výsledků MISSING_IDENTITY. Důvod je jednoduchý, jelikož proběhla první rekonciliace, nebyly v CzechIdM ještě žádné identity, které koncovým účtům odpovídají. Proto CzechIdM zahlásilo, že identita chybí, a vytvořilo ji. Pro odchod stačí kliknout na tlačítko Zavřít.

Závěr

V tomto krátkém díle jsme si ukázali, jak nastavit synchronizaci a rekonciliaci na CzechIdm. Po nastavení a spuštění by měly být všechny naše účty aktuální.

V případě jakýchkoliv dotazů pište prosím na michal.stejskal@bcvsolutions.eu.

 

První krůčky s CzechIdM Kapitola 2: Připojení databázové tabulky

czechidm

V tomto díle našeho krátkého seriálu o práci v CzechIdM se podíváme na to, jak definovat konektor pro koncový systém, jak připojit námi vytvořenou tabulku ke koncovému systému a nakonec se podíváme, jak vytvořit roli pro náš koncový systém.

Vytvoření databázové tabulky

V minulém dílu jsme si nainstalovali MySQL, zatím ale stále nemáme žádné přívětivé prostředí, kde můžeme s databázemi pracovat. Proto si nainstalujeme MySQL workbench. Instalace tohoto prostředí není nijak složitá, stačí v terminálu zadat

$sudo apt-get install mysql-workbench

Po skončení instalace zadáme opět v terminálu mysql-workbench

  • Ze záložky Database vybereme možnost Manage Connection. Zde pojmenujeme naše připojení a klikneme na Test connection. Pokud nastali problémy, zkontrolujte si prosím parametry připojení:

Záložka Connection

Connection Method: Standard (TCP/IP)

Hostname: 127.0.0.1

Port: 3306

Username: root

  • Ze záložky Database vybereme Connect to Database. U možnosti Stored Connection vyberem námi vytvořené připojení a klikneme na OK.
  • Zobrazí se nám prostředí pro práci s databázemi. Uprostřed je bílé okno pro vykonávání SQL příkazů. Do něj zadáme:
CREATE SCHEMA `test` ;
CREATE TABLE test.datas (
`ID` INT,
`firstName` TEXT,
`lastName` TEXT,
`login` TEXT,
`address` TEXT,
`city` TEXT,
`dateOfBirth` TEXT,
`company` TEXT,
`possition` TEXT,
`salary` INT,
`timeStamp` TEXT);

a klikneme na žlutý blesk v horní části obrazovky. Tím se vykoná SQL příkaz, který vytvoří nové schéma test a v něm tabulku datas se sloupci jméno, příjmení, email… .

  • Dalším krokem je nastavení primárního klíče. V levé části obrazovky máme světle modré pole. Pokud máme mysql-workbench spuštěný poprvé, je toto pole prázdné. Klikneme na něj tedy pravým tlačítkem a vybereme Refresh All. Zobrazí se námi vytvořené schéma a v něm naše zatím prázdná tabulka.
  • Klikneme na ní opět pravým tlačítkem a zvolíme Alter table. Otevře se nám dialog pro nastavení tabulky test. Zaškrtneme parametry PK a NN u sloupce ID. Parametr PK znamená, že daný sloupec bude primárním klíčem. Pomocí primárního klíče se jednoznačně identifikuje každý záznam v tabulce. To znamená, že žádné ID v naší tabulce nemůže být shodné s dalším, nebo že žádné ID nesmí být prázdné. Toho docílíme právě zaškrtnutím NN parametru (nut null). Dále zaškrtneme možnost AI (Auto Increment), kterým nastavíme, že každé další ID bude o jedna větší než ID předchozí.
  • Nyní nasypeme nějaká testovací data do naší nové tabulky. Do záložky Query 1 v horní části obrazovky  zkopírujeme následující kód:
INSERT INTO test.data (`firstName`, `lastName`, `login`, `address`, `city`, `dateOfBirth`, `company`, `possition`, `salary`, `timeStamp`) VALUES ('Drahoslav', 'Miler', 'Drahoslav@Miler.cz', 'Stráň 122', 'Lobeč', '10.10.1957', 'b', 'Lorem ', '20077', '12.4.2014');

Opět klikneme na žlutý blesk vlevo nahoře do naší databáze se přidá první záznam. Takto můžeme vkládat kolik záznamů chceme. Vždy do hodnoty VALUES vložíme data přesně tak, jak je to ukázáno v kódu nahoře. Pokud si chceme zkontrolovat výsledek, klikneme pravým tlačítkem myši na tabulku datas a zvolíme Select rows – 1000 limit.

Pokud si o databázích chcete přečíst něco podrobnějšího, podívejte se například na tento seriál: http://www.linuxsoft.cz/article.php?id_article=731

Definování typu systému pro konektor

Prvním krokem je vydefinování typu systému pro Database Table konektor v CzechIdM. Tento krok stačí provést pouze jednou, a to když připojujete nějaký systém pomocí tohoto konektoru poprvé. Přejdeme tedy na záložku

Systémy → Typy systémů → Nový typ.

Zaškrtneme možnost, že se má použít lokální connector server a klikneme na Pokračovat. Posledním krokem je pojmenování nového typu systému a vybrání správného balíku. My náš typ pojmenujeme Database Table Konektor a jako balík vybereme org.identityconnectors.databasetable-1.1.xx.jar.

Nyní stačí už jenom náš nový typ systému uložit a máme hotovo.

Připojení systému s databázovou tabulkou

Snímek obrazovky pořízený 2014-07-27 23:06:42

Nyní již propojíme námi vytvořenou tabulku s CzechIdM. Pro tento krok musíme vytvořit nový systém, který bude sloužit k připojení k tabulce. Přejděme tedy na záložku

Systémy → Systémy → Nový systém
  • Vybereme konektor, který jsme vytvořili v předchozím kroku, tedy Database Table Konektor a klikneme na Next.
  • V nové tabulce vyplníme Název systému na SystemTest1, kolonku Název pro uživatele necháme v tuto chvíli volnou.
  • Authority level nastavíme na 0. Tímto číslem určujeme jak moc bude náš systém autoritativní pro data v CzechIdM. Čím je toto číslo větší, tím více je systém autoritativní. Prakticky to bývá tak, že level 1 je zdrojový systém (systém je zdroj dat pro identity v CzechIdM), level 0 je koncový systém (CzechIdM je zdroj dat pro koncový systém).
  • Pouze ke čtení nebudeme zaškrtávat, protože budeme v budoucnu upravovat tabulku pomocí CzechIdM.
  • Další položkou, kterou vyplníme, je port. Nastavíme ho na 3306, tam nám totiž běží MySQL databáze.
  • Dále jako Key Column zvolíme login. Key Column nám určuje, který atribut bude použit jako identifikátor jak při zobrazování, tak i například při synchronizaci systému.
  • Initial JNDI Properties v tuto chvíli necháme volné.
  • Do položky Host zadáme místo, kde nám běží server, tedy localhost.
  • All native nebudeme zaškrtávat.
  • Name quoting necháme volné.
  • Do políčka Table zadáme jméno námi vytvořené tabulky, tedy datas.
  • Pokud jste nechali při instalaci MySQL serveru políčko pro heslo roota prázdné, nevyplňujte ani políčko User Password. V opačném případě zadejte heslo, jež jste si nastavili pro MySQL roota.
  • Do kolonky Database se zadává jméno databáze, ke které se připojujeme. V našem případě se databáze jmenuje test.
  • Change Log Column (Sync) nastavíme na timeStamp. Tím jsme nastavili, který atribut bude použit při synchronizaci systémů jako časová značka změněných řádků.
  • Password Column necháme také volné, protože v naší databázové tabulce nemáme žádný sloupec obsahující hesla.
  • JDBC Connection URL nastavte na jdbc:mysql://%h:%p/%d. Tím jsme určili URL pro spojení CzechIdM a databáze.
  • Native Timestamps a Enable writing empty string nebudeme zaškrtávat, ale položku Rethrow all SQLExceptions označíme.
  • Validate Connection Query necháme volné.
  • Do pole User napíšeme root, což je uživatelské jméno, přes které se připojujeme k MySQL databázi.
  • Datasource Path necháme volné.
  • JDBC Driver nastavíme na com.mysql.jdbc.Driver. Tím jsme určili třídu konektoru pro připojení do databáze.

Nyní klikneme na tlačítko Test. Tím se otestuje zda-li je náš systém pro připojení správně nastaven. Zobrazí-li se hláška o úspěšném navázání spojení, klikněte na Pokračovat.

Snímek obrazovky pořízený 2014-07-27 23:08:06

Nyní se dostaneme do okna, kde můžeme editovat atributy. Klikneme tedy na Editovat atributy a zobrazí se nám jména sloupců z námi vytvořené databázové tabulky.  Do sloupce IdmName vyplníme jednotlivé atributy tak, aby CzechIdM poznalo, o který atribut se jedná, Tedy pokud pojmenujeme atribut firstName, pro CzechIdM opět firstName, CzechIdM bude vědět, že se jedná o křestní jméno. Poté klikneme na tlačítko Uložit.

Pokud si chceme zobrazit výsledky naší práce, klikneme na na odkaz Zobrazit všechny účty na seznamu našich systémů. Měli bychom vidět pouze prázdný seznam a až po kliknutí na tlačítko Hledat se nám zobrazí všechny účty z našeho koncového systému. Můžeme rozklikávat jednotlivé účty a prohlížet si jejich detaily. Ve chvíli, kdy skončíme, klikneme na tlačítko Zavřít.

Vytvoření role pro připojený systém

Poslední krok, který si v tomto článku ukážeme, je vytvoření role v CzechIdM, která vytváří účty na připojeném systému, jakmile je přiřazena uživateli. Přejdeme na záložku

Role → Role → Nová role

a zde na záložce Základní informace vyplníme název nové role (např. Test system account). Poté přejdeme na záložku Schémata zdrojů a klikneme na odkaz Přidat u systému Test end system v pravé tabulce (se seznamem všech připojených systémů). Poté klikneme na odkaz Editovat v levé tabulce (se seznamem systémů, ke kterým opravňuje tato role).

Na následující stránce můžeme nastavit, jak budou atributy účtu plněny touto rolí v závislosti na svých potřebách. Zatím to ponecháme beze změny a klikneme na Nastavit.

Naši novou roli už jen Uložíme. Tuto roli můžeme přidělit libovolné identitě a tím pro ni vytvořit nový účet na napojeném koncovém systému.

Závěr

V tomto článku jsme si ukázali, jak připojit databázovou tabulku pomocí Database Table konektoru, a jak si zobrazit data z tabulky. Dále jsme si ukázali, jak vytvořit roli, jež nám vytvoří účet pro identitu v databázové tabulce. V příštím díle se podíváme na to, jak sesynchronizovat účty a jak nastavit rekonciliaci.

Pokud jste v článku nalezli nějakou chybu, nebo máte nějaký dotaz, prosím napište mi na michal.stejskal@bcvsolutions.eu .

 

První krůčky s CzechIdM Kapitola 1: Instalace potřebných programů

czechidm

Dobrý den, vítejte u první části našeho detailního seriálu, ve kterém si ukážeme, jak nainstalovat a nakonfigurovat náš systém pro CzechIdM, a také si ukážeme základní práci s CzechIdM. V této části si nainstalujeme programy, bez kterých bychom CzechIdM nemohli zprovoznit. Každý z těchto programů je důležitý stejně tak jako jeho následné nastavení, proto vyskytnou-li se problémy, pokuste se je spravit nebo mne kontaktujte.

Nyní přistoupíme k samotné instalaci. Pro korektní běh aplikace CzechIdM jsou potřeba pouze tři věci (MySQL, Java (jdk, jre), JBoss). Všechny tři programy spolu nyní nainstalujeme, nastavíme a vysvětlíme jejich důležitost pro běh CzechIdM. Veškeré nastavení a instalace budou prováděny v rámci operačního systému Ubuntu ve verzi 14.04 64bit. Všechny příkazy začínající $ jsou příkazy pro terminál.

Instalace MySQL

MySQL je důležité pro práci s databází. V databázi budou drženi jednotliví uživatelé a CzechIdM se do MySQL bude přes konektor připojovat. Bez MySQL bychom měli sice velmi silný nástroj na správu identit, ale žádná data, se kterými bychom pracovali. Přejděme tedy k instalaci MySQL.

Nejdříve nainstalujeme MySQL a MySQL server. Tato instalace probíhá přes balíčkovací systém yum. Pokud Vám při zadání prvního příkazu instalace vyskočí chybová hláška o chybějící programu yum, jednoduše ho doinstalujte zadáním sudo apt-get install yum do Vašeho terminálu.

$yum install mysql
$yum install mysql-server

 

Nyní nastartujeme MySQL server pomocí příkazu

$sudo /etc/init.d/mysql start

Pokud nenastala žádná chyba, máme nyní úspěšně nainstalované aplikace spravující databáze.

Instalace Javy a konektoru pro připojení k MySQL

Druhým krokem, který musíme udělat, než spustíme náš server s CzechIdm, je instalace Javy a to konkrétně JDK. JDK v sobě mimo jiné obsahuje Java Runtime Enviroment, jež je potřeba ke spouštění aplikací napsaných právě v Javě. Začněme tedy s instalací.

Přejdeme na stránku http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html a stáhneme si zde JDK ve verzi 1.7 pro 64bitový systém Linux. Stažený archiv si rozbalíme a překopírujeme do adresáře /opt pomocí příkazů

$tar -xzf jdk-7u51-linux-x64.tar.gz
$mv jdk1.7.0_51 /opt/

Instalační skript pro JBoss má zadanou cestu k Javě. Jelikož by bylo zbytečně složité pokaždé přepisovat instalační skript pro instalaci, vytvoříme symbolický odkaz na složku, kde máme umístěnou Javu.

$ln -s /opt/jdk1.7.0_51 /opt/jdk

Dále nainstalujeme prostředí pro spuštění Javy

sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java7-installer

Poslední věc, kterou musíme udělat, je nastavit JAVA_HOME v .bashrc. Nejdříve zjistíme, kde máme Javu, spustíme tedy příkaz

$which java

Dostaneme umístění Javy. V našem případě máme Javu v /usr/bin/java. Ny přejdeme do našeho domovského adresáře a otevřeme si .bashrc a vložíme následující řádky (pokud Vám příkaz which java ukázal jiné umístění, uložte do proměnné JAVA_HOME cestu, která platí pro Váš systém)

$vim .bashrc
JAVA_HOME=/usr/bin/java 
export JAVA_HOME 
PATH=$PATH:$JAVA_HOME 
export PATH

Nyní máme úspěšně staženou Javu a můžeme si stáhnout JDBC konektor. Konektor budeme používat pro připojení JBoss serveru k naší MySQL databázi, aby mohl pracovat s jejími záznamy. Přejděte na stránku http://search.maven.org/remotecontent?filepath=mysql/mysql-connector-java/5.1.8/mysql-connector-java-5.1.8.jar a uložíme si ho do adresáře /tmp.

Instalace JBoss serveru

Úspěšně jsme nainstalovali MySQL a rozběhli Javu, která je důležitá pro běh JBoss serveru. Přejděme tedy k tomu nejdůležitějšímu, a to je instalace JBoss serveru společně s CzechIdm. Ze stránky http://download.czechidm.com/doku.php si stáhneme nejnovější release a stažený balíček rozbalíme

$tar -xzf czechidm-jboss-2014q1.tar.gz

Nyní přejdeme do složky scripts, kde je uložen instalační skript. Tento skript zkontroluje, zda máme nainstalované všechny potřebné programy, a pokud ano, nainstaluje JBoss.

$cd czechidm-jboss-2014q1/scripts

Pomocí příkazu

$./install_jboss.sh

skript spustíme.

Při instalaci budeme vyzváni k zadání hesla pro uživatele root v MySQL. Pokud jste heslo nenastavovali, nechte pole prázdné a potvrďte, jinak zadejte heslo. Nemusíte se ničeho obávat, toto heslo se nikde neukládá, vyplňujeme me ho pouze proto, aby instalační skript mohl vytvořit databázi pro CzechIdM. Další věc, kterou musíme při instalaci udělat, je zadat absolutní cestu k našemu staženému konektoru. JDBC jsme si stáhli do složky /tmp zadáme tedy tuto cestu

$/tmp/mysql-connector-java-5.1.8.jarm

Pokud při instalaci nenastaly žádné problémy, budeme uvítáni následujícím textem:

================================================
WELCOME to JBoss & CzechIdM installation script!
================================================

Creating home directory for CzechIdM: /opt/czechidm... done.

Creating repository and its admin for CzechIdM...
  (MySQL root) Enter password: 
Done.

Installing JBoss AS to /opt/czechidm... done.

Adding MySQL connector to JBoss...
  Enter the location of the MySQL connector JAR file (or type SKIP to configure it manually):
/tmp/mysql-connector-java-5.1.8.jar 
Done.

Configuring JBoss as a service to /etc/init.d/jboss... done.

JBoss for CzechIdM installation completed.

You can start JBoss with the command 'service jboss start'.

JBoss máme nainstalovaný, takže spustíme server příkazem:

$service jboss start

Samotné spuštění chvilku trvá, většinou se připravte na 2 až 3 minuty čekání. Mezitím se tedy přesuneme do složky, kde je uložený log ze serveru, a budeme kontrolovat, zda-li se při startu neobjeví nějaká chyba. Přesuneme se  tedy do složky s logem a pomocí příkazu tail -f se podíváme na log.

$cd /opt/czechidm/jboss/server/default/log/
$tail -f server.log

Po úspěšném spuštění JBoss serveru budeme mít na posledním řádku zobrazeno

[org.hibernate.util.NamingHelper] (JbpmJobExecutor@127.0.0.1:Executor-1) JNDI InitialContext properties:{} 
Instalace CzechIdM

Nyní máme úspěšně nainstalované a spuštěné prostředí pro CzechIdM. Přejdeme tedy k jeho instalaci. Jako první krok se přesuneme do složky, kde máme uložený instalační skript

$cd /tmp/czechidm-jboss-2014q1/scripts

a spustíme instalaci CzechIdM

$./install_czechidm.sh

Pokud proběhne vše v pořádku, máme vyhráno. Úspěšně jsme nainstalovali CzechIdM a můžeme se s ním začít učit. Spustíme prohlížeč, zadáme adresu http://localhost:8080/idm a můžeme se začít seznamovat s CzechIdM.

Snímek obrazovky pořízený 2014-07-27 20:43:38

Odinstalace CzechIdM

Pokud se z nějakého důvodu rozhodneme odinstalovat CzechIdM z počítače, musíme nejprve vypnout JBoss server pomocí příkazu

$service jboss stop

Pak přejdeme do složky, kde máme CzechIdM

$cd /tmp/czechidm-jboss-2014q1/scripts

A spustíme odinstalaci

$./uninstall.sh

Tento skript nám odinstaluje CzechIdM z počítače.

Závěr

V tomto článku jsme si ukázali, jak nainstalovat prostředí pro spuštění CzechIdM a jak nainstalovat samotné CzechIdm do našeho počítače. Příště si ukážeme, jak vytvořit tabulku v MySQL, jak nastavíme konektor pro systém a propojíme CzechIdM s databází.

V případě jakýchkoliv dotazů, pište na michal.stejskal@bcvsolutions.eu .

Oracle – co dělat když se rozsype ASM

Na Oracle clusteru používáme ASM pro ukládání souborů databáze. Když všechno běží, je to paráda. Když se něco pokazí, je to paráda trochu menší, ale náprava naštěstí nebývá složitá. Jednoho dne se v našem ASM pokazila metadata a následkem toho ztratilo přehled o discích s daty. Co se vlastně stalo a co s tím dělat se dočtete dále.

Co to vlastně je ASM?

Diskgroups

U Oraclích databází máme dvě možnosti, kam ukládat data – buď klasicky na filesystém nebo na ASM. ASM stojí na principu tzv. groups. Grupa je zhruba analogická oddílu filesystému – může na ní ležet jedna nebo více databází, podle potřeby.

ASM potom podle nastavené redundance dat v grupě (external=žádná, normal=mirror, high=mirror s dvěma kopiemi dat) využívá datová úložiště a samo se stará o uložení a správu datových bloků, tzv. extents.

Aby to nebylo tak jednoduché, grupa je rozdělena na logické celky, kterým se říká failgroups. Pro ty platí vše, co jsme zatím zmínili o grupě. Pokud má grupa jen jeden disk, je tento disk vlastně samostatnou failgrupou.

Podle nastavené redundance je pak vyžadován určitý počet failgroup v grupě. Například pokud budeme mít normal redundancy grupu DBG a v ní failgrupu DBFG1 s jedním diskem. Po přidání dalšího disku do DBG se automaticky vytvoří DBFG2, pokud mu to ovšem explicitně nezakážeme. Tyto failgroup jsou vzájemně mirrorem. Pokud bychom přišli o celou DBFG1, databáze stále poběží, protože všechna data máme v kopii v DBFG2.

ASM instance

Ačkoli jde o datové úložiště, dokáže se ASM do určité míry chovat jako instance databáze. K této instanci pak jako klienti lokálně přistupují jednotlivé databáze.

K administraci ASM slouží utilita asmcmd, což je ekvivalent přizpůsobené a hodně osekané příkazové řádky. Protože se ale ASM dokáže chovat jako databázová instance, nic nám nebrání se k ní připojit přes sqlplus. Potom si můžeme v klasickém SQL stylu spouštět i dotazy na vlastnosti, stav a aktuální akce.

Co se vlastně stalo

„Příčina nehody: neznámá. Místo: neznámé. Čas: neznámý. Doufám, že tyto informace pomohou objasnit nehodu, ke které tu došlo.“ –Kryton, seriál Červený trpaslík

Citát to vystihuje naprosto přesně. ASM se jednoho dne prostě rozhodlo, že se mu DBFG1 nelíbí, vyhodilo z ní všechny disky a pak se ji pokusilo z DBG odebrat. Odebírání disků z grupy je běžná věc – jde o automatický mechanismus, kdy ASM při zjištění mrtvého disku (nelze z něj číst nebo na něj zapisovat) tento disk po určité době odstraní. Následně přesype data v grupě, aby vyžila s tím, co jí zůstalo, a zároveň co možná nejlépe splnila podmínky na redundanci dat. Odstraněným diskům se nastaví hromada příznaků, aby šlo poznat, co se s nimi dělo. ASM také každé odstranění zaloguje.

Stav po zjištění problému byl následující: u disků právě probíhalo odstraňování, ASM ale nepřesýpalo data, příznaky u disků byly podivně nastavené a v logách instance bylo prázdno. Podle operačního systému byly disky dostupné po celou dobu běhu serveru.

Vše tedy ukazovalo na neplechu v ASM. Takže aktuálně vyřešit nápravu a potom hledat příčinu, pokud ji vůbec máme šanci najít.

Chybový stav

Připojil jsem se do ASM jako „sqlplus / as sysasm“ a vypsal si grupy:

SQL> select mount_status, header_status, state, failgroup, os_mb, total_mb, path from v$asm_disk;

MOUNT_STATUS	HEADER_STATUS	STATE	FAILGROUP	OS_MB	TOTAL_MB	PATH
--------------------------------------------------------------------------------------------------------
MISSING		UNKNOWN		FORCING	DBFG1		0	26624
CLOSED		MEMBER		NORMAL			26624	0		/dev/mapper/dbfg1_disk
CACHED		MEMBER		NORMAL	DBFG2		26624	26624		/dev/mapper/dbfg2_disk

Můžete si všimnout, že disk z DBFG1 podle ASM nemá korektní hlavičku. Tady s ním moc neuděláme, podíváme se přímo do operačního systému.

kfed

Kfed je šikovná utilita, která člověku umožňuje hrabat se přímo v metadatech ASM disku. Navíc nepotřebuje, aby běželo cokoliv z Oracle stacku. Stačí mít disk namountovaný v operačním systému nebo mít fungující ASMlib (pokud je používán). Pomocí „kfed read“ si vypíšeme hlavičku disku (offsety úplně nesedí, protože DBG a DBFG jsou upravené názvy):

[root@node1 ~]# kfed read /dev/mapper/dbfg1_disk
...
kfbh.type:                            1 ; 0x002: KFBTYP_DISKHEAD
...
kfdhdb.grptyp:                        2 ; 0x026: KFDGTP_NORMAL
kfdhdb.hdrsts:                        3 ; 0x027: KFDHDR_MEMBER
kfdhdb.dskname:               	  DBG_0 ; 0x028: length=5
kfdhdb.grpname:                     DBG ; 0x048: length=3
kfdhdb.fgname:                	  DBFG1 ; 0x068: length=5
...

Stručný význam jednotlivých polí, konkrétní hodnoty si můžete vyčíst třeba zde:

type - typ hlavičky, zde nám říká, že jde o ASM diskovou hlavičku
grptyp - typ redundance grupy, kam disk patří
hdrsts - stav disku vůči grupě
dskname - jméno disku
grpname - jméno grupy
fgname - jméno failgrupy

Takže tímhle to nebude. Ještě pomocí „kfed find“ zkontrolujeme metadata disku:

[root@node1 ~]# kfed find /dev/mapper/dbfg1_disk
Block 0 has type 1
Block 1 has type 2
Block 2 has type 3
... (všechno další musí být "type 3")

Příkaz find projde bloky disku a vyzkouší, zda sedí metadata bloků. Odhalí tedy špatné checksumy, ale nikoli chyby v datech. Pokud budou v bloku poškozená data, ze kterých bude správně spočten checksum, nedozvíme se to.

Náprava

Poškozená fyzická data nás momentálně netrápí, protože databáze normálně běží a klienti v ní spouštějí dotazy. Disk z grupy vypadl před nějakou dobou, a tedy ho stejně musíme sesynchronizovat, aby obsahoval aktuální data. Protože disk nevypadá poškozený, prostě ho do grupy našťoucháme zpátky:

SQL> alter diskgroup DBG add failgroup DBFG1 disk '/dev/mapper/dbfg1_disk';

Na což Oracle zareaguje hlášením, že disk už součástí nějaké grupy je. Trochu příkaz upravíme (protože v tomto případě nic rozbít nemůžeme):

SQL> alter diskgroup DBG add failgroup DBFG1 disk '/dev/mapper/dbfg1_disk' force;

Což už projde. Inu, co nejde silou…
Teď jsme tedy přidali disk do grupy a proběhne přesýpání (tzv. rebalance). ASM má najednou více failgroup, takže si na ně rozhodí data kvůli redundanci. Proces chvilku trvá a lze ho uspíšit explicitním zvýšením priority. Konkrétní dotaz, který jsem použil při nápravě:

SQL> alter diskgroup DBG add failgroup DBFG1 disk '/dev/mapper/dbfg1_disk' force rebalance power 4;

Parametr „power“ může nabývat hodnot 0-11 (0-STOP,11-TURBO:) ), default je 1. Grupa se rebalancovala a od té doby běží vše tak, jak má.
U velkých databází může rebalance trvat dlouho, proto je dobré použít „power“ a trochu přesýpání pomoci. Aktuální činnost ASM lze získat výpisem:

SQL> select * from v$asm_operation;
GROUP_NUMBER	OPERA	STATE	POWER	ACTUAL	SOFAR	EST_WORK	EST_RATE	EST_MINUTES	ERROR_CODE
------------------------------------------------------------------------------------------------------------------
1		REBAL	RUN	4	2	475	2310		1360		0

Závěr

V článku jsem představil postup nápravy chybného stavu ASM za použití standardních utilit dodávaných s Oracle databází. Dále jsme si ukázali utilitku kfed, jakožto rychlého pomocníka pro orientaci v datech ASM disků. Podobný postup se uplatňuje, pokud disky skutečně oprávněně vypadnou z ASM grupy – v takovém případě není třeba nic „forcovat“. Pokud vás článek zaujal, nebo byste se chtěli zeptat na cokoliv ohledně ASM a Oracle DB, neváhejte mne kontaktovat na petr.fiser@bcvsolutions.eu.

CzechIdM na Windows? Není problém!

Windows-supportPři příležitosti vydání nového releasu CzechIdM a jeho zveřejnění jsme řešili, jak udělat instalaci CzechIdM co nejjednodušší a tím nejvíce dostupnou.

Vznikl instalační návod a několik instalačních skriptů, které automaticky konfigurovaly potřebné aplikační prostředí. Protože ale vývoj CzechIdM probíhá na Linuxu a zároveň všechny dosavadní instalace jsou na Linuxu, vznikly tyto skripty právě jen pro Linux. Jak CzechIdM, tak i aplikační server na kterém CzechIdM běží jsou napsané v Javě, proto není problém ho spustit na všech systémech.

Jako cíl jsme si tedy dali zprovoznění CzechIdM i pro Windows o kterém budu právě pojednávat v tomto článku. Celkově se instalace na Windows liší pouze v odlišné konfiguraci specifické pro Windows. Pokud by vás zajímalo více obecně o instalaci a jejích detailech, přečtěte si článek Zjednodušení instalace CzechIdM.

Stažení balíčku CzechIdM

Nejprve si stáhneme distribuční balíček CzechIdM z http://www.czechidm.com/getstarted/. Ten obsahuje aplikační server, potřebné sql skripty na úvodní naplnění dat a uploader. Nejprve si zkopírujeme složku jboss-5.1.0.GA tam, kde chceme mít CzechIdM nainstalované. Zde je třeba dát pozor na příslušná oprávnění – je dobré zkopírovat tuto složku do nějaké uživatelem vlastněné složky. Kdybychom ji zkopírovali například do Program files, je možné, že by CzechIdM nenaběhlo z důvodu výších nároků na práva.

Zprovoznění aplikačního prostředí

Nejprve je třeba stáhnout a nainstalovat MySQL server a databázi. Najdeme ho na adrese http://dev.mysql.com/downloads/. Podporované jsou verze 5 a vyšší. Spustíme MySQL server (nachází se ve složce bin/mysqld.exe). Nyní je třeba založit databázi a nakonfigurovat uživatele, přes kterého se CzechIdM do MySQL připojuje. Na to naštěstí máme skripty, které vše udělají za nás. Překopírujeme všechny sql skripty do lokace, kam jsme nainstalovali MySQL do složky bin. Přesměrujeme skript initial_import.sql na standartní vstup mysql přes CMD.

mysql -u root < create_repository.sql

Dále stáhneme MySQL JDBC connector z http://search.maven.org/remotecontent?filepath=mysql/mysql-connector-java/5.1.8/mysql-connector-java-5.1.8.jar. To je konektor, který umožnuje CzechIdM se připojit právě do MySQL databáze kam si ukládá svoje vlastní data. Tento konektor musíme nakopírovat do složky, kde máme překopírovaný jboss do server/default/lib/ a server/default/deploy/CzechIdM-ear.ear/lib/. Zároveň ho musíme zkopírovat do složky, kam jsme stáhli distribuci CzechIdM do IdmUploader/IdmUploader_lib/.

Jako poslední bude třeba stáhnout a nainstalovat aplikační prostředí Javy. Najdeme ho na http://www.oracle.com/technetwork/java/javase/downloads a stáhneme JDK 1.7. Úspěšnou instalaci můžeme zkontrolovat v CMD zadáním

java -version

Instalace CzechIdM

V této fázi máme již vše potřebné připravené. Zbývá již jen spustit aplikační server JBoss a nahrát počáteční import dat do databáze. Server spustíme tak, že půjdeme na umístění, kam jsme ho zkopírovali do složky bin, kde spustíme run.bat. Tím by se měl začít server spouštět. Počkáme, než kompletně naběhne. To poznáme, že poslední věta v konzoli bude vypadat jako JNDI InitialContext properties:{}

Teď potřebujeme importovat počáteční data do databáze. Ty nám vytvoří výchozí uživatele v CzechIdM. Jdeme do složky MySQL/bin a zde zadáme do CMD

mysql -u root < initial_import.sql

Jako poslední úkol je nahrání aplikační logiky do CzechIdM. K tomu slouží program IdmUploader, který je ve složce distribuce, kterou jsme stáhli na začátku článku. Zde je třeba spustit runIdmUploader.bat. Import dat trvá obecně okolo 30 sekund.

Dokončení instalace

Jakmile máme AS JBoss spuštěný, MySQL máme připojený do CzechIdM a zároveň jsme provedli počáteční import, můžeme se přihlásit do administrátorského rozhraní. To se typicky nachází na adrese http://localhost:8080/idm. Pro přihlášení použijeme účet superadministrátora, která má login „admin“ a počáteční heslo je stejné. Nezapomeňte si toto heslo v konfiguraci změnit jako první!

Závěr

Tímto by měla být instalace CzechIdM hotová a můžete se k němu připojit přes http://localhost:8080/idm, kde se příhlásíte jako admin s heslem admin. Kdyby jste měli nějaké otázky či problémy s instalací CzechIdM na Windows, neváhejte se obrátit na filip.mestanek@bcvsolutions.eu.