ˇ e vysok´e uˇcen´ı technick´e v Praze Cesk´ Fakulta elektrotechnick´a
ˇ VUT FEL katedra pocˇı´tacˇu˚ C
Bakal´aˇrsk´a pr´ace
Datab´ aze pacient˚ u Zdenˇek Kˇrepela
Vedouc´ı pr´ace: Ing. Zdenˇek Tron´ıˇcek, Ph.D.
Studijn´ı program: Elektrotechnika a informatika strukturovan´ y bakal´aˇrsk´ y Obor: Informatika a v´ ypoˇcetn´ı technika ˇcerven 2008
ii
Podˇ ekov´ an´ı Chtˇel bych na tomto m´ıstˇe podˇekovat panu Ing. Zdeˇ nku Tron´ıˇckovi, Ph.D. za jeho trpˇelivost a podporu, kter´e mi pomohly pˇri zpracov´an´ı bakal´aˇrsk´e pr´ace.
iii
Prohl´ aˇ sen´ı Prohlaˇsuji, ˇze jsem svou bakal´aˇrskou pr´aci vypracoval samostatnˇe a pouˇzil jsem pouze podklady uveden´e v pˇriloˇzen´em seznamu. Nem´am z´avaˇzn´ y d˚ uvod proti uˇzit´ı tohoto ˇskoln´ıho d´ıla ve smyslu §60 Z´akona ˇc. 121/2000 Sb., o pr´avu autorsk´em, o pr´avech souvisej´ıc´ıch s pr´avem autorsk´ ym a o zmˇenˇe nˇekter´ ych z´akon˚ u (autorsk´ y z´akon).
Abstract The work is concerned with remote procedure call communication in distributed systems environment. It is focused especially on Web Services technology and platform independent SOAP protocol. The part of the work is sample database application based on the JEE architecture.
Abstrakt Tato pr´ace se zab´ yv´a komunikac´ı zaloˇzen´e na vzd´alen´em vol´an´ı procedur v distribuovan´ ych syst´emech. Je zamˇeˇrena pˇredevˇs´ım na technologii Webov´ ych sluˇzeb a platformnˇe nez´avisl´ y protokol SOAP. Souˇca´st´ı je uk´azkov´a datab´azov´a aplikace postaven´a na architektuˇre JEE.
Navrhnˇete a implementujte uk´azkovou JEE aplikaci. Aplikace bude obsahovat datab´ azi pacient˚ u a bude pˇr´ıstupn´a pˇres webov´e sluˇzby. Pro kaˇzdou sluˇzbu implementujte klienta, kter´y umoˇzn´ı ovˇeˇrit funkˇcnost webov´e sluˇzby. V tomto pˇr´ıpadˇe je tedy pr´ace n´avrhovˇe-implementaˇcn´ıho charakteru. S vedouc´ım pr´ace jsme se jiˇz pˇredem dohodli na pouˇzit´e technologii, kter´a je tak uvedena pˇr´ımo v zad´an´ı. Chtˇel bych d´ale uk´azat, ˇze pouˇzit´ı webov´ ych sluˇzeb ˇreˇs´ı probl´em univerz´alnosti rozhran´ı pro komunikaci mezi objektovˇe distribuovan´ ymi syst´emy. Zkratka JEE (Java Platform, Enterprise Edition) naznaˇcuje, ˇze pro implementaci bude pouˇzit programovac´ı jazyk Java. JEE1 (dˇr´ıve J2EE2 ) je sada d´ılˇc´ıch technologi´ı, kter´e n´am umoˇzn ˇuj´ı jednoduˇse vyv´ıjet, nasazovat a udrˇzovat v´ıcevrstv´e aplikace pˇredevˇs´ım na stranˇe serveru. Zp˚ usob, jak´ ym tyto technologie mezi sebou spolupracuj´ı je definov´an specifikac´ı. Abychom mohli vyuˇz´ıvat veˇsker´e moˇznosti, kter´e n´am tato specifikace nab´ız´ı, existuj´ı r˚ uzn´e implementace, kter´ ym ˇr´ık´ame aplikaˇcn´ı servery. Pro tuto pr´aci jsem si zvolil volnˇe dostupn´ y aplikaˇcn´ı server JBoss3 . JBoss je ˇsiroce rozˇs´ıˇren´ y open source aplikaˇcn´ı server, certifikovan´ y pro platformu J2EE 1.4. Plnˇe vˇsak podporuje technologie EJB 3.0 a JAX-WS, kter´e bych chtˇel v t´eto pr´aci pouˇz´ıt. JBoss je distribuov´an pod LGPL licenc´ı. Je zaloˇzen na architektuˇre mikroj´adra, kter´e pokytuje pouze kl´ıˇcov´e sluˇzby a ˇcin´ı tak z JBossu vysoce modul´arn´ı syst´em. Lze tak jednoduˇse pˇridat sluˇzby jako transakˇcn´ı manager, jmennou sluˇzbu, webov´ y server, ejb kontejner atd. Za zm´ınku stoj´ı t´eˇz aplikaˇcn´ı servery WebSphere (IBM) nebo GlassFish, coˇz je referenˇcn´ı implementace od firmy Sun Microsystems. GlassFish je postaven jiˇz na technologii JEE 5. V´ yhody t´eto technologie oproti J2EE lze struˇcnˇe charakterizovat jako zjednoduˇsen´ y programovac´ı model. V t´eto pr´aci v´ ybˇer aplikaˇcn´ıho serveru nen´ı pˇr´ıliˇs podstatn´ y. R´ad bych t´eˇz zm´ınil, ˇze Enterprise aplikace dodrˇzuj´ıc´ı specifikaci jsou ve vˇetˇsinˇe pˇr´ıpad˚ u velmi dobˇre pˇrenositeln´e, coˇz znamen´a, ˇze je lze v pˇr´ıpadˇe potˇreby pˇresunout z jednoho aplikaˇcn´ıho serveru na 1
druh´ y bez v´ yrazn´ ych z´asah˚ u do zdrojov´eho k´odu. Z´asah do konfiguraˇcn´ıch soubor˚ u, kter´e jsou ned´ılnou souˇc´ast´ı takov´e aplikace, je ale v praxi vˇetˇsinou nutn´ y.
Kapitola 2 Webov´ e sluˇ zby Webov´e sluˇzby je ˇcesk´ ym pˇrekladem anglick´eho term´ınu Web Services. V dneˇsn´ı dobˇe tento term´ın m˚ uˇze b´ yt ponˇekud zav´adˇej´ıc´ı, neb jak si ˇrekneme d´ale, nejedn´a se pouze o sluˇzby poskytovan´e pˇres webov´e (http) rozhran´ı. Web Services jsou dalˇs´ı alternativn´ı technologi´ı pro vzd´alen´e vol´an´ı procedur v distribuovan´ ych syst´emech. W3C[9] definuje webovou sluˇzbu jako softwarov´ y syst´em podporuj´ıc´ı interoperabiln´ı s´ıt’ovou komunikaci ” mezi dvˇema poˇc´ıtaˇci a definovan´ y vˇetˇsinou jazykem WSDL“. Vzd´alen´e vol´an´ı procedur nen´ı nic nov´eho. Za podobn´ ym u ´ˇcelem zde byla jiˇz v roce 1991 uvedena specifikace CORBA1 , kter´a definovala interoperabilitu mezi vzd´alen´ ymi poˇc´ıtaˇcov´ ymi uzly, bˇeˇz´ıc´ımi v heterogenn´ım prostˇred´ı. Mezi dalˇs´ı objektov´e technologie vzd´alen´e komunikace patˇr´ı napˇr´ıklad DCOM2 od firmy Microsoft. Narozd´ıl od tˇechto pˇredch˚ udkyˇ n webov´e sluˇzby v poˇca´tc´ıch nebyly tak vyspˇel´e a nepodporovaly napˇr´ıklad zabezpeˇcenou komunikaci, spolehlivost pˇri doruˇcov´an´ı zpr´av nebo transakce. V dneˇsn´ı dobˇe je ale situace jin´a a vzniklo mnoho dalˇs´ıch specifikac´ı pod zkratkou WS-*, kter´e rozˇsiˇruj´ı schopnosti a moˇznosti webov´ ych sluˇzeb a umoˇzn ˇuj´ı tak napˇr´ıklad pouˇz´ıvat i v´ yˇse zm´ınˇenou bezpeˇcnost, digit´aln´ı podpisy nebo transakˇcn´ı zpracov´an´ı. Webov´e sluˇzby jsou modul´arnˇe sloˇzeny z nˇekolika specifikac´ı. Neexistuje tedy jeden dokument, v nˇemˇz by bylo obsaˇzeno vˇse. Veˇsker´e kl´ıˇcov´e technologie jsou vˇsak otevˇren´e standardy organizac´ı W3C[9] nebo OASIS[4]. • SOAP - Simple Object Access Protocol je platformˇe, procesorovˇe a jazykovˇe nez´avisl´ y komunikaˇcn´ı protokol zaloˇzen´ y na standardu XML a urˇcen´ y k pˇrenosu zpr´av v heterogenn´ım s´ıt’ov´em prostˇred´ı, viz kapitola 2.2 • WSDL - Web Service Definition Language je XML jazyk urˇcen´ y pro popis rozhran´ı k Webov´ ym sluˇzb´am. Specifikuje um´ıstˇen´ı sluˇzby a operace (metody), kter´e sluˇzba poskytuje, viz kapitola 2.3 • UDDI - Universal Description, Discovery and Integration slouˇz´ı jako adres´aˇr k ukl´ad´an´ı informac´ı o webov´ ych sluˇzb´ach. Jsou zde uloˇzeny rozhran´ı ve formˇe WSDL. Adres´aˇr umoˇzn ˇuje tyto sluˇzby vyhled´avat, pˇr´ıpadnˇe publikovat. 2.4 D´ıky tˇemto standard˚ um je moˇzn´e rychle a jednoduˇse vytvoˇrit rozhran´ı k aplikac´ım pˇr´ıstupn´ ym pˇres web a vystavit tak nˇekter´e jejich sluˇzby. Tyto technologie budou po1 2
Common Object Request Broker Architecture - http://www.omg.com Distributed Component Object Model
3
´ SLUZBY ˇ KAPITOLA 2. WEBOVE
4
drobnˇe probr´any v dalˇs´ım textu. Nejprve se ale pojd’me pod´ıvat na z´akladn´ı stavebn´ı prvek webov´ ych sluˇzeb a t´ım je znaˇckovac´ı jazyk XML3 .
2.1
XML
XML je znaˇckovac´ı jazyk podobn´ y HTML4 . Z´akladn´ı rozd´ıl mezi tˇemito dvˇema jazyky je uˇz v samotn´em u ´ˇcelu pouˇzit´ı. HTML byl vyvinut za u ´ˇcelem zobrazov´an´ı informac´ı a toho, jak v´ ysledn´e zobrazen´ı vypad´a. Naproti tomu XML je od sam´eho poˇc´atku urˇceno pro popis informac´ı a dat, kter´e tyto informace v sobˇe obsahuj´ı. Vlevo je kr´atk´ y v´ ypis k´odu v HTML, kter´ y ˇr´ık´a, zobraz n´asleduj´ı text Hello“ tuˇcn´ ym p´ısmem. Vpravo je pak ” uk´azka XML dokumentu, kter´ y pouze nese urˇcitou informaci a neˇr´ık´a nic o tom, jak se tato informace d´ale vyuˇzije[12]. Hello
123456Jane <surname>Knuth
Protoˇze XML dokument m˚ uˇze obsahovat libovoln´e objekty, lze pro jejich z´apis t´eˇz vyuˇz´ıt libovoln´e tagy. XML dokument nen´ı sv´az´an urˇcitou mnoˇzinou tag˚ u jako je tomu v napˇr´ıklad v HTML. Je moˇzn´e si nadefinovat vlastn´ı. Pro definici tag˚ u je moˇzn´e vyuˇz´ıt DTD5 nebo XSD6 , kter´e je k tomu pˇr´ımo urˇceno a umoˇzn ˇuje mnohem podrobnˇejˇs´ı popis. XSD umoˇzn ˇuje pouˇz´ıvat napˇr´ıklad z´akladn´ı datov´e typy, enumerace, dovoluje rozhodnout, zda dan´ y element m˚ uˇze b´ yt vynech´an, nebo kter´e znaky m˚ uˇze obsahovat. N´asleduj´ıc´ı uk´azka demonstruje ˇca´st jednoduch´eho XML sch´ema, kter´e definuje nˇekter´a pravidla a omezen´ı pro v´ yˇse zm´ınˇen´ y typ person. V z´apisu je vynech´ana hlaviˇcka pro u ´sporu m´ısta. <xs:element name=’person’> <xs:complexType> <xs:sequence> <xs:element name=’id’ type=’xs:int’/> <xs:element name=’name’> <xs:simpleType> <xs:restriction base=’xs:string> <xs:pattern value=’[a-zA-Z]{3,9}’/> <xs:attribute name=’sex’ type=’xs:string’ use=’required’/> 3
Extensible Markup Language Hypertext Markup Language 5 Document Type Definition 6 XML Schema Definition 4
2.1. XML
5
T´ımto se omezila hodnota id pouze na ˇc´ısla typu xs:int. Element name je pak typu xs:string a m˚ uˇze obsahovat pouze velk´a nebo mal´a p´ısmena v minim´aln´ım poˇctu tˇr´ı a maximim´aln´ım poˇctu devˇet. Podrobnˇejˇs´ı informace lze nal´ezt na str´ank´ach W3C7 . D´ale definice ˇr´ık´a, ˇze element person obsahuje atribut typu xs:string, kter´ y je povinn´ y. Symbol xs urˇcuje odkaz na takzvan´ y namespace, neboli jmenn´ y prostor, ze kter´eho poch´az´ı dan´ y element. Jmenn´ y prostor se pouˇz´ıv´a k tomu, abychom mˇeli zajiˇstˇenou jedineˇcnost pojmenov´an´ı. Vˇsechny elementy uvnitˇr jmenn´eho prostoru mus´ı b´ yt unik´atn´ı. Jde o to pˇredej´ıt situaci, kdy se nˇekdo rozhodne vytvoˇrit stejn´ y typ person, kter´ y jsme nadefinovali v´ yˇse, pouze s t´ım rozd´ılem, ˇze id bude typu xs:string. Jak tedy potom rozhodnout, ˇ sen´ı je pr´avˇe v o kterou osobu se vlastnˇe jedn´a a kter´ y typ vloˇzit do elementu id . Reˇ pouˇzit´ı jmenn´eho prostoru. Pokud do hlaviˇcky XML Sch´ematu vloˇz´ıme n´asleduj´ıc´ı dva ˇra´dky, <xs:schema xmlns:xs=’http://www.w3.org/2001/XMLSchema’ targetNamespace=’http://naseosoba’> ˇr´ık´ame atributem targetNamespace, ˇze n´ami definovan´a osoba je ze jmenn´eho prostoru http://naseosoba. Nen´ı povinnost zad´avat namespace jako URL, dodrˇzuje se vˇsak konvence, ˇze jmenn´e prostory se takto zad´avaj´ı. Pˇrisp´ıv´a to i k dodrˇzen´ı unik´atnosti, neb na internetu standardnˇe nemohou existovat dvˇe stejn´e URL adresy. D´ale je zde tak´e vidˇet, kde se vzal prefix xs. Specifikace definuje hned nˇekolik z´akladn´ıch jmenn´ ych prostor˚ u, kter´e n´am umoˇzn ˇuj´ı vytvoˇrit XML Dokument a vedle nˇej XML Sch´ema, kter´e tento dokument popisuje. Z´apisem xmlns:xs=’http://www.w3.org/2001/XMLSchema’ ˇr´ık´ame, ˇze veˇsker´e elementy a datov´e typy prefixovan´e symbolem xs poch´azej´ı ze jmenn´eho prostoru XMLschema. D´ale tak pˇri pouˇzit´ı prefixu m˚ uˇzeme odkazovat na datov´e typy element, attribute, complexType, simpleType a dalˇs´ı, kter´e n´am umoˇzn´ı definovat vlastn´ı datov´e typy. Definice vlastn´ıch typ˚ u pak d´ale dovoluje vytv´aˇret strukturovan´e XML dokumenty, kter´e vyhovuj´ı pˇredloze ve formˇe XML sch´ematu a je moˇzn´e je validovat. Simple type I kdyˇz jsme nikde nedefinovali typy xs:int a xs:string, pˇresto jsou v definici typu person pouˇzity. Tyto typy se zpˇr´ıstupnily pr´avˇe pouˇzit´ım jmenn´eho prostoru XMLSchema, ve kter´em jsou jiˇz vydefinov´any. Jedn´a se o takzvan´e zabudovan´e typy. V Pˇr´ıpadˇe xs:string jde o zabudovan´ y primitivn´ı typ a v pˇr´ıpadˇe xs:int jde o primitivn´ı typ odvozen´ y od primitivn´ıho typu xs:decimal takzvanou restrikc´ı. Restrikce jednoduˇse znamen´a, ˇze na nadˇrazen´ y typ byla aplikov´ana nˇekter´a omezen´ı. V pˇr´ıpadˇe xs:int se m˚ uˇze jednat napˇr´ıklad o omezen´ı intervalu. Je moˇzn´e t´eˇz vytvoˇrit vlastn´ı jednoduch´ y typ t´ım, ˇze omez´ıme nˇekter´ y jiˇz existuj´ıc´ı, a pouˇz´ıt ho pˇri definici sch´ematu. Takto napˇr´ıklad vytvoˇr´ıme typ, do kter´eho je moˇzn´e pˇriˇradit pouze hodnoty A, B atd. T´ım jsme de facto vytvoˇrili datov´ y typ enumerace zn´am´ y z programovac´ıch jazyk˚ u. 7
World Wide Web Consorcium http://www.w3c.org
6
´ SLUZBY ˇ KAPITOLA 2. WEBOVE <xs:simpleType name=’krevniSkupina’> <xs:restriction base=’xs:string’> <xs:enumeration value=’A’/> <xs:enumeration value=’B’/> .... Deklarace takto nadefinovan´eho typu v XML Sch´ema vypad´a n´asledovnˇe: <element name=’pacientTypKrve’ type=’krevniSkupina’ /> Dalˇs´ı informace o jednotliv´ ych pˇreddefinovan´ ych typech lze nal´ezt na str´ank´ach W3C.
Complex type Simple type a Complex type se od sebe liˇs´ı t´ım, ˇze jednoduch´ y typ v sobˇe nem˚ uˇze obsahovat dalˇs´ı elementy nebo atributy. N´aˇs typ person je tedy n´azorn´ ym pˇr´ıkladem komplexn´ıho typu. Je vˇsak nutn´e rozliˇsovat dva druhy. Komplexn´ı typ s jednoduch´ ym obsahem m˚ uˇze obsahovat pouze atributy nebo textov´ y obsah. Nesm´ı obsahovat ˇz´adn´e dalˇs´ı elementy. Takov´e typy mohou vzniknout napˇr´ıklad restrikc´ı ˇci rozˇs´ıˇren´ım jednoduch´ ych typ˚ u a pˇrid´an´ım atributu. <xs:element name=’student’ type=’studentType’> <xs:complexType name=’studentType’> <xs:simpleContent> <xs:extension base=’xs:string’> <xs:attribute name=’class’ type=’xs:integer’ /> Takto potom vypad´a XML element, kter´ y vyhovuje v´ yˇse uveden´emu sch´ematu: <student class=’4’>John Smith Nam´ısto toho komplexn´ı typ s komplexn´ım obsahem vnoˇren´e elementy obsahovat m˚ uˇze, viz typ person, coˇz je pˇr´ıklad komplexn´ıho typu s komplexn´ım obsahem. XML Dokument Doposud jsme mluvili vesmˇes o XML Sch´ematu, coˇz je definice, kter´a umoˇzn ˇuje popisovat XML Dokumenty. Pokud jiˇz m´ame vytvoˇrenou definici, je na ˇcase vytvoˇrit instanci“ tohoto sch´ematu. Tou je pr´avˇe XML Dokument. Jedn´a se o ” klasick´ y xml soubor, kter´ y v hlaviˇcce odkazuje na pˇr´ısluˇsn´e xml sch´ema (xsd soubor) pomoc´ı atributu schemaLocation, aby bylo jasn´e, kde se nach´az´ı popis jednotliv´ ych element˚ u. ...
2.2. PROTOKOL SOAP
7
schemaLocation m´a prefix xsi, kter´ y je v hlaviˇcce pˇridruˇzen jmenn´emu prostoru XMLSchema-instance. Tento prostor obsahuje typy a atributy pro pouˇzit´ı v XML instanc´ıch. person.xsd je soubor ,kter´ y v tomto pˇr´ıpadˇe obsahuje definici a popis tohoto XML Dokumentu v podobˇe XML Sch´ematu. V´ıme tedy, jak vytvoˇrit XML Dokument popisuj´ıc´ı nˇejak´ y objekt. Jak tento objekt pˇren´est, bude pˇredmˇetem dalˇs´ı kapitoly.
2.2
Protokol SOAP
SOAP8 je obecnˇe komunikaˇcn´ı protokol pro v´ ymˇenu informac´ı ve formˇe XML zpr´av. Umoˇzn ˇuje pos´ıl´an´ı zpr´av mezi dvˇema aplikacemi a pracuje tedy na principu peer-to-peer. Tyto aplikace pˇritom mohou bˇeˇzet decentralizovanˇe na r˚ uzn´ ych operaˇcn´ıch syst´emech a mohou b´ yt naps´any v r˚ uzn´ ych programovac´ıch jazyc´ıch. Decentralizac´ı je myˇsleno, ˇze aplikace mohou b´ yt um´ıstˇen´e na r˚ uzn´ ych m´ıstech v s´ıti. Jedn´a se tedy o s´ıt’ov´ y protokol. S´ıt’ov´a komunikace jako takov´a je rozdˇelena do vrstev, kter´e mezi sebou spolupracuj´ı. • Fyzick´ a vrstva - umoˇzn ˇuje pˇr´ıstup k fyzick´emu s´ıt’ov´emu zaˇr´ızen´ı (Ethernet, Token Ring, FDDI). • S´ıt’ov´ a vrstva - zajiˇst’uje pˇredevˇs´ım adresaci, smˇerov´an´ı a pˇred´av´an´ı datagram˚ u, a je tedy implementov´ana ve vˇsech prvc´ıch s´ıtˇe (IP). • Transportn´ı vrstva - poskytuje koncov´ ym syst´em˚ um spojov´e (TCP) ˇci nespojov´e sluˇzby (UDP) • Aplikaˇ cn´ı vrstva - jednotliv´e aplikace (procesy) bˇeˇz´ıc´ı na koncov´em syst´emu, kter´e vyuˇz´ıvaj´ı s´ıt’ov´ ych sluˇzeb (HTTP, SMTP, Telnet) SOAP je postaven nad aplikaˇcn´ı vrstvou. Vyuˇz´ıv´a pˇrev´aˇznˇe HTTP pˇr´ıpadnˇe HTTPS pˇrenosu a je t´ım p´adem tak´e bezestavov´ y a dobˇre prostupn´ y pro firewall. Nˇekdy je proto oznaˇcov´an jako lightweight a toto je tak´e jeden z argument˚ u pro jeho pouˇzit´ı ve webov´ ych sluˇzb´ach. Kromˇe v´ yˇse zm´ınˇen´ ych protokol˚ u lze t´eˇz vyuˇz´ıt transportu pˇres SMTP nebo pˇres jak´ ykoliv jin´ y protokol aplikaˇcn´ı vrstvy. Pojem Webov´e sluˇzby“, kter´ y ” sp´ıˇse naznaˇcuje pouˇzit´ı v HTTP vˇsak z˚ ustal nezmˇenˇen. Vzd´alen´e vol´an´ı procedur je urˇcitˇe zn´am´e v trochu jin´e podobˇe. N´asleduj´ıc´ı pˇr´ıklad demontruje zavol´an´ı funkce secti se dvˇema parametry pˇredan´e metodou GET. Pokud server obsahuje danou funkci, provede seˇcten´ı a vr´acen´ı v´ ysledku. http://www.example.org/secti.php?x=1&y=2 Nev´ yhodou takov´eho pˇr´ıstupu je jednak omezen´ı d´elky URL v nˇekter´ ych prohl´ıˇzeˇc´ıch a tak´e skuteˇcnost, ˇze v´ ysledek vol´an´ı dostaneme vˇetˇsinou v HTML. Je urˇcitˇe jasn´e, ˇze parsovat HTML pro z´ısk´an´ı v´ ysledku by bylo ponˇekud neohraban´e. Probl´emy by nast´avaly t´eˇz s validac´ı. Metoda POST nab´ız´ı pohodlnˇejˇs´ı zp˚ usob, jak pˇren´est data na server. Od t´e doby, co byl standardizov´an form´at multipart/form-data (viz [6]) pro nahr´av´an´ı soubor˚ u, kter´ y je narozd´ıl od application/x-www-form-urlencode efektivnˇejˇs´ı pro pˇrenos soubor˚ u a bin´arn´ıch dat, nic uˇz nebr´anilo v tom, pˇren´aˇset v tˇele HTTP XML Dokumenty. XML m´a tu v´ yhodu, ˇze umoˇzn ˇuje pˇren´aˇset jak objekty (viz. 8
Simple Object Access Protocol
´ SLUZBY ˇ KAPITOLA 2. WEBOVE
8
person v kapitole 2.1) ˇci dokonce kolekce tˇechto objekt˚ u, tak tak´e bin´arn´ı data jako napˇr´ıklad obr´azky. V kombinaci se sch´ematem, kter´e n´am urˇcuje pˇredlohu XML Dokumentu je nav´ıc moˇzn´e popsat strukturu pˇred´avan´ ych dat a t´ım zajistit interoperabilitu na obou stran´ach. Pokud nav´ıc pˇrid´ame jmenn´e prostory 2.1, zamez´ıme t´ım konflikt˚ um v pojmenov´an´ı tˇechto xml objekt˚ u. Uk´aˇzeme si nyn´ı, jak vypad´a SOAP poˇzadavek zaslan´ y serveru (request) a pˇr´ıchoz´ı odpovˇed’ (response). <soap:Envelope xmlns:soap=’http://www.w3.org/2001/12/soap-envelope’ soap:encodingStyle=’http://www.w3.org/2001/12/soap-encoding’> <soap:Header> <m:SessionId xmlns:m=’http://www.example.org/session/’ soap:mustUnderstand=’1’>11111 <soap:Body xmlns:ns1=’http://www.example.org/obchod’> <ns1:UlozDoKosiku> <ns1:IdZbozi>123456 Elementy s prefixem soap tvoˇr´ı z´akladn´ı kostru SOAP zpr´avy. Ta se tedy skl´ad´a z povinn´e ob´alky soap:Envelop, kter´a tvoˇr´ı koˇrenov´ y element a mus´ı b´ yt vˇzdy uvedena. D´ale je zde nepovinn´a hlaviˇcka soap:Header, kter´a ve vˇetˇsinˇe pˇr´ıpad˚ u rozˇsiˇruje informace obsaˇzen´e v tˇele zpr´avy. M˚ uˇze obsahovat autentizaˇcn´ı u ´daje jako jm´eno nebo heslo, ˇcasov´e raz´ıtko nebo elektronick´ y podpis, kter´ y zabezpeˇc´ı danou zpr´avu v˚ uˇci zmˇenˇe mezi odes´ılatelem a pˇr´ıjemcem. V tomto pˇr´ıpadˇe nese hlaviˇcka sessionID, kter´e identifikuje klienta. Pokud je hlaviˇcka v ob´alce pˇr´ıtomna, mus´ı b´ yt uvedena jako prvn´ı ele9 ment n´asleduj´ıc´ı po elementu soap:Envelop. Specifikace protokolu SOAP d´av´a nav´ıc moˇznost oznaˇcit u ´daje uveden´e v hlaviˇcce jako povinn´e. To je zajiˇstˇeno nastaven´ım atributu soap:mustUnderstand na hodnotu “1” nebo “true”. Pˇr´ıjemce takov´e zpr´avy je povinen hlaviˇcku zpracovat(rozpoznat dan´ y element) nebo vygenerovat chybu a zaslat zpˇet na klienta. T´ım m˚ uˇzeme napˇr´ıklad zajistit, ˇze autentizaˇcn´ı u ´daje, kter´e poˇsleme v ’ hlaviˇcce na server, budou bud serverem rozpozn´any a zpracov´any, nebo nikoliv a v tom pˇr´ıpadˇe server bude ignorovat tˇelo zpr´avy a zaˇsle zpˇet chybu. Tˇelo zpr´avy soap:Body, jak je vidˇet z pˇr´ıkladu, pak obsahuje samotn´ y XML Dokument se vˇsemi n´aleˇzitostmi, kter´e jsme uvedli v kapitole 2.1. XML element UlozDoKosiku obsahuje podˇr´ızen´ y element IdZbozi, kter´ y v sobˇe nese posloupnost ˇc´ısel zak´odovanou napˇr´ıklad do jednoduch´eho typu xs:long. Obecnˇe se d´a ˇr´ıci, ˇze tˇelo zpr´avy tvoˇr´ı ˇz´adost o proveden´ı nˇejak´e sluˇzby. Obsah odpovˇedi pak tvoˇr´ı v´ ysledek tohoto poˇzadavku nebo v pˇr´ıpadˇe ne´ uspˇeˇsn´eho proveden´ı chyba. Pˇredpokl´adejme, ˇze server tento request zpracoval a zaˇsle klientovi odpovˇed’, kter´a m˚ uˇze vypadat napˇr´ıklad takto. 9
http://www.w3.org/TR/soap
2.2. PROTOKOL SOAP
9
<soap:Envelope xmlns:soap=’http://www.w3.org/2001/12/soap-envelope’ soap:encodingStyle=’http://www.w3.org/2001/12/soap-encoding’> <soap:Body xmlns:ns1=’http://www.example.org/obchod’> <ns1:UlozDoKosikuResponse> <ns1:Status>OK Server t´ım d´av´a najevo, ˇze uloˇzen´ı probˇehlo u ´spˇeˇsnˇe. V pˇr´ıpadˇe chyby, server vr´at´ı takzvan´ y SOAP Fault. Pro u ´sporu m´ısta uvedu jen tˇelo zpr´avy. Ob´alka z˚ ust´av´a stejn´a jako u pˇredchoz´ıho pˇr´ıkladu. <soap:Body xmlns:ns1=’http://www.example.org/obchod’> <env:Fault> <env:faultcode>env:Server <env:faultstring>Nevalidni ID <env:detail> ID musi obsahovat alespon 5 znaku Takto m˚ uˇze napˇr´ıklad vypadat reakce serveru na ˇspatnˇe vyplnˇenou poloˇzku IdZbozi, kterou server nedok´aˇze zpracovat. Pro chybov´e zpr´avy plat´ı, ˇze element env:Fault, pokud je obsaˇzen, mus´ı b´ yt um´ıstˇen jako prvn´ı v tˇele zpr´avy. V praxi se o tyto z´aleˇzitosti staraj´ı jednotliv´e implementace specifikac´ı webov´ ych sluˇzeb. Program´ator se tak m˚ uˇze v´ıce soustˇredit na dan´ y probl´em a nemus´ı se zab´ yvat parsov´an´ım element˚ u popˇr´ıpadˇe validac´ı zpr´av. Protoˇze syst´em pˇrenosu a odhalov´an´ı chyb je velmi d˚ uleˇzit´ y pˇri v´ yvoji distribuovan´ ych syst´em˚ u, bude na nˇej kladen velk´ y d˚ uraz i v t´eto uk´azkov´e aplikaci. Objasn´ım ve struˇcnosti, co kter´e poloˇzky znamenaj´ı. Pˇredem bych chtˇel ˇr´ıci, ˇze je zde n´azornˇe vidˇet v´ yhoda protokolu SOAP a webov´ ych sluˇzeb jako takov´ ych, oproti technologi´ım typu RMI, CORBA, DCOM. Veˇsker´a data, tedy i chybov´e zpr´avy, se ˇs´ıˇr´ı v textov´e podobˇe a je tedy v pˇr´ıpadˇe nutnosti snadn´e je odchytit a urˇcit m´ısto probl´emu. To samozˇrejmˇe neplat´ı v pˇr´ıpadˇe pouˇzit´ı ˇsifrovan´e komunikace (HTTPS). Nicm´enˇe za u ´ˇcelem ladˇen´ı syst´emu je vˇzdy moˇzn´e toto ˇsifrov´an´ı vypnout a pˇrej´ıt na komunikaci neˇsifrovanou. Element faultcode tedy m˚ uˇze obsahovat n´asleduj´ıc´ı hodnoty. VersionMismatch pokud pˇr´ıjemce nalezne ˇspatn´ y jmenn´ y prostor pro koˇrenov´ y element env:Envelop. MustUnderstand v pˇr´ıpadˇe, ˇze element v hlaviˇcce s nastaven´ ym atributem mustUnderstand na “1” nebo “true” nebyl pˇr´ıjemcem rozpozn´an.
´ SLUZBY ˇ KAPITOLA 2. WEBOVE
10
Client indikuje, ˇze pˇr´ıchoz´ı zpr´ava byla nekorektnˇe zformov´ana nebo obsahuje nekorektn´ı informace Server znaˇc´ı probl´em na serverov´e stranˇe. Server napˇr´ıklad nebyl schopn´ y zpracovat request d´ıky nevalidn´ımu obsahu, nebo mohla nastat chyba v komunikaci s datab´az´ı. K upˇresnˇen´ı tˇechto k´od˚ u slouˇz´ı element detail, ve kter´em m˚ uˇzeme pos´ılat n´ami vyspecifikovan´e informace. Pokud napˇr´ıklad poˇzadujeme, aby se na klienta pˇren´aˇsela naˇse vlastn´ı v´ yjimka, pak toto je m´ısto, kam ji um´ıstit. Aby obˇe strany, kter´e spolu komunikuj´ı, vˇedˇely, jak´e informace si mohou mezi sebou vymˇen ˇovat, a kter´e elementy a parametry mohou od protˇejˇs´ı strany oˇcek´avat, byl ustaven form´at WSDL10 , kter´ ym je moˇzn´e tuto komunikaci popsat.
2.3
WSDL
WSDL je jazyk na b´azi XML, kter´ y slouˇz´ı pro popis rozhran´ı webov´ ych sluˇzeb. Verze 2.0 je definov´ana svou specifikac´ı [11]. Pˇredchoz´ı verze 1.2 nebyla organizac´ı W3C [9] schv´alena jako specifikace, nicm´enˇe zde existuje jej´ı working draft11 . Je to hlavnˇe z toho d˚ uvodu, ˇze mnoho dneˇsn´ıch v´ yvojov´ ych n´astroj˚ u a implementac´ı webov´ ych sluˇzeb zat´ım neposkytuje dostateˇcnou podporu pro specifikaci 2.0. WSDL dokument je de facto sada definic´ı. Je to jednoduch´ y XML dokument, kter´ y obsahuje n´asleduj´ıc´ı sekce jakoˇzto povinn´e elementy: <definitions> definice datov´ ych typ˚ u... <message> definice struktury zpr´ av... <portType> popis sluˇ zby, operac´ ı a zpr´ av... definice protokolu a form´ atu zpr´ av... Types je sekce, ve kter´e jsou nadefinov´any datov´e typy, jenˇz dan´a sluˇzba pouˇz´ıv´a. WSDL neposkytuje nov´ y jazyk pro definici datov´ ych typ˚ u. Nam´ısto toho pouˇz´ıv´a XML Sch´ema. Nen´ı vˇsak vylouˇceno z hlediska budouc´ıho v´ yvoje, ˇze se typov´ y syst´em m˚ uˇze zmˇenit. Gramatika WSDL tuto rozˇsiˇritelnost umoˇzn ˇuje. 10
Web Service Description Language Working Draft je dokument, kter´ y byl publikov´an organizac´ı W3C ke zhodnocen´ı. Je to tzv. Pracovn´ı N´ avrh a je to poˇc´ ateˇcn´ı stupeˇ n ve schvalovac´ım procesu dokumentu. Koneˇcn´ y stupeˇ n se st´av´a standardem a oznaˇcuje se jako WC3 Recommendation. V´ıce viz [9] 11
2.3. WSDL
11
Messages je sekce, kter´a definuje strukturu vstupn´ıch, tj. pˇr´ıchoz´ıch a v´ ystupn´ıch, tj. odes´ılan´ ych zpr´av. Obsahuje odkazy na datov´e typy, kter´e se v t´eto zpr´avˇe vyskytuj´ı. Z hlediska bˇeˇzn´eho programovac´ıho jazyka je moˇzn´e na tuto sekci nahl´ıˇzet jako na definici argument˚ u vstupuj´ıc´ıch do metod nebo z metod vystupuj´ıc´ıch. PortType je sekce, kter´a popisuje samotnou webovou sluˇzbu. Jsou zde uvedeny operace, kter´e tato sluˇzba poskytuje a u kaˇzd´e operace jsou t´eˇz pops´any vstupn´ı a v´ ystupn´ı zpr´avy s touto operac´ı spojen´e. Pokud se na tuto sekci opˇet pod´ıv´ame z hlediska bˇeˇzn´eho programovac´ıho jazyka, lze ji pˇrirovnat ke tˇr´ıdˇe, kter´a poskytuje urˇcit´e metody, nebo jeˇstˇe l´epe k jej´ımu rozhran´ı. Stejnˇe tak jako v bˇeˇzn´em programovac´ım jazyce existuj´ı metody, kter´e nemaj´ı ˇz´adn´ y vstupn´ı argument (void) nebo nemaj´ı ˇza´dn´ y n´avratov´ y typ, existuj´ı i zde operace, kter´e jsou jednosmˇern´e, tj. nevrac´ı ˇza´dn´ y response. Pokud v operaci neuvedeme v´ ystupn´ı element, jedn´a se o tzv. One-Way operaci neboli ping. Nen´ı to totiˇz tak, ˇze sluˇzba v˚ ubec neodpov´ı. Nesm´ıme zapom´ınat, ˇze SOAP je nadstavbou protokolu HTTP. One-Way tedy odpov´ı, ale to, zda kromˇe hlaviˇcky obsahuje i nˇejak´a XML data z´aleˇz´ı pˇredevˇs´ım na pouˇzit´em BindingStyle. Binding je sekce, obsahuj´ıc´ı informace o pouˇzit´em komunikaˇcn´ım protokolu, napˇr. (HTTP) a definuje form´at zpr´av (BindingStyle). Tato sekce obsahuje operace, kter´e jsou ve skuteˇcnosti vystaven´e klient˚ um. BindingStyle Je zp˚ usob, jak´ ym se zpr´avy napojuj´ı na podˇr´ızen´ y protokol (vˇetˇsinou SOAP). Protoˇze tento atribut dosti ovlivˇ nuje tvar WSDL a v˚ ubec cel´ y zp˚ usob komu12 nikace, vˇenuji mu p´ar ˇra´dk˚ u. BindingStyle m˚ uˇze b´ yt typu RPC nebo typu document. Jeho pouˇzit´ı m˚ uˇze b´ yt encoded nebo literal. Vznikaj´ı n´am tak 4 r˚ uzn´e modely pouˇzit´ı. Pro lepˇs´ı pˇredstavu uvedu pˇr´ıklad. Vyjdeme z n´asleduj´ıc´ı metody. public void soucet(int x, int y); ˇ ast WSDL pro v´ 1. RPC/encoded C´ yˇse uvedenou operaci vypad´a n´asledovnˇe: <message name=’vstup’> <part name=’x’ type=’xsd:int’/> <part name=’y’ type=’xsd:int’/> <message name=’vystup’/> <portType name=’portname’>
Po zavol´an´ı takov´eto metody pˇrijde na server request v n´asleduj´ıc´ı podobˇe: 12
Remote Procedure Call
´ SLUZBY ˇ KAPITOLA 2. WEBOVE
12
<soap:body> <soucet> <x xsi:type=’xs:int’>6 7
Tento styl m´a nˇekolik v´ yhod. WSDL je opravdu jednoduch´e a srozumiteln´e. Jm´eno operace je obsaˇzeno v tˇele zpr´avy, a pro server je tedy jednoduch´e rozpoznat, kterou z vystaven´ ych metod m´a vyvolat. Nev´ yhoda spoˇc´ıv´a v tom, ˇze typ encoding vkl´ad´a k jednotliv´ ym argument˚ um metody tak´e ˇc´ast XML Sch´ema, kter´e popisuje typy tˇechto argument˚ u. Protoˇze parsov´an´ı XML je samozˇrejmˇe procesorovˇe n´aroˇcn´a operace, m˚ uˇze tento typ zpr´av pˇri obs´ahlejˇs´ım dotazu sniˇzovat v´ ykon. Dalˇs´ı nev´ yhodou m˚ uˇze b´ yt nemoˇznost validace t´eto pˇr´ıchoz´ı zpr´avy. Vstupn´ı argumenty x a y obsahuj´ı informace, na z´akladˇe kter´ ych je moˇzno ovˇeˇrit, zda obsah vstupn´ıch element˚ u opravdu odpov´ıd´a ˇc´ısl˚ um typu xs:int. Element soucet zde vˇsak pˇredstavuje jm´eno operace a nikoliv typ z XML Sch´ematu. Toto znemoˇzn ˇuje validaci. I pˇresto, ˇze je tento typ WSDL validn´ı, nen´ı doporuˇcen organizac´ı WS-I, viz kapitola 2.6. 2. RPC/literal WSDL pro tento typ je vˇetˇsinou stejn´e, a tedy jednoduch´e. Zpr´ava zaslan´a na server se zde liˇs´ı pouze v tom, ˇze u jednotliv´ ych vstupn´ıch element˚ u nen´ı obsaˇzena ˇca´st XML Sch´ema. To n´am zajiˇst’uje pouˇzit´ı literal. Jm´eno operace je opˇet obsaˇzeno v tˇele zpr´avy, a je tedy snadn´e zpr´avu pˇredat t´e spr´avn´e metodˇe. Bohuˇzel tak st´ale nen´ı moˇzn´e prov´est validaci t´eto zpr´avy. Tento typ vyhovuje doporuˇcen´ı organizace WS-I. 3. Document/encoded V praxi se t´emˇeˇr nepouˇz´ıv´a a nen´ı ani doporuˇcen organizac´ı WS-I. Nebudu se s n´ım proto zab´ yvat. 4. Document/literal Oproti RPC/literal zde nast´av´a drobn´a zmˇena ve WSDL. Uk´aˇzeme si jen ˇc´ast message. <message name=’soucet’> <part name=’x’ element=’TypX’/> <part name=’y’ element=’TypY’/>
Jak je vidˇet, m´ısto typ˚ u u jednotliv´ ych argument˚ u, je ud´an odkaz na element do sekce types, kter´a zde nen´ı uvedena. V n´ı je pak obsaˇzena pˇresn´a definice tohoto elementu. Zmˇenila se i pˇr´ıchoz´ı zpr´ava. <soap:body> 67
2.4. UDDI
13
Takto tvarovan´a pˇr´ıchoz´ı zpr´ava n´am eliminuje nˇekter´e nedostatky pˇredchoz´ıch typ˚ u. Pˇredevˇs´ım je moˇzn´e tuto zpr´avu zvalidovat, neb veˇsker´e informace pˇren´aˇsen´e v tˇele jsou popsan´e v XML Sch´ematu uvnitˇr WSDL. Zpr´ava neobsahuje nadbyteˇcn´e encoding informace. Tento styl m´a vˇsak tak´e sv´a omezen´ı. Doporuˇcen´ı organizace WS-I dovoluje pouze jeden podˇr´ızen´ y element v tˇele zpr´avy. Je to pr´avˇe z d˚ uvodu pˇriˇrazen´ı zpr´av jednotliv´ ym operac´ım. Tˇelo totiˇz v tomto pˇr´ıpadˇe neobsahuje jm´eno operace a pokud bychom vystavili dvˇe metody se vstupn´ım argumentem void, server by nevˇedˇel, kter´e metodˇe m´a request pˇriˇradit. Odstranili jsme tedy nˇekter´a omezen´ı pˇredchoz´ıch typ˚ u, ale ztratili jsme jm´eno operace. 5. Document/literal wrapped je ˇreˇsen´ım pˇredchoz´ıho probl´emu. Pˇr´ıchoz´ı zpr´ava na server vypad´a stejnˇe jako v pˇr´ıpadˇe RPC/literal, kromˇe jedn´e drobnosti. Element soucet zde nen´ı jm´eno operace, n´ ybrˇz jm´eno tzv. zaobalovac´ıho elementu (wrraped). Form´at zpr´avy je pak d´an n´asleduj´ıc´ı definic´ı ve WSDL:
Na element soucet lze pak nahl´ıˇzet jako na komplexn´ı typ, kter´ y zahrnuje podˇr´ızen´e elementy x a y. Tento zp˚ usob napojov´an´ı zpr´av je doporuˇcen organizac´ı WS-I, avˇsak nen´ı souˇc´ast´ı ˇza´dn´e specifikace. Poch´az´ı od firmy Microsoft a organizace WS-I doporuˇcuje tento styl pr´avˇe kv˚ uli interoperabilitˇe mezi MS a ostatn´ımi implementacemi Webov´ ych sluˇzeb. [1] V t´eto pr´aci tedy bude pouˇzit tento typ napojen´ı.
2.4
UDDI
Universal Description Discovery and Integration neboli registr pro evidenci, popis a integraci webov´ ych sluˇzeb. Jedn´a se o adres´aˇr, kter´ y umoˇzn ˇuje vyhled´avat, kter´e jsou na internetu k dispozici a publikovat nov´e. Tento registr nebudeme v naˇs´ı pr´aci vyuˇz´ıvat. V´ıce se lze dozvˇedˇet zde [7].
2.5
WS-Security
WS-Security [10] je pˇr´ıkladem jednoho z mnoha rozˇs´ıˇren´ı protokolu soap o mechanizmus ˇsifrov´an´ı a digit´aln´ıch podpis˚ u. V´ yhodou oproti standardn´ımu ˇsifrov´an´ı, kter´e zajiˇst’uje transportn´ı protokol SSL (TLS), je ten, ˇze WS-Security aplikuj´ı ˇsifrov´an´ı na kaˇzdou zpr´avu zvl´aˇst’ a tud´ıˇz zabezpeˇcuj´ı pˇrenos od odes´ılatele aˇz ke koncov´emu pˇr´ıjemci, bez ohledu na to kudy zpr´ava putovala. Nev´ yhodou m˚ uˇze b´ yt pomalejˇs´ı zpracov´an´ı vzhledem k pouˇz´ıt´ı asymetrick´e kryptografie. SSL po nav´az´an´ı spojen´ı pˇrech´az´ı na symetrickou kryptografii, kter´a v´ yznamnˇe zvyˇsuje rychlost pˇrenosu.
´ SLUZBY ˇ KAPITOLA 2. WEBOVE
14
2.6
WS-I
Mnoho implementac´ı webov´ ych sluˇzeb ˇcasto ne zcela vych´az´ı z dan´e specifikace. Organizace WS-I13 byla zformov´ana proto, aby vyjasnila tyto nesrovnalosti a umoˇznila vˇetˇs´ı interoperabilitu mezi tˇemito frameworky. Organizace poskytuje profily, vzorov´e aplikace a testovac´ı n´astroje, kter´e napom´ahaj´ı zjistit, zda webov´a sluˇzba vyhovuje doporuˇcen´ı.
13
Web Service Interoperability Organization
Kapitola 3 Anal´ yza a n´ avrh implementace Pod´ıvejme se nyn´ı na syst´em evidence pacient˚ u z hlediska pouˇzit´e technologie JEE. Dˇr´ıve se pˇri v´ yvoji rozs´ahlejˇs´ıch aplikac´ı pouˇz´ıvala tzv. monolitick´a architektura, kdy datab´azov´a vrstva, aplikaˇcn´ı vrstva a prezentaˇcn´ı vrstva spl´ yvaly do jedin´eho monolitick´eho celku. Cel´ y syst´em tak bˇeˇzel na jednom centr´aln´ım poˇc´ıtaˇci a klienti se pˇripojovali prostˇrednictv´ım termin´al˚ u. V´ yrazn´a nev´ yhoda takov´eho ˇreˇsen´ı je samozˇrejmˇe spolehlivost, nebot’ pokud tento server selˇze, pak je mimo provoz cel´ y syst´em. Dalˇs´ım evoluˇcn´ım stupnˇem se stala dvouvrstv´a architektura, nebo t´eˇz architektura klient - server. Jak jiˇz n´azev napov´ıd´a, je zde aplikace rozdˇelena do dvou vrstev. Oddˇelen´a je prezentaˇcn´ı (klientsk´a) a datab´azov´a (serverov´a) vrstva. Aplikaˇcn´ı logika je pˇresunuta bud’ na klientskou ˇca´st (tlust´ y klient), nebo na server (tenk´ y klient). Nev´ yhody t´eto architektury se objevily s pˇr´ıchodem komplexn´ıch syst´em˚ u, kde poˇcet pˇripojen´ ych uˇzivatel˚ u vzr˚ ust´a. V pˇr´ıpadˇe tlust´eho klienta doch´az´ı ke zv´ yˇsen´ı n´arok˚ u na klientsk´e poˇc´ıtaˇce v d˚ usledku n´aroˇcnˇejˇs´ı aplikaˇcn´ı logiky. V pˇr´ıpadˇe tenk´eho klienta se aplikaˇcn´ı logika pˇresouv´a na server a vzr˚ ustaj´ı n´aroky na v´ ykon serveru. Pokud nav´ıc syst´em udrˇzuje pro kaˇzd´eho klienta spojen´ı (keep alive), m˚ uˇze velmi ˇcasto doj´ıt k vyˇcerp´an´ı syst´emov´ ych zdroj˚ u. ˇ sen´ı se naˇslo v podobˇe pˇrid´an´ı dalˇs´ıch vrstev, kter´e byly vloˇzeny mezi vrstvu dataReˇ b´azovou a prezentaˇcn´ı. Samozˇrejmˇe bylo nutn´e znovu vyspecifikovat funkce jednotliv´ ych vrstev a jejich role v cel´em syst´emu. Aplikaˇcn´ı logika se zde kompletnˇe pˇresouv´a na server. Zat´ıˇzen´ı je v t´eto architektuˇre efektivnˇe rozdˇeleno mezi datab´azov´ y stroj, aplikaˇcn´ı server a klienta. Je to pˇredevˇs´ım z toho d˚ uvodu, ˇze datab´azov´ y stroj m˚ uˇze komunikovat s v´ıce aplikaˇcn´ımi servery a ty d´ale propaguj´ı data k jednotliv´ ym klient˚ um. [8] Aplikaˇcn´ı servery umoˇzn ˇuj´ı rozdˇelen´ı z´atˇeˇze (load balancing) nebo pˇred´an´ı ˇr´ızen´ı jin´emu aplikaˇcn´ımu serveru v pˇr´ıpadˇe v´ ypadku (fail over). Dalˇs´ı moˇznosti, jak zv´ yˇsit spolehlivost aplikace, je propojen´ı aplikaˇcn´ıch server˚ u do clusteru a umoˇznit replikaci session a v pˇr´ıpadˇe JEE architektury t´eˇz dalˇs´ıch komponent. Session je objekt uloˇzen´ yv pamˇeti dan´eho aplikaˇcn´ıho serveru, jehoˇz u ´ˇcelem je drˇzet uˇzivatelsk´a data a t´ım obej´ıt napˇr´ıklad bezestavovost protokolu HTTP. Klient se tak m˚ uˇze nach´azet v urˇcit´em stavu, napˇr´ıklad b´ yt pˇr´ıhl´aˇsen´ y pod urˇcit´ ym uˇzivatelsk´ ym jm´enem. Replikace session zajist´ı v pˇr´ıpadˇe v´ ypadku jednoho uzlu pˇrenesen´ı tohoto objektu do pamˇeti dalˇs´ıho aplikaˇcn´ıho serveru tak, ˇze hroz´ı jen minim´aln´ı ztr´ata dat a client m˚ uˇze pokraˇcovat ve sv´e rozdˇelan´e pr´aci. Clustering nen´ı dom´enou pouze aplikaˇcn´ıch server˚ u, n´ ybrˇz i nˇekter´ ych datab´az´ı. Napˇr´ıklad datab´aze Oracle nebo PostgreSQL umoˇzn ˇuje zaˇradit do clusteru jednotliv´e instance a t´ım zajistit vˇetˇs´ı spolehlivost datov´e vrstvy. Zapojen´ı do clusteru, pˇr´ıpadnˇe load balancing je ot´azkou sp´ıˇse nasazen´ı takov´eho syst´emu do ostr´eho provozu. V uk´azkov´e 15
16
´ ´ KAPITOLA 3. ANALYZA A NAVRH IMPLEMENTACE
aplikaci nem´a tento krok pˇr´ıliˇs velk´ y v´ yznam, proto jej pˇri implementaci vynech´ame. N´asleduj´ıc´ı obr´azek ukazuje sch´ema tˇr´ıvrstv´e architektury JEE aplikace.
Obr´azek 3.1: Tˇr´ıvrstv´a architektura
3.1
Use Case Model
Ze vˇseho nejdˇr´ıve je podstatn´e vyspecifikovat, co m´a navrhovan´ y syst´em umˇet, a kter´e sluˇzby m´a poskytovat. Pokud nˇejak´ y syst´em implementujeme, nen´ı dobr´e zaˇc´ıt ps´at hned zdrojov´ y k´od s t´ım, ˇze vˇse podstatn´e m´ame v hlavˇe. Softwarov´e inˇzen´ yrstv´ı definuje postupy a modely, kter´e napom´ahaj´ı zjednoduˇsit v´ yvoj aplikace od samotn´eho n´avrhu aˇz po nasazen´ı. Prvn´ım m´ ym krokem bylo vytvoˇrit Model jedn´an´ı, kter´ y zobrazuje hranice syst´emu, d´ale uˇzivatele, kteˇr´ı s n´ım interaguj´ı a funkce, kter´e by tento syst´em mˇel poskytovat. Hranice syst´emu na obr´azku 3.1 , je tvoˇrena datab´azovou a aplikaˇcn´ı vrstvou. Klientsk´a vrstva pˇrestavuje bud’ pˇristupuj´ıc´ı okoln´ı syst´emy (nemocnice) , nebo jednotliv´e uˇzivatele (l´ekaˇre). V modelu jedn´an´ı (Use Case Model) vˇsak pouˇzit´a architektura nen´ı podstatn´a. Mˇeli bychom zde popsat uˇzivatelsk´e akce a ud´alosti, na kt´ere syst´em mus´ı umˇet zareagovat. Roli zde hraje uˇzivatel. Mˇely by zde b´ yt t´eˇz jasnˇe vymezeny hranice, tj. kter´a ud´alost je souˇc´ast´ı syst´emu a kter´a jiˇz stoj´ı mimo nˇej. Ukaˇzme si Use Case model pro roli Administr´aror. 4.1 Od uˇzivatele vedou ˇc´ary k jednotliv´ ym pˇr´ıpad˚ um uˇzit´ı. Z obr´azku je vidˇet, ˇze administr´ator bude m´ıt moˇznost zakl´adat, vyhled´avat a pˇr´ıpadnˇe upravit a odstranit l´ekaˇre. Symbol <> naznaˇcuje, ˇze l´ekaˇr p˚ ujde upravit ˇci odstranit ze syst´emu pouze prostˇrednictv´ım sc´en´aˇre pro vyhled´an´ı. Je to tak proto, ˇze nelze upravovat l´ekaˇre, aniˇz bychom si pˇred t´ım naˇcetli ze syst´emu aktu´aln´ı data. Pˇri odstranˇen´ı plat´ı to sam´e.
3.1. USE CASE MODEL
17
Obr´azek 3.2: Use Case - Administr´ator syst´emu Pro implementaci testovac´ıho prostˇred´ı jsem zvolil variantu tlust´eho klienta napsan´eho v jazyce Java (knihovna Swing). Je to proto, ˇze pˇr´ımo samotn´ y klient bude generovat dotazy, zas´ılat serveru a starat se o zobrazov´an´ı pˇr´ıchoz´ıch informac´ı. Kromˇe toho bude obsahovat validace pro vstupn´ı formul´aˇre. Je samozˇrejmˇe moˇzn´e pouˇz´ıt pro pˇr´ıstup i tenk´eho klienta. Pouze jsem se rozhodl pro jednu z moˇzn´ ych variant. V pˇr´ıpadˇe tenk´eho klienta (webov´ y prhl´ıˇzeˇc), kter´ y neobsahuje tuto aplikaˇcn´ı logiku, bychom museli pouˇz´ıt server jako meziˇcl´anek, ke kter´emu by klient pˇristupoval a teprve tento server by generoval odchoz´ı SOAP zpr´avy pro vzd´alen´ y syst´em. Use Case Model poskytuje pouze z´akladn´ı pˇrehled sluˇzeb. Pro podrobnˇejˇs´ı popis je nutn´e dopsat jednotliv´e sc´en´aˇre. Ty definuj´ı kroky, kter´e uˇzivatel mus´ı v tomto sc´en´aˇri prov´est pro dosaˇzen´ı avizovan´eho c´ıle. V souvislosti s pˇredchoz´ım diagramem (obr. 3.2) uvedu sc´en´aˇre pro roli Administr´ator. UC01: Zaloˇ zen´ı l´ ekaˇ re 1. Uˇzivatel siskne tlaˇc´ıtko Zaloˇzen´ı l´ekaˇre.“ ” 2. Syst´em zobraz´ı formul´aˇr se vstupn´ımi pol´ıˇcky jm´eno, pˇr´ıjmen´ı, rodn´e ˇc´ıslo, datum narozen´ı, adresa, telefon, uˇzivatelsk´e jm´eno, heslo a pole urˇcuj´ıc´ı platnost u ´ˇctu. Souˇc´ast´ı adresy je ulice, ˇc´ıslo popisn´e a psˇc. 3. Uˇzivatel zad´a vstupn´ı u ´daje a stiskne tlaˇc´ıtko Uloˇzit.“ ” 4. Syst´em ovˇeˇr´ı, zda byla spr´avnˇe vyplnˇena vstupn´ı pole a provede validaci na povinn´e poloˇzky. U rodn´eho ˇc´ısla a uˇzivatelsk´eho jm´ena syst´em ovˇeˇr´ı zda jsou unik´atn´ı. U
´ ´ KAPITOLA 3. ANALYZA A NAVRH IMPLEMENTACE
18
rodn´eho ˇc´ısla nav´ıc ovˇeˇr´ı dˇelitelnost 11. Pokud je vˇse splnˇeno, uloˇz´ı z´aznam do datab´aze. V opaˇcn´em pˇr´ıpadˇe zobraz´ı popis chyby. UC02: Vyhled´ an´ı l´ ekaˇ re 1. Uˇzivatel stiskne tlaˇc´ıtko Vyhled´an´ı l´ekaˇre“. ” 2. Syst´em zobraz´ı formul´aˇr se vstupn´ımi pol´ıˇcky jm´eno, pˇr´ıjmen´ı, rodn´e ˇc´ıslo. 3. Uˇzivatel zad´a vyhled´avac´ı krit´eria a stiskne tlaˇc´ıtko Vyhledat“. ” 4. Syst´em ovˇeˇr´ı, ˇze bylo vyplnˇeno alespoˇ n jedno vstupn´ı pol´ıˇcko a v pˇr´ıpadˇe rodn´eho ˇc´ısla zvaliduje na modulo 11. Pot´e bud’ zobraz´ı poˇzadovan´e z´aznamy, nebo popis chyby. 5. Uˇzivatel vybere z tabulky zobrazen´ ych z´aznam˚ u poˇzadovan´eho l´ekaˇre. UC03: Odstranˇ en´ı l´ ekaˇ re 1. Uˇzivatel nejprve provede UC02. Ze zobrazen´eho seznamu vybere poˇzadovan´ y z´aznam. 2. Syst´em zobraz´ı formul´aˇr se vstupn´ımi pol´ıˇcky jm´eno, pˇr´ıjmen´ı, rodn´e ˇc´ıslo, datum narozen´ı, adresa, telefon, uˇzivatelsk´e jm´eno, heslo a pole urˇcuj´ıc´ı platnost u ´ˇctu. Souˇc´ast´ı adresy je ulice, ˇc´ıslo popisn´e a psˇc. 3. Uˇzivatel uvede pole urˇcuj´ıc´ı platnost u ´ˇctu do neaktivn´ıho stavu. 4. Syst´em zkontroluje, zda uˇzivatel pracuje s aktu´aln´ım z´aznamem. Pokud ano, zneplatn´ı l´ekaˇre v syst´emu. V opaˇcn´em pˇr´ıpadˇe zobraz´ı popis chyby. ´ UC04: Uprava l´ ekaˇ re 1. Uˇzivatel nejprve provede UC02. Ze zobrazen´eho seznamu vybere poˇzadovan´ y z´aznam. 2. Syst´em zobraz´ı formul´aˇr se vstupn´ımi pol´ıˇcky jm´eno, pˇr´ıjmen´ı, rodn´e ˇc´ıslo, datum narozen´ı, adresa, telefon, uˇzivatelsk´e jm´eno, heslo a pole urˇcuj´ıc´ı platnost u ´ˇctu. Souˇc´ast´ı adresy je ulice, ˇc´ıslo popisn´e a psˇc. 3. Uˇzivatel uprav´ı pˇr´ısluˇsn´e z´aznamy a stiskne tlaˇc´ıtko Upravit“. ” 4. Syst´em ovˇeˇr´ı spr´avnost zadan´ ych u ´daj˚ u a v pˇr´ıpadˇe rodn´eho ˇc´ısla zvaliduje na modulo 11. D´ale zkontroluje, ˇze z´aznam je aktu´aln´ı. Pot´e bud’ uprav´ı dan´e u ´daje v datab´azi, nebo zobraz´ı popis chyby. Na z´akladˇe tˇechto sc´en´aˇr˚ u jsme z´ıskali z´akladn´ı pˇredstavu o tom, jak´e funkce mus´ı poskytovat syst´em pro uˇzivatele v roli administr´ator. Jelikoˇz vyhled´avac´ı funkce budou vracet v´ıce z´aznam˚ u, pro u ´pravu je nutn´e nejprve vyhledat konkr´etn´ı z´aznam. UC03 Odstranˇen´ı l´ekaˇre neznamen´a jeho fyzick´e odstranˇen´ı ze syst´emu. Z´aznam se pouze zneplatn´ı. Je to tedy speci´aln´ı pˇr´ıpad UC04, coˇz je zde vyznaˇceno ˇsipkou a znaˇckou <<extends>>. Nyn´ı n´asleduje Use Case model pro roli l´ekaˇr. Pro u ´sporu m´ısta zde nebudu vypisovat vˇsechny sc´en´aˇre. Najdete je v pˇr´ıloze A.
´ ´ VRSTVA 3.2. DATABAZOV A
19
Obr´azek 3.3: Use Case - L´ekaˇr
3.2
Datab´ azov´ a vrstva
Dalˇs´ım krokem v anal´ yze je vyspecifikovat datov´ y model nebo t´eˇz E-R diagram. Teorie ˇr´ık´a, ˇze tabulky by mˇely b´ yt alespoˇ n ve tˇret´ı norm´aln´ı formˇe. Norm´aln´ı formy slouˇz´ı pro omezen´ı redundance dat v datab´azi a zefektivˇ nuj´ı SQL dotazy. 1NF ˇr´ık´a, ˇze vˇsechny atributy pouˇzit´e ve sloupc´ıch by mˇely b´ yt atomick´e. Kdybychom tak uloˇzili napˇr´ıklad ˇ a CP ˇ do jednoho sloupce ADRESA, tˇeˇzko bychom pak z´ıskali vˇsechny ULICI, PSC ˇ T´ım bychom poruˇsili 1NF. 2NF se t´ z´aznamy t´ ykaj´ıc´ı se napˇr´ıklad dan´eho PSC. yk´a sp´ıˇse pˇr´ıpad˚ u, kdy se v tabulk´ach vyskytuje sloˇzen´ y prim´arn´ı kl´ıˇc. Budeme se proto snaˇzit veˇsker´e tabulky navrhnout tak, aby prim´arn´ım kl´ıˇcem bylo ID. Protoˇze ve vˇetˇsinˇe datab´az´ı se prim´arn´ı kl´ıˇce automaticky indexuj´ı, coˇz napom´ah´a rychlejˇs´ımu vyhled´av´an´ı, vˇzdy je efektivnˇejˇs´ı indexovat jeden nam´ısto dvou sloupc˚ u. 3NF n´am ˇr´ık´a, ˇze ˇza´dn´e dva nekl´ıˇcov´e atributy tabulky na sobˇe nesm´ı b´ yt z´avisl´e. Informace o pacientovi budeme ukl´adat do tabulky PACIENT. Informace o l´ekaˇr´ıch budeme ukl´adat do tabulky LEKAR. Protoˇze l´ekaˇr je z´aroveˇ n uˇzivatelsk´a role, a mus´ı m´ıt nˇekde uloˇzeny pˇrihlaˇsovac´ı u ´daje, mˇel by je m´ıt z bezpeˇcnostn´ıch d˚ uvod˚ u uloˇzeny ’ ve zvl´aˇst tabulce. Proto vytvoˇr´ıme t´eˇz tabulku osoba (PERSON), kter´a bude obsahovat pˇrihlaˇsovac´ı u ´daje vˇcetnˇe zaˇsifrovan´eho hesla. Kdokoliv bude pˇristupovat k syst´emu, mus´ı m´ıt z´aznam v tabulce PERSON. Zde tedy bude uloˇzen i administr´ator. K zaˇsifrov´an´ı hesla pouˇzijeme jednosmˇernou hashovac´ı funkci MD51 , kter´a sice jiˇz nen´ı nejbezpeˇcnˇejˇs´ı, 1
RFC 1321
´ ´ KAPITOLA 3. ANALYZA A NAVRH IMPLEMENTACE
20
ale pro n´aˇse u ´ˇcely postaˇc´ı. V´ ysledn´ y otisk zak´odujeme pomoc´ı Base642 , aby v datab´azi nebyl vidˇet pˇr´ımo hash. I kdyˇz klient bude umoˇzn ˇovat pro jednu osobu pˇrihl´aˇsen´ı bud’ jako administr´ator nebo jako l´ekaˇr, z hlediska n´avrhu mus´ı b´ yt moˇzn´e pˇriˇradit jednomu uˇzivateli v´ıce rol´ı. Na klienta by se tak po pˇrihl´aˇsen´ı vr´atil seznam rol´ı, kter´e m˚ uˇze vyuˇz´ıt a klient by se dot´azal v jak´e roli chce uˇzivatel pracovat. Z toho d˚ uvodu je dobr´e um´ıstit tabulku rol´ı (ROLES) zvl´aˇst’ a odkazovat z n´ı ciz´ım kl´ıˇcem na tabulku PERSON. Ciz´ım kl´ıˇcem zde bude pˇrihlaˇsovac´ı jm´eno, kter´e v tabulce PERSON bude unik´atn´ı. V praxi by se zˇrejmˇe pˇrihlaˇsovac´ı u ´daje oddˇelily u ´plnˇe na jin´ y datab´azov´ y stroj. To je ale v tomto pˇr´ıpadˇe zbyteˇcn´e. Protoˇze jak pacient, tak l´ekaˇr mohou m´ıt svou adresu, vytvoˇr´ıme pro adresu zvl´aˇst’ tabulku (ADRESA) a do tabulek PACIENT a LEKAR budeme ukl´adat pouze jej´ı ID. Sloˇzka praktick´eho l´ekaˇre m´a b´ yt pˇr´ıstupn´a tak´e pˇres webovou sluˇzbu. Um´ıst´ıme ji tedy do zvl´aˇst’ tabulky (PRAKT LEKAR) a spoj´ıme pˇres ciz´ı kl´ıˇc v tabulce PACIENT, aby bylo po vyhled´an´ı pacienta jasn´e, zda jiˇz sloˇzku zaloˇzenou m´a (ID sloˇzky) a nebo nem´a (NULL). Protoˇze pacient m˚ uˇze m´ıt pouze jednu sloˇzku, bude se jednat o vzah 1:1. Tabulka PACIENT obsahuje t´eˇz informace o zdravotn´ı pojiˇst’ovnˇe, krevn´ı skupinˇe a RH faktoru pacienta. Pokud bychom k´od a n´azev pojiˇst’ovny ukl´adali pˇr´ımo do tabulky PACIENT, poruˇsili bychom t´ım tˇret´ı norm´aln´ı formu. K´od a n´azev jsou totiˇz na sobˇe pˇr´ımo z´avisl´e. Proto vytvoˇr´ıme ˇc´ıseln´ık zdravotn´ıch pojiˇst’oven (CIS POJISTOVNY) a postav´ıme ho mimo tabulku PACIENT vztahem 1:N. Pokud se nˇekter´a pojiˇst’ovna v budoucnosti pˇrejmenuje, bude staˇcit zmˇenit z´aznam pouze v ˇc´ıseln´ıku a nebudeme muset sloˇzitˇe upravovat vˇsechny z´aznamy v tabulce PACIENT. Krevn´ı skupiny jsou 4 typy a z hlediska budouc´ıho v´ yvoje lidstva, tˇeˇzko nˇekdo objev´ı dalˇs´ı. Jedn´a se nav´ıc o informaci, kde k´od krevn´ı skupiny m´a plnou vypov´ıdac´ı hodnotu a nepotˇrebuje dalˇs´ı popis. Proto je celkem zbyteˇcn´e vytv´aˇret kv˚ uli tomu dalˇs´ı tabulku v podobˇe ˇc´ıseln´ıku. Zesloˇzitili bychom t´ım vyb´ır´an´ı a pro datab´azov´ y stroj by to znamenalo reˇzii nav´ıc. Krevn´ı skupina je tedy sp´ıˇse kandid´atem na typ enumerace. To sam´e plat´ı o RH faktoru. Dan´ y pacient m˚ uˇze ˇci nemus´ı trpˇet nˇejakou chorobou. Tyto informace budou ukl´ad´any do zvl´aˇst’ tabulky NEMOC. Protoˇze pacient m˚ uˇze v danou chv´ıli trpˇet i v´ıce chorobami, bude se jednat o vztah 1:N. Vzhledem k tomu, ˇze kaˇzd´a nemoc dle Mezin´arodn´ı Klasifikace Nemoc´ı m´a pˇriˇrazen jednoznaˇcn´ y identifik´ator, vytvoˇr´ıme t´eˇz ˇc´ıseln´ık diagn´oz, kde bude kaˇzd´a choroba klasifikov´ana dle k´odu. Na obr´azku 3.4 je na z´akladˇe tohoto rozboru uveden E-R diagram, kter´ y splˇ nuje prvn´ı tˇri norm´aln´ı formy.
3.2.1
JPA
Java Persistence API je souˇc´ast´ı specifikace EJB 3.0, vytvoˇren´a ke zjednoduˇsen´ı pr´ace s datovou vrstvou. Protoˇze JPA definuje jednotn´ y interface kter´ y vˇsak m˚ uˇze pouˇz´ıvat r˚ uzn´e implementace. Napˇr´ıklad aplikaˇcn´ı server GlassFish je zaloˇzen´ y na implementaci TopLink zat´ımco n´ami zvolen´ y JBoss pouˇz´ıv´a Hibernate. Tyto ORM 3 n´astroje lze samozˇrejmˇe pouˇz´ıt i samostatnˇe mimo aplikaˇcn´ı server. V kombinaci s aplikaˇcn´ım serverem vˇsak dost´av´ame velmi mocn´ y n´astroj pro objektovˇe relaˇcn´ı mapov´an´ı pˇr´ıstupn´e pˇr´ımo z vrstvy 2
RFC3548 Objektovˇe relaˇcn´ı mapov´ an´ı. Tak se naz´ yv´a pˇr´ıstup, kter´ y umoˇzn ˇuje mapov´an´ı objekt˚ u na tabulky relaˇcn´ı datab´ aze 3
´ ´ VRSTVA 3.2. DATABAZOV A
21
Obr´azek 3.4: E-R Diagram
v´ ykonn´e logiky d´ıky dependency injection. EJB kontejner nav´ıc umoˇzn ˇuje ˇr´ıdit jednotliv´e transakce, poskytuje auto-commit ˇci rollback. Pokud toho ovˇsem chceme vyuˇz´ıt. Je moˇzn´e definovat hranice transakc´ı programovˇe, to vˇsak v t´eto aplikaci nepotˇrebujeme. Transakˇcn´ı zpracov´an´ı je d˚ uleˇzit´e v pˇr´ıpadˇe, ˇze budeme cht´ıt prov´est v´ıce datab´azov´ ych operac´ı typu DELETE nebo UPDATE v jedn´e atomick´e operaci. Pokud napˇr´ıklad budeme upravovat z´akladn´ı informace l´ekaˇre, rozloˇzen´e v tabulk´ach LEKAR a ADRESA, JPA provider vygeneruje v´ıce datab´azov´ ych pˇr´ıkaz˚ u UPDATE. M˚ uˇze se lehce st´at, ˇze prvn´ı UPDATE uspˇeje zat´ımco druh´ y z nˇejak´eho d˚ uvodu neprobˇehne. Datab´aze by se nach´azela v nekonzistentn´ım stavu. Pokud provedeme tyto dvˇe operace v jedn´e transakci, je tato v pˇr´ıpadˇe ne´ uspˇechu oznaˇcena pro rollback“. Samotn´e transakce ovˇsem k za” bezpeˇcen´ı konzistence nestaˇc´ı.
´ ´ KAPITOLA 3. ANALYZA A NAVRH IMPLEMENTACE
22
Optimistick´ e zamyk´ an´ı Pˇredstavme si situaci, kdy dva r˚ uzn´ı l´ekaˇri maj´ı naˇctenou sloˇzku pacienta a upravuj´ı stejn´ y z´aznam. Oba l´ekaˇri se pokus´ı uloˇzit tento z´aznam a oba uspˇej´ı. V datab´azi vˇsak budou u ´loˇzeny jen data l´ekaˇre, kter´ y ukl´adal jako posledn´ı“. Do” jde k pˇreps´an´ı z´aznamu uloˇzen´eho prvn´ım l´ekaˇrem, aniˇz by ho nˇekdo nˇekdy ˇcetl. Tomuto jevu se ˇr´ık´a lost update nebo t´eˇz ztracen´ y z´apis“. Ve vysoce konkureˇcn´ım prostˇred´ı ” lze pouˇz´ıt pesimistick´e zamyk´an´ı, kdy se pˇr´ımo zamkne dan´a tabulka pˇr´ıpadnˇe z´aznam a ostatn´ı klienti mus´ı ˇcekat dokud z´amek nen´ı uvolnˇen. Takov´ y pˇr´ıstup ale znaˇcnˇe ovlivˇ nuje v´ ykonnost a propustnost syst´emu. V pˇr´ıpadˇe, ˇze se takov´e prostˇred´ı nepˇredpokl´ad´a4 je pouˇzit´ı pesimistick´ ych z´amk˚ u zbyteˇcn´ y nadstandard. V tomto pˇr´ıpadˇe tedy pouˇzijeme variantu optimistick´eho zamyk´an´ı. O implementaci tohoto pˇr´ıstupu bude ˇreˇc v kapitole 4.
EntityManager Je pr´avˇe t´ım spojovac´ım mostem mezi vrstvou v´ ykonn´e logiky a datab´azov´ ym strojem. Entity jsou v jazyce java reprezentov´any obyˇcejn´ ymi tˇr´ıdami (objekty), kter´e obsahuj´ı metody set a get. Tabulku PACIENT lze tak napˇr´ıklad reprezentovat tˇr´ıdou Pacient, tabulku ADRESA tˇr´ıdou Adresa atd. Protoˇze mezi tˇemito entitami existuje relace, um´ıst´ıme do tˇr´ıdy pacient referenci na tˇr´ıdu adresa. Pro bliˇzˇs´ı specifikaci tohoto vztahu, pˇr´ıpadnˇe dalˇs´ıch integritn´ıch omezen´ı n´am poslouˇz´ı jiˇz zmiˇ novan´e anotace. Takto pˇrevedeme datov´ y model do modelu objektov´eho a podrobnˇejˇs´ı u ´daje jako n´azvy sloupc˚ u, kardinalitu vztah˚ u urˇc´ıme anotacemi. EntityManager pak umoˇzn ˇuje pracovat s datab´azov´ ymi tabulkami skrze tyto objekty. Poskytuje metody pro vyhled´av´an´ı, ukl´ad´an´ı ˇci u ´pravy a umoˇzn ˇuje nadefinovat vlastn´ı dotazy do datab´aze.
3.3
Vrstva v´ ykonn´ e logiky
ˇ Casto se t´eˇz uˇz´ıv´a term´ınu business logika. Architektura JEE nab´ız´ı pro programov´an´ı business logiky takzvan´e Enterprise Java Beany (EJB). Enterprise Beana je softwarov´a komponenta, kter´a byla navrˇzene pro zjednoduˇsen´ı s´ıt’ov´e logiky a spr´avu pamˇeti. Tuto komponentu tvoˇr´ı interface a implementaˇcn´ı tˇr´ıda pˇr´ıpadnˇe do tˇretice konfiguraˇcn´ı soubor, kter´ y popisuje nˇejak´e jej´ı dalˇs´ı vlastnosti. Od verze EJB 3.0 je moˇzn´e pˇren´est informace specifikovan´e v souborech pˇr´ımo do implementaˇcn´ı tˇr´ıdy v podobˇe anotac´ı. Aplikaˇcn´ı server JBoss, kter´ y budeme pouˇz´ıvat, EJB 3.0 plnˇe podporuje, tud´ıˇz k detailn´ımu popisu chov´an´ı komponent pouˇzijeme anotace. Z hlediska program´atora nen´ı EJB nic jin´eho, neˇz kus k´odu bˇeˇz´ıc´ı ve specializovan´em prostˇred´ı, kter´e se naz´ yv´a EJB kontejner. Ten poskytuje komponent´am bezpeˇcn´e, transakˇcn´ı a distribuovan´e prostˇred´ı. Umoˇzn ˇuje komponent´am snadno pˇristupovat k dalˇs´ım zdroj˚ um, coˇz m˚ uˇze b´ yt napˇr´ıklad datab´aze, fronta zpr´av nebo jin´e komponenty tˇreba i na vzd´alen´em stroji. Program´ator se tak m˚ uˇze soustˇredit pˇr´ımo na dan´ y probl´em a nemus´ı se zaob´ırat t´ematikou jako multithreading, konkurentn´ı pˇr´ıstup, connection pooling, atd. To vˇse ˇreˇs´ı kontejner. Veˇsker´a business logika, kterou pouˇzijeme k implementaci, bˇeˇz´ı uvnitˇr EJB kontejneru. EJB 3.0 specifikace poskytuje dvˇe z´akladn´ı komponenty. 4
Pacient se vˇzdy m˚ uˇze nach´ azet pouze u jednoho l´ekaˇre, kter´ y vyplˇ nuje jeho kartu. Pokud by napˇr´ıklad ve stejnou chv´ıli pˇriˇsly jin´emu l´ekaˇri v´ ysledky z laboratoˇre, a bylo nutn´e je do syst´emu vloˇzit, optimistick´e zamyk´ an´ı zaruˇcuje, ˇze nebudou pˇreps´ any aktu´alnˇejˇs´ı data
´ ´ LOGIKY 3.3. VRSTVA VYKONN E
23
Message Driven Beans Tyto komponenty byly navrˇzeny pˇrev´aˇznˇe k asynchronn´ı komunikaci. Pracuj´ı na principu vyb´ır´an´ı z fronty zpr´av a v naˇsem syst´emu je nebudeme potˇrebovat. Session Beans Protoˇze se bav´ıme o vrstvˇe v´ ykonn´e logiky, jsou to pr´avˇe session beans, kter´e vykon´avaj´ı r˚ uzn´e operace na t´eto u ´rovni. Existuj´ı dva druhy tˇechto komponent. Stateless a Statefull. Jak jiˇz n´azev napov´ıd´a, Stateless session beans neudrˇzuj´ı sv˚ uj stav pˇres v´ıce klientsk´ ych poˇzadavk˚ u. Jin´ ymi slovy, pokaˇzd´e, kdyˇz server obdrˇz´ı request z klienta, m˚ uˇze ke zpracov´an´ı pouˇz´ıt jakoukoliv pr´avˇe dostupnou instanci session beany z EJB kontejneru. Naproti tomu Statefull jsou schopn´e udrˇzet stav mezi jednotliv´ ymi klientsk´ ymi requesty. Vzhledem k tomu, ˇze logika na serveru bude kompletnˇe bezestavov´a, Statefull session beany nebudeme v t´eto pr´aci vyuˇz´ıvat. Naopak Stateless session beany budou pˇredstavovat v´ ykonn´e j´adro cel´eho syst´emu. T´ım zajist´ıme bezpeˇcnou, transakˇcn´ı aplikaˇcn´ı vrstvu. Zde budou um´ıstˇeny metody pro pˇr´ıstup k samotn´e datab´azi, doplnˇen´e o validaˇcn´ı procedury, ale tak´e rozhran´ı k webov´ ym sluˇzb´am. Rozhran´ı je v terminologii objektov´eho programov´an´ı interface, kter´y v pˇr´ıpadˇe EJB 3.0 poskytuje aplikaˇcn´ımu serveru abstraktn´ı popis dan´e komponenty v podobˇe n´ azvu metody a vstupn´ıch a v´ystupn´ıch parametr˚ u. Aplikaˇcn´ı server pak deleguje poˇzadavky na jakoukoliv instanci tˇr´ıdy, kter´a je pr´avˇe dostupn´a v EJB kontejneru a implementuje toto rozhran´ı. Protoˇze aplikace bude umoˇzn ˇovat pr´aci oddˇelenˇe s daty l´ekaˇre a daty pacienta, vytvoˇr´ıme dvˇe session beany, kter´e budou m´ıt za u ´kol obsluhovat poˇzadavky na u ´rovni t´eto vrstvy. Kaˇzd´a beana bude urˇcena pro jednu uˇzivatelskou roli a bude obsahovat operace potˇrebn´e k naplnˇen´ı funkˇcnosti vyspecifikovan´e v Use Case diagramu. V pˇr´ıpadˇe role administr´ator a pr´aci s daty l´ekaˇre, mus´ı beana umˇet vyhledat l´ekaˇre, zaloˇzit, upravit, anebo odstranit ze syst´emu. V pˇr´ıpadˇe role l´ekaˇr mus´ı umˇet to sam´e vˇcetnˇe podˇr´ızen´ ych z´aznam˚ u jako jsou nemoci ˇci sloˇzka praktick´eho l´ekaˇre. Pop´ıˇseme si konkr´etnˇe jednotliv´e pˇr´ıpady, z hlediska aplikaˇcn´ı logiky. Budeme pˇredpokl´adat, ˇze klient zaslal poˇzadavek na server. Server pˇretransformuje SOAP request z XML do Java objekt˚ u a pˇred´a pˇr´ısluˇsn´e metodˇe business logiky. D´ale mohou nastat tˇri situace. INSERT Pokud metoda rozpozn´a, ˇze jde o insert, zjist´ı zda v tabulce do n´ıˇz insert smˇeruje, neexistuje nˇekter´ y z unik´atn´ıch kl´ıˇc˚ u. To by znamenalo, ˇze podobn´ y z´aznam jiˇz existuje a mus´ıme o tom informovat klienta. V pˇr´ıpadˇe vloˇzen´ı l´ekaˇre jsou tyto unik´atn´ı kl´ıˇce dva (login a rodn´e ˇc´ıslo). Pokud bychom chtˇeli informovat klienta, kter´ y z kl´ıˇc˚ u byl poruˇsen, museli bychom tabulku LEKAR zamknout. Bˇehem testu na duplicitu a samotn´ ym vloˇzen´ım z´aznamu, je totiˇz ˇcasov´a prodleva, v n´ıˇz m˚ uˇze jin´a transakce do tabulky norm´alnˇe vkl´adat. To je samozˇrejmˇe z´avisl´e na izolaˇcn´ı u ´rovni nastaven´e na datab´azi. PostgreSQL m´a standardnˇe nastavenou u ´roveˇ n READ COMMITED, ze kter´e budu d´ale vych´azet. Nastaven´ım na u ´roveˇ n SERIALIZABLE, kter´a zabraˇ nuje pa´ raleln´ımu bˇehu transakc´ı, bychom zbyteˇcnˇe sn´ıˇzili propustnost syst´emu. Uroveˇ n READ COMMITED nezabraˇ nuje fenom´en˚ um jako Nonrepeatable read a Phantom read. Skuteˇcnost ˇze test na duplicitu a vloˇzen´ı z´aznamu bˇeˇz´ı v jedn´e transakci tedy neznamen´a, ˇze
24
´ ´ KAPITOLA 3. ANALYZA A NAVRH IMPLEMENTACE
na u ´rovni datab´azov´eho stroje nem˚ uˇze paralelnˇe probˇehnout transakc´ı v´ıce. Kontejner ’ zajiˇst uje pouze commit ˇci rollback a nikoliv izolaˇcn´ı u ´roveˇ n datab´aze. Pokud pˇrece jen dojde k poruˇsen´ı unik´atnosti dat ve sloupci, Entity Manager vyhazuje v´ yjimku EntityExistsException, kterou lze snadno odchytit a informovat klienta obecnˇe o tom, ˇze byl poruˇsen unik´atn´ı kl´ıˇc. Probl´em je s t´ım, ˇze pˇresnˇe nev´ıme kter´ y. To lze samozˇrejmˇe zjistit parsov´an´ım v´ ypisu z´asobn´ıku, coˇz ale nen´ı pˇr´ıliˇs elegantn´ı zp˚ usob. V pˇr´ıpadˇe l´ekaˇre, kter´ y m´a dva unik´atn´ı kl´ıˇce, tedy budeme tabulku zamykat pro z´apis (ˇc´ıst bude moˇzn´e). V pˇr´ıpadˇe vloˇzen´ı pacienta s jedn´ım unik´atn´ım kl´ıˇcem postaˇc´ı odchytit v´ yˇse zm´ınˇenou v´ yjimku. Pokud je tedy vˇse v poˇra´dku, metoda pˇrejde k uloˇzen´ı objektu. UPDATE Pokud metoda rozpozn´a, ˇze jde o update, znamen´a to, ˇze v datab´azi jiˇz takov´a entita existuje a vstupn´ı data mus´ı obsahovat ID a vzhledem k optimistick´emu pˇr´ıstupu t´eˇz verzi upravovan´eho z´aznamu. Z toho plynou i poˇzadavky na validace na stranˇe serveru. Pakliˇze nebude obsahovat ID nebo verzi je to chyba a mus´ı b´ yt informov´an klient. JPA poskytuje nˇekolik moˇznost´ı jak entitu upravit. Prvn´ım zp˚ usobem je vyhled´an´ı entity pomoc´ı prim´arn´ıho kl´ıˇce, tedy ID, kter´e v tomto pˇr´ıpadˇe m´ame k dispozici. EntityManager vr´at´ı nalezenou entitu v tzv. attached stavu. Struˇcnˇe ˇreˇceno to znamen´a, ˇze jak´akoliv operace, kterou provedeme na entitˇe v tomto stavu je po skonˇcen´ı transakce prom´ıtnuta do datov´e vrstvy. D´alˇs´ı moˇznost´ı je vytvoˇrit zcela nov´ y objekt a nastavit mu hodnoty z requestu. Takto vytvoˇren´ y objekt se nach´az´ı ve stavu detached a m˚ uˇzeme s n´ım prov´adˇet jak´ekoliv operace bez vlivu na datov´ y model. Ve chv´ıli, kdy objekt pˇred´ame metodˇe EntityManager.merge(), pˇrevedeme objekt do attached stavu a po skonˇcen´ı transakce se uprav´ı v datab´azi. Nesm´ıme vˇsak zapomenout nastavit ID a Verzi upravov´an´eho z´aznamu jinak optimistick´e zamyk´an´ı nebude fungovat. Pokud Entity Manager nebude m´ıt k dispozici ID, nebude vˇedˇet kter´ y z´aznam upravit a pokus´ı se zaloˇzit nov´ y. Probl´em u tohoto zp˚ usobu spoˇc´ıv´a v tom, ˇze mus´ıme spr´avnˇe nastavit reference na ostatn´ı entity. Pokud bychom napˇr´ıklad upravovali tabulku LEKAR, vytvoˇrili bychom nov´ y objekt l´ekaˇr. Tomuto objektu bychom museli nastavit reference na vˇsechny tabulky, na kter´e l´ekaˇr odkazuje. To umoˇzn ˇuje metoda EntityManager.getReference(). Potˇrebujeme vˇsak k tomu zn´at ID referenˇcn´ı entity. M˚ uˇze se st´at, ˇze jej nebudeme m´ıt vˇzdy k dispozici. Napˇr´ıklad pokud budeme upravovat z´akladn´ı informace pacienta (tabulka PACIENT), tˇeˇzko budeme souˇcasnˇe vˇedˇet ID z´aznamu z tabulky PRAKT LEKAR. Museli bychom na klienta zas´ılat ID vˇsech podˇr´ızen´ ych z´aznam˚ u. Proto je lepˇs´ı pouˇz´ıt prvn´ı zp˚ usob a entitu si nejprve naˇc´ıst. Aby EntityManager nenaˇc´ıtal automaticky vˇsechny podˇr´ızen´e entity, je moˇzn´e nastavit anotac´ı tzv. LAZY loading. To zp˚ usob´ı, ˇze EntityManager z´ısk´a podˇr´ızenou entitu z datab´aze aˇz v momentˇe, kdy ji opravdu budeme potˇrebovat. V praxi to znamen´a vol´an´ı metody get na t´eto entitˇe nebo v pˇr´ıpadˇe seznamu zavol´an´ı metody size. V pˇr´ıpadˇe LAZY naˇc´ıt´an´ı m˚ uˇzou vˇsak vznikat nekonzistence ˇ a je potˇreba tyto situace nˇejak oˇsetˇrit. Reˇsen´ı, kter´e dle m´eho n´azoru nejm´enˇe sniˇzuje propustnost syst´emu je z´amek dan´eho ˇra´dku v nadˇr´ızen´e tabulce. (SELECT FOR UPDATE) Po vyhled´an´ı entity zkontrolujeme ˇc´ısla verz´ı pˇrich´azej´ıc´ıch z klienta. Pokud se liˇs´ı, z´aznam byl upraven nˇek´ ym jin´ ym a klient obdrˇz´ı informaci. Pokud se neliˇs´ı provedeme transformaci z Java objekt˚ u pˇrich´azej´ıc´ıch z rozhran´ı do entitn´ıch objekt˚ u. Protoˇze business logika bude pˇripravovat odpovˇed’ pro klienta, v n´ıˇz mus´ı b´ yt osaˇzeno vˇzdy ID upravovan´eho z´aznamu a novˇe zvˇetˇsen´e ˇc´ıslo verze, je nutn´e donutit Entity
´ ´ LOGIKY 3.3. VRSTVA VYKONN E
25
Manager, aby provedl veˇsker´e zmˇeny ihned, a neˇcekal na konec transakce. Pokud by zmˇeny provedl aˇz na konci transakce, kter´a standardnˇe nast´av´a pˇri zavol´an´ı return na business metodˇe, nemohli bychom v t´eto metodˇe jiˇz pˇripravit response. Pˇr´ıkazem EntityManager.flush(). tedy z´ısk´ame aktu´aln´ı ˇc´ıslo verze, kter´e spolu s ID m˚ uˇzeme opˇet pˇretransformovat do objekt˚ u rozhran´ı a poslat na klienta. DELETE K maz´an´ı z´aznam˚ u, stejnˇe jako k u ´pravˇe, potˇrebujeme zn´at ID a ˇc´ıslo verze. Pˇri maz´an´ı pacienta budeme prov´adˇet CASCADE DELETE vˇsech z´aznam˚ u, jinak 5 by mohlo doj´ıt k nekonzistenc´ım. Princip ale z˚ ust´av´a podobn´ y jako pˇri u ´pravˇe. Vyhled´ame entitu a provedem test verz´ı. Pokud se neshoduj´ı, z´aznam nem˚ uˇze b´ yt smaz´an, neb byl mezit´ım nˇek´ ym upraven. Pˇri shodˇe m˚ uˇzeme z´aznam smazat. Pokud se bude jednat o pacienta, zkontrolujeme dle UC09 zda l´ekaˇr, kter´ y pacienta odstraˇ nuje je souˇcasnˇe t´ım, kdo jej zaloˇzil. Tuto informaci budeme uchov´avat ve sloupci autupd. Pokud je vˇse v poˇr´adku, smaˇzeme z´aznam z datab´aze pˇr´ıkazem EntityManager.remove(). Pseudok´od by vypadal nˇejak takto. Pacient p = EntityManager.find(Pacient.class, pacientID) ...test verze zaznamu.... ...test vlatnika zaznamu EntityManager.remove(p)
3.3.1
Rozhran´ı webov´ e sluˇ zby
Popsali jsme analyticky, jak bude fungovat j´adro cel´eho syst´emu. Nyn´ı se pod´ıv´ame na rozhran´ı webov´e sluˇzby, kter´e by mˇelo poskytovat funkce vyspecifikovan´e v Use Case diagramu a zpˇr´ıstupnit je jako webovou sluˇzbu. I kdyˇz je toto rozhran´ı souˇca´st´ı business logiky, vˇenuji mu speci´aln´ı odstavec, protoˇze bude slouˇzit jako vstupn´ı bod do syst´emu. V´ıme, kter´e operace m´a syst´em poskytovat vzd´alen´ ym klient˚ um. Abychom mohli vytvoˇrit v´ ykonnou logiku je potˇreba vyspecifikovat co maj´ı b´ yt vstupn´ı a v´ ystupn´ı argumenty. Protoˇze pˇrenos bude prob´ıhat v XML je potˇreba navrhnout takov´e XML Sch´ema, kter´e bude umoˇzn ˇovat objektovˇe popsat request a response a z´aroveˇ n bude obsahovat pˇr´ısluˇsn´e elementy odpov´ıdaj´ıc´ı datab´azov´ ym sloupc˚ um. Abychom toto sch´ema nemuseli ps´at v jazyce XML m˚ uˇzeme pouˇz´ıt JAXB6 a v XML doladit pˇr´ıpadn´e detaily. JAXB umoˇzn ˇuje, na z´akladˇe anotac´ı, mapovat tˇr´ıdy v jazyce Java na XML objekty. Takto bychom v XML nadefinovali komplexn´ı typ adresa jehoˇz instanci by bylo moˇzn´e zaslat v tˇele SOAP zpr´avy.
V datab´ azi nem˚ uˇze existovat podˇr´ızen´ y z´aznam jiˇz neexistuj´ıc´ıho pacienta Java Architecture For XML Binding
26
´ ´ KAPITOLA 3. ANALYZA A NAVRH IMPLEMENTACE
Adekv´atn´ı javovsk´a tˇr´ıda po zpracov´an´ı Binding Compileru m˚ uˇze vypadat n´asleduj´ıc´ım zp˚ usobem: @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = ’CtAdresa’, propOrder = { ’bydliste’, ’cp’, ’psc’ }) public class CtAdresa { protected String bydliste; protected String cp; protected String psc; } Anotace @XmlAccessorType(XmlAccessType.FIELD) n´am ˇr´ık´a, ˇze pˇr´ıstup serializ´atoru ke tˇr´ıdˇe je skrze promˇenn´e a nikoliv skrze metody. Druh´a anotace n´am mapuje tˇr´ıdu na komplexn´ı typ CtAdresa a urˇcuje poˇrad´ı jednotliv´ ych element˚ u v sekvenci. Typ xs:string je pouˇzit i na ˇc´ıseln´e poloˇzky proto, ˇze na nˇej lze aplikovat regul´arn´ı v´ yrazy pˇri validaci sch´ematu. Je tak moˇzn´e validovat d´elku pˇr´ıpadnˇe vzor. Takto budeme tedy postupovat pˇri definici rozhran´ı webov´e sluˇzby. Abychom nepouˇz´ıvali spoleˇcn´e datov´e typy jako adresa zvl´aˇst’ pro pacienta a zvl´aˇst pro l´ekaˇre, pouˇzijeme jmenn´e prostory a budeme se v nich odkazovat na jeden konkr´etn´ı datov´ y typ. Jm´enn´e prostory jsou adekv´atn´ı javovsk´ ym bal´ıˇck˚ um. V XML sch´ematu se pak m´ısto konkr´etn´ıho typu objev´ı reference na jiˇz nadefinovan´ y komplexn´ı nebo jednoduch´ y typ. Protoˇze tyto tˇr´ıdy budou velmi podobn´e tˇr´ıd´am JPA, koneˇcn´a transformace mezi nimi uvnitˇr business logiky bude o to snaˇzˇs´ı. V tˇele SOAP zpr´avy m˚ uˇze b´ yt dle doporuˇcen´ı WS-I jen jeden koˇrenov´ y XML element. Zabal´ıme tedy vˇsechny informace nutn´e k pˇrenosu do jednoho Java objektu, kter´ y v XML sch´ematu bude reprezentov´an jedn´ım komplexn´ım typem. Rozhran´ı pak bude vypadat napˇr´ıklad takto: @WebMethod public VyhledaniLekareResponse vyhledaniLekare( VyhledaniLekareRequest request) @WebMethod public UlozeniLekareResponse ulozeniLekare( UlozeniLekareRequest request) ...atd... Nyn´ı se pod´ıvejme, jak budou vypadat vstupn´ı a v´ ystupn´ı argumenty u jednotliv´ ych metod.
´ ´ LOGIKY 3.3. VRSTVA VYKONN E
27
VYHLEDANI Vyhled´avac´ı metody budou vˇzdy vracet seznam z´azn´am˚ u na z´akladˇe nˇejak´eho vstupn´ıho filtru, kter´ y mus´ıme pˇren´est smˇer server. Souˇca´st´ı filtru budou vyhled´avac´ı krit´eria. V pˇr´ıpadˇe l´ekaˇre ˇci pacienta to budou poloˇzky jm´eno, pˇr´ıjmen´ı a rodn´e ˇc´ıslo. V pˇr´ıpadˇe vyhled´av´an´ı nemoc´ı, kde bude umoˇznˇeno str´ankov´an´ı, bude souˇc´ast´ı filtru ID pacienta, maxim´aln´ı poˇcet vr´acen´ ych z´aznam˚ u(velikost seznamu) a ˇc´ıslo datab´azov´e str´anky. Smˇerem na klienta budeme pˇred´avat seznam vyhledan´ ych poloˇzek. Pˇren´aˇset se budou pouze z´akladn´ı data nutn´a k identifikaci osoby pˇr´ıpadnˇe nemoci, nikoliv cel´a tabulka. Abychom pˇredeˇsli zahlcen´ı s´ıtˇe, budeme vˇzdy v pˇr´ıpadˇe osob vracet prvn´ıch 100 z´aznam˚ u. Pokud uˇzivatel nedostane poˇzadovan´ y z´aznam bude muset z´ uˇzit vyhled´avac´ı krit´eria. V pˇr´ıpadˇe nemoc´ı bude na 100 z´aznam˚ u omezena maxim´aln´ı velikost str´anky. Pokud klient zad´a vˇetˇs´ı, bude tato velikost ignorov´ana. NACTENI Naˇc´ıtac´ı metody rozhran´ı budou jako vstup obsahovat vˇzdy ID poˇzadovan´eho z´aznamu. Jako v´ ystup pak budou vracet data z pˇr´ısluˇsn´e tabulky. Abychom byli schopni urˇcit, ze kter´e tabulky m´ame data vz´ıt, dopln´ıme do vstupn´ıch argument˚ u atribut projekce. Mohli bychom samozˇrejmˇe pˇren´aˇset veˇsker´e u ´daje pacienta, ale t´ım bychom ’ zbyteˇcnˇe zatˇeˇzovali nejen s´ıt , ale tak´e v´ ypoˇcetn´ı kapacitu serveru. Atribut projekce bude v pˇr´ıpadˇe pacienta urˇcovat, zda naˇc´ıt´ame z´akladn´ı informace, sloˇzku praktick´eho l´ekaˇre, pˇr´ıpadnˇe konkr´etn´ı nemoc. Pro l´ekaˇre tento atribut nem´a smysl, protoˇze vˇzdy naˇc´ıt´ame vˇsechny z´akladn´ı u ´daje, kter´ ych nen´ı mnoho. Souˇca´st´ı odpovˇedi mus´ı b´ yt t´eˇz aktu´aln´ı ˇc´ıslo verze dan´eho z´aznamu. Toto ˇc´ıslo bude klient zas´ılat zpˇet pˇri poˇzadavku na u ´pravu ˇci smaz´an´ı. INSERT, UPDATE, DELETE Vzhledem k tomu, ˇze tyto operace budou pracovat vˇzdy se stejnou mnoˇzinou dat, spoj´ıme tyto tˇri operace do jedn´e a o konkr´etn´ım v´ yznamu pˇr´ıchoz´ıho poˇzadavku rozhodne atribut statement. Ten bude nab´ yvat jak jinak neˇz tˇr´ı hodnot: INSERT, UPDATE a DELETE. Souˇca´st´ı poˇzadavku s atributem INSERT a UPDATE mus´ı b´ yt i ukl´adan´a ˇci upravovan´a data. V pˇr´ıpadˇe UPDATE pak tento poˇzadavek mus´ı n´est z´aroveˇ n ID z´aznamu a verzi. V pˇr´ıpadˇe DELETE staˇc´ı ID a verze z´aznamu. Stejnˇe jako pˇri naˇc´ıt´an´ı jsme urˇcovali projekc´ı konkr´etn´ı tabulku, nebo skupinu tabulek, pouˇzijeme projekci i pro tyto situace. V pˇr´ıpadˇe pacienta n´am tak vznik´a ˇsest r˚ uzn´ ych kombinac´ı. Je vidˇet, ˇze pokud bychom implementovali pro kaˇzdou operaci zvl´aˇst’ sluˇzbu, mohli bychom u vˇetˇs´ıho syst´emu narazit na probl´em s pˇr´ıliˇsnou sloˇzitost´ı. ´ STAVY Zb´ CHYBOVE yv´a rozhodnout, jak budeme postupovat v pˇr´ıpadˇe ˇze nastane chyba. Je samozˇrejmˇe d˚ uleˇzit´e, aby se klient dozvˇedˇel, jak dopadl jeho poˇzadavek. Pokud v syst´emu nastane chyba kterou dok´aˇzeme rozpoznat, mˇela by b´ yt ve v´ ystupn´ı odpovˇedi obsaˇzena. To m˚ uˇzeme zajistit dˇediˇcnost´ı. Kaˇzd´ y objekt typu response bude napˇr´ıklad dˇedit od tˇr´ıdy BasicResponse, kter´a obsahuje n´asleduj´ıc´ı datov´ y typ. @XmlType(name=’CtFault’) public class CtFault { private Integer errCode; private String errMessage; private String detail; }
´ ´ KAPITOLA 3. ANALYZA A NAVRH IMPLEMENTACE
28
Kdykoli nastane chyba, m´ısto standardn´ı odpovˇedi zaˇsleme na klienta chybov´ y k´od, d˚ uvod chyby a detail. V pˇr´ıpadˇe nˇekter´ ych RuntimeException, jako tˇreba NullPointerException7 nen´ı ˇza´douc´ı zas´ılat tyto informace na klienta. Proto budeme tyto v´ yjimky odchyt´avat na nejvyˇsˇs´ı vrstvˇe, a zabal´ıme je do naˇs´ı specifick´e v´ yjimky, do kter´e vloˇz´ıme zpr´avu srozumitelnˇejˇs´ı. Pokud napˇr´ıklad selˇze spojen´ı s datab´az´ı pˇri vyhled´av´an´ı l´ekaˇre. Vr´at´ıme na klienta text Nepodaˇrilo se vyhledat l´ekaˇre. Kontaktujte pros´ım admin” istr´atora.“ Protoˇze naˇse aplikace je uk´azkov´a a ˇza´dn´eho administr´atora nem´a, budeme zas´ılat na klienta ˇc´ast chybov´eho v´ ypisu, aby bylo moˇzn´e pˇri testov´an´ı l´epe odhalit pˇr´ıˇcinu chyby.
3.4
Prezentaˇ cn´ı vrstva
Prezentaˇcn´ı vrstvu bude tvoˇrit vzd´alen´ y klient. V technologii JEE tuto vrstvu vetˇsinou obstar´av´a webov´ y kontejner na stranˇe serveru. Stejnˇe jako v EJB kontejneru zde existuj´ı komponenty, kter´e jsou navrˇzen´e pˇrev´aˇznˇe pro zpracov´an´ı HTTP poˇzadavk˚ u z klienta. Tyto komponenty se naz´ yvaj´ı servlety. Cel´a komunikace prob´ıh´a tak, ˇze servlet odbav´ı“ pˇr´ıchoz´ı request, zjist´ı co klient ” poˇzaduje a na z´akladˇe toho zavol´a pˇr´ısluˇsnou metodu na niˇzˇs´ı vrstvˇe. V pˇr´ıpadˇe webov´e aplikace servlet na z´akladˇe v´ ysledku vol´an´ı dan´e metody zformuje odpovˇed’ (nejˇcastˇeji ve formˇe HTML) a zaˇsle zpˇet na klienta. Klientem m˚ uˇze b´ yt napˇr´ıklad webov´ y prohl´ıˇzeˇc. V naˇsem pˇr´ıpadˇe tomu nebude jinak, pouze s t´ım rozd´ılem, ˇze komunikaˇcn´ı protokol je SOAP. Servlet zachyt´ı pˇr´ıchoz´ı HTTP request smˇeˇruj´ıc´ı na adresu webov´e sluˇzby. Na z´akladˇe definice webov´e sluˇzby ve WSDL (viz.2.3) se pokus´ı rozpoznat, kter´e operaci m´a pˇredat ˇr´ızen´ı. V naˇsem syst´emu reprezentuj´ı operace jednotliv´e metody v´ ykonn´e logiky. Protoˇze metod´am se nepˇred´av´a XML, ale samotn´a data, jeˇstˇe pˇred t´ım, neˇz servlet pˇred´a ˇr´ızen´ı metod´am business logiky, mus´ı vyparsovat pˇr´ısluˇsn´e informace z tˇela SOAP zpr´avy. Cel´ y tento proces bude obstar´avat modul JBossWS8 , kter´ y je souˇca´st´ı aplikaˇcn´ıho serveru JBoss. Verze JBossWS 3.0.1, kterou budeme pouˇz´ıvat, v tuto chv´ıli t´emˇeˇr zcela n´asleduje specifikaci JAX-WS9 . Tento modul tak poskytuje kompletn´ı framework pro v´ yvoj webov´ ych sluˇzeb v Javˇe. Umoˇzn ˇuje oznaˇcit session beany speci´aln´ımi anotacemi a t´ım je zpˇr´ıstupnit jako webovou sluˇzby. T´ım odpad´a starost se psan´ım parsovac´ıho enginu pˇresnˇe dodrˇzuj´ıc´ıho specifikaci. Je samozˇrejmˇe moˇzn´e napsat na z´akladˇe specifkace vlastn´ı modul pro zpracov´an´ı SOAP protokolu, ale to nen´ı pˇredmˇetem t´eto pr´ace. I kdyˇz prvn´ı kontakt s klientskou aplikac´ı zajiˇst’uje servlet, nelze pˇr´ıliˇs mluvit o prezentaˇcn´ı vrstvˇe. Servlet zde sp´ıˇse slouˇz´ı jako dispatcher, kter´ y rozdˇeluje jednotliv´e poˇzadavky. Webov´a vrstva serveru v tomto pˇr´ıpadˇe odpad´a a dost´av´ame se tak k opravdov´e prezentaˇcn´ı vrstvˇe, kterou v tomto pˇr´ıpadˇe pˇredstavuje swingov´ y klient.
3.4.1
Swingov´ y klient
Jak uˇz n´azev napov´ıd´a, klient bude implementov´an v programovac´ım jazyce Java s po´ moc´ı knihovny Swing. Uvodn´ ı obrazovka mus´ı b´ yt pˇrihlaˇsovac´ı se vstupn´ımi pol´ıˇcky username a password. Protoˇze klient bude bezestavov´ y, pˇrihl´aˇsen´ım se klient pouze dopt´a 7
Tyto chyby by nast´ avat nemˇely, ovˇsem nikdo nen´ı neomyln´ y http://jbws.dyndns.org/mediawiki/index.php?title=JBossWS 9 http://jcp.org/en/jsr/detail?id=224 8
ˇ 3.5. BEZPECNOST
29
webov´e sluˇzby jakou m´a v syst´emu roli. Na z´akladˇe toho pˇresmˇeruje uˇzivatele bud’ na obrazovku pro l´ekaˇre nebo na obrazovku pro administr´atora. Pokud by uˇzivatel mˇel v´ıce rol´ı, musel by se klient dot´azat v jak´e roli chce uˇzivatel pracovat. Vzhledem k vyspecifikovan´ ym dvˇema rol´ım toto nebude implementov´ano. Obrazovky klienta budou kop´ırovat jednotliv´e sc´en´aˇre Use Case diagramu. Vol´an´ı webov´ ych sluˇzeb jsou ˇcasovˇe n´aroˇcn´e operace a jako takov´e pobˇeˇz´ı v nov´em vl´aknˇe, abychom nebrzdili Event Dispatch Thread. Na vstupn´ı pol´ıˇcka budou aplikov´any validaˇcn´ı metody, kter´e zamez´ı uˇzivateli zad´an´ı nespr´avn´eho vstupu.
3.5
Bezpeˇ cnost
V kapitole 2.2 bylo uk´az´ano vol´an´ı protokolu SOAP. SOAP pˇren´aˇs´ı pouze XML Dokumenty v norm´aln´ı textov´e podobˇe. V pˇr´ıpadˇe ostr´eho syst´emu se ale m˚ uˇze jednat o citliv´a data pacient˚ u a jako takov´a by mˇela b´ yt zabezpeˇcena. K syst´emu t´eˇz nem˚ uˇze pˇristupovat kaˇzd´ y, proto je nutn´e nejprve prov´est autentizaci. M´ame na v´ ybˇer z tˇechto moˇznost´ı. Basic Autentizace Je zaloˇzena na tom, ˇze uˇzivatel zaˇsle v hlaviˇcce protokolu HTTP sv´e uˇzivatelsk´e jm´eno a heslo. Tyto jsou zak´odovany pomoc´ı Base64, coˇz neposkytuje t´emˇeˇr ˇza´dnou ochranu pˇred pˇr´ıpadn´ ym odposlechem. Proto se ˇcasto kombinuje tento zp˚ usob a zabezpeˇcen´ı pomoc´ı SSL/TLS. Digest autentizace Vznikla na z´akladˇe poˇzadovan´e vyˇsˇs´ı bezpeˇcnosti, neˇz kterou zajiˇst’uje basic autentizace. V tomto pˇr´ıpadˇe klient zas´ıla pouze MD5 otisk uˇzivatelsk´eho jm´ena, hesla, ˇretˇezce kter´ y obdrˇzel od serveru, HTTP metody dan´eho poˇzadavku a 10 poˇzadovan´eho URI . Certifik´ aty Protoˇze protokol HTTP nezajiˇst’uje potˇrebnou ochranu, pouˇz´ıv´a se obvykle niˇzˇs´ı vrstva, kter´a zajiˇst’uje ˇsifrovanou komunikaci prostˇrednictv´ım certifik´at˚ u. K tomu slouˇz´ı transportn´ı protokol SSL pˇr´ıpadnˇe jeho vylepˇsen´ı TLS. Kromˇe tˇechto tˇr´ı zp˚ usob˚ u, kter´e nab´ız´ı protokol HTTP, poskytuj´ı i WS-Security moˇznost zvanou UserToken, kter´a pos´ıl´a autentizaˇcn´ı u ´daje v SOAP hlaviˇcce. JBossWS framework vˇsak v dobˇe, kdy jsem zaˇc´ınal ps´at tuto pr´aci, neumoˇzn ˇoval pos´ılat tyto informace zabezpeˇcen´e. Nav´ıc by bylo nutn´e s klientem distribuovat dalˇs´ı nativn´ı knihovny, kter´e by tyto u ´daje vkl´adaly do hlaviˇcky SOAP zpr´avy. Proto jsem zvolil jako ˇreˇsen´ı HTTP basic autentizaci. Pouˇzit´ı WS-Security ponech´am jako moˇznost budouc´ıho rozˇs´ıˇren´ı. Vzhledem k tomu, ˇze syst´em neudrˇzuje ˇza´dn´ y stav s klientem, pˇri kaˇzd´em vol´an´ı sluˇzby mus´ı HTTP hlaviˇcka obsahovat autentizaˇcn´ı u ´daje. Jak jsem jiˇz zm´ınil, tato komunikace nen´ı pr´avˇe nejbezpeˇcnˇejˇs´ı. Proto je lepˇs´ı jako transportn´ı protokol pouˇz´ıt SSL pˇr´ıpadnˇe TLS. HTTPS je vˇsak zabezpeˇcen´ı point-to-point a to m˚ uˇze m´ıt nˇekdy sv´e nev´ yhody. Rozˇs´ıˇren´ı webov´ ych sluˇzeb WS-Security (viz kapitola 2.5) aplikuje ˇsifrov´an´ı pˇr´ımo na elementy SOAP zpr´avy, ˇc´ımˇz poskytuje zabezpeˇcen´ı i v pˇr´ıpadˇe ˇze zpr´ava putuje k c´ıli pˇres jednotliv´e prostˇredn´ıky (multi-hop relay) nebo je uloˇzena ve frontˇe ˇci na disku. Nav´ıc umoˇzn ˇuje pˇridat elektronick´ y podpis, kter´ y zaruˇcuje, ˇze zpr´ava na sv´e cestˇe k c´ıli nebude 10
Uniform Resource Identifier
30
´ ´ KAPITOLA 3. ANALYZA A NAVRH IMPLEMENTACE
modifikov´ana. Tato rozˇs´ıˇren´ı lze pouˇz´ıt i v t´eto aplikaci. Je vˇsak nutn´e vygenerovat certifik´aty pro klienta a server a nastavit konfiguraˇcn´ı soubory. V praxi by pak kaˇzd´ y klient mohl m´ıt certifik´at uloˇzen´ y napˇr´ıklad na chipov´e kartˇe a ovˇeˇren´ı totoˇznosti by prob´ıhalo prostˇrednictv´ım ˇctec´ıho zaˇr´ızen´ı a chipov´e karty. Autorizaci tedy zajiˇst’uje aplikaˇcn´ı server na z´akladˇe uˇzivatelsk´eho jm´ena a hesla zas´ılan´eho basic autentizac´ı. Aby se klient dozvˇedˇel jakou uˇzivatelskou roli mu syst´em pˇridˇelil, dot´aˇze se prostˇrednictv´ım webov´e sluˇzby. U bezestavov´e komunikace mˇe nenapad´a jin´a moˇznost jak toto zaˇr´ıdit. Klient potˇrebuje zn´at roli z toho d˚ uvodu, aby ’ uˇzivatele pˇresmˇeroval na spr´avnou obrazovku. Bud administr´atorskou nebo l´ekaˇrskou. V praxi by byl sp´ıˇse implementov´an klient zvl´aˇst’ pro roli administr´ator a zvl´aˇst’ pro roli ´ l´ekaˇr. Ukolem t´eto je pr´ace je vˇsak implementovat klienta pro ovˇeˇren´ı funkˇcnosti syst´emu.
Kapitola 4 Popis implementace Pro implementaci jsem zvolil v´ yvojov´e prostˇred´ı Eclipse1 a pluginy pro spouˇstˇen´ı aplikaˇcn´ıho serveru JBoss, XML editor a CVS plugin. Aplikaci jsem rozdˇelil do dvou projekt˚ u. Projekt samotn´eho syst´emu a projekt klienta, kter´ y m´a ovˇeˇrit funkˇcnost. Protoˇze syst´em je vˇzdy potˇreba zabalit do specifick´ ych bal´ıˇck˚ u a prov´est deployment na server, 2 pouˇzil jsem Ant , kter´ y umoˇzn ˇuje cel´ y proces automatizovat.
4.1
Datab´ azov´ a vrstva
Pro implementaci datov´e vrstvy jsem se rozhodl zvolit datab´azi PostgreSQL. Je to multiplatformn´ı datab´azov´ y syst´em s otevˇren´ ym zdrojov´ ym k´odem. Plnˇe podporuje ciz´ı kl´ıˇce, indexy, vnoˇren´e dotazy a operace join. Umoˇzn ˇuje t´eˇz pouˇz´ıt´ı trigger˚ u a funkc´ı. Mapov´an´ı jednotliv´ ych typ˚ u na konkr´etn´ı datov´e typy dan´e datab´aze zajiˇst’uje konkr´etn´ı JDBC ovladaˇc. Na z´akladˇe entity diagramu byly vytvoˇreny n´asleduj´ıc´ı tabulky. Tabulka PERSON CREATE TABLE ’person’ ( ’id’ int8 NOT NULL, ’datupd’ timestamp NULL, ’login’ varchar(255) NULL, ’passwd’ varchar(50) NOT NULL, ’jmeno’ varchar(255) NOT NULL, ’prijmeni’ varchar(255) NOT NULL, ’version’ int8 NULL, ’platny’ varchar(255) NOT NULL, ’autupd’ int8 NOT NULL, CONSTRAINT person_pkey PRIMARY KEY (id), CONSTRAINT fk_person_person FOREIGN KEY (autupd) REFERENCES person (id), CONSTRAINT person_login_key UNIQUE (’login’) ); 1 2
http://www.eclipse.org http://ant.apache.org
31
32
KAPITOLA 4. POPIS IMPLEMENTACE
V t´eto tabulce jsou um´ıstˇeni uˇzivatel´e syst´emu, jejich hesla a pˇrihlaˇsovac´ı jm´ena doplnˇen´a o z´akladn´ı informace. Prim´arn´ım kl´ıˇcem je Id. Sloupec platny indikuje, zda dan´a osoba m´a platn´ yu ´ˇcet ˇci nikoliv. Pˇrihlaˇsovat do syst´emu se mohou pouze l´ekaˇri ˇci administr´atoˇri s platn´ ym u ´ˇctem. Maz´an´ı l´ekaˇre tak neprob´ıh´a opravdov´ ym odstranˇen´ım l´ekaˇre ze syst´emu, n´ ybrˇz zneplatnˇen´ım u ´ˇctu. V pˇr´ıpadˇe, ˇze bychom l´ekaˇre smazali, museli bychom smazat t´eˇz vˇsechny jeho pacienty. To vˇsak neodpov´ıd´a realitˇe. V kaˇzd´e tabulce je uchov´av´ana informace, kdo (AUTUPD) a kdy (DATUPD) naposled data upravoval. Sloupec datupd se pln´ı automaticky triggerem, kter´ y se spouˇst´ı na operaci insert ˇci update. Sloupec AUTUPD bude vyplˇ nov´an pˇres aplikaci a bude obsahovat vˇzdy ID osoby, kter´a z´aznam upravovala. V pˇr´ıpadˇe, ˇze z aplikace nepˇrijde konkr´etn´ı ID, trigger vloˇz´ı syst´emov´eho uˇzivatele. Ten bude zaloˇzen souˇcasnˇe se zakl´adac´ım skriptem a bude m´ıt roli administr´ator. Sloupec version slouˇz´ı k optimistick´emu zamyk´an´ı, o kter´em bude ˇreˇc na konci tohoto odstavce. Tato tabulka je v programu reprezentov´ana entitou Person.java. Protoˇze sloupce AUTUPD a DATUPD jsou souˇc´ast´ı kaˇzd´e entity a JPA vyuˇz´ıv´a objektov´eho pˇr´ıstupu byla pro tyto dva sloupce vytvoˇrena abstraktn´ı tˇr´ıda BasicEntity.java, od kter´e kaˇzd´a entita dˇed´ı. Tato entita byla oznaˇcena anotac´ı @MappedSuperclass, kter´a zaj´ıst´ı, ˇze nebude ovlivnˇena struktura tabulek. Sloupec AUTUPD je v t´eto entitˇe namapov´an na tabulku PERSON n´asleduj´ıc´ı anotac´ı. @JoinColumn(name= autupd‘‘,nullable=false) ’’ @ManyToOne(fetch=FetchType.LAZY) protected Person autupd; Kromˇe toho, jak se sloupec bude jmenovat n´am anotace ˇr´ıkaj´ı, ˇze dan´a osoba m˚ uˇze b´ yt autorem updatu u v´ıce stejn´ ych entit a naopak kaˇzd´a entita mus´ı m´ıt pr´avˇe jednoho autora updatu. Parametr fetch zajist´ı, ˇze pˇri kaˇzd´em dotaˇzen´ı entity se nebude z´aroveˇ n dotahovat i osoba, kter´a ji naposledy upravila. Tabulka ROLES CREATE TABLE ’roles’ ( ’id’ int8 NOT NULL, ’datupd’ timestamp NULL, ’role’ varchar(255) NULL, ’autupd’ int8 NOT NULL, ’login’ varchar(255) NOT NULL CONSTRAINT roles_pkey PRIMARY KEY (id), CONSTRAINT fk_roles_person_login FOREIGN KEY (’login’) REFERENCES person (’login’), CONSTRAINT fk_roles_person_id FOREIGN KEY (autupd) REFERENCES person (id) ); V t´eto tabulce jsou um´ıstˇeny uˇzivatel´e ve vztahu k rol´ım. Ciz´ı kl´ıˇc na sloupci LOGIN napov´ıd´a, ˇze uˇzivatel m˚ uˇze m´ıt v´ıce rol´ı a NOT NULL znaˇc´ı, ˇze kaˇzd´a konkr´etn´ı role mus´ı m´ıt uˇzivatele. Opˇet jsou zde sloupce DATUPD a AUTUPD pro uchov´an´ı ˇcasu posledn´ı u ´pravy a autora t´eto u ´pravy, coˇz je ID do tabulky PERSON, tedy ID konkr´etn´ıho u ´ˇctu uˇzivate. Tato tabulka je v programu reprezentov´ana entitou Roles.java. Sloupec LOGIN je namapov´ana n´asleduj´ıc´ı anotac´ı.
´ ´ VRSTVA 4.1. DATABAZOV A
33
@ManyToOne(cascade=CascadeType.PERSIST,optional=false) protected Person user; Parametr cascade ˇr´ık´a, ˇze souˇcasnˇe s rol´ı m´a b´ yt vloˇzen i uˇzivatelsk´ yu ´ˇcet. Parametr optional ˇr´ık´a, ˇze nesm´ı existovat role bez uˇzivatele. Tabulka LEKAR CREATE TABLE ’lekar’ ( ’id’ int8 NOT NULL, ’titul’ varchar(255) NOT NULL, ’rc’ varchar(10) NOT NULL, ’adresa_fk’ int8 NULL, CONSTRAINT lekar_pkey PRIMARY KEY (id), CONSTRAINT fk_lekar_adresa FOREIGN KEY (adresa_fk) REFERENCES adresa (id), CONSTRAINT fk_lekar_person FOREIGN KEY (id) REFERENCES person (id), CONSTRAINT lekar_rc_key UNIQUE (rc) ); Tabulka LEKAR m´a s tabulkou PERSON spoleˇcn´ y prim´arn´ı kl´ıˇc, coˇz indikuje, ˇze LEKAR je t´eˇz uˇzivatelem a m˚ uˇze se pˇrihl´asit do syst´emu, pokud m´a platn´ yu ´ˇcet. JPA toto umoˇzn ˇuje opˇet zajistit dˇediˇcnost´ı. Anotace @Inheritance(JOINED) na tabulce PERSON ˇr´ık´a, ˇze pro jak´ ykoliv z´aznam, kter´ y od ni dˇed´ı, se pouˇzije zvl´aˇst’ tabulka. RC je zde unik´atn´ı kl´ıˇc, tud´ıˇz nemohou existovat dva l´ekaˇri se stejn´ ym rodn´ ym ˇc´ıslem. Tato tabulka je reprezentov´ana entitou Lekar.java. Adresa je namapov´ana vztahem @OneToOne(cascade={CascadeType.PERSIST,CascadeType.MERGE}) protected Adresa adresa; Parametr cascade ˇr´ık´a, ˇze chceme adresu upravovat z´aroveˇ n pˇri vol´an´ı persist ˇci merge na entitˇe L´ekaˇr. Protoˇze pˇri naˇc´ıt´an´ı l´ekaˇre vˇzdy budeme potˇrebovat souˇcasnˇe adresu, nech´ame parametr fetch na defaultn´ı hodnotˇe (EAGER). V praxi to znamen´a, ˇze JPA provider vygeneruje nam´ısto dvou selekt˚ u pouze jeden s operac´ı JOIN.
34
KAPITOLA 4. POPIS IMPLEMENTACE Tabulka ADRESA CREATE TABLE ’adresa’ ( ’id’ int8 NOT NULL, ’datupd’ timestamp NULL, ’bydliste’ varchar(33) NULL, ’cp’ varchar(15) NULL, ’psc’ varchar(5) NULL, ’version’ int8 NULL, ’autupd’ int8 NOT NULL, CONSTRAINT adresa_pkey PRIMARY KEY (id), CONSTRAINT fk_adresa_person FOREIGN KEY (autupd) REFERENCES person (id) MATCH SIMPLE );
Tato tabulka opˇet obsahuje sloupec VERSION, kter´ y slouˇz´ı pro optimistick´e zamyk´an´ı. Data jsou souˇca´st´ı z´akladn´ıch informac´ı pacienta a l´ekaˇre a m˚ uˇze zde tedy nast´avat konkurentn´ı pˇr´ıstup. Tato tabulka je reprezentov´ana entitou Adresa.java. Tabulka PACIENT CREATE TABLE ’pacient’ ( ’id_pacient’ int8 NOT NULL, ’datupd’ timestamp NULL, ’jmeno’ varchar(255) NOT NULL, ’prijmeni’ varchar(255) NOT NULL, ’rc’ varchar(255) NOT NULL, ’birth’ date NULL, ’telefon’ varchar(255) NULL, ’krevni_skupina’ varchar(255) NULL, ’rh_faktor’ varchar(255) NULL, ’poznamky’ varchar(255) NULL, ’version’ int8 NULL, ’autupd’ int8 NOT NULL, ’adresa_fk’ int8 NULL, ’pl_id’ int8 NULL, ’id_pojistovny’ varchar(255) NULL, CONSTRAINT pacient_pkey PRIMARY KEY (id_pacient), CONSTRAINT fk_pacient_adresa FOREIGN KEY (adresa_fk) REFERENCES adresa (id) CONSTRAINT fk_pacient_cis_pojistovny FOREIGN KEY (id_pojistovny) REFERENCES cis_pojistovny (kod_pojistovny) CONSTRAINT fk_pacient_person FOREIGN KEY (autupd) REFERENCES person (id) CONSTRAINT fk_pacient_prakt_lekar FOREIGN KEY (pl_id) REFERENCES prakt_lekar (id) CONSTRAINT pacient_rc_key UNIQUE (rc) );
´ ´ VRSTVA 4.1. DATABAZOV A
35
Pacient je tedy v´ ychoz´ı tabulka pro vˇsechny podˇr´ızen´e z´aznamy, se kter´ ymi l´ekaˇr m˚ uˇze pracovat. Z´akladn´ı informace se budou z´ısk´avat pˇr´ımo z t´eto tabulky a z´aroveˇ n z tabulky adresa, kter´a je s touto spojena ciz´ım kl´ıˇcem adresa fk. Na z´aznamy praktick´eho l´ekaˇre ukazuje ciz´ı kl´ıˇc pl id. Sloupec datupd opˇet uchov´av´a datum vkl´adan´eho pˇr´ıpadnˇe upravovan´eho z´aznamu. Sloupec autupd odkazuje do tabulky PERSON na identifik´ator l´ekaˇre, kter´ y zaloˇzil tohototo pacienta. Zde provedeme v´ yjimku a do tohoto sloupce zap´ıˇseme pouze pˇri vkl´ad´an´ı nov´eho z´aznamu. Je to proto, ˇze chceme uchov´avat informaci o tom, kter´ y l´ekaˇr pacienta zaloˇzil. Pouze ten je opr´avnˇen pacienta smazat, pˇr´ıpadnˇe upravit jeho z´akladn´ı u ´daje. Spojen´ı na ˇc´ıseln´ık pojiˇst’oven je pˇres ciz´ı kl´ıˇc id pojistovny. Protoˇze ’ k´od pojiˇst ovny je v tomto ˇc´ıseln´ıku unik´atn´ı a je tedy prim´arn´ım kl´ıˇcem, vkl´ad´a se do tabulky PACIENT pˇr´ımo tento k´od. Tato tabulka je reprezentov´ana entitou Pacient.java. ˇ ıseln´ık zdravotn´ıch pojiˇst’oven je namapov´an anotac´ı: C´ @ManyToOne(fetch=FetchType.LAZY) protected CisZdrPojistovny zdravotniPojistovna; Adresa je opˇet ve vztahu jedna ku jedn´e a vˇsechny operace na osobˇe se propaguj´ı i na adresu: @OneToOne(cascade={CascadeType.ALL}) protected Adresa adresa; Sloˇzka praktick´eho m˚ uˇze b´ yt pouze jedna a nen´ı ˇz´adouc´ı ji dotahovat vˇzdy z´aroveˇ n s pacientem. @OneToOne(cascade={CascadeType.ALL},fetch=LAZY) protected PraktickyLekar praktickyLekarInfo; Kaˇzd´ y pacient m˚ uˇze m´ıt v´ıce chorob a pˇri vloˇzen´ı nemoci do seznamu poˇzadujeme zaloˇzen´ı i pˇr´ısluˇsn´eho z´aznamu v tabulce NEMOC. Vlastn´ıkem vztahu je entita Nemoc a v n´ı pole pacient, kter´e drˇz´ı ciz´ı kl´ıˇc @OneToMany(cascade=CascadeType.ALL, mappedBy=’pacient’) protected List nemoci; Tabulka PRAKT LEKAR CREATE TABLE ’prakt_lekar’ ( ’id’ int8 NOT NULL PRIMARY KEY, ’datupd’ timestamp NULL, ’vaha’ varchar(255) NOT NULL, ’vyska’ varchar(255) NOT NULL, ’nestovice’ bool NOT NULL, ’priusnice’ bool NOT NULL, ’spala’ bool NOT NULL, ’spalnicky’ bool NOT NULL, ’zardenky’ bool NOT NULL, ’version’ int8 NULL, ’autupd’ int8 NOT NULL, CONSTRAINT fk_prakt_lekar_person FOREIGN KEY (autupd) REFERENCES person (id) );
36
KAPITOLA 4. POPIS IMPLEMENTACE
Zde jsou uveny informace ze sloˇzky praktick´eho l´ekaˇre. Zda byl pacient oˇckov´an ˇci kolik mˇeˇril nebo v´aˇzil pˇri preventivn´ı prohl´ıdce. Opˇet zde mus´ıme poˇc´ıtat s konkurentn´ım pˇr´ıstupem a um´ıstit zde sloupec VERSION. Tato tabulka je reprezentov´ana entitou PraktickyLekar.java. Tabulka CIS POJISTOVNY CREATE TABLE ’cis_pojistovny’ ( ’kod_pojistovny’ varchar(255) NOT NULL, ’datupd’ timestamp NULL, ’nazev’ varchar(255) NULL, ’autupd’ int8 NOT NULL, CONSTRAINT cis_pojistovny_pkey PRIMARY KEY (kod_pojistovny), CONSTRAINT fk_cis_pojistovny_person FOREIGN KEY (autupd) REFERENCES person (id) ); Funkci ˇc´ıseln´ıku zdravotn´ıch pojiˇst’oven, jsem vysvˇetlil v kapitole 3. Zde bych jen poznamenal, ˇze prim´arn´ım kl´ıˇcem bude samotn´ y k´od pojiˇst’ovny. Ten by mˇel b´ yt unik´atn´ı. ’ N´azev pojiˇst ovny slouˇz´ı sp´ıˇs jako dokumentaˇcn´ı sloupec. Tato tabulka je reprezentov´ana entitou CisZdrPojistovny.java. Pˇr´ıstup k ˇc´ıseln´ıku z webov´e sluˇzby nezajiˇst’uj´ı metody session beany n´ ybrˇz speci´aln´ı DAO3 objekt implementovan´ y jako singleton. Ten je vytvoˇren pouze jednou a pˇri kaˇzd´em dotazu pouˇzije voln´e datab´azov´e spojen´ı z connection poolu. Maxim´aln´ı velikost connection poolu aplikaˇcn´ıho sereru JBoss ve standardn´ım nastaven´ı je 20, coˇz pro tuto aplikaci plnˇe postaˇc´ı. Pokud by bylo souˇcasnˇe vyuˇzito 20 spojen´ı, dalˇs´ı klienti by museli ˇcekat na uvolnˇen´ı jednoho z nich. V´ yhodou pouˇzit´ı DAO objektu jsou rychl´e dotazy pˇr´ımo na vrstvˇe JDBC. Tabulka CIS DIAGNOZA CREATE TABLE ’cis_diagnoza’ ( ’kod_diagnoza’ varchar(255) NOT NULL, ’datupd’ timestamp NULL, ’nazev’ varchar(255) NULL, ’popis’ varchar(255) NULL, ’poznamka’ varchar(255) NULL, ’kod_skdiagnoza’varchar(255) NULL, ’pohlavi’ varchar(255) NULL, ’autupd’ int8 NOT NULL, CONSTRAINT cis_diagnoza_pkey PRIMARY KEY (kod_diagnoza), CONSTRAINT fk_cis_diagnoza_person FOREIGN KEY (autupd) REFERENCES person (id) MATCH SIMPLE ); 3
Data Access Object
´ ´ VRSTVA 4.1. DATABAZOV A
37
ˇ ıseln´ık diagn´oz bude slouˇzit podobn´emu u C´ ´ˇcelu jako ˇc´ıseln´ık pojiˇst’oven. Obsahuje k´od diagn´ozy z tabulky NEMOC. Klient bude moci uloˇzit pouze nemoc, jej´ıˇz diagn´oza je v tomto ˇc´ıseln´ıku. Pro pˇr´ıstup z webov´e sluˇzby bude opˇet vytvoˇren DAO objekt. Tato tabulka je reprezentov´ana entitou CisDiagnoza.java Tabulka NEMOC CREATE TABLE ’nemoc’ ( ’id_nemoc’ int8 NOT NULL, ’datupd’ timestamp NULL, ’kod’ varchar(255) NOT NULL, ’datumod’ timestamp NULL, ’datumdo’ timestamp NULL, ’poznamka’ varchar(255) NULL, ’stav’ varchar(255) NULL, ’pacient_fk’int8 NOT NULL, ’version’ int8 NULL, ’autupd’ int8 NOT NULL CONSTRAINT nemoc_pkey PRIMARY KEY (id_nemoc), CONSTRAINT fk_nemoc_cis_diagnoza FOREIGN KEY (kod) REFERENCES cis_diagnoza (kod_diagnoza) CONSTRAINT fk_nemoc_pacient FOREIGN KEY (pacient_fk) REFERENCES pacient (id_pacient) CONSTRAINT fk_nemoc_person FOREIGN KEY (autupd) REFERENCES person (id) ); Dan´a nemoc nesm´ı existovat bez diagn´ozy a bez pacienta. Pro stejn´eho pacienta bychom mˇeli zamezit duplicitˇe v k´odu diagn´ozy. Pacient m˚ uˇze trpˇet v´ıce chorobami, ale nˇemˇel by m´ıt dvakr´at stejnou diagn´ozu. Toto provedeme v aplikaˇcn´ı vrstvˇe. Mapov´an´ı entity je n´asleduj´ıc´ı. Tento typ m´a defaultnˇe nastaven EAGER loading, tj. pˇri dotaˇzen´ı nemoci se z´aroveˇ n dot´ahne k´od diagn´ozy. @ManyToOne protected CisDiagnoza kod; Tato entita je t´eˇz vlastn´ıkem ciz´ıho kl´ıˇce na tabulku PACIENT. Pˇri dotaˇzen´ı nemoci budeme potˇrebovat z´aroveˇ n ID a verzi pacienta. Proto pouˇzijeme defaultn´ı EAGER loading. @ManyToOne @JoinColumn(name = ’pacient_fk’, nullable = false) protected Pacient pacient; Optimistick´ e zamyk´ an´ı Optimistick´e zamyk´an´ı se nejˇcastˇeji implementuje pˇrid´an´ım dalˇs´ıho sloupce do kter´eho se zapisuje takzvan´a verze z´aznamu. Verze je ˇc´ıslo, kter´e se inkrementuje pˇri kaˇzd´em z´apisu do dan´e tabulky. Pˇri naˇc´ıt´an´ı dat je ˇc´ıslo verze z´ısk´ano a odesl´ano na klienta. Klient pot´e uprav´ı z´aznam a odeˇsle zpˇet na server s p˚ uvodn´ım ˇc´ıslem verze. Pokud se verze shoduj´ı m˚ uˇze probˇehnut u ´prava v datab´azi. Pokud se verze
38
KAPITOLA 4. POPIS IMPLEMENTACE
liˇs´ı, znamen´a to, ˇze z´aznam byl mezit´ım upraven. JPA provider umoˇzn ˇuje takto kontrolovat sloupce oznaˇcen´e anotac´ı @Version. Tento sloupec je pouˇzit na vˇsech tabulk´ach, kter´e mohou b´ yt editov´any na klientsk´em syst´emu a kde se pˇredpokl´ad´a konkurentn´ı pˇr´ıstup. Kompletn´ı zakl´adac´ı sch´ema vˇcetnˇe trigger˚ u, sekvenc´ı a s konkr´etn´ımi datov´ ymi typy pro PostgreSQL je um´ıstˇeno na pˇriloˇzen´em CD. Triggery jsou pouˇzity pro plnˇen´ı sloupc˚ u AUTUPD a DATUPD. Trigger na AUTUPD se spust´ı jen v pˇr´ıpadˇe, ˇze vstupuj´ıc´ı ID je null. Napˇr´ıklad pro uˇzivatele administrator vkl´ad´an´eho pˇres zakl´adac´ı skript. Sekvence jsou nastaveny na poˇca´teˇcn´ı hodnotu deset. ID administr´atora je 1 a v pˇr´ıpadˇe, ˇze bychom nastavili poˇca´teˇcn´ı hodnotu sekvence v tabulce PERSON na 0 mohlo by prvn´ım vloˇzen´ı uˇzivatele doj´ıt k poruˇsen´ı unik´atnosti na sloupci prim´arn´ıho kl´ıˇce. Skript obsahuje t´eˇz naplnˇen´ı ˇc´ıseln´ık˚ u.
4.2
Vrstva v´ ykonn´ e logiky
D´ale n´asleduje v´ ypis jednotliv´ ych tˇr´ıd a metod, kter´e budou prov´adˇet operace na stranˇe serveru. Na konci kaˇzd´e operace se zaloguje jej´ı n´azav a doba trv´an´ı. Logov´an´ı poskytuje lepˇs´ı orientaci a hled´an´ı pˇriˇciny v pˇr´ıpadˇe chyby, ale tak´e lepˇs´ı ladˇen´ı a optimalizaci ve f´azi v´ yvoje. LekarBean.java Jak jiˇz bylo ˇreˇceno v anal´ yze, tato komponenta obluhuje poˇzadavky administr´atora. Protoˇze administr´ator pracuje s u ´daji l´ekaˇre, nazval jsem tˇr´ıdu LekarBean.java. Obsahuje 3 business metody, kter´e obstar´avaj´ı jednotliv´e poˇzadavky. public VyhledaniLekareResponse findLekar(VyhledaniLekareRequest req); Tato metoda nejprve provede validaci vstupn´ıch dat na z´akladˇe regul´arn´ıch v´ yraz˚ u a pot´e se pokus´ı vyhledat poˇzadovan´e z´aznamy. Datab´azov´ y select je omezen na 100 z´aznam˚ u, abychom nezahltili datab´azi a stejnˇe tak je omezen i seznam nalezen´ ych l´ekaˇr˚ u, kter´e zas´ıl´ame na klienta. Tady zase hroz´ı zahlcen´ı s´ıtˇe. Tato metoda generuje pouze jeden datab´azov´ y select a je tedy zbyteˇcn´e, aby bˇeˇzela v transakci. Proto m´a nastaven transakˇcn´ı scope na NOT_SUPPORTED. Vyhled´avac´ı dotazy byly implementov´any jako @NamedQuery, pro lepˇs´ı efiktivitu a znovupouˇzitelnost. public UlozeniLekareResponse saveLekar(UlozeniLekareRequest req); Tato metoda nejprve provede validaci vstupn´ıch dat, na z´akladˇe regul´arn´ıch v´ yraz˚ u. Pˇred t´ım, neˇz zkontroluje unik´atn´ı kl´ıˇce zamkne tabulku person pro z´apis. Pot´e na z´akladˇe atributu Statement provede pˇr´ısluˇsnou operaci typu INSERT, UPDATE, DELETE. V pˇr´ıpadˇe UPDATE a DELETE t´eˇz zkontroluje ˇc´ısla verz´ı. Protoˇze je zapisov´ano do v´ıce tabulek souˇcasnˇe je nutn´e, aby tato metoda bˇeˇzela v transakci. To zajist´ıme anotac´ı REQUIRES_NEW, coˇz zp˚ usob´ı start nov´e transakce a v pˇr´ıpadˇe chyby odrolov´an´ı vˇsech datab´azov´ ych zmˇenov´ ych operac´ı. public NacteniLekareResponse getLekar(NacteniLekareRequest req);
´ ´ LOGIKY 4.2. VRSTVA VYKONN E
39
Tato metoda nejprve provede validaci vstupn´ıch dat, na z´akladˇe regul´arn´ıch v´ yraz˚ u. Protoˇze zde jsou naˇc´ıt´any z´aznamy z r˚ uzn´ ych tabulek metodou LAZY, je nutn´e zajistit konzistenci naˇc´ıtan´ ych dat. K tomu poslouˇz´ı z´amek na entitˇe l´ekaˇr. Protoˇze LAZY loading vyˇzaduje bˇeh uvnitˇr transakce, transakˇcn´ı scope bude REQUIRES_NEW. S naˇc´ıtan´ ymi daty pˇred´av´a metod´am rozhran´ı t´eˇz ID z´aznamu a ˇc´ıslo aktu´aln´ı verze. PacientBean V pˇr´ıpadˇe role l´ekaˇr bude beana trochu sloˇzitˇejˇs´ı. L´ekaˇr m´a totiˇz moˇznost upravovat i z´aznamy z jin´ ych tabulek. Nejednoduˇs´ı metoda je opˇet ta vyhled´avac´ı. public VyhledaniPacientResponse findPacient(VyhledaniPacientRequest req) Tato metoda nejprve provede validaci vstupn´ıch dat na z´akladˇe regul´arn´ıch v´ yraz˚ u. Na z´akladˇe vstupn´ıho filtru se se pokus´ı vyhledat dan´e z´aznamy. V pˇr´ıpadˇe pacienta je filtr tvoˇren rodn´ ym ˇc´ıslem, jm´enem ˇci pˇr´ıjmen´ım. V pˇr´ıpadˇe nemoc´ı se vyhled´av´a jejich seznam pro zadan´e ID pacienta. Protoˇze JPA provider umoˇzn ˇuje str´ankov´an´ı, vyuˇzil jsem tuto moˇznost a seznam nemoc´ı bude moˇzn´e z´ısk´avat postupnˇe. Vstupn´ı filtr bude t´eˇz obsahovat ˇc´ıslo poˇzadovan´e str´anky a velikost seznamu. Tu jsem omezil na maxim´aln´ı hodnotu 100. Tato metoda v pˇr´ıpadˇe z´akladn´ı projekce generuje pouze selecty. V pˇr´ıpadˇe vyhled´an´ı nemoc´ı je nutn´e zkontrolovat, zda pacient st´ale existuje. Abychom zajistili integritu mezi dotazem do tabulky pacient a dotazem do tabulky nemoc je nutn´e z´aznam pacienta zamknout. Vzhledem k pouˇzit´ı LAZY naˇcten´ı pacienta tato metoda pobˇeˇz´ı v transakci REQUIRED. public NacteniPacientResponse getPacient(NacteniPacientRequest req) Tato metoda nejprve provede validaci vstupn´ıch dat, na z´akladˇe regul´arn´ıch v´ yraz˚ u. Atributy projekce a ID z´aznamu vstupuj´ıc´ı z requestu jednoznaˇcnˇe urˇcuj´ı z´aznam, kter´ y klient poˇzaduje. Protoˇze v pˇr´ıpadˇe pacienta se vyuˇz´ıv´a LAZY loading podˇr´ızen´ ych z´aznam˚ u, je nutn´e pouˇz´ıt z´amek na nadˇr´ızen´e entitˇe. Z´amek bude pro z´apis a bude aplikov´an na konkr´etn´ıho pacienta, tak aby neovlivˇ noval ostatn´ı ˇra´dky. Kdokoliv bude cht´ıt upravit pacienta pˇr´ıpadnˇe pracovat s jeho daty rozloˇzen´ ymi ve v´ıce tabulk´ach, bude muset nejprve z´ıskat tento z´amek. Pokud bychom se chtˇeli vyhnout pouˇzit´ı z´amk˚ u, museli bychom naˇc´ıtat data atomicky. public UlozeniPacientResponse savePacient(UlozeniPacientRequest req) Tato metoda nejprve provede validaci vstupn´ıch dat, na z´akladˇe regul´arn´ıch v´ yraz˚ u. Na z´akladˇe atributu projekce a atributu statement provede pˇr´ısluˇsnou operaci INSERT, UPDATE, DELETE. V pˇr´ıpadˇe vkl´ad´an´ı pacienta ˇci sloˇzky praktick´eho l´ekaˇre nen´ı co zamykat. Unik´atnost rodn´eho ˇc´ısla je zajiˇstˇena pˇr´ımo na sloupci v datab´azi a pˇri pokusu o vloˇzen´ı jiˇz existuj´ıc´ıho ˇc´ısla odchyt´ıme v´ yjimku. V pˇr´ıpadˇe vkl´ad´an´ı nemoci mus´ıme ovˇeˇrit, zda pro tohoto pacienta jiˇz stejn´a diagn´oza nebyla stanovena. Abychom nemuseli zamykat celou tabulku NEMOC pro z´apis a t´ım omezovat ostatn´ı l´ekaˇre, aplikujeme z´amek na entitu pacienta. V pˇr´ıpadˇe u ´pravy a odstranˇen´ı jak´ehokoliv z´aznamu opˇet pouˇzijeme z´amek na nadˇr´ızen´e entitˇe, kterou je pacient. Transakˇcn´ı scope je nastaven na REQUIRES_NEW, coˇz zajiˇst’uje start nov´e transakce a v pˇr´ıpadˇe chyby odrolov´an´ı vˇsech datab´azov´ ych zmˇenov´ ych operac´ı.
40
KAPITOLA 4. POPIS IMPLEMENTACE
NemServiceBean Tato komponenta reprezentuje rozhran´ı webov´e sluˇzby. Pˇredstavuje vstupn´ı bod do syst´emu a rozdˇeluje poˇzadavky na z´akladˇe rol´ı. M´a nastaven transakˇcn´ı scope na NOT_SUPPORTED. Veˇsker´e transakce se tedy startuj´ı aˇz s metodami tˇr´ıd PacientBean a LekarBean. Je tak zaruˇceno, ˇze chybov´e stavy, kter´e nast´avaj´ı aˇz po skonˇcen´ı transakce, mohou b´ yt v t´eto komponentˇe odchyceny. Metody rozhran´ı vyhazuj´ı v´ yjimku ServerException, kter´a m˚ uˇze b´ yt zobrazena na klientsk´em syst´emu jako chybov´a zpr´ava. Ostatn´ı v´ yjimky vznikl´e napˇr´ıklad pˇri validaci, kdy se aplikaˇcn´ı logika nedostala v˚ ubec do hry, se na klientovi zaobal´ı do obecn´e zpr´avy pro uˇzivatele. Napˇr´ıklad “Chyba v syst´emu. Kontaktujte administr´atora.” Rozhran´ı tedy vystavuje celkem ˇsest metod business logiky plus jedn´e metody pro autorizaci uˇzivatele. Dalˇs´ı dvˇe sluˇzby umoˇzn ˇuj´ı dotahovat data z ˇc´ıseln´ıku diagn´oz a zdravotn´ıch pojiˇst’oven. Protoˇze klient tyto poloˇzky vyplˇ nuje ve formul´aˇr´ıch, je d˚ uleˇzit´e, aby hodnoty v ˇc´ıseln´ıc´ıch byly totoˇzn´e. To zaruˇc´ıme dotaˇzen´ım aktu´aln´ıch dat pˇr´ımo ze serveru. Pokud bychom tyto dvˇe sluˇzby postavili mimo bezpeˇcnostn´ı dom´enu, kter´a v tuto chv´ıli vyˇzaduje autentizaci a zabraˇ nuje tak anonymn´ımu pˇr´ıstupu, mohly by je tak vyuˇz´ıt i dalˇs´ı okoln´ı syst´emy. Prostˇrednictv´ım anotac´ı aplikaˇcn´ıho serveru JBoss, zajist´ıme, aby webov´a sluˇzba byla zpˇr´ıstupnˇena pod n´ami definovan´ ym URL. @WebContext(contextRoot=’services’,urlPattern=’/NemService’) ... http://server:port/services/NemService Jak´akoliv SOAP zpr´ava smˇeˇruj´ıc´ı na tuto adresu je odchycena servletem a v pˇr´ıpadˇe, ˇze souhlas´ı autentizaˇcn´ı u ´daje, pˇretransformov´ana z XML do Java objekt˚ u a zasl´ana ke zpracov´an´ı niˇzˇs´ı vrstvˇe. Cel´e rozhran´ı je pops´ano jazykem WSDL a najdete jej v pˇr´ıloze C. Souˇca´st´ı jsou i XML sch´emata pro jednotliv´e komplexn´ı ˇci jednoduch´e typy. Transformaˇ cn´ı tˇ r´ıdy Rozhran´ı netvoˇr´ı jen samotn´a NemServiceBeana, ale tak´e tˇr´ıdy do kter´ ych se transformuj´ı XML objekty. Jak jiˇz bylo pops´ano v anal´ yze jsou to tˇr´ıdy, kter´e umoˇzn ˇuj´ı mapovat Java objekty na XML dokumenty. Protoˇze z tˇechto objekt˚ u mus´ıme pˇretransformovat vstupn´ı data do entitn´ıch objekt˚ u, je nutn´e vytvoˇrit transformace. V pˇr´ıpadˇe zmˇeny rozhran´ı napˇr´ıklad pˇrid´an´ım elementu je snadn´e upravit pouze tuto transformaci nam´ısto vˇsech roztrouˇsen´ ych v´ yskyt˚ u dan´eho elementu v aplikaci. Z toho d˚ uvodu je dobr´e um´ıstit transformaci do jednoho m´ısta. Zvolil jsem tedy pˇr´ımo tyto tˇr´ıdy rozhran´ı, kter´e po pˇrevodu z XML budou obsahovat formul´aˇrov´a data z klienta. V business metodˇe pak staˇc´ı zavolat pˇr´ısluˇsnou transformaˇcn´ı metodu, kter´a vr´at´ı pˇr´ımo naplnˇen´ y entitn´ı objekt, kter´ y do t´eto transformace vstupuje. Podobnˇe se postupuje i v opaˇcn´em pˇr´ıpadˇe. Abychom nemuseli dvakr´at parsovat ˇc´ıslo verze, vrac´ı tyto transformaˇcn´ı metody boolean hodnotu, kter´a informuje business logiku, zda vyhovuj´ı ˇc´ısla verz´ı upravovan´eho objektu. V pˇr´ıpadˇe, ˇze ne, je zformov´ana chybov´a odpovˇed’ a informov´an klient. Pro transformaci z´akladn´ıch datov´ ych typ˚ u, napˇr´ıklad Long a String, byl zvolen syst´em adapt´er˚ u. ID v entitn´ım objektu je typu Long, avˇsak do XML ho tranformujeme jako xs:string. Je to z toho d˚ uvodu, ˇze na ˇretˇezce lze aplikovat regul´arn´ı v´ yraz. D´ale xs:string je v hierarchii typ˚ u z´akladn´ım typem. Zat´ımco xs:long je odvozen´ y dvojitou restrikc´ı a hroz´ı, ˇze ne vˇsechny implementace webov´ ych sluˇzeb jej budou umˇet spr´avnˇe
ˇ ´I VRSTVA 4.3. PREZENTACN
41
vyparsovat. JBossWS, stejnˇe jako referenˇcn´ı implementace JAX-WS, pro tyto pˇr´ıpady umoˇzn ˇuje vytvoˇrit tˇr´ıdu adapt´er˚ u, ve kter´e m˚ uˇzeme specifikovat jednotliv´e transformace. public static class LongAdapter extends XmlAdapter<String, Long> { @Override // java to xml public String marshal(Long v) throws Exception { return v.toString(); } @Override // xml to java public Long unmarshal(String v) throws Exception { return Long.parseLong(v); } } Tento adapt´er lze aplikovat pouˇzit´ım anotace pˇr´ımo v konkr´etn´ı tˇr´ıdˇe rozhran´ı. @XmlType(name=’UlozeniPacientRequest’) public class UlozeniPacientRequest { @XmlJavaTypeAdapter(Adapters.LongAdapter.class) protected Long id; ... }
4.3
Prezentaˇ cn´ı vrstva
Klient m´a k dispozici definici webov´e sluˇzby ve formˇe WSDL, na z´akladˇe kter´e je schopn´ y volat jednotliv´e metody rozhran´ı. Aby klient mohl odes´ılat a pˇrij´ımat SOAP zpr´avy, potˇrebuje tak´e umˇet transformovat z Java objekt˚ u do XML a naopak. Modern´ı jazyky typu Java a .NET a jejich v´ yvojov´e n´astroje ˇcasto um´ı vygenerovat tyto tˇr´ıdy pˇr´ımo z WSDL automaticky. JBossWS k tomu poskytuje d´avkov´ y soubor wsconsume.bat, kter´ y uvnitˇr pouˇz´ıv´a pˇr´ısluˇsnou knihovnu. Po aplikaci na WSDL soubor m´ame tedy na klientovy pˇresn´ y obraz rozhran´ı serveru spolu s tˇr´ıdou, kter´a umoˇzn ˇuje zavolat webovou sluˇzbu. Takto vygenerovan´e spojky jsou ˇcasto nedostateˇcn´e. Neobsahuj´ı atributy pro nastaven´ı autentizace a ˇsifrov´an´ı a je proto nutn´e je do k´odu dopsat. Zpr´avu je pak moˇzn´e odeslat naplnˇen´ım vstupn´ıch objekt˚ u a zavol´an´ım pˇr´ısluˇsn´e metody, napˇr. vyhledaniLekare. Odpovˇed’ z´ısk´ame v n´avratov´em Java objektu, kter´ y m˚ uˇzeme snadno pˇretransformovat do formul´aˇrov´ ych pol´ı. K implementaci samotn´eho vol´an´ı a transformace byla pouˇzita tˇr´ıda SwingWorker, kter´a umoˇzn ˇuje spouˇstˇet v´ ykonovˇe n´aroˇcn´e operace v samotn´em vl´aknˇe. Str´ankov´an´ı v pˇr´ıpadˇe nemoc´ı bylo implementov´ano kompletnˇe na klientovi. Klient naˇcte ze serveru o jeden z´aznam v´ıce, neˇz pak zobraz´ı na obrazovce. V pˇr´ıpadˇe ˇze naˇcten´e u ´daje obsahuj´ı v´ıce z´aznam˚ u neˇz zobrazujeme, zpˇr´ıstupn´ı se tlaˇc´ıtko dalˇs´ı str´anka. Pro udrˇzen´ı ˇc´ısla str´anky je vyuˇzita statick´a Cache implementovan´a jako rozhran´ı. Tu pouˇz´ıvaj´ı vˇsechny tˇr´ıdy, u kter´ ych je potˇreba udrˇzovat stav. Bezestavov´ y klient si tak uchov´av´a poslednˇe naˇcten´eho pacienta a jeho verzi. Pˇri pˇresunu z jedn´e editaˇcn´ı z´aloˇzky
42
KAPITOLA 4. POPIS IMPLEMENTACE
na druhou tak klient umoˇzn ˇuje pˇr´ımo volat naˇc´ıtac´ı metody na serveru a t´ım obej´ıt proces vyhled´av´an´ı. V pˇr´ıpadˇe, ˇze mezi t´ım nˇekdo pacienta odstran´ı, je server pˇripraven o tom klienta informovat a ten zareaguje pˇresmˇerov´an´ım uˇzivatele na vyhled´avac´ı obrazovku.
Obr´azek 4.1: Klient - Zaloˇzen´ı pacienta
Kapitola 5 Z´ avˇ er V´ ysledkem pr´ace je JEE aplikace poskytuj´ıc´ı univerz´aln´ı rozhran´ı k datab´azov´emu syst´emu pacient˚ u. Toto rozhran´ı je pops´ano jazykem WSDL, je zaloˇzen´e na webov´ ych sluˇzb´ach a platformˇe nez´avisl´em protokolu SOAP. Umoˇzn ˇuje tedy zabezpeˇcen´ y pˇr´ıstup z jak´ehokoliv m´ısta v s´ıti. Pro vol´an´ı sluˇzby je moˇzn´e pouˇz´ıt klienta, kter´ y je souˇca´st´ı t´eto pr´ace, nebo jak´ehokoliv jin´eho klienta napsan´eho v libovoln´em programovac´ım jazyce a bˇeˇz´ıc´ım na jak´ekoliv platformˇe. Zp˚ usob komunikace pˇres webov´e sluˇzby, kter´ y je zde demonstrov´an, lze tak v praxi pouˇz´ıt pro snadnou integraci jiˇz existuj´ıc´ıch syst´em˚ u beˇz´ıc´ıch t´eˇz na r˚ uzn´ ych platform´ach. Bezpeˇcnost je vˇzdy z´aleˇzitost individu´aln´ı a z´avisl´a na konkr´etn´ıch poˇzadavc´ıch. Pro uk´azkovou aplikaci je dle m´eho n´azoru pouˇzit´e sch´ema basic autentizace dostateˇcn´e. WS-Security jsem se nakonec rozhodl ponechat vypnut´e. Jedn´a se prakticky pouze o konfiguraˇcn´ı z´aleˇzitost. Na klientovi je vˇsak nutn´e pouˇz´ıt knihovny, kter´e budou odes´ılan´e zpr´avy ˇsifrovat, pˇr´ıpadnˇe podepisovat a pˇred kaˇzd´ ym vol´an´ım webov´e sluˇzby tyto knihovny pouˇz´ıt. Dal jsem pˇrednost distribuci klienta bez nativn´ıch knihoven a ponech´av´am toto jako moˇznost rozˇs´ıˇren´ı. Validaci pˇr´ıchoz´ıch zpr´av na server oproti XML sch´ema, je moˇzn´e zapnout v konfiguraˇcn´ım souboru na serveru. N´avod je uveden v uˇzivatelsk´e pˇr´ıruˇcce. Tlust´ y klient m´a v´ yhodu v tom, ˇze umoˇzn ˇuje volat pˇr´ımo vzd´alen´ y syst´em a poskytuje ˇsirok´e moˇznosti z hlediska implementace. V pˇr´ıpadˇe tenk´eho klienta bychom museli pouˇz´ıt nˇejak´eho prostˇredn´ıka. Probl´em s distribuc´ı tlust´ ych klient˚ u na koncov´e uzly je moˇzn´e ˇreˇsit technologi´ı Java Web Start, kter´a umoˇzn ˇuje pouh´ ym otevˇren´ım URL adresy st´ahnout klientskou aplikaci z centr´aln´ıho serveru na lok´aln´ı disk a v pˇr´ıpadˇe dostateˇcn´ ych pr´av, nadefinovan´ ych v souboru java.policy, spustit. Pˇri nasazen´ı nov´e verze klientsk´e aplikace staˇc´ı pouze vymˇenit“ pˇr´ısluˇsn´ y archiv na serveru. V tomto syst´emu je klient ” takto dostupn´ y pˇres koˇrenov´ y kontext /nem
http://server:port/nem 43
5.1
Testov´ an´ı
Testov´an´ı aplikace prob´ıhalo v pr˚ ubˇehu cel´eho v´ yvoje. D´ıky logov´an´ı a a odchyt´av´an´ı v´ yjimek se mi v pˇr´ıpadˇe chyby vˇzdy podaˇrilo snadno detekovat jej´ı p˚ uvod a chybu opravit. I pˇresto nem˚ uˇzu zaruˇcit, ˇze se mi podaˇrilo otestovat vˇsechny moˇzn´e kombinace vstup˚ u, kter´e mohou v aplikaci nastat. Pokude pˇresto nastane v aplikaci chyba, mˇela by b´ yt ˇr´adnˇe odchycena, zalogov´ana a zobrazena na klientovi. Klient umoˇzn ˇuje otestovat toto rozhran´ı jednoduch´ ymi sc´en´aˇri popsan´ ymi v kapitole 3.1. Pro roli l´ekaˇr jsou sc´en´aˇre uvedeny v pˇr´ıloze A. Na pˇriloˇzen´em CD je um´ıstˇen n´avod pro instalaci a uˇzivatelsk´a pˇr´ıruˇcka. Viz pˇr´ıloha B.
Literatura [1] Article - Which style of WSDL should I use? . http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl. [2] CSTUG - CS Tex Users Group - hlavn´ı str´anka . http://www.cstug.cz/. [3] Latex - online manu´al . http://www.cstug.cz/latex/lm/frames.html. [4] OASIS - Organizace ˇr´ıd´ıc´ı v´ yvoj a adaptaci otevˇren´ ych standard˚ u . http://www.oasis-open.org. [5] PostgreSQL - Triggery, Transakce . http://www.postgresql.org/. [6] RFC1876 - Form-based File Upload . http://www.faqs.org/rfcs/rfc1867.html. [7] UDDI - Universal Description Discovery and Integration . http://www.oasis-open.org/committees/uddi-spec. [8] V´ıcevrstv´e aplikace . http://www.herkules.cz/doc/rp/node6.html. [9] W3C - Organizace definuj´ıc´ı standardy internetu . http://www.w3c.org. [10] WS-Security Specification . http://www.oasis-open.org/committees/wss/index.shtml. [11] WSDL - Web Service Description Language . http://www.w3.org/TR/wsdl20. [12] XML Tutorial . http://www.w3schools.com/xml/. [13] R. R. Debu Panda, Derek Lane. EJB3 in Action. Manning Publications, 2007. [14] B. Kiszka. 1001 Tip˚ u a trik˚ u pro programov´an´ı v jazyce Java. Computer Press, 2003. [15] R. Pichlik. Tˇr´ıvrstv´a architektura v kostce I. (Pˇrevzat obr. 3.1) . http://www.sweb.cz/pichlik/archive/2004_11_07_archive.html. 45
Dodatek A Pˇ r´ıloha A - Use Case L´ ekaˇ r Sc´en´aˇre pro roli l´ekaˇr. UC05: Vyhled´ an´ı pacienta 1. Uˇzivatel stiskne tlaˇc´ıtko Vyhled´an´ı pacienta“. ” 2. Syst´em zobraz´ı formul´aˇr se vstupn´ımi pol´ıˇcky jm´eno, pˇr´ıjmen´ı, rodn´e ˇc´ıslo. 3. Uˇzivatel zad´a vstupn´ı hodnoty a stiskne tlaˇc´ıtko Vyhledat“. ” 4. Syst´em ovˇeˇr´ı, ˇze bylo vyplnˇeno alespoˇ n jedno vstupn´ı pol´ıˇcko a v pˇr´ıpadˇe rodn´eho ˇc´ısla zvaliduje na modulo 11. Pot´e bud’ zobraz´ı vyhovuj´ıc´ı z´aznamy nebo popis chyby. UC06: Zaloˇ zen´ı pacienta 1. Uˇzivatel stiskne tlaˇc´ıtko Zaloˇzen´ı pacienta“. ” 2. Syst´em zobraz´ı formul´aˇr se vstupn´ımi pol´ıˇcky jm´eno, pˇr´ıjmen´ı, rodn´e ˇc´ıslo, datum narozen´ı, adresa, telefon, zdravotn´ı pojiˇstovna, krevn´ı skupina, rh faktor a pozn´amky. Souˇc´ast´ı adresy je ulice, ˇc´ıslo popisn´e a psˇc. 3. Uˇzivatel zad´a vstupn´ı hodnoty a stiskne tlaˇc´ıtko Uloˇzit“. ” 4. Syst´em ovˇeˇr´ı, ˇze byla spr´avnˇe vyplnˇena vˇsechna povinn´a vstupn´ı pol´ıˇcka, login a rodn´e ˇc´ıslo je unik´atn´ı a rodn´e ˇc´ıslo nav´ıc dˇeliteln´e jeden´acti. Pokud ano, vloˇz´ı z´aznam o pacientovi do datab´aze. Pokud ne, zobraz´ı popis chyby. UC07: Naˇ cten´ı pacienta 1. Uˇzivatel nejprve provede UC05. 2. Uˇzivatel vybere ze seznamu poˇzadovan´ y z´aznam. 3. Syst´em zobraz´ı z´akladn´ı informace v podobˇe formul´aˇre s pˇredvyplnˇen´ ymi pol´ıˇcky jm´eno, pˇr´ıjmen´ı, rodn´e ˇc´ıslo, datum narozen´ı, adresa, telefon, zdravotn´ı pojiˇstovna, krevn´ı skupina, rh faktor, pozn´amky. Adresa je sloˇzena z ulice, ˇcp a psˇc. 47
´ UC08: Uprava z´ akladn´ıch informac´ı 1. Uˇzivatel nejprve provede UC07. 2. Uˇzivatel uprav´ı poˇzadovan´a formul´aˇrov´a pole a stiskne tlaˇc´ıtko Upravit“. ” 3. Syst´em zkontroluje, zda jsou vˇsechny upraven´e u ´daje validn´ı a uloˇz´ı upraven´e z´aznamy do datab´aze. V pˇr´ıpadˇe nevalidn´ıch z´aznam˚ u zobraz´ı popis chyby. Z´akladn´ı informace mohou b´ yt upravov´any pouze l´ekaˇrem, kter´ y pacienta zaloˇzil. Pˇri pokusu upravit ciz´ı z´aznam syst´em ozn´am´ı tuto skuteˇcnost uˇzivateli. UC10: Naˇ cten´ı zdravotn´ı pojiˇ st’ovny 1. Bˇehem UC08 nebo UC06 uˇzivatel stiskne tlaˇc´ıtko Naˇcten´ı pojiˇst’ovny“ ve for” mul´aˇri. 2. Syst´em zobraz´ı seznam zdravotn´ıch pojiˇst’oven, kter´e jsou aktu´alnˇe k dispozici. 3. Uˇzivatel vybere poˇzadovan´ y z´aznam ze seznamu. 4. Syst´em dopln´ı k´od zdravotn´ı pojiˇst’ovny do formul´aˇre. UC09: Odstranˇ en´ı pacienta 1. Uˇzivatel nejprve provede UC07. 2. Uˇzivatel stiskne tlaˇc´ıtko Odstranit“. ” 3. Syst´em zkontroluje, zda l´ekaˇr pracuje s aktu´aln´ım z´aznamem a zda jde o l´ekaˇre, kter´ y pacienta zaloˇzil. V pˇr´ıpadˇe ˇze ano, odstran´ı pacienta ze syst´emu. V opaˇcn´em pˇr´ıpadˇe zobraz´ı popis chyby. UC11: Zobrazen´ı sloˇ zky praktick´ eho l´ ekaˇ re 1. Uˇzivatel nejprve provede UC07. 2. Uˇzivatel se pˇrepne na z´aloˇzku Praktick´ y l´ekaˇr. 3. Syst´em zobraz´ı sloˇzku praktick´eho l´ekaˇre v podobˇe pˇredvyplnˇen´ ych formul´aˇrov´ ych pol´ıˇcek v´aha(povinn´a), v´ yˇska(povinn´a), detaily o povinn´em oˇckov´an´ı.V pˇr´ıpadˇe pr´azdn´e sloˇzky budou pol´ıˇcka pr´azdn´a. ´ UC12: Uprava sloˇ zky praktick´ eho l´ ekaˇ re 1. Uˇzivatel nejprve provede UC11. 2. Uˇzivatel uprav´ı poˇzadovan´a formul´aˇrov´a pole a stiskne tlaˇc´ıtko Upravit“. ” 3. Syst´em zkontroluje, zda l´ekaˇr pracuje s aktu´aln´ım z´aznamem a v pˇr´ıpadˇe, ˇze ano, uprav´ı z´aznam v datab´azi. V opaˇcn´em pˇr´ıpadˇe zobraz´ı popis chyby.
UC13: Odstranˇ en´ı sloˇ zky praktick´ eho l´ ekaˇ re 1. Uˇzivatel nejprve provede UC11. 2. Uˇzivatel stiskne tlaˇc´ıtko Odstranit“. ” 3. Syst´em zkontroluje, zda l´ekaˇr pracuje s aktu´aln´ım z´aznamem a v pˇr´ıpadˇe, ˇze ano, odstran´ı z´aznam v datab´azi. V opaˇcn´em pˇr´ıpadˇe zobraz´ı popis chyby. UC14: Vyhled´ an´ı nemoci 1. Uˇzivatel nejprve provede UC07. 2. Uˇzivatel se pˇrepne na z´aloˇzku Nemoci. 3. Syst´em zobraz´ı seznam nemoc´ı pacienta. Z´aznamy jsou dˇelen´e po jednotliv´ ych str´ank´ach. K navigaci slouˇz´ı tlaˇc´ıtka Pˇredchoz´ı“ a Dalˇs´ı“. V pˇr´ıpadˇe ˇze pa” ” cient nem´a ˇza´dn´ y z´aznam, zobraz´ı pr´azdn´ y seznam s tlaˇc´ıtkem pro zaloˇzen´ı nov´eho z´aznamu. UC15: Zaloˇ zen´ı nemoci 1. Uˇzivatel nejprve provede UC14. 2. Uˇzivatel stiskne tlaˇc´ıtko Nov´ y“. ” 3. Syst´em zobraz´ı formul´aˇr pro zad´an´ı detailu nemoci. Souˇca´st´ı formul´aˇre je n´azev diagn´ozy (povinn´e), k´od diagn´ozy (povinn´e), tlaˇc´ıtko pro dotaˇzen´ı diagn´ozy dle k´odu, datum od(povinn´e), datum do, stav(povinn´e) a pozn´amka. 4. Uˇzivatel vypln´ı pˇrisluˇsn´a pole. V pˇr´ıpadˇe k´odu diagn´ozy vep´ıˇse k´od diagn´ozy a stiskne tlaˇc´ıtko Dotaˇzen´ı diagn´ozy“. Syst´em bud’ dot´ahne n´azev diagn´ozy nebo ” zobraz´ı zpr´avu, ˇze diagn´oza s takov´ ym k´odem neexistuje. Pokud je vˇse v poˇra´dku stiskne uˇzivatel tlaˇc´ıtko Uloˇzit“ ” 5. Syst´em zkontroluje, zda jsou vyplnˇena povinn´a pole a zda jiˇz stejn´a diagn´oza nebyla stanovena. V pˇr´ıpadˇe, ˇze je vˇse v poˇra´dku, zaloˇz´ı nemoc do datab´aze. V opaˇcn´em pˇr´ıpadˇe zobraz´ı popis chyby. UC16: Naˇ cten´ı nemoci 1. Uˇzivatel nejprve provede UC14. 2. Uˇzivatel vybere poˇzadovan´ y z´aznam ze seznamu. 3. Syst´em zobraz´ı detailn´ı informace o nemoci v podobˇe formul´aˇre s pˇredvyplnˇen´ ymi pol´ıˇcky. Souˇca´st´ı formul´aˇre je n´azev diagn´ozy(povinn´e), k´od diagn´ozy (povinn´e), datum od(povinn´e), datum do, stav(povinn´e) a pozn´amka.
´ UC17: Uprava nemoci 1. Uˇzivatel nejprve provede UC16. 2. Uˇzivatel stiskne tlaˇc´ıtko Upravit“. ” 3. Syst´em zpˇr´ıstupn´ı formul´aˇrov´a pole pro editaci. 4. Uˇzivatel uprav´ı pˇrisluˇsn´a pole. V pˇr´ıpadˇe k´odu diagn´ozy vep´ıˇse k´od diagn´ozy a stiskne tlaˇc´ıtko Dotaˇzen´ı diagn´ozy“. Syst´em bud’ dot´ahne n´azev diagn´ozy nebo ” zobraz´ı zpr´avu, ˇze diagn´oza s takov´ ym k´odem neexistuje. Pokud je vˇse v poˇra´dku stiskne uˇzivatel tlaˇc´ıtko Uloˇzit“ ” 5. Syst´em zkontroluje, zda jsou vyplnˇena povinn´a pole, zda je z´aznam aktu´aln´ı a zda jiˇz stejn´a diagn´oza nebyla stanovena. V pˇr´ıpadˇe, ˇze je vˇse v poˇr´adku, uloˇz´ı upraven´e z´aznamy do datab´aze. V opaˇcn´em pˇr´ıpadˇe zobraz´ı popis chyby. UC18: Odstranˇ en´ı nemoci 1. Uˇzivatel nejprve provede UC16. 2. Uˇzivatel stiskne tlaˇc´ıtko Odstranit“. ” 3. Syst´em zkontroluje, zda je z´aznam aktu´aln´ı. V pˇr´ıpadˇe, ˇze je vˇse v poˇra´dku, odstran´ı z´aznam z datab´aze. V opaˇcn´em pˇr´ıpadˇe zobraz´ı popis chyby.
Dodatek B Pˇ r´ıloha B - Obsah CD - app postgres Instalaˇcn´ı archiv pro datab´azi PostgreSQL 8.2.4 pro platformu Microsoft Windows. Nutn´a instalace. V´ıce viz instalaˇcn´ı pˇr´ıruˇcka. nem-sis Obsahuje archiv se zabalen´ ymi podadres´aˇri client, server a bˇehov´e prostˇred´ı. Klient potˇrebuje ke sv´emu bˇehu JRE 1.6 z d˚ uvodu pouˇzit´ı knihovny SwingWorker. Nen´ı nutn´a instalace. V´ıce viz instalaˇcn´ı a uˇzivatelsk´a pˇr´ıruˇcka. sql Obsahuje zakl´adac´ı a mazac´ı skript pro datab´azi PostgreSQL.
- src client Obsahuje zdrojov´e k´ody testovac´ıho klienta. server Obsahuje zdrojov´e k´ody serverov´e ˇc´asti.
- doc instalace Instalaˇcn´ı a uˇzivatelsk´a pˇr´ıruˇcka. src Zdrojov´ y k´od bakal´aˇrsk´e pr´ace v jazyce LATEX text Text bakal´aˇrsk´e pr´ace ve form´atech pdf, dvi a ps. wsdl Popis rozhran´ı webov´e sluˇzby ve form´atu WSDL.
51
Dodatek C Pˇ r´ıloha C - Popis rozhran´ı webov´ e sluˇ zby - WSDL datoveTypy.xsd Datov´e typy spoleˇcn´e pro popis struktury l´ekaˇre a pacienta. <xs:schema targetNamespace=’http://ws.services/datoveTypy’ xmlns:tns=’http://ws.services/datoveTypy’ xmlns:xs=’http://www.w3.org/2001/XMLSchema’ version=’1.0’> <xs:element <xs:element <xs:element <xs:element