MASARYKOVA UNIVERZITA FAKULTA INFORMATIKY Diplomová práce
Webový obchodní systém s využitím SOAP Dušan Hanuš
Brno, 2008
1
Kopie zadání práce zde
2
Prohlášení Prohlašuji, že tato práce je mým původním autorským dílem, které jsem vypracoval samostatně. Všechny zdroje prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj.
Dušan Hanuš
3
Shrnutí Cílem práce je navrhnout a zrealizovat jednoduchý a univerzální obchodní systém, který využije webové služby pro přenosy objektů v něm uložených. Práce je rozčleněna přibližně na tři části. V první části popíšu co jsou webové služby a jaké jsou jejich případné alternativy. V dalším textu se podíváme na příklad již existujícího řešení eshopu využívajícího SOAP a WSDL pro distribuci popisů zboží a krátce shrnu jeho přednosti a nedostatky. Poslední část práce se věnuje analýze požadavků a návrhu nového obchodního systému. V dalším textu jsou rozebrány jednotlivé části navrhované aplikace. Na závěr jsou uvedeny některé implementační detaily z realizace aplikace.
Klíčová slova Webové služby, SOAP, WSDL, XML, univerzální e-shop, PHP
4
Obsah 1 Úvod.........................................................................................................................................7 2 Webové služby..........................................................................................................................8 2.1 Webové služby..................................................................................................................8 2.2 SOAP...............................................................................................................................8 2.3 WSDL..............................................................................................................................8 2.4 UDDI................................................................................................................................9 2.5 Alternativy webových služeb............................................................................................9 2.5.1 Java RMI..................................................................................................................9 2.5.2 CORBA....................................................................................................................9 2.5.3 XML-RPC..............................................................................................................10 2.5.4 REST......................................................................................................................10 3 Existující systémy...................................................................................................................11 3.1 TechData Data Exchange................................................................................................11 3.1.1 Autentizace.............................................................................................................11 3.1.2 Rozhraní služby......................................................................................................12 3.1.3 Typická komunikace...............................................................................................13 3.1.4 Zhodnocení služby..................................................................................................13 4 Analýza obchodního systému.................................................................................................14 4.1 Požadavky na navrhovaný systém..................................................................................14 4.2 Základní vlastnosti obchodního systému........................................................................14 4.2.1 Reprezentace položek.............................................................................................15 4.2.2 Vlastnosti zboží......................................................................................................15 4.2.3 Zboží, typy zboží....................................................................................................15 4.2.4 Objednávky, ostatní dokumenty.............................................................................16 4.2.5 Atributy..................................................................................................................16 4.2.6 Kategorie zboží.......................................................................................................17 4.3 Webové služby................................................................................................................17 4.3.1 Klient – server........................................................................................................17 4.3.2 Klient – server + klient – server..............................................................................18 4.3.3 Offline přístup........................................................................................................18 4.3.4 Online přístup.........................................................................................................18 4.3.5 Zřetězení přístupů...................................................................................................18 4.3.6 Srovnání vzdálených přístupů.................................................................................21 4.3.7 Vzdálené operace....................................................................................................23 4.3.8 Vstupní a výstupní filtry objektů............................................................................27 4.3.9 Ostatní skupinové operace......................................................................................28 4.3.10 Pohledy.................................................................................................................28 5
4.4 Autentizace vzdálených klientů .....................................................................................29 4.4.1 Vedení informací o klientech SOAP.......................................................................29 4.4.2 Sémantika atributů..................................................................................................29 4.4.3 Další nedostatky.....................................................................................................30 5 Návrh a realizace systému......................................................................................................31 5.1 Základní návrh................................................................................................................31 5.2 Použité technologie........................................................................................................31 5.2.1 PHP........................................................................................................................31 5.2.2 MySQL ..................................................................................................................32 5.2.3 Šablonovací systém Smarty....................................................................................32 5.2.4 P4A.........................................................................................................................32 5.3 Komponenty aplikace.....................................................................................................33 5.3.1 Jádro aplikace.........................................................................................................33 5.3.2 SOAP server...........................................................................................................34 5.3.3 SOAP klient............................................................................................................35 5.4 Rozhraní aplikace...........................................................................................................35 5.4.1 Uživatelské rozhraní ..............................................................................................35 5.4.2 Administrační rozhraní...........................................................................................36 5.5 Implementace aplikace...................................................................................................37 5.5.1 Implementace objektů a jejich vlastností................................................................37 5.5.2 Objekty...................................................................................................................37 5.5.3 Implementace přístupu k objektům.........................................................................38 5.5.4 Implementace WSDL.............................................................................................39 5.5.5 Implementace košíku..............................................................................................39 5.6 Zhodnocení systému.......................................................................................................40 5.6.1 Univerzálnost.........................................................................................................40 5.6.2 Rozšiřitelnost..........................................................................................................40 5.6.3 Bezpečnost.............................................................................................................41 6 Závěr......................................................................................................................................42 7 Použitá literatura.....................................................................................................................43
6
1 Úvod Internet je médium, které na rozdíl od reálného světa stále skýtá mnoho možností a prostoru pro expanzi obchodních aktivit. S elektronickým obchodem se na tomto médiu lze setkat téměř na každém kroku a s rostoucím množstvím dat v obchodech jde ruku v ruce nutnost jejich údržby. Setkat se lze jistě s mnoha přístupy, na straně velkoprodejců např. s tištěním materiálů, lépe pak vytvářením nebo generováním elektronických ceníků v tabulkových formátech apod. Na straně malo prodejce jde o opak předchozího – tedy např. opisováním z tiskovin, import z tabulkového souboru atd. Ani jedna z uvedených variant není zcela ideální, obzvláště když si uvědomíme, že další práce a zdržování mohou vyplynout i při postupování objednávek zpět směrem k dodavatelům. Při delším řetězci obchodníků se pak vše může oběma směry dosti protáhnout. Díky výpočetní technice a dostupnosti internetu ovšem můžeme k řešení tohoto problému přistoupit z velké části zcela automatizovaně. Jako zajímavý a vhodný prostředek se v prostředí internetu (ale i lokálních sítí) nabízí využití webových služeb.
7
2 Webové služby 2.1 Webové služby Anglicky Web Services, je obecně softwarový systém (nebo sada systémů) navržený pro umožnění vzájemné komunikace aplikací nebo strojů přes sít. V principu se jedná o rozhraní procedur, která tím poskytují nástroj pro jejich vzdálené volání v distribuovaném prostředí. Komunikace probíhá ve standardizované formě, zpravidla předáváním zpráv v jazyce XML a je tak zaručena vzájemná interoperabilita mezi různými komunikujícími platformami. Webové služby mohou být provozovány v součinnosti s více možnými přenosovými protokoly, lze se tak běžně setkat s přenosy přes HTTP, HTTPS ale i SMTP. Nejdůležitějšími stavebními kameny webových služeb jsou SOAP, WSDL a UDDI.
2.2 SOAP Původně jako zkratka pro Simple Object Access Protocol, dnes jen SOAP. Byl navržen v roce 1998 a jde o standard pro přenos zpráv po sítích v textovém formátu zapsaném ve strukturovaném jazyce XML. Vychází z principu vzdáleného volání procedur (RPC). Veškerá komunikace probíhá pomocí zpráv. Každá zpráva je reprezentována obálkou (Envelope) , případnými hlavičkami (Header) a tělem zprávy (Body). Díky své textové reprezentaci je vhodný mj. právě pro přenos pomocí HTTP, který nejsnáze prochází síťovými prvky jako firewally apod. Na druhou stranu je to současně z pohledu objemu dat i určitou nevýhodou.
Obr 1: Příklad požadavku SOAP, převzato z [2]
2.3 WSDL Web Services Description Language je popis rozhraní webové služby, opět pomocí jazyka XML. Definuje názvy a typy použitých parametrů a návratových hodnot, názvy funkcí, bindings a services, což jsou informace o tom, kde se služba nachází a jak může být volána. Tento popis bývá velmi často k dispozici jako soubor dostupný přes HTTP.
8
2.4 UDDI Universal Description Discovery and Integration je univerzální adresář na bázi XML, který má umožnit firemním subjektům vystavit své webové služby na internetu a k nalezení obchodních partnerů.
Obr 2: Vztah mezi SOAP, WSDL a UDDI, převzato z [3]
2.5 Alternativy webových služeb 2.5.1
Java RMI
Java Remote Method Invocation API, nebo též Java RMI, je rozhraním pro vzdálené volání metod objektů pro jazyk Java. Na rozdíl od Web Services (SOAP) sice nejsou nezávislé na programovacím jazyce, ale datová komunikace je efektivnější.
2.5.2
CORBA
Common Object Request Broker Architecture je rovněž standard pro vzdálené volání metod objektů. Pomocí jazyka IDL specifikuje vnější rozhraní objektů (obdoba WSDL). CORBA dále specifukuje tzv. mapování z IDL do mnoha konkrétních programovacích jazyků. Komunikace mezi vzdálenými stranami probíhá přes tzv. ORB (Object Request Broker), samotná data jsou přenšena v binární formě.
9
2.5.3
XML-RPC
Protokol používá značkovací jazyk XML a pro přenos HTTP. Velkou výhodou tohoto protokolu je jeho jednoduchost, definice zahrnuje pouze několik základních datových typů a příkazů. Díky tomu je i dnes hojně využíván, přestože se fakticky jedná o předchůdce SOAP.
Obr 3: Příklad požadavku XML-RPC, převzato z [6]
2.5.4
REST
Representational State Transfer nebyl zcela navržen jako náhrada nebo konkurent webových služeb, ale přesto se v jejich souvislosti velmi často uvádí. Nejde o obdobu RPC, ale spíše o popis principů. REST přiděluje zdrojům aplikace unikátní odkazy (URI) a spolu s nimi definuje jednotné typy dat a operace pro práci se nimi.
10
3 Existující systémy Na internetu je možné najít poměrně velké množství softwarových produktů určených pro obchodní sféru, které ve svých specifikacích uvádějí podporu SOAP. Bohužel jen těžce se hledá aplikace pro běžný internetový obchod, která by jednoduchým způsobem spojila e-shop a webové služby. Můžeme zmínit velké platformy jako SAP NetWeaver, MS BizTalk nebo IBM WebSphere. Všechny tyto systémy jsou ale svým rozsahem možných použití a cílovým segmentem zcela mimo rozsah námi zamýšleného projektu. Popišme si nyní vybrané referenční řešení obchodu, který umožňuje využití webových služeb.
3.1 TechData Data Exchange Reprezentativní řešení pro předávání informací o zboží a obchodních dokladech nabízí na svém webu česká pobočka americké firmy s výpočetní technikou Tech Data Corporation, Tech Data Distribution, s.r.o. Společnost provozuje online obchod, který vzhledem k tomu, že se firma zabývá jen velkoobchodním prodejem, je přístupný pouze registrovaným obchodníkům. Samotná webová aplikace není v podstatě ničím výjimečná, obchodníkovi je v ní umožněno provádět běžné operace, jako je procházení katalogu zboží, vkládání zboží do nákupního košíku, revizi a objednání obsahu košíku apod. Vzhledem k dále popisované webové službě stojí ale za zmínku i možnost objednání zboží na adresu, která není adresou registrovaného zákazníka. Pro nás podstatnou částí popisovaného systému je služba, marketingově pojmenovaná Data Exchange, která zákazníkovi firmy umožňuje většinu operací volat vzdáleně. Při správné aplikaci do zákazníkova systému tak odpadá nejen nutnost přihlašování a objednávání přes webové rozhraní ale v ideálním případě je možné většinu postupů provádět zcela automatizovaně. Služba využívá standard SOAP pro volání vzdálených procedur. Implementována je v jazyce PHP za použití knihovny NuSOAP. Ke službě jsou zároveň k dispozici i jednoduché informační stránky (generované právě knihovnou NuSOAP) a soubor WSDL kde najdeme standardizovaný popis rozhraní.
3.1.1
Autentizace
Protože se službou přenáší relativně citlivé informace, je potřeba ji zabezpečit proti zneužití. Proto je nutno se při každém přístupu ke službě autentizovat pomocí kombinace přiděleného jména a hashe hesla.
11
3.1.2
Rozhraní služby
Z popisu WSDL lze vyčíst funkce, které systém podporuje. Protože ne všechny funkce (procedury) jsou pro tuto práci relevantní, vyberu z nich část, kterou podrobněji popíšu. 3.1.2.1
Funkce getGroups, getGroupsStr
Protože veškeré zboží je pro přehlednost zatříděno do stromu kategorií a tento je nutno nějak získat, tyto funkce poskytnou jako odpověď právě seznam kategorií. Liší se pouze výstupním parametrem. Zatímco u funkce getGroups je výstupem čistý XML dokument, kde každá položka seznamu má patřičné atributy (jako název, kód nebo rodič), funkce getGroupsStr poskytne data formou textového seznamu CSV (ale samozřejmě korektně vloženého do SOAP, tj. XML odpovědi). 3.1.2.2
Funkce getProductsFlat
GetProductsFlat je klíčová funkce co se informací o produktech týče. Vstupem je omezení na výrobce a kategorii (získanou z getGroups). Výstupem je multidimensionální pole se seznamem produktů, včetně jejich parametrů (atributů). Funkce má více alternativ pro různá použití, např. getProductsStr poskytuje seznam ve formátu CSV, nebo getProductsDiffStr, která vrací přírůstek v seznamech zboží oproti předchozímu stavu, taktéž v CSV. 3.1.2.3
Funkce getOrdersList, getOrders, getInvoicesList, getInvoices
Jde o obdobné dvojice funkcí. Pomocí funkce s příponou List se dotážeme na seznam všech uložených dokumentů (objednávek, resp. faktur) a konkrétní instance (detaily) pak získáme voláním funkce getOrders resp. getInvoices se seznamem identifikátorů dokumentů jako parametr. 3.1.2.4
putOrders, putOrdersEU
Jako poslední uvádím dvě velmi důležité funkce putOrders a putOrdersEU. Tyto funkce slouží pro automatizované vytvoření objednávky ze strany obchodníka. Vstupem jsou především adresou doručení, volby objednávky (jako druh dopravy apod.) a seznam produktů (jejich identifikátorů) spolu s množstvím. Funkce putOrdersEU slouží pro vytvoření objednávky s přímou dodávkou koncovému zákazníkovi, proto se liší ještě dodatečnými informacemi na vstupu jako jsou nacionále zákazníka, fakturační adresa a u položek zboží i jejich cena, která bude uvedena na faktuře přiložené k zásilce. 3.1.2.5
Další funkce
Další funkce webové služby zahrnují dotazy na seznamy výrobců, sériových čísel, vztažených produktů apod.
12
3.1.3
Typická komunikace
Typický průběh komunikace mezi klientem a službou Data Exchange proběhne v několikd krocích V první fázi si klient pomocí funkce getGroups vyžádá stromovou strukturu všech kategorií do níž je zboží rozděleno. Následně se požádá o údaje o zboží, např. pomocí getProductsFlat. Aby nedošlo k zastarání dat u klienta, komunikace sestává z pravidelné (obvykle týdenní) akvizice aktualizovaného seznamu zboží s případnými denními aktualizacemi cen a přírůstků zboží. Toto řešení je zvoleno kvůli velkému objemu obchodovaných položek, řádově se jedná o tisíce. Při 10000 položkách pak textový CSV seznam obsahující mj. kód zboží, název, popis, název souboru s obrázkem a několik dalších číselných identifikátorů. Při průměru 400 znaků na produkt pak dostáváme přibližně 40 MB textu, což je sice poměrně malé množství, ale generování i zpracování požadavku již může vyžadovat více systémových zdrojů. Při větším počtu abonentů služby navíc může docházet k nakumulování požadavků a vytížení serverů.
3.1.4
Zhodnocení služby
Firma TechData nedodává klientskou část aplikace (jen odkazuje na produkt od firmy CyberSoft, který jejich rozhraní podporuje). Protože tím cílí na programátory, je nutné jako pozitivum brát i přehledné a jasné rozdělení jednotlivých kroků do exportovaných funkcí. Také možnost volby mezi alternativními výstupy důležitých funkcí (CSV nebo formátované XML) mohou být pro sestavení klientské aplikace velmi výhodné. Na druhou stranu ale shrňme i vlastnosti, kterých bychom se chtěli v našem systému vyhnout. Každá položka v obchodě má pevně definované atributy. To s sebou nese úskalí při změně nebo rozšíření atributů. Vezměme například v úvahu, že se ke každé položce zboží přidá seznam souvisejících položek. Změna funkce getProductsFlat a s tím i změna popisu WSDL připadá sice v úvahu, ale již je nutné počítat s tím že stávajícími klienti služby budou muset své aplikace upravit, aby mohli novou službu korektně používat. Pokud bychom novou službu nasadili namísto staré (tedy pokud bychom neponechali i straší rozhraní služby) vystavili bychom se dalším problémům, třeba pokud klient nesprávně indexuje prvky pole (např. se spoléhá na pořadí) atd. Se změnou atributů je toto samozřejmě ještě horší, lépe je tedy pro další atributy buďto zavést nové rozhraní WDSL anebo přidat samostatnou novou funkci, což je právě i případ funkce pro vrácení seznamu vztažených produktů getRelatedProductsStr. Další nevýhodou je prakticky nemožnost online přístupu ke zboží. Jedinou cestou je zaslat požadavek na kompletní (nebo částečný, např. filtrovaný podle zvolené kategorie zboží) seznam a s tím pracovat, ale takovému použití se služba aktivně brání limitováním počtu volání příslušné metody na jedenkrát denně.
13
4 Analýza obchodního systému 4.1 Požadavky na navrhovaný systém Na systém jsou kladeny následující omezení a počáteční požadavky Systém bude webovou aplikací, jeho výstupem budou data zobrazitelná v běžných webových prohlížečích. Bude nabízet alespoň základní funkce jako běžný internetový obchod.
●
Návštěvníkovi obchodu umožní zejména prohlížení katalogu rozčleněného do kategorií, vkládání položek do košíku a jejich objednání.
●
Obsluze obchodu (tedy osobě autentizované pomocí správných přístupových údajů) bude umožněno prohlížení, přidávání, úpravy a odebírání zboží a dokumentů (objednávek).
●
Nulové nebo nízké náklady na technologii Protože cena je jedním z velmi důležitých faktorů, budou zvoleny technologie, které budou volně nebo velmi levně dostupné.
●
Změna vzhledu Protože cílovým konzumentem systému je uživatel, který může měnit vzhled aplikace, ale i z důvodů oddělení prezentační a aplikační logiky, budou pro prezentační část použity oddělené soubory tzv. šablony.
●
Použití webových služeb Dalším požadavkem je aby systém umožnil přístup k datům v něm definovaných pomocí webových služeb.
●
4.2 Základní vlastnosti obchodního systému Systém, kromě toho, že bude obsluhovat běžné požadavky klientů bude zároveň SOAP serverem nebo SOAP klientem nebo obojím zároveň. Základní schéma komunikace ilustruje obrázek č. 2.
14
Obr 4: Komunikace mezi obchody Klíčovým prvkem v našem obchodu bude zboží, se kterým bude manipulováno, jeho XML reprezentace bude posílána pomocí SOAP a jeho HTML (nebo i jiná) bude prezentována ve webovém prohlížeči klienta.
4.2.1
Reprezentace položek
Na rozdíl od ukázaného řešení Data Exchange bude navrhovaný systém koncipován tak, aby umožňoval reprezentaci pokud možno libovolného obchodního artiklu se všemi jeho vlastnostmi.
4.2.2
Vlastnosti zboží
Při pohledu na většinu elektronických obchodů a jejich položky lze vypozorovat, že existují jakoby dva druhy zboží. Jedním druhem budiž to, které má čistě popisné informace a ze strany zákazníka je možné takové zboží pouze vložit do košíku. Druhým pak to, kde má zákazník možnost volby některých jeho parametrů. Příkladem může být velikost trička, barva apod. Z toho si vyvodíme, že zboží bude muset mít dva druhy vlastností. Nazvěme je souhrnně atributy, resp. parametry, budeme-li hovořit o libovolných, resp. jen o zákazníkem volitelných atributech.
4.2.3
Zboží, typy zboží
Abychom mohli snadno zboží definovat, zavedeme pojmenované skupiny atributů, které budou sloužit jako typy zboží. Na obrázku je příklad dvou typů zboží
15
Obr 5: Atributy a typy zboží Každé zboží bude jednoznačně označeno svým identifikátorem a dále typem, který určuje skupinu atributů, které má dané zboží mít. Instance zboží bude tím pádem určena identifikátorem, typem a hodnotami jednotlivých atributů. Protože typy zboží (a později i objektů) budou použity i pro rozlišení zdrojů dat (lokální, vzdálený), budeme u nich vést i tuto vlastnost, například v podobě URL odkazu na popis rozhraní WSDL vzdáleného systému, v případě určení lokálního zdroje dat pak postačí tuto vlastnost nevyplňovat.
4.2.4
Objednávky, ostatní dokumenty
Vezmeme-li si za typický příklad obchodního dokumentu, objednávku, pak usoudíme, že je také, zrovna tak jako zboží, reprezentována nějakými atributy. Proto již dále nebudeme považovat zboží a dokumenty za rozdílné objekty, ale naopak za shodné, jen používající jinou množinu atributů. Příkladem atributů může být například číslo objednávky, adresa odběratele a položky objednávky. Jediný významnější rozdíl je právě v posledně jmenovaném příkladu, v položkách. Každá položka sama o sobě je definována alespoň jedním, obvykle ale několika atributy. V jednoduchém případě to bude jméno, cena, počet kusů. Abychom mohli takovou skupinu atributů k dokumentu (nebo jinému objektu) přiřadit jako hodnotu jednoho atributu, stanovíme jednoduché pravidlo, že atribut může buď nabývat nějaké hodnoty, nebo může být odkazem na jiný, lokálně dostupný objekt (možnost skládat takto lokální a vzdálené atributy úplně vypustíme, je totiž zcela mimo rozsah našeho záměru). Tím zajistíme možnost vytvářet strom atributů. To jestli bude odkazem anebo bude hodnotou nám může říkat např. typ atributu.
4.2.5
Atributy
Základní entity ze kterých se budou skládat objekty budou právě atributy. Pro přehlednost budou definovány svým unikátním jménem, typem a dále ponesou informaci o tom, jsou-li volitelné zákazníkem či nikoliv (tedy jde-li o parametr). Při obecnějším pohledu na tuto informaci se ale stejného, nebo lepšího výsledku dá docílit pomocí přístupových práv k atributu následujícím způsobem. Bude-li mít přistupující v daném okamžiku patřičné právo pro zápis, bude atribut hrát roli parametru – jeho hodnota bude volitelná, v případě absence práva zápisu
16
bude hodnota atributu pouze pro čtení, nebude-li uživatel oprávněn ani ke čtení, atribut nebude v daném kontextu uživateli vůbec přístupný. Takto lze docílit i víceúrovňového rozčlenění přístupových úrovní, minimálně však budeme potřebovat dvě – jednu pro reprezentaci nakupujícího zákazníka, druhou pro administrátora obchodu, který by měl mít ke každému objektu a jeho hodnotám neomezený přístup. Pod dalšími úrovněmi si můžeme představit rozlišení přihlášeného a nepřihlášeného zákazníka, administraci obchodu s více úrovněmi oprávnění apod. Typem atributu budeme rozumět nějakou informaci, která nám říká, jakým způsobem se dá měnit hodnota atributu, je-li v daném kontextu parametrem. Protože prezentační vrstvou systému budou výhradně HTML stránky, odpovídá typ atributu přibližně druhu formulářového prvku HTML (select box, checkbox, textarea atd.). Protože omezení hodnot atributu pouze na základě typu nebude vždy dostatečné, měli bychom mít možnost definovat jakých hodnot může nabývat, resp. možnost kontroly vkládané hodnoty, např. oproti regulárnímu výrazu. Tím dáme možnost vytvořit atributy vhodné pro vkládání specifických hodnot, jako třeba e-mail, telefonní číslo nebo webová adresa. Samozřejmě, že regulární výraz nebude mít smysl aplikovat na každý typ atributu – např. formulář typu checkbox uživateli ani jinou hodnotu než ano / ne zadat nedovolí, takže ve skutečnosti to bude mít smysl pouze pro textové vstupy. Jelikož se může vyskytovat vlastnost objektu o které nemůžeme předem říci jestli bude u objektu zopakovaná vícekrát či nikoliv, bude definice každého atributu zahrnovat také informaci o tom, může-li se jeho hodnota vyskytovat v objektu vícekrát. Například název objektu (zboží) budeme chtít patrně jen jednou, zatímco obrázků (názvů souborů) k objektu přiřazených může být více, proto atribut s obrázkem můžeme zadefinovat jako vícenásobný.
4.2.6
Kategorie zboží
Abychom uživatelům (zákazníkům) obchodu umožnili snadnou navigaci při procházení katalogu zboží, poskytneme prostředek pro rozčlenění zboží do stromu kategorií. Stanovíme si, že každá kategorie může obsahovat jedno nebo více zboží, ale každé zboží může být i ve více kategoriích. Kategorie bude mít především svůj identifikátor a název. Dále budou odkazovat na tzv. pohled (bude popsán později), který určí jaké objekty do kategorie spadají.
4.3 Webové služby Aby bylo možné s objekty pracovat vzdáleně, je potřeba sestavit skupinu operací, které budou požadovanou činnost nad objekty skrze webové služby poskytovat. Ukažme si nejdříve možné scénáře komunikace mezi systémy.
4.3.1
Klient – server
Jde o typický případ, kdy klient požaduje objekty (zboží), které jsou uloženy v databázi serveru. Jako další činnost pak provádí například ukládání objednávek zpět na server. 17
Samozřejmě bychom mohli uvažovat i jiná užití, ale pro ilustraci stačí tyto.
4.3.2
Klient – server + klient – server
Komunikace klienta probíhá obdobně jako v prvním případě jen s tím rozdílem, že serverový systém je zároveň také klientským a data nebo část dat je mu dostupná také vzdáleně. Požadavky na vzdálené objekty tak bude překládat dál. Protože nelze zajistit, aby identifikátory všech objektů ve všech systémech byly vždy unikátní, ale lze snadno dodržet unikátnost identifikátorů v rámci jediného systému, bude podmínkou to, aby z informace o požadovaném objektu bylo možné rozpoznat, ke kterému systému je objekt příslušný – např. prefix identifikátoru apod. Pro klienta se ale nic nezmění, data stále požaduje po tomtéž systému. Protože identifikátory bude poskytovat nadřazený systém, nemusí se klient nijak o význam identifikátorů starat, pouze je použije k dotazu na konkrétní objekt. Pro poslední server se také nic nemění, roli klienta zde hraje předřazený systém. Může vzniknout i vícenásobné zřetězení. Plynoucím nedostatkem je teoretická možnost sestavit z diskutovaných systémů cyklus. K tomuto problému se vrátíme v následujícím textu. Pokud připustíme resp. nepřipustíme případnou inkonzistenci mezi skutečnými vzdálenými objekty na straně serveru a jejich lokálními reprezentacemi u klienta, můžeme pak začít hovořit i o offline resp. online přístupu klienta ke vzdáleným datům.
4.3.3
Offline přístup
V tomto případě tedy půjde především o dávkový, časově úzce lokalizovaný přenos dat, kdy se v dávce přenese kompletní požadovaný balík objektů. Důležitou veličinou tohoto přístupu bude případný interval v jakém se přenosy opakují, obzvláště ve vztahu k posouzení vhodnosti použití tohoto přístupu a k požadavkům na systémové zdroje. Protože jde o offline přenos, rychlost přenosu, nebo zpracování zpráv zde nebudou podstatné.
4.3.4
Online přístup
Jak je patrné již z označení, komunikace mezi systémy a přenos objektů bude probíhat až v momentě kdy u klienta nastane požadavek. Tento druh přístupu můžeme také označit jako Just-In-Time, JIT. Pro posouzení praktické vhodnosti této přístupové metody bude hrát roli více důležitých faktorů, resp. rychlostí. Rychlost vytvoření požadavku, rychlost síťového přenosu, rychlost zpracování požadavku (a vytvoření odpovědi) a rychlost zpracování odpovědi budou klíčové, všechny dohromady ale můžeme shrnout jako dobu odezvy vzdáleného systému.
4.3.5 4.3.5.1
Zřetězení přístupů Posloupnost offline přístupů
V tomto případě je situace poměrně jednoduchá, objekty každého jednotlivého systému jsou 18
udržovány v lokálních databázích. Protože každý další přenos bude offline, vytvoří se tedy případnou dávkou pouze další kopie, která nebude nikterak ovlivněna prvotním původem dat. Objekty budou v každém systému reprezentovány jako jeho vlastní. Podívejme se ještě na případné zacyklení takového řetězce. Pokud budeme uvažovat jednoduchý cyklus dvou systémů, které svá data pořizují jeden od druhého. Je samozřejmostí, že pokud žádný ze systémů nebude obsahovat žádné objekty, nedojde ani k žádné duplikaci, tudíž je cyklus v pořádku. V případě zavedení pokusného objektu O do jednoho ze systému, řekněme do systému A, je ale situace jiná. V dalším kroku kdy systém B požádá o objekty systém A, dojde ke korektní replikaci. Nyní oba systémy budou obsahovat kopii objektu O. Protože oba budou reprezentovány lokálně, budou mít v obou instancích přiřazeny obecně různé identifikátory. Pokud bychom tedy v dalším kroku, kdy se systém A dotáže na objekty systému B spoléhali při vylučování totožných objektů na jejich identifikátor, neuspěli bychom a došlo by ke zdvojení objektu O. V každém dalším kroku by se vytvořila další kopie téhož objektu, je proto zřejmé, že budeme muset použít jiné řešení. Jinou variantou cyklu, bude akvizice objektů z více systémů, mezi kterými jsou již data replikována. Problém je stále tentýž – rozpoznání identických objektů. Musíme si ale uvědomit, že tento problém se nemusí týkat pouze cyklů, ale i běžných zřetězení a to za předpokladu, že u lokálních kopií nebudeme udržovat původní identifikátory, díky kterým bychom duplikátní data byli schopni rozpoznat. Jako řešení problému použijeme označení objektů tak, že atribut nebo skupinu atributů objektů, označíme jako klíčové, tedy v rámci množiny lokálních objektů unikátní a identifikující daný objekt. Protože hodnoty atributů budou i po přenosu tytéž (ačkoliv ne zcela nutně, více dále), bude i při vícenásobné replikaci možné přijaté objekty ztotožnit proti lokálním kopiím a nový objekt ignorovat anebo případné rozdíly použít pro aktualizaci hodnot lokálního objektu. 4.3.5.2
Posloupnost online přístupů
Další možností zřetězení systémů bude složením online přenosů. Vzhledem k tomu, že v žádném ze systémů se nebude udržovat lokální kopie dat, bude při potřebě daného objektu nutné kontaktovat vždy nadřazený systém se žádostí o správná data. Protože ale i v tomto může být objekt dostupný pouze online z dalšího systému, přeloží jej v takovém případě dále. Pokud tímto způsobem dotaz projde opět k systému, který je již v řetězci (čekající na výsledky předchozího dotazu), aplikace opět odešle dotaz do nadřazeného systému a čeká dále na výsledky. Dojde tedy k zacyklení. Jako prevenci cyklu lze k dotazu připojit postupně všechny identifikátory systému (např. URL obchodu, WSDL specifikace nebo jiné), kterými dotaz již prošel a při shledání téhož identifikátoru v příchozím dotazu jej zamítnout. Toto řešení ale nemusí být vždy vhodné. Ne vždy totiž musí být v zájmu provozovatelů obchodu aby bylo možné identifikovat systémy kterými dotaz prošel nebo aby bylo možné určit jejich počet. Představme si třeba, že nechci aby můj dodavatel věděl kolika dalším obchodům data poskytuji, což by v tomto případě šlo docela snadno zjistit tak, že by po jistou dobu počítal kolik různých identifikátorů se nachází v dotazech, které mu do systému přicházejí. 19
Jiným řešením by mohlo být v každém ze systémů generovat identifikátory při každém dotazu náhodně a udržovat pouze seznam použitých identifikátorů, na které nebyla ještě obdržena odpověď. Navíc aby se znemožnilo i zjištění hloubky (počtu předřazených systémů), mohou být identifikátory náhodně dlouhé a mohou se řetězit. Bohužel při zcela náhodných identifikátorech se může stát, že ačkoliv s velmi malou pravděpodobností přesto vygenerujeme kombinaci, kterou má právě některý z nadřazených systémů vedenu jako identifikátor pro otevřenou (nezodpovězenou) žádost. Odhadovat s jakou pravděpodobností se to stane není příliš snadné. Do odhadu vstupuje velmi mnoho faktorů, jako třeba návštěvnosti obou systémů, které ovlivní počty nových požadavků na jedné straně resp. počty nezodpovězených dotazů na straně druhé, rychlost síťového propoje k dalším systémům nebo minimální délka identifikátoru jsou jen některé z nich. Proto nám postačí fakt, že k tomu může sice dojít, ale při „rozumné délce“ identifikátoru k tomu s dostatečně vysokou pravděpodobností nedojde. Nesmíme zapomenout i na možnost, že budeme problém cyklů kompletně ignorovat a necháme zcela na uživatelích systému aby případnému chybnému zřetězení předešli. V naší implementaci bude tento přístup použit. V dalším textu popíšeme situace, kdy dvě různé dvojice systémů použijí jiný druh přístupu k datům (offline a online). 4.3.5.3
Offline před online přístupem
Obr 6: Online přístup do offline kopie Pokud dvojice, která se v komunikačním řetězci vyskytuje jako první použije offline přístup k akvizici dat, pak následný online přístup k replikovaným objektů bude probíhat zcela běžným způsobem, aniž by se o předchozích přenosech muselo cokoliv předpokládat. Pouze se degraduje výhoda aktuálnosti dat. 4.3.5.4
Online před offline přístupem
20
Obr 7: Offline přístup (dávkový) do online kopie Dojde-li k situaci, že se v řetězci vyskytne offline přístup do obchodu, který svá data pořizuje online metodou, dojde při offline požadavku na dávkové pořízení objektů k tomu, že veškerá data, která hierarchicky nadřazený systém pořizuje online, bude muset pořídit naráz. V takovém okamžiku se prakticky minimálně znehodnotí veškeré výhody online přístupu. Nejen totiž že se data pořídí hromadně ačkoliv původní záměr (ať již z jakéhokoliv důvodu) byl data pořizovat až v okamžiku potřeby, ale budou se znovu pořizovat při každém dalším opětovném přístupu k nim. Při větším množství klientů (obchodů) kteří by data žádali offline se situace zhorší. Jako řešení by se dalo uvažovat zařazení cache paměti, která by udržovala naposledy obdržené objekty. Pokud by ale celkový objem dat (celkové množství objektů), které bychom museli naráz přenést přesáhl velikost takového bufferu, bylo by řešení prakticky nefunkční. Dalším možným východiskem by mohlo být jednoduše neumožnit takto přístupy kombinovat, tedy požadavky na data, která nejsou v systému dostupná buď vůbec nepovolovat. Zároveň tím klientům nezakazujeme přístup k objektům, které jsou v systému udržovány (ať již jako kopie objektů z jiných systémů nebo jako původní objekty). V případě použití tohoto řešení je potřeba přihlédnout také k tomu, že se tím kompletně zamezí zřetězování online přenosů. Jiným řešením může být zavedení limitů pro jednorázovou akvizici dat.
4.3.6
Srovnání vzdálených přístupů
V následující tabulce uvádím srovnání přístupových metod, jejich výhod a nevýhod při akvizici objektů.
21
Výhody
Nevýhody
Offline ● rychlé operace na straně klienta bez ● neaktuálnost dat v okamžiku použití prodlevy ● synchronizovaný dávkový přístup ● netrpí případným síťovým klientů může mít negativní dopad na výpadkem výkon serveru. ● snadné úpravy vlastností objektů ● pro malé objemy dat úspornější ● relativní nezávilost na rychlosti sítě ● snadná kombinace více zdrojů do jedné kategorie ● snadné zřetězení systémů Online ● aktuální data v okamžiku použití ● přenos pouze potřebných dat (při velkých celkových objemech) ● rozložení zátěže serveru
časová prodleva při přístupu ke zboží ● větší pravděpodobnost výpadku systému ● při malých objemech celkových dat neefektivní ● složitější řetězení systémů, delší řetězec zvětšuje možnost výpadku ●
Tabulka 1: Srovnání online a offline přístupu V tabulce vidíme, že deklaruji větší úspornost pro offline přenosy pro malé objemy dat, naopak pro větší objemy je úspornější online přístup. Zkusme si metody srovnat na ukázce konkrétního případu. Mějme v distribučním obchodě 1000 položek zboží, reprezentace každé položky v XML formátu pro přenos bude mít průměrně 500 bajtů. Obal každé přenesené zprávy pak dalších 1000B. Stanovme, že ke klientskému obchodu denně přistoupí 100 lidí, každý prohlédne 20 různých produktů. Spočítejme pouze dotazy na samotné zboží (vynecháme dotazy na seznamy zboží apod.). Pří online přístupu (nebudeme předpokládat žádnou cache) se musí postupně načíst 500 objektů. Tj. pro všechny dotazy a odpovědi celkem 500 * ( 500B + 1000B + 1000B) což je přibližně 1,2 MB. Na rozdíl od toho se offline přístup dotáže jen jednou a dostane jednu odpověď tj. 500 *(500B + 1000B) což je méně než 0,75 MB. V tomto případě je tedy vůči objemu dat výhodnější použít offline přenos. Při dvojnásobném původním množství objektů a stejném počtu přístupů jsou již ale výsledky opačné, metodou online přeneseme stále stejné množství dat (1,2 MB) na rozdíl od offline přenosu, který bude již potřebovat zhruba 1,5 MB. Je zřejmé, že jako absolutní hodnoty jsou to ve srovnání s běžnými rychlostmi internetu stále velmi malá čísla, jde pouze o modelový příklad.
22
4.3.7
Vzdálené operace
Protože jsme stanovili, že instance každého objektu bude definována svým identifikátorem, typem a výčtem hodnot jednotlivých atributů, můžeme nad skupinou těchto určujících hodnot vytvořit operace pro použití při přenosu přes SOAP. Transformace těchto vlastností do XML formátu bude zcela přímočará, jediný problém mohou způsobit „vnořené“ objekty. Proto stanovíme, že pokud některý z atributů daného objektu bude odkazem (přesněji, že typ atributu bude definovat význam jeho hodnoty jako odkaz), přeneseme jej jako jakoukoliv jinou hodnotu (kterou bude identifikátor objektu na který se odkazuje) a odkazovaný objekt vložíme do přenášených dat jako další v pořadí, pokud se již v aktuálně přenášených objektech nevyskytl. Vzhledem k tomu, že není nikde stanoven limit zanoření budeme u všech operací, které budou objekty přenášet akceptovat parametr který bude počet požadovaných zanoření upravovat, s tím, že bude stanovena implicitní hodnota tohoto argumentu. 4.3.7.1
GetObject
Jako první budeme uvažovat jednoduchou operaci, kterou nazveme getObject. Při volání z klientského systému bude mít tato funkce za úkol sestavení požadovaného objektu (na straně „serverového“ obchodu) do správného XML formátu (stromu atributů) a jeho odeslání zpět. Kromě toho, že musí být jasné o jaký konkrétní objekt jde, bylo také již bylo zmíněno, že musí být rozpoznatelné, zda-li se jedná o lokální objekt nebo ne. Proto parametrem této funkce bude jednoznačný identifikátor objektu na straně poskytovatele objektu a také identifikátor typu objektu, který bude v dotazovaném systému sloužit právě pro rozlišení lokálních a vzdálených objektů. Ještě zmiňme, že klient musí být schopen přijmout jako odpověď na tento požadavek nikoliv pouze jeden, ale i více objektů. Důvodem jsou již uvedené rekurzivně vložené objekty. Protože požadavek nemusí být oprávněný (např. nedostatečná přístupová práva ze strany žadatele) anebo objekt již nemusí být v okamžiku přístupu k dipozici (smazaný, nedostupný), bude se při takové události generovat chybová zpráva, která bude odeslána klientovi. Ve WSDL specifikaci bude tato metoda reprezentována dvojicí zpráv getObjectRequest a getObjectResponse. 4.3.7.2
GetObjects
Pro umožnění snadnější akvizice více objektů naráz vytvoříme také alternativní funkci getObjects, která bude téměř totožná s funkcí getObject jen s tím rozdílem, že místo jediné dvojice identifikátoru a typu objektu bude požadovat seznam takovýchto dvojic. Výsledkem pak bude seznam reprezentací všech požadovaných objektů, včetně případných vložených objektů. 4.3.7.3
PutObject
Komplementární funkcí k funkci getObject bude funkce putObject, která bude odesílat správně zformátovaný (XML) objekt k uložení z klientské aplikace do aplikace serverové. 23
Příkladem použití této funkce bude odeslání (uložení) objednávky do nadřazeného systému. Argumentem volání bude cílový typ objektu a objekt samotný. Při korektním uložení objektu bude klient informován návratovou hodnotou v podobě přiděleného identifikátoru. Budeme-li v tomto případě chtít uložit objekt s jiným vloženým objektem, použijeme toto volání vícekrát tak, abychom prve uložili nejvíce vnořené objekty a jejich identifikátory použili jako hodnoty pro vztažené atributy v nadřazených objektech. O případném nezdaru uložení bude klient informován serverem vygenerováním adekvátní chybové zprávy SOAPfault. Pro předchozí operace bylo řečeno, že jako jeden z argumentů požadují typ cílového objektu. Přestože klient nemusí význam tohoto typu znát protože jej obdrží spolu s identifikátorem od serveru (viz dále), musí obdržené objekty přesto nějakým způsobem použít, ať už formou textového výstupu nebo uložením do databáze. Proto bude nutné, aby se dozvěděl jak je který vzdálený typ reprezentován. 4.3.7.4
GetObjectAttributes
Každý objekt se bude i ve vzdáleném systému skládat z jednotlivých atributů, proto bude nutné aby i klient věděl jaké vlastnosti má ten který atribut mít. Pro tento účel zavedeme funkci getObjectAttributes. Operace nebude vyžadovat žádné argumenty, klient po jejím volání obdrží kompletní seznam úplných definic atributů ve volaném systému, s výjimkou výskytu chyby ve volaném systému, kdy obdrží chybovou zprávu. 4.3.7.5
GetObjectTypes
Aby byla informace o objektech ucelená, musí se klient dotázat i na definice vzdálených typů objektů. K tomu bude sloužit právě operace getObjectTypes. Její úlohou bude vzít všechny lokálně uložené typy objektů, zformátovat je do vhodného XML tvaru a odeslat klientovi. Ovšem s jednou malou výjimkou – nebude přenášet zdroj dat tohoto typu. Jedním důvodem je to, že se pro klienta zdrojem daných typů stane právě nadřazený systém (tedy klient si tuto informaci k typu sám doplní) a druhým, sekundárním důvodem je to, že nechceme, aby klient mohl z typů vyčíst zdroje nadřazeného systému. Přestože ani tato operace nebude od klienta požadovat žádné argumenty, může se stát že dotaz selže na straně serveru, proto i zde bude případnou chybu oznamovat adekvátní chybová zpráva. K funkci getObjectAttributes ani getObjectTypes nebudeme tvořit žádnou alternativu (např. putObjectTypes). Hlavně proto, že se pomocí SOAP rozhraní nebudeme snažit suplovat kompletní přístup k administraci obchodu a mimo to klientský obchod nebude mít žádný důvod vytvářet nové typy objektů u svého nadřazeného systému.
24
4.3.7.6
GetObjectGroups
Pro pořízení seznamu kategorií vytvoříme metodu getObjectGroups, ta na svém výstupu předá seznam názvů a identifikátorů všech položek ze stromové struktury kategorií. 4.3.7.7
Filtry
Abychom mohli o objekty ze vzdáleného systému požádat, potřebujeme znát jejich určující dvojice – identifikátory a typy. Potřebujeme tedy operaci, kterou bychom nadřazený systém o tyto údaje požádali. Musíme tedy nějakým jiným způsobem než pomocí takových dvojic specifikovat o jaké objekty máme jako klienti zájem. V tomto případě přijde na řadu filtr. Filtr bude definovat hodnoty nebo rozsahy hodnot atributů požadovaných objektů pomocí jednoduchého výrazu. Pro označování jednotlivých atributů v tomto výrazu použijeme název atributu, např takto: jmeno=“Novák“ Tento filtr bude jednoduše říkat, že máme zájem o objekty, které mají atribut s názvem „jmeno“ a zároveň má tento atribut hodnotu „Novák“. Protože ale může nastat i situace, kdy bychom potřebovali filtrovat objekty nikoliv podle hodnot jejich vlastních atributů, ale např. i podle hodnot atributu vnořeného objektu, zavedeme do označování atributů i tečkovou notaci, kdy název atributu nadřazeného objektu bude před tečkou vlevo (a vždy jen takový, který je svým typem definován jako odkaz) a název atributu odkazovaného (vnořeného) objektu bude za tečnou, vpravo: zakaznik.jmeno=“Novák“ Takový výraz řekne dotazovanému systému, aby vyhledal objekty, které mají atribut s názvem „zakaznik“, jehož hodnota je identifikátorem lokálního objektu (v dotazovaném systému), který má atribut s názvem „jmeno“ a hodnotou „Novák“. Aby mohly filtry správně fungovat, je nutné aby platila důležitá podmínka, která stanoví, že jména všech atributů budou v systému unikátní, abychom srovnávali vždy jen srovnatelné hodnoty. Jako možné rozšíření na tomto místě se nabízí implementace výrazů včetně logických operátorů OR a AND, nebo i možnost závorkování výrazů. Ale není to zcela nutné, což můžeme ilustrovat na příkladu použití takového filtru. Typickým případem použití filtrů bude totiž rozčlenění všeho zboží do kategorií. Každý objekt reprezentující zboží bude mít atribut, jehož hodnota bude odpovídat jedné nebo více kategoriím (v případě více hodnot téhož atributu). My pak budeme moci snadno popsat objekty v konkrétní kategorii pomocí filtru, který by mohl vypadat např. kategorie=“TV“ 25
kde „TV“ bude identifikátor dané kategorie. S pomocí filtrů jsme schopni požádat o seznam odpovídajících objektů, jenže protože nelze předem určit kolik objektů bude danému filtru vyhovovat (a tedy by přenos dat mohl trvat neúměrně dlouho), nebude serverový systém při takové žádosti odesílat zpět kompletní instance objektů, ale pouze seznam jejich určujících dvojic – identifikátorů a typů. Ale i zde samozřejmě může nastat situace, kdy objektů bude takové množství že i takový zkrácený seznam bude neúměrně dlouhý (a při online přenosu třeba přesáhne dobu po kterou webový prohlížeč, nebo jiný klientský obchod čeká na odezvu a vyprší časový limit apod.) Jako řešení tohoto problému můžeme navrhnout takové dotazování na seznam objektů, které by po serveru požadovalo pouze „výřez“ dat, systém by se tedy mohl dotazovat pouze na krátkou posloupnost objektů, podobně jako při použití klíčového slova LIMIT v jazyce SQL. Příkladem použití bude opatření pouze těch objektů, které klientský systém potřebuje pouze pro aktuální stránku se zbožím (např. pouze 10 položek). 4.3.7.8
Offline a online dotazy
Při komunikaci bude logicky po dotazu na identifikátory objektů následovat volání dotazu na konkrétní instance všech těchto objektů. Při offline režimu pak s těmito objekty může systém již libovolně manipulovat jako s lokálními objekty. Trochu odlišná bude situace při online přenosech. Představíme-li si v běžném internetovém obchodě nějakou kategorii zboží, která obsahuje mnoho položek zboží, bývá kvůli pohodlí a přehlednosti obvyklé, aby si zákazník mohl zvolit režim setřídění zobrazených položek (např. podle jména, ceny apod.) Protože ale online obchod nemá v okamžiku přístupu do takové kategorie všechny objekty k dispozici, nebo alespoň hodnoty těch atributů podle kterých by setřídění mělo proběhnout, musíme zodpovědnost za správné uspořádání delegovat na systém ve kterém tato data k dispozici jsou, tedy na serverový systém. Další komplikace nastane při zřetězení online přístupů. Filtr objektů můžeme samozřejmě naráz aplikovat pouze na jeden systém, navíc musíme v každém mezilehlém systému rozlišit zda-li a jaký nadřazený systém máme případně dále kontaktovat. Tento problém vyřešíme tak, že nadřazenému systému nebudeme požadované kategorie odesílat v rámci filtru, ale samostatně jako seznam kategorií, ve kterých probíhá vyhledávání – identifikace atributů, které definují kategorii by totiž jinak byla o dost složitější (obecně se mohou jmenovat jakkoliv) a tímto způsobem zajistíme na straně serveru možnost snadného porovnání požadavku s kategoriemi, ke kterým máme udržovánu informaci o jejich zdroji. Tím pádem budeme snadno vědět které další zdroje kontaktovat. Proto abychom mohli výsledky z více zdrojů snadno spojit dohromady ale potřebujeme ještě mechanismus pro správné setřídění. Abychom mohli přijaté seznamy z nadřazených systémů (včetně případných lokálních seznamů) setřídit, musíme k seznamům identifikačních údajů objektů přidat také hodnoty atributu dle kterého probíhá třídění, takže místo původní dvojice identifikátoru a typu bude nyní každý objekt reprezentován trojicí identifikátor, typ a hodnota. V případě, že se klient dotazuje jen na určitý výřez ze seznamu objektů, nemůžeme 26
případným nadřazeným systémům odesílat požadavek na stejný výřez, ale musíme odstranit spodní hranici výřezu. Tím zaručíme, že následně sloučený a setříděný seznam bude obsahovat i klientem požadovaný výřez. Všechny přijaté seznamy následně sloučíme, setřídíme a odešleme je klientovi, případně vezmeme jen požadovaný výřez a ten odešleme. 4.3.7.9
GetObjectList
Výše popsané shrneme do SOAP operace, kterou pojmenujeme getObjectsList. Ta bude od klientského systému jako argumenty požadovat filtr popisující požadované objekty, seznam vzdálených kategorií ve kterých výběr probíhá a název atributu, podle kterého budeme objekty třídit spolu s uvedením směru setřídění. Dále pak případný rozsah výběru objektů a také booleovský parametr určující jestli požadujeme také seznam hodnot atributu podle kterého třídíme. Výstupem funkce bude seznam identifikátorů, typů a volitelně i hodnot atributů objektů, které odpovídají podmínkám daným filtrem.
4.3.8
Vstupní a výstupní filtry objektů
Pomocí nadefinovaných operací pro přenos objektů již dokážeme zajistit jejich základní přenos mezi lokálním a vzdáleným systémem, ale podíváme-li se na přenos z obchodního kontextu, chybí nám jedna velmi podstatná věc. Dodává-li totiž nějaký obchodník zboží jinému obchodníkovi, který jej dále přeprodává, je to v naprosté většině případů motivováno finančním ziskem obou partnerů, proto je běžné, že každý další prodej téže věci se v tomto řetězci uskutečňuje za stále vyšší cenu až do okamžiku finálního prodeje koncovému zákazníkovi. A protože v námi navrhovaném systému si takto obchodníci budou vyměňovat informace o tomto zboží, musíme nějakým způsobem zajistit, aby si obchodník mohl změnit ceny u zboží, nebo obecněji aby mohl měnit veškeré hodnoty, které instance objektů reprezentují. Za samozřejmou budeme považovat možnost změny hodnot atributů lokálně uložených objektů přes administrační rozhraní systému, ale to bohužel není zcela dostatečné. Částečně to může být vyhovující pouze v případě, kdy nebudeme používat online přístup do nadřazeného systému, což je ale vlastně pouze obdoba dávkového importu, takže dále již jde vše naprosto stejně jako s úpravami lokálních objektů. Bohužel ale, pokud se replikační dávka provede znovu nejspíše o úpravy přijdeme (pokud nezměníme i identifikátor objektu, ale v tom případě zase přijdeme o možnost aktualizace hodnot, které neupravujeme). Při online přístupu k objektům je změna hodnot běžným způsobem zcela nemožná. Proto zavedeme tzv. vstupní a výstupní modifikátory objektů. Výstupním filtrem budeme rozumět sadu pravidel, která se bude aplikovat na každý ze systému odchozí objekt. Obráceně pak za vstupním filtrem můžeme vidět sadu pravidel, která bude ovlivňovat všechny příchozí objekty. Nebude přitom ale záležet zda-li objekt přijímáme jako klient v rámci návratové hodnoty některé z funkcí, anebo jde o objekt, který jako serverový systém obdržíme v rámci volání požadavku na vytvoření (uložení) nového objektu z klientského systému. 27
Všechna tato pravidla budou mít za úkol požadovaným způsobem změnit hodnoty jednotlivých atributů. Protože nemůžeme zaručit, že všechny přenášené objekty budou pouze jednoho typu a není patrně možné vytvořit jeden univerzální filtr pro všechny typy objektů, stanovíme, že každý vstupní nebo výstupní filtr se na objekt aplikuje pouze v případě, že typ objektu odpovídá typu specifikovaném v daném filtru. Tím můžeme dosáhnout např. zvýšení ceny u objektů jednoho druhu zboží, zatímco u jiného druhu zboží kromě zvýšení ceny také navýšíme údaj o délce záruky (právě za předpokladu, že tyto druhy zboží jsou objekty různých typů).
4.3.9
Ostatní skupinové operace
Abychom mohli v klientském systému správně zobrazit např. počet stránek se zbožím, potřebujeme zjistit, kolik zboží našemu dotazu odpovídá, nebo kolik je sumárně položek skladem. K tomuto účelu zavedeme operaci getGroupResult. Jejími parametry budou, podobné jako u funkce getObjectList, filtr popisující požadované objekty, seznam vzdálených kategorií ve kterých výběr probíhá a navíc také název atributu a název funkce. Název funkce bude retězec určující jakou operaci si přejeme s hodnotami uvedeného atributu vykonat. Jako skupinové funkce zavedeme mj. „SUM“ pro součet daného atributu, „COUNT“ pro počet položek, „MIN“ a „MAX“ pro extrémy. Je možné samozřejmě implementovat i další operace. Návratovou hodnotou funkce getGroupResult bude pouze výsledek požadované operace.
4.3.10
Pohledy
Protože ne všechny objekty, které budou k dispozici na serverovém systému budou pro klienta relevantní, nebo bude dokonce přímo nežádoucí, aby některé z nich byly dostupné pro každý klientský systém, musíme zavést nějaký aparát abychom mohli rozlišit jaké objekty budeme kterému klientovi chtít zpřístupnit. Například objednávky uložené klientem A budou dostupné pouze jemu a nadřazenému systému, nikoliv již však klientovi B. Naopak objekty popisující katalogové informace o zboží budou nejspíše dostupné klientovi A i B. Zavedeme proto systém ne nepodobný filtrům, respektive zavedeme pojmenované struktury které budou definovat filtry a typy objektů pro který se filtr aplikuje (abychom při implementaci nemuseli vždy prohledávat kompletní množinu lokálně uložených objektů). Tyto struktury pojmenujeme pohledy (které tím pádem budou velmi podobné pohledům známým z SQL databází. Pohledy budou použity jako zdroje dat pro jednotlivé pohledy kategorií. Takto definované pohledy samy o sobě neponesou informaci o tom, kterému klientu bude k pohledu umožněn přístup a kterému nikoliv. Tato informace bude vedena u jiné struktury, která bude mít na starost udržovat i jiné informace o všech klientech webových služeb, kterou zmíníme později.
28
4.4 Autentizace vzdálených klientů Abychom mohli rozlišovat mezi klienty a abychom zamezili neoprávněným přístupům, bude se každý klient přistupující ke zdrojům vzdáleného systému muset při každém přístupu autentizovat. Zajistit to můžeme v principu dvěma způsoby. V prvém případě může autentizační informaci klient odesílat v každé odeslané SOAP zprávě, tedy pomocí standardních mechanizmů webových služeb (rozšíření WS-Security). Druhým řešením bude autentizovat klienta nikoliv v jednotlivých SOAP zprávách, ale již při samotné komunikaci přes HTTP protokol pomocí standardních nástrojů, které tento protokol nabízí – např. HTTP Basic Authentication. Šifrování přenášených dat se v tomto projektu nebudeme zabývat, omezíme se na konstatování, že je lze řešit také na úrovni SOAP zpráv (kde je poté možno šifrovat jen část zprávy), anebo můžeme šifrovat již na úrovni přenosového protokolu, např. použitím SSL (HTTPS).
4.4.1
Vedení informací o klientech SOAP
Abychom mohli jakoukoliv autentizaci klienta provést (rozumějme klienta, který bude využívat přenosu objektů přes SOAP, nikoliv zákazníka obchodu), musíme mít v systému k dipozici potřebné údaje. Těmito údaji budeme mít na mysli především jméno a heslo, případně jméno a otisk hesla. Výhodné by mohlo být i uložení dalších údajů, jako adresa, fakturační konstanty apod. Tato data musíme samozřejmě udržovat v nějaké struktuře, kterou bychom mohli definovat. V navrhovaném systému se nám ale nabízí docela jiná, výrazně jednodušší možnost. Protože jsme si původně strukturu zboží zobecnili na objekty s libovolnými atributy, můžeme to s výhodou použít i pro reprezentaci klientů našeho systému. V našem návrhu tedy nemusíme vymýšlet žádnou novou strukturu, jediné co budeme muset udělat je ve finální implementaci systému nadefinovat nový typ objektů (pojmenovaný např. KlientiSOAP), který bude sdružovat atributy, které si přejeme pro každého klienta udržovat (včetně autorizačních údajů) a jednotlivé klienty pak vytvoříme jako instance objektů tohoto typu. Výhoda tohoto řešení spočívá v tom, že můžeme jednak využít systém pravomocí pro správu objektů a také můžeme v případě potřeby informace o klientech také přenášet do vzdálených systémů.
4.4.2
Sémantika atributů
Tento návrh obchodního systému, který bude mimo jiné na veškeré zboží nahlížet jako na obecné objekty a jejich atributy s sebou nese jistou komplikaci. Tou bude nedefinovaná sémantika atributů objektů. Za příklad nám poslouží třeba scénář, kdy uživatel zvolí vložení vybraného zboží do nákupního košíku. Očekávaná odezva je zobrazení nákupního košíku, kde je zobrazen řekněme název zboží a jeho cena. V případě více kusů, nebo více různých položek pak ještě i celková cena. Jenomže právě tyto součty je již pro takto navržený systém velmi obtížné realizovat – význam jednotlivých atributů není nikde definován a tak z hlediska aplikace není rozdíl mezi názvem, cenou nebo skladovým číslem dané položky. Přestože jsme tím 29
docílili jisté univerzálnosti, je to také zároveň nedostatek celého systému. Jakým způsobem můžeme problém částečně vyřešit popíšeme v následujícím textu. 4.4.2.1
Bez řešení
I přesto, že bychom problém ignorovali bychom mohli sestavit relativně funkční obchod. Protože výstup obchodu bude formátován pomocí html šablon, mohli bychom v šablonách zkrátka definovat na kterém místě zobrazíme jaký atribut, čímž mu vlastně pro uživatele v kontextu grafického výstupu přiřadíme jistý význam. V případě prohlížení zboží by o problém nešlo, bohužel v případě nákupního košíku by nám stále chyběl nástroj pro sčítání položek, výpočtu DPH, nebo i složitějších operací. 4.4.2.2
Dynamické šablony
Velmi výhodně se pro náš problém jeví použití dynamických šablon, tedy takových, které nejsou prostým HTML (anebo i XML či jiným) souborem s vyznačením místa pro danou proměnnou, ale jsou jakýmsi skriptem, kterému předáme potřebná data s tím, že v šabloně můžeme nadefinovat jednoduché operace pro případné úpravy těchto dat. Dá se říct, že tím porušíme požadavek na oddělení aplikační a prezentační části, ale v místě šablon dojde nejčastěji pouze k jednoduchým, většinou spíše jen formátovacím úpravám dat. Přesto se ale může stát, že na některém místě v šabloně bude nutné provést nějakou operaci, která mění stav aplikace. Je to bohužel právě důsledek faktu, že prvním místem, kde je konkrétní atribut zpracován dle svého významu jsou právě šablony. Protože použijeme šablonovací systém, veškeré další otázky použitého formátu výstupu (HTML, XHTML, XML) již budou záležet pouze na šablonách a díky tomu bude vzhled aplikace a výstupu jednotlivých objektů velmi snadno přizpůsobitelný.
4.4.3
Další nedostatky
Protože celý systém založíme na přenosu textových XML zpráv, nebude přenos datově zcela efektivní, ale to by nemělo být za současných rychlostí sítí velkým problémem. Dalším omezením systému je nemožnost přiřadit atributům zcela libovolné hodnoty, vždy musí jít pouze o předdefinované typy, které byly předem navrženy.
30
5 Návrh a realizace systému 5.1 Základní návrh Pro lepší pochopení funkce systému a o představě jakým způsobem bude komunikovat s okolím navrhneme základní schéma systému. Výsledek návrhu je na následujícím obrázku.
Obr 8: Základní schéma systému . Ze schématu je patrné, že jsme systém rozčlenili na tři základní bloky. Těmito jsou jádro systému, SOAP server a SOAP klient. Abychom se mohli detailněji podívat na řešení jednotlivých modulů, nejdříve stanovíme technologie, které v rámci systému použijeme.
5.2 Použité technologie Protože jedním z prvotních předpokladů na systém je použití minimálních nebo ideálně žádných prostředků na použité technologie, byly zvoleny jedny z nejčastěji používaných open source aplikací pro programování a běh výsledné aplikace. Celý projekt byl vytvořen pro operační systém Linux za použití webového serveru Apache a skriptovacího jazyka PHP. Jako databázový server posloužila aplikace MySQL. Bylo použito i dalších řešení, která popíšu dále.
5.2.1
PHP
PHP (původně Personal Home Page, posléze PHP: Hypertext Preprocessor) je skriptovací jazyk určený pro psaní dynamických webových stránek, kdy se skripty vykonávají na straně
31
serveru. Jazyk je ale možné použít i pro jiné účely, např. pro programování aplikací určených pro desktopové prostředí (za pomocí PHP-GTK) nebo i pro konzolové skripty. Výhodou jazyka PHP je jeho použitelnost rámci různých platforem, bez větších problémů je možné tytéž skripty provozovat jak v operačních systémech na bázi UNIX tak i v systémech Windows. Tento skriptovací jazyk byl zvolen také pro svou velmi dobrou použitelnost pro psaní webových aplikací, podporu objektového programování a dostupnost SOAP rozšíření. V předešlých verzích interpreteru se pro tento účel používala knihovna NuSOAP, v novějších je podpora SOAP již původní součástí (ačkoliv lze stále použít i knihovnu NuSOAP). Protože ve verzi PHP 5 se objektově orientované programování mírně liší od předchozích verzí několika vylepšeními, bude se práce opírat právě o tuto verzi.
5.2.2
MySQL
Jako datové úložiště použijeme velmi oblíbený a zdarma dostupný open-source SQL server od švédského výrobce MySQL AB. Pro volbu MySQL hovořila mimo ceny i jeho rozsáhlá dokumentace a velmi snadná instalace pro většinu operačních systémů, nehledě na to, že MySQL spolu s PHP a Apache jsou asi nejpoužívanější kombinací databázového stroje, skriptovacího jazyka a webového serveru. Je to díky tomu také velmi solidně prověřená platforma pro vývoj webových aplikací. V posledních verzích již MySQL podporuje také vložené funkce, vložené procedury a triggery. Ačkoliv byl ale zvolen jeden konkrétní SQL server, transformace dotazů tak, aby celý systém mohl běžet ve spolupráci s jiným databázovým strojem na bázi SQL by měla být v zásadě pouze kosmetickou úpravou.
5.2.3
Šablonovací systém Smarty
Jde o velmi komplexní open-source šablonovací systém vytvořený kompletně v jazyce PHP, na svém vlastním webu se označuje dokonce za framework. Poskytuje velmi rozsáhlé funkce, umí cachovat výsledky, dovolí definovat vlastní funkce, přidávat pluginy apod. Důležitý je pro nás také fakt, že můžeme celou aplikaci oddělit od šablon aniž bychom nějak výrazně omezili prostředky pro manipulaci s výstupem ze systému. Díky tomu pak můžeme umožnit úpravy šablon i osobám, které jinak nesmějí mít přístup k samotné aplikaci.
5.2.4
P4A
P4A, nebo také PHP For Applications je objektově orientovaným frameworkem pro PHP. Jako jedny z nejdůležitějších specifik tohoto systému můžeme považovat stavovost a událostmi řízené programování. Koncept celého systému je postaven na bázi návrhového vzoru MVC (Model-View-Controller). Hlavním úkolem tohoto návrhového vzoru je rozdělení aplikační a prezentační logiky na tři relativně nezávislé celky s důrazem na to, aby při změně jednoho z nich nebyly nutné změny
32
i u ostatních dvou. View je část aplikace, která je zodpovědná za prezentaci dat obdržených z modelu uživateli. Reprezentuje tedy výstup aplikace. Celek view má obecně volný přístup do modelu, ale za běžných okolností by neměl měnit jeho stav. V rámci P4A je celek view tvořen šablonovacím systémem. Controller je ta vrstva aplikace, která se stará o vyřizování vstupů od uživatele a jejich aplikaci na model nebo view. Obvykle je zodpovědná za volání těch metod z modelu, které mění jeho stav. P4A implementuje model jako unikátní instanci třídy aplikace, která zpracovává přijaté HTTP vstupy a také rozhoduje o předávání řízení jiným třídám, které reprezentují dílčí části aplikace, což jsou jednotlivé funkční celky odpovídající různým případům užití. Konečně model je celek reprezentující funkční a datové jádro samotné aplikace. Toto jádro se někdy též nazývá Business Logic nebo též Domain Logic. Ve frameworku P4A rozumíme modelem v podstatě všechny ostatní třídy které vstupují do aplikace svým stavem a metodami. Obvykle to jsou právě samostatné třídy odpovídající různým případům užití aplikace. Implementace obchodního systému nebude využívat zcela kompletní P4A, ale pouze některé jeho části. Primárním důvodem bylo propojení části vlastního (obdobného systému) a frameworku P4A a také propojení s jiným zvoleným šablonovacím systémem, se Smarty. Přestože budeme používat tento derivát, základní vlastnosti frameworku zůstanou v aplikaci zachovány.
5.3 Komponenty aplikace Jak jsme již v základním návrhu zmínili, aplikace se bude skládat z několika samostatných komponent, které budou mít každý svoji specifickou funkci.
5.3.1
Jádro aplikace
Přestože v základním návrhu tvoří jádro jeden celek, bude se samo skládat z několika funkčních částí. Z logického pohledu můžeme aplikaci rozdělit na administrační část a na část uživatelskou. Protože jde v podstatě nezávislé celky, mohly by se obě části implementovat jako dvě samostatné aplikace. V našem systému je ale spojíme do jednoho celku, protože obě části budou stavět na shodných principech, které nyní popíšeme. Základní část aplikace přebere z frameworku P4A jeho architektonický vzor Model-ViewController a tak se její jednotlivé části budou odvíjet od tohoto faktu. Základní komponentou aplikace bude třída Application, která se bude starat o zpracování příchozích HTTP požadavků. Zejména bude přiřazovat hodnoty z formulářových polí (a ostatní data předaná skriptu metodou POST nebo GET) odpovídajícím strukturám a stanovíme, že bude
33
zodpovědná za předání řízení jednotlivý funkčním celkům na základě proměnné předané v URL požadavku (GET). Pro každý funkční celek vytvoříme samostatnou třídu která bude zodpovědná za jeho aktuální stav a bude poskytovat metody pro jeho transformaci. Uveďme nyní konkrétní případ. Pokud aplikaci nepředáme žádné parametry v URL, hlavní třída rozhodne, že je o náhled na katalog zboží a řízení předá třídě Katalog. Ale pokud uživatel odešle odkaz s parametrem tvaru „strana=detail&id=343“ řídící třída rozhodne o předání řízení třídě Detail, která pak bude sama zodpovědná, za obstarání případných dalších potřebných dat potřebných pro správné sestavení výsledků, použije tedy další předaný parametr (ID) pro určení objektu k zobrazení. Pro každé použití aplikace vytvoříme odpovídající model v podobě jedné třídy. Za zobrazení výsledků ale nebudou odpovědny přímo jednotlivé třídy, ty budou pouze určovat co chtějí zobrazit. Samotné zobrazení bude záležitostí dynamického šablonovacího systému Smarty. Abychom ale byli schopni určit jaká šablona má být v jakém okamžiku použita, bude součástí informací, které budou jednotlivé třídy definovat i informace o šabloně. Šablony od aplikace vždy obdrží relevantní data pro utvoření požadovaného výstupu. Například pro šablonu detailu zboží dostane šablona hodnoty jednotlivých atributů objektů. Takto předané informace ale nemusí být vždy jediné, které šablona potřebuje. Řekněme, že na stránce budeme mimo zboží chtít zobrazit také informace o stavu nákupního košíku. Musíme tedy šabloně umožnit i přístup ke všem ostatním informacím, které v systému udržujeme (jinými slovy vrstvě View zpřístupníme vrstvu Model). Protože Smarty používá pro definici šablon odlišný jazyk od PHP, ale umožňuje nám poměrně snadno definovat nové funkce pomocí zásuvných modulů. Toho využijeme a vytvoříme několik funkcí, které nám v šablonách zpřístupní jinak nedostupné informace z aplikace (modelu). Jmenujme např. funkci getPage, která nám zpřístupní informace o právě použitém pohledu. Dalším příkladem může být funkce showModule, která zajistí zavolání metody pro renderování výstupu (a předání k zobrazení do šablony) některého z vizuálních komponent systému (např. zobrazení katalogového menu).
5.3.2
SOAP server
Dalším stavebním komponentem systému bude modul obsluhující požadavky přicházející přes rozhraní SOAP (přes protokol HTTP). Nadefinujeme takovou třídu, která bude implementovat všechny metody definované ve WSDL popisu a tuto třídu použijeme pro svázání se SOAP serverem z rozšíření v PHP. V případě funkcí getObject a getObjects resp. putObject bude metoda vždy zodpovědná za zavolání příslušného výstupního resp. vstupního filtru. Filtry mohou být definovány jako seznam objektů v rámci administračního rozhraní. Odtud pro každý typ objektu jednoduchým dotazem vyčteme název souboru se samotným filtrem. Tím bude vždy jednoduchý PHP skript s funkcí, která požadovaným způsobem modifikuje předložený seznam atributů a hodnot. Pro přístup k lokálním objektům bude SOAP server využívat lokálních metod popisovaných dále. Vzdálené objekty (tedy ty, které jsou dostupné jen online), které bude klient v rámci svého 34
volání požadovat rozpoznáme podle zmiňované dvojice identifikátoru a typu objektu, které volající systém předloží. Z definice typu objektu zjistíme příslušný zdroj dat (pro vzdálený systém tedy odkaz na WSDL) a původní typ. Tyto hodnoty pak použijeme při volání metody další komponenty systému, SOAP klienta.
5.3.3
SOAP klient
Požadavky tohoto komponentu budou přicházet od zbylých dvou modulů – z jádra aplikace a ze SOAP serveru. SOAP klient bude pro každou různou adresu zdroje (WSDL) udržovat jen jednu instanci PHP třídy SoapClient, která bude obsluhovat veškeré funkce který jí budou z popisu WSDL dostupné.
5.4 Rozhraní aplikace 5.4.1
Uživatelské rozhraní
Ve velké části pohledů na aplikaci budou hrát primární roli objekty, resp. nějaký objekt který bude na daném pohledu nějakým způsobem prezentován. Vezměme za příklad zobrazení detailu zboží – objektem je zboží, zobrazení košíku – objektem je nákupní košík) ale také stránka, kde zákazník vyplňuje třeba fakturační údaje. V takovém případě bude objekt obsahovat fakturační údaje, a může být následně po objednání použit jako vložený objekt do objektu tvořícího samotnou objednávku. Ačkoliv by se mohlo zdát, že zde je rozdíl v tom, jestli objekt pouze zobrazujeme nebo nabízíme k úpravám, není to tak. U jednotlivých atributů objektů jsme si určitým způsobem definovali práva pro zápis a čtení a ta se právě zde při výstupu objektu do prohlížeče zohlední. Na všechny objekty tak může být v zásadě nahlíženo zcela stejně. Abychom se vyhnuli duplicitám při vytváření pohledů a jejich obsluhujících tříd, vytvoříme pouze jednu třídu, která bude všechny obdobné pohledy obsluhovat. Protože s každým pohledem potřebujeme vědět jaká šablona, případně jaké jiné doplňující informace odpovídají jakému pohledu, měli bychom zavést novou strukturu (tabulku), která by tyto informace nesla. Totéž můžeme ale uskutečnit pomocí námi definovaných objektů – v obchodě vytvoříme nový typ objektů s námi požadovanými atributy, především ale s unikátním názvem stránky (která bude porovnána s hodnotou v URL) a názvem adekvátní šablony. Tím umožníme administrátorovi libovolné vytváření nových pohledů aniž bychom přitom museli měnit kód aplikace. Tento princip se uplatní například v košíku. Jiné pohledy, které budou vyžadovat složitější aplikační logiku budou muset být vytvořeny běžným způsobem, tedy vytvořením třídy, která bude zodpovědná za správnou funkci pohledu. Příkladem bude zobrazení seznamu objektů, který bude pro uživatele reprezentovat katalog zboží.
35
5.4.2
Administrační rozhraní
Tato část systému bude tvořena zcela identicky jako uživatelské rozhraní. Každý možný pohled (odpovídající nějaké činnosti) bude mít v rámci modelu definovánu svou samostatnou řídící třídu. Protože činnosti, které budou v rámci administrace prováděny nesmí být dostupné běžným uživatelům, bude pro přístup do této části systému vyžadováno jméno a odpovídající heslo. V rámci našeho systému dovolíme přístup více administrátorům, ale nebudeme již mezi nimi žádným způsobem rozlišovat, každý administrátor bude mít veškerá možná oprávnění. Uveďme nyní jaké primární činnosti bude mít administrátor v rozhraní k dispozici: ●
správa oprávněných uživatelů (administrátorů)
●
tvorba a úpravy definic atributů objektů
●
tvorba a úpravy definic typů objektů
●
tvorba a úpravy pohledů
●
úpravy stromového menu (pro účely katalogu objektů – zboží), včetně přiřazování
pohledů k jednotlivým položkám ●
správa WSDL zdrojů
●
tvorba a úpravy objektů podle definovaných typů
V předchozích odstavcích jsme se ale bavili také o tom, že v rámci systému budeme chtít vést některé další seznamy. Jejich správu zajistíme sekundárním způsobem, tedy pomocí předchozích operací které bude mít administrátor k ruce. Půjde zejména o následující: ¨ ●
Správa účtů klientů pro použití v rámci SOAP (autentizace)
●
Správa vstupních a výstupních filtrů SOAP
●
Správa jednoduchých pohledů
●
Správa jiných seznamů
Pod jiným seznamem si můžeme představit například seznam výrobců zboží, seznam různých stavů objednávek apod.
36
5.5 Implementace aplikace 5.5.1
Implementace objektů a jejich vlastností
5.5.2
Objekty
Fyzicky uložené objekty budou v databázi reprezentovány tabulkou „objects“, která o nich povede následující údaje Id
Typ_id
Vytvořeno
Je viditelný?
1
1
2007-5-25
True
2
1
2007-12-1
False
Tabulka 2: Instance objektů Z tabulky vidíme, že o objektu nebudeme udržovat ani informaci jako např. jméno objektu, jedinými důležitými údaji bude identifikátor (Id) a odkaz na identifikátor typu (Typ_id). Informace o času vytvoření je v podstatě pouze sekundární informaci, která bude sloužit jen pro přehlednější setřídění posledních objektů. Údaj o viditelnosti nám zajistí abychom mohli mít uloženy rozpracované objekty, které nebudou jiným subjektům než administrátorům obchodu viditelné. 5.5.2.1
Typy objektů
Navrhli jsme, že údaj o typu objektů budou popisovat jaké skupiny atributů budou s daným objektem svázány. U typů objektů budeme udržovat informace o jméně, zdroji dat a protože více typů bude moci referovat na stejné atributy, bude každý typ svázán s atributy pomocí vazební tabulky. 5.5.2.2
Atributy
Definice atributů (nikoliv jejich instancí) bude následovat návrh, zmiňme podstatné informace, které tabulka o každém atributu ponese – unikátní jméno, typ (tedy jde-li o text nebo roletkové menu), dále informace o tom, zda-li je atribut odkazem, může-li mít více hodnot nebo číselná informace o potřebných přístupových právech pro zápis a čtení atributu. 5.5.2.3
Instance atributů
Protože instance každého objektu bude definována i hodnotami svých atributů, kterých bude předem neznámý počet, musíme je vést uloženy v samostatné databázové tabulce.
37
Id
Attribute_id
Object_id
Value
1
10
1
Lednička Plus
2
11
1
ETA
Tabulka 3: Instance atributů Tabulka č. 3 nám říká, že každá instance atributu referuje pomocí cizích klíčů na definici atributu (Attribute_id) a na objekt, ke kterému je hodnota přiřazena (Object_id). Příklad z tabulky bychom mohli interpretovat jako hodnoty dvou různých atributů téhož objektu, třeba jako jména výrobku a jména výrobce.
5.5.3
Implementace přístupu k objektům
Abychom si v celé aplikaci usnadnili přístup k objektům, vytvoříme obalovou třídu, která nám určitým způsobem skryje podrobnosti o tom, jak a dokonce i kde je objekt uložen. Tato třída pak bude fyzicky uložený, ale i nově tvořený objekt reprezentovat svou strukturou v paměti a poskytne nám několik užitečných metod pro modifikace hodnot. Třídu nazveme virtualObject, jelikož veškerá manipulace s hodnotami jejich atributů bude probíhat pouze v rámci paměti, dokud nedojde k volání metody, která bude mít z úkol data z paměti uložit do databáze anebo odeslat ke zpracování vzdálenému systému. Ukažme si zkrácený zápis třídy s některými vybranými metodami. class virtualObject { function setObjectType( $type ); function setObjectId( $id ); function setForeignId( $foreignId, $typeId, $wsdl ) { function setAttributeValue ( $attribute, $value ); function getAttributeValue ( $attribute, $value ); function getPathValue($path, $fetchMissing=true); function saveObject (); function sendObject ( $wsdl ); ... } Metoda setObjectType slouží k nastavení typu objektu, který bude instance třídy představovat. Voláním této metody si objekt mj. připraví seznam atributů daného typu a nastaví iniciální hodnoty. Metody setObjectId a setForeignId mají obdobnou funkci, slouží pro načtení hodnot atributů objektu identifikovaného zadanými parametry z lokální databáze resp. ze vzdáleného systému. Samotný požadavek na vzdálený objekt vyřizuje zmiňovaný modul aplikace označený jako „SOAP klient“. 38
SetAttributeValue a getAttributeValue jsou příkladem metod pro manipulaci s hodnotami atributů. Obdobná je i metoda getPathValue – ta může rekurzivně načíst hodnoty atributů i z vnořených objektů dle zadané cesty (např. „adresa.ulice“). Pro finální uložení objektu slouží dvojice funkcí saveObject resp. sendObject, které objekt buďto uloží v lokální databázi resp. odešlou k uložení do vzdáleného systému určeného parametrem. V případě vzdáleného volání je opět použito komponenty „SOAP klient“, která požadavek zpracuje. V případě metody getPathValue jsme zmínili rekurzivní načítání hodnot atributů. Samozřejmě bychom nechtěli aby si každá instance virtuálního objektu vytvořila nové instance vnořených objektů především v případě, že tentýž objekt je odkazován z více objektů – např. informace o jediném výrobci. Proto vytvoříme také třídu reprezentující všechny objekty v paměti, která bude definována dle návrhového vzoru singleton. Tato třída bude existovat pouze v jediné instanci a pomocí jejích metod budeme vytvářet instance virtuálních objektů, abychom se vyhnuli zbytečným duplicitním kopiím v paměti.
5.5.4
Implementace WSDL
Při implementaci WSDL jsem vycházel z návrhu jednotlivých operací. Protože použitá extenze PHP nepodporuje automatizované vytvoření WSDL dokumentu, musel jsem tento dokument vytvořit jiným způsobem. Protože v něm popisované struktury jsou ale poměrně komplexní a při ručním zápisu by velmi snadno došlo k chybě musel jsem použít externí nástroj. Jako vyhovující se ukázalo vývojové prostředí Eclipse, které umožňuje WSDL dokument včetně typů a všech metod velmi snadno nadefinovat. Ještě zmiňme, že aplikace nijak do WSDL souboru nezasahuje, proto je při přesunu aplikace na jinou adresu potřeba soubor mírně upravit
5.5.5
Implementace košíku
Košík bude vytvořen sekundárním způsobem, tedy jako objekt v seznamu jednoduchých dokumentů. Bude mít přiřazen svoji šablonu a bude operovat nad virtuálním objektem, který bude udržovat seznam v košíku uložených položek. Šablona košíku bude také zodpovědná za umístění formulářových prvků, které budou volat jednotlivé funkce pro manipulaci s položkami. Velmi podobným způsobem budou realizovány další kroky objednání, např. zadávání údajů o zákazníkovi bude rovněž pouze jednoduchý dokument se šablonou určenou k zobrazení formuláře pro manipulace s objektem. Výsledná objednávka bude v systému vytvořena sloučením všech takovýchto objektů.
39
5.6 Zhodnocení systému 5.6.1
Univerzálnost
Systém byl od počátku koncipovaný s ohledem na co největší univerzálnost, především v oblasti reprezentace zboží a objektů. Díky zcela libovolným atributům a parametrům máme možnost v jednom obchodě reprezentovat i velmi odlišné položky a proto věřím, že je použitelný pro drtivou většinu zboží, která se v internetových obchodech může vyskytovat. Reprezentace obchodních dokumentů následuje zcela totožné principy jako zboží, proto je možné pomocí objektů popsat nejenom libovolně strukturované objednávky, ale i jiné, dopředu nezamýšlené soubory dat. Rozhraní SOAP je navrženo s ohledem na přenášená data, proto pro jakékoliv systémem popsatelné objekty není třeba jej žádným způsobem měnit.
5.6.2
Rozšiřitelnost
Celá aplikace je naprogramována prostředky OOP, což poskytlo dobrou výchozí pozici pro její další rozšiřovaní. Každému funkčnímu celku byla v rámci možností a hierarchie vymezena samostatná třída. Jednotlivé administrační i klientské pohledy jsou v rámci systému řešeny formou přídavných modulů, které stačí k současným modulům pouze přidat (výjimkou je prozatím pouze menu v administraci, které je řešeno „natvrdo“), proto je možné aplikaci rozšiřovat o další funkce, obzvláště směrem k plnohodnotnému elektronickému obchodu. Navržený systém má mnoho částí, kterým by se dala věnovat delší pozornost. Uveďme proto příklady několika z nich. Mohli bychom rozšířit řadu typů jednotlivých atributů, které jsou popsány jako přibližně korespondující s formulářovými prvky HTML. Například bychom mohli chtít přímo jako hodnotu atributu ukládat i binární data apod. Autentizace SOAP klientů nám může z objektu, kterým je klient reprezentován poskytovat data, která bychom mohli zohlednit např. v rámci filtrů objektů. Tak bychom byly schopni v rámci filtrů rozlišovat např. cenové hladiny jednotlivých zákazníků. V rámci vzdálených služeb bychom mohli rozšířit také řadu skupinových operací, které budou podporovány, především o statistické funkce. Protože klient je při nákupu v e-shopu obvykle informován formou mailu, měli bychom vytvořit prostředek pro transformaci a odesílání objektů tímto médiem. S tím souvisí také možnost registrace a přihlašování zákazníků, kontrola jimi vytvořených objektů – objednávek, určování cenových hladin apod. Za úvahu by rovněž stálo vytvoření externích SOAP adaptérů, které by umožnily získávání dat z jiných zdrojů (nebo poskytování dat jiným zdrojům), popř. transformovali jinou podobnou službu na sadu funkcí navržených pro náš SOAP server. Jednoduchým adaptérem by mohl být třeba import a export tabulkových souborů (CSV apod.)
40
5.6.3
Bezpečnost
Zabezpečení systému ze strany webových služeb aplikace je uskutečněno vyžadováním autentizačních údajů uživatele. To samo o sobě nezajišťuje bezpečný přístup, data se v takovém případě posílají nezabezpečeným kanálem a oba dva směry přenosu zpráv mohou být odposlechnuty neoprávněnou osobou. Oba případy jsou nežádoucí – jednak může dojít k prozrazení údajů uživatele (ačkoliv díky použití otisku nedojde k prozrazení původního hesla, může útočník použít otisk tak jak jej odposlechne). Ve druhém případě je škoda způsobená únikem samotných přenášených objektů, což v případě přenosu objednávek, faktur atd. mohou být velmi citlivá data. Pro zajištění vyššího zabezpečení dat kódováním je nutné sáhnout k prostředkům podkladového protokolu HTTPS. Tento režim přístupu je nutné nastavit minimálně pro část aplikace tvořící SOAP server (soapserver.php) a ve WSDL popisu služby musíme změnit port pro použití správného protokolu. Jako prevenci můžeme navrhnout periodické změny hesel klientů, např. tím, že omezíme platnost každého hesla jen na omezenou dobu. Dalším možným opatřením může být vytvoření nového volitelného atributu u objektů popisujících klienty služby, který bude obsahovat IP adresu stroje ze kterého je klient oprávněn přistupovat. V případě zabezpečení webového rozhraní je situace v zásadě stejná, administrátor používá pro přístup do systému také dvojice jména a hesla, zde ale navíc hrozí možnost, že při nekódovaném přístupu dojde k prozrazení původního tvaru hesla (to se odešle z formulářového prvku nezměněné do aplikace). Použití zabezpečeného protokolu HTTPS je proto velmi vhodné, nejméně pro přístup k administračnímu rozhraní. Samotná aplikace ale nebude přístup nijak omezovat, volbu ponecháme na uživateli.
41
6 Závěr Cílem práce bylo navrhnout a vytvořit jednoduchý a univerzální obchodní systém, který bude jako jedno z svých rozhraní využívat webové služby SOAP. To se v rámci práce podařilo. Přestože přiložený systém není zcela vyčerpávající implementací návrhu, pokrývá jeho podstatnou část. Po dokončení může výsledná aplikace sloužit jako základní pilíř pro další rozšiřování a praktické nasazení. Osobně se domnívám, že tento nebo obdobný systém by mohl v řadách malých až středních internetových obchodů nalézt své uplatnění a pro firmy zabývající se velkoprodejem zboží by mohl představovat platformu pro budování základů infrastruktury svých potenciálních odběratelů.
42
7 Použitá literatura [1] http://www.w3.org/XML/ [2] http://cs.wikipedia.org/wiki/Simple_Object_Access_Protocol [3] http://en.wikipedia.org/wiki/Web_service [4] http://en.wikipedia.org/wiki/Web_Services_Description_Language [5] http://en.wikipedia.org/wiki/UDDI [6] http://en.wikipedia.org/wiki/XML-RPC [7] http://en.wikipedia.org/wiki/CORBA [8] http://en.wikipedia.org/wiki/Representational_State_Transfer [9] http://en.wikipedia.org/wiki/Java_remote_method_invocation [10] http://www.techdata.cz/dataexchange/dataexchange.htm [11] http://www.php.net/ [12] http://www.mysql.com/ [13] http://www.apache.org/ [14] http://p4a.crealabsfoundation.org/ [15] http://www.smarty.net/ [16] http://php.vrana.cz/webove-sluzby-v-php-xml-rpc-a-soap.php [17] http://www.eclipse.org/ [18] http://www.ics.muni.cz/~makub/soap/
43
44