====== Semestrální práce ====== Termín odevzdání je do pondělí večer 12. 6. 23:59. * Semestrální práce se nahrává na [[https://cw.felk.cvut.cz/brute/|BRUTE]] (assignment bude vytvořen). * Cvičící Vám program ohodnotí a muže Vám jej vrátit s připomínkami k opravení. * Jakmile budete chtít práci definitivně odevzdat, domluvíte si s cvičícím konzultaci, kde práci obhájíte (můžete obhajovat na cvičení). * Za odevzdanou se považuje po osobní obhajobě práce s cvičícím (může být dohodnuto jinak). ===== Hodnocení ===== Můžete získat nejvýše 30 bodů a to: ^ Počet bodů ^ Poznámka ^ | 10 | z testů funkčnosti | | 10 | z testů rychlosti | | 10 | za návrh | ===== Kritéria hodnocení návrhu ===== ^ Kritérium ^ Max počet bodů^ | Cache je správně navržená (ukládá správně data, pracuje správně se soft referencí, ...) |1| | Server je správně navržený (správně navazuje spojení, správně čte request a zapisuje response, správně reaguje na chyby, ...) |1| | Server je neblokující |1| | Řešení používá reaktivní a funkcionální programování |1| | Řešení používá reaktivní cache |1| | Řešení používá reaktivní server |1| | Řešení dodržuje principy správného návrhu, jako DRY, ... |1| | Kód je čistý podle kritérií definovaných v Checklistu kvality kódu (níže) |1| | Řešení používá dependency injection (spring, guice, vlastní řešení, ..). Dávám 0.5 bodu, když nemáte tightly coupled komponenty (tj. závislosti si předáváte konstruktorem) |1| | Řešení obsahuje originální a inventivní prvky |1| Celkem tedy lze získat 10 bodů. ===== Kritéria hodnocení výkonu ===== Budou jasná jakmile více lidí odevzdá. Zatím mám v plánu použít Apache Benchmark: * ab -n 1000 -c 100 -w http://127.0.0.1:8081/image.jpg - musí projít každému bez chyb * ab -n 10000 -c 1000 -w http://127.0.0.1:8081/image.jpg - očekávám > 1000 req/sec (na notebooku s i5) * ab -kc 500 -t 60 -w http://127.0.0.1:8081/image.jpg - očekávám cca 1000 req/sec ==== Kde najít apache benchmark ==== * Apache benchmark můžete najít například jako součást balíčku [[https://sourceforge.net/projects/xampp/files/XAMPP%20Windows/1.8.3/xampp-portable-win32-1.8.3-5-VC11.zip/download|XAMPP]] na umístění: "xampp-portable-win32-1.8.3-5-VC11.zip\xampp\apache\bin\ab.exe" ==== Tipy na zvýšení výkonu ==== * Pokud chcete, aby vaše výkonnostní testy dopadly dobře, měl by váš server ve výchozím nastavení logovat pouze úroveň WARN a ERROR. Pokud váš server zaměstnaný vypisováním na konzoli, nebude stíhat vyřizovat požadavky dostatečně rychle! * Doporučuji přidat další argument, kterým zapnete podrobnější logování pro Vaše potřeby * Možné optimalizace: * vytvořte si mapu Soubor -> Vyžadované heslo, aby jste neustále nenačítali heslo z htaccess (či opakovaně nekontrolovali, zdali je soubor chráněný) a tím minimalizovali přístup na filesystém * můžete si celý statický obsah nacachovat při startu serveru * pokud používáte blokující response writer: * zkuste ho přepsat na neblokující podle [[https://pastebin.com/1ZwKtuae|šablony]] * zkuste využít ThreadPool por zápis (podobně, jako v HW3) * na accept v ResponseWriteru můžete velmi snadno zavolat submit nad executor service! Samozřejmě vůbec nemusíte čekat na to, až se future dokončí, právě naopak! * zkuste paralelizovat reaktivní stream (podobně, jako v HW3) ==== Jak profilovat server ==== * Pro profiling doporučuji používat jvisualvm, který je součástí JDK: "Java\jdk8\bin\jvisualvm.exe" * Spusťte svůj server * Spusťte jvisualvm * Vlevo v seznamu otevřete dvojklikem běžící server * Na záložce "sampler" klikněte na "CPU" * Spusťte benchmark * Po skončení klikněte na "stop" a následně níže na "snapshot" * vytvoří se snapshot, ve kterém je níže záložka "Hot spots" * Seřaďte si volání podle "self-time" od nejvyššího po nejnižší * Na podezřelé volání klikněte pravým tlačítkem myši a zvolte "Find in call tree" pro bližší inspekci volání ===== Zadání ===== Implementujte jednoduchý statický reaktivní webový server. O tom co reaktivní server je a jak ho vytvořit více na cvičení. Studenti, kteří mají server hotový z minulého běhu předmětu nemusí celý server na reaktivní předělávat a dostanou individuální pokyny. Požadavky na Vaše řešení: * schopnost přijmutí velkého počtu požadavků najednou (~100 simultánních požadavků) * cache * implementace zpracování GET, POST, HEAD PUT a DELETE hlaviček (info [[http://www.w3.org/Protocols/rfc2616/rfc2616.html|zde]]) * implementace HTTP BASIC autentifikace (info [[http://cs.wikipedia.org/wiki/Basic_access_authentication|zde]]) * server bude umět poskytovat statický obsah stránek (textová i binární data) * unit testy jednotlivých modulů (JUnit / TestNG) * stress testy celého systému * použijte [[https://httpd.apache.org/docs/2.4/programs/ab.html|apache benchmark]] (viz kritéria hodnocení výkonu) * můžete si vyzkoušet také [[http://jmeter.apache.org/|JMeter]] * Java 1.8 * Tam kde to má smysl používejte Observable rozhranní * Pro reaktivní programování preferuji RxJava2, ale můžete použít svůj oblíbený reaktivní framework * Použijte logger a implementujte logování napříč serverem (bude vysvětleno na cvičení) * použijte SLF4J + logback (případně místo logbacku jiný oblíbený logger) * Server lze spustit z příkazové řádky s parametry PORT a WEB_ROOT * Př.: "java -jar server.jar 8080 ../document_root" * Př.: "java -jar server.jar 8080 C:/web/web_root_0" * Př.: "java -jar server.jar 8081 C:/web/web_root_1" * Projekt obsahuje v rootu soubor "htaccess" (bez tečky, BRUTE ho jinak nenahraje!) s uživatelem "test" a heslem "123456" zakódovaný vaším hash-salt algoritmem ===== Checklist funkčnosti ===== - **Server stažený z BRUTE lze zkompilovat příkazem "mvn package"** - Požadavek "/" (požadavek o root directory) vrací index.html (pokud existuje, jinak HTTP 404) - Požadavek "../../soubor.txt" nevrátí soubor mimo document root serveru - Požadavek "C:\windows\system32\..." nevrátí soubor mimo document root serveru - Server správně posílá obrázky, které se správně zobrazí (tj. Váš server umí binární data) - Na požadavek o neexistující soubor vrátí server HTTP hlavičku 404 - Na nesmyslný požadavek, například s metodou NONEXISTING_METHOD vrátí server HTTP 400 (Bad request) - Web server nevrátí uživateli soubor ".htaccess" a bude předstírat, že tento soubor neexistuje, i když existuje - Web server je schopný zpracovat URL encoding * [[https://cw.fel.cvut.cz/wiki/_media/courses/a4b77ass/ass-servevrtest.zip|Servertest]] * Aktualizováno 2. 6. 2017 * zbuildujte pomocí "mvn package" * spusťte shade verzi pomocí: "java -jar servertest-0.0.1-SNAPSHOT-shaded.jar 8080" * nově se zadává pouze port, na kterém se očekává, že běží Váš server, servertest tedy nyní pouze testuje již běžící server * servertest musí běžet relativně ke složce home (vykopírujte si jar z targetu o adresář výše) * obsahuje testovací web ve složce "home" * generuje výstup "functional-report.html", který obsahuje výsledek funkčního testu včetně získaných bodů * bude použit pro automatickou **objektivní** evaluaci funkčnosti serveru ==== Časté chyby ==== * Nefunguje mi obrázek * někde špatně pracujete s kódováním, snažte se pracovat s byte[] polem namísto Stringů. Pokud pracujete se stringy, tak nepřevádějte kódování * Dostávám [[https://docs.oracle.com/javase/8/docs/api/java/nio/channels/ClosedChannelException.html|ClosedChannelException]] * operujete nad kanálem (socketem), který byl již zavřený. Ujistěte se, že kanál neberete z cache spolu s daty souboru! * Často pracujete špatně s WWW-Authentication hlavičkou. Tu máte vracet s odpovědí 401 pro vyžádání hesla od uživatele a to s hodnotou "Basic" (tedy: WWW-Authentication: Basic). Na hlavičku WWW-Authentication prohlížeč uživateli ukáže [[https://evolpin.files.wordpress.com/2012/08/401_a.png|toto okno]]. ==== Odevzdávání ==== * Řídí se [[podmínkami odevzdávání domácích úkolů]] ==== Autentifikace ==== Server umožní uživateli (administrátorovi webových stránek) prohlásit složku za chráněnou. Use case: Firma SpringfieldAuto prodává ojeté automobily ve Springfieldu. Má webovou stránku se svou nabídkou, která je veřejná pro všechny uživatele internetu. Pro VIP zákazníky má skrytou sekci webu s nabídkou speciálních automobilů. Tuto sekci má zaheslovanou. Uživatelské jméno a heslo zasílá svým klientům obálkou. Server bude pokládat složku za chráněnou, pokud bude obsahovat soubor .htaccess, který bude mít následující formát: user:base64(hashed(salt+password)) Příklad: webuser1:da39a3ee5e6b4b0d3255bfef95601890afd80709 Kde webuser1 je uživatelské jméno, da39a3ee5e6b4b0d3255bfef95601890afd80709 je hash osaltovaného hesla. Můžete se podívat na [[https://pastebin.com/Fcdmr2si|příklad hashování v javě]] [pastebin]. Pokud složka takový soubor obsahuje, webserver musí vyžadovat heslo pro přístup ke všem jejím souborům a souborům v podadresářích. Prohlížeč posílá přihlašovací údaje ve formě user:pass, které jsou zakódované v base64. Při kontrole hesla tedy musíte přijaté údaje dekódovat a následně heslo zahashovat, abyste ho mohli porovnat s uloženým heslem. ==== Kontrola kvality kódu ==== Součástí hodnocení návrhu je také posouzení kvality kódu s použitím maven pluginu findbugs. Abyste si mohli kontrolu zapnut i vy už v průběhu vývoje, přidejte si následující text do pom.xml: org.codehaus.mojo findbugs-maven-plugin findbugs-check compile check Max 3.0.0 org.apache.maven.plugins maven-compiler-plugin 3.2 1.8 1.8 Po přidání //// konfigurace do pluginu se kontrola kódu bude spouštět vždy při kompilaci (//mvn compile//). ==== Checklist kvality kódu ==== Na semestrální úlohu máte dostatek času. Ideálním výsledkem je kód, který můžete publikovat, jako součást portfolia své kvalitní práce z dob studií. Nejeden zaměstnavatel po Vás ukázku kvalitního kódu bude chtít. Takový kód by měl být čistý a bez zbytečností. Před odevzdáním semestrální práce prosím projděte seznam níže, pro kontrolu, zdali jste v kódu nenechali něco nechtěného. - parciální funkce mají návratový typ Optional a vrací Optional.empty namísto null (jinými slovy: pokud si potřebujete předat zprávu "žádný výsledek", vracejte Optional.empty() a ne null). - kód neobsahuje zakomentovaný kód - kód neobsahuje nesmyslné komentáře (např.: "To change this license header, choose License Headers in Project Properties.") - kód neobsahuje nic neříkající javadoc author (např.: @author SuperMegaMan) - kód je hezky naformátovaný - kód se vejde na běžnou obrazovku (to, že doma máte dva 4k monitory vedle sebe není důvod mít v kódu kilometrové řádky) - kód se čte jako pohádka (důležité metody vysoké abstrakce nahoře, ta nejméně důležitá dole) - kód neobsahuje [[https://en.wikipedia.org/wiki/Magic_number_(programming)|magic number]] konstanty - konstanty jsou smysluplně pojmenovány a okomentovány - public metody mají javadoc, který vysvětluje roli dané metody v rámci systému