====== 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.mojofindbugs-maven-pluginfindbugs-checkcompilecheckMax3.0.0org.apache.maven.pluginsmaven-compiler-plugin3.21.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