piątek, 31 października 2014

Quick&Easy : H2 embedded mode + Spring integration

Podczas prowadzenia terningów z Springa czy JPA zdarzyło mi się, że środowisko nie było poprawnie przygotowane jeśli chodzi o bazy danych.
Czasem jest Mysql lub inna baza czasem jej nie ma, czasem nie można się połączyć bo blokowany jest port itd. Jest to irytujące i deprymujące. Ale jest na to super rozwiązanie .



Baza H2, która może działać w trybie wbudowanym podobnie jak baza hsqldb.
Takie rozwiązania super nadają się do testów.

Ale do rzeczy...

Gradle :
Spring Config :
Logi :(Creating new JDBC Connection to jdbc:h2:tcp://localhost:9092/mem:przodownik;DB_CLOSE_DELAY=-1])


Otrzymuje pod linkiem http://localhost:8082/ konsole H2 w trybie Web !






















Podsumowanie :
W ten oto sposób można się uwolnić od problemów z relacyjną bazą danych.
H2 świetnie współpracuje z Hibernate a tym samym z JPA.
Prototypując taką aplikację możesz łatwo i szybko sprawdzić stan w bazie danych nie mają zainstalowanych żadnych wymyślnych klientów SQL'a






Camel Monitoring : Hawtio : Standalone solution : part 1

Monitorowanie procesów to bardzo ważna sprawa, gdyż pozwala wypełnić SLA projektu.
Zbieranie statystyk i monitoring powinien być procesem ciągłym i trwać przez cały proces developmentu oraz w pewnej określonej formie znajdować się na systemie produkcyjnym.


Samo podejście do monitorowanie nie jest specjalnie łatwe ale możemy wykorzystać tutaj cały arsenał features javy jak JMX, AOP (może nie koniecznie javy w tym przypadku,), biblioteki jak Metrics, Spring Boot Actuator, Guava StopWatch, JavaMelody, itd.





W Apache Camel można jeszcze wyróżnić komponenty jak :
 - Wiretap
 - Advicewith
 - Intercept
 - Log
 - Tracer
 - NotifyBuilder
 - DataSet
 - Metrics (since 2.14.0)

Ja jakiś czas temu zacząłem używać Hawtio do wizualizacji procesów Apache Camel.
Wygląda to świetnie.
Pokaże jak można szybko te dwie rzeczy zintegrować.

Prosta trasa :
Konfiguracja
Zwróć szczególną uwagę na klasę Main, którą użyłem .. teraz przykład z dokumentacji.
Pozwala ona na minimalizację pracy  programisty i łatwe wygaszanie procesów Camela. Bez niej musiałeś wszystko robić z palca lub też odpalać kontekst np na jakiś określony do testów czas.

Tip : Można wygaszać trasę Camela poprzez jej identyfikator ID - to często się przydaję, zwłaszcza w testach integracyjnych.
Intergracja z Hawtio :
Odpalam i widzę logi :
i teraz otrzymuje takie piękne wykresy i statystyki :) - zajebiscie :) - tylko dla tak pięknego dashboardu warto używać hawtio.








































Podsumowanie : 
Monitoring to konieczna podstawa wszyskiego jeśli mówimy o chęci zachowania SLA czy późniejszej poprawie wydajności czy eliminacji wąskich gardeł.
Poznając sposoby monitorowania poprawiasz jakość, bezpieczeństwo , wydajność swojego softu.
Dalsze możliwe formy monitorowania, które wymieniłem na początku  opiszę w następnych postach.
cdn

Useful tools&tips generate some data


Cykl ultra-krótkich postów.
Rzeczy, które mogą się przydać i trzeba tego szukać w necie.
 
Czasem musimy np. do testów wygenerować jakiś zbiór danych w formacie JSON. I tu właśnie przyjdzie Ci z pomocą narzędzie JSON-Generator



Jeśli chcesz wygenerować jakieś testowe dane do bazy lub pliku płaskiego, excela, json czy xml to generateData przyjdzie Ci z pomocą.

Quick&Easy : Simple CRUD : Spring Boot + JSP - continue

W poprzednim poście pokazałem jak szybko wystartować prosty projekt typu Web oparty na Spring Boot i JSP - który jest już dawno deprecated ale ....
sporo osób go jeszcze zna, więc nadal jest używany i do pokazania jakiś mechanizmów jeszcze się nadaje.
Zadanie :
- Stworzyć mechanizm prostego CRUD'a
- Użyć tagi JSTL oraz Spring tags dla JSP
- Zasymulować repozytorium danych.


Pierwsze co dodaje do ostatniego projektu to repozytorium. Nie chce używać póki co żadnej składnicy danych , więc zasymulujemy to za pomocą zwykłej listy.


Tworzę szybko API :
Teraz implementacja (użyjemy API javy 8 bo to zdrowo również dla kodu) :
Zarejestrowanie repozytorium (skanuje  pakiet ale rejestruje  tylko klasy ze sterotypem Repository):
Klasa domenowa jest prosta :

Kontroler też całkiem prosty :
Widok dla przeglądania (spring:url - dynamiczne tworzenie linków oraz jstl dla c:foreach - pętla oraz c:out - wyświetlanie + escape html tags):
Widok dla dodawania : (spring tag form dla ułatwienia tworzenia formularza)
No tak jeszcze plik z importem tagów (nie chce powielać tego typu informacji w każdym pliku JSP - centralizuję więc):
Jak to wygląda w przeglądarce :


































Jeszcze przetestujmy API :
I widzimy, że działa :) (nie jest to jakiś wysublimowany test ale jakaś namiastka testu zawsze jest, warto stosować TDD a nauka tego w tak prostym case'ie to sama przyjemość)


Tyle..
Pokazałem jak robić prostego CRUD'a z użyciem JSP + Spring Boot'a.
Repository jest zasymulowane przez zwyczajną listę i to w tej chwili wystarczy.
Potem będzięmy stopniowo rozszerzać implementację o :
 - walidację,
 - internationalization,
 -  obsługę błędów,
 - białe listy,
 -  zabezpieczenie,
 -  paging,
 -  cache,
 -  filtry  itd.


Kod do posta jest tutaj    branch nazywa się : stub_repo

czwartek, 30 października 2014

Quick&Easy : Simple configuration : Spring Boot + jsp + favicon

Na koniec miesiąca coś prostego głównie dla nowych adeptów frameworka Spring.

Zadanie :
 - Skonfigurować prostą aplikację web z wykorzystaniem starego już JSP

- Wyświetlić favicon w zakładce przeglądarki.

- Dodać prosty message i załadować tagi JSP.

- Generalnie wykorzystać możliwości propotypowania Spring Boot'a.





Tworzę konfigurację PoC czyli edytuję sobię application.properties to samo mógłbym zrobić lepiej używająć yaml'a
To jest równoznaczne temu :

Startuje aplikację dzięki stworzonej klasie :
Kontroler jest prosty (http://localhost:8080/hello) :
A widok jeszcze bardziej (location: /WEB-INF/templates/hello.jsp) : Tagi - zobacz build.gradle (runtime("javax.servlet:jstl"))
Json'a serwuje tak : (http://localhost:8080/json) 
Szybko wprowadzam modyfikację :
   - czyszczę application.properties i usuwam z niego mapowania szablonów JSP
   - tworzę klasę WebConfig i dodaje mapowania templatów JSP oraz static'ow
Otwiera mi to drogę do zastosowania favicon w zakładce przeglądarki :












Na koniec build.gradle wygląda jak poniżej :
Kod do posta jest tutaj ->
Kontynuacja posta -> 

czwartek, 16 października 2014

Gradle vs Maven integration test - comparison


W tym poście poznasz postawowe zasady konfiguracji testów w narzędziach jak Maven czy Gradle, które to wspomagają procesy wytwarzania softu.
Bardzo ważne jest rozróżnienie fazy integracji i testów jednostkowych. Integracja zazwyczaj trwa dłużej i nikt nie chce aby wykonywała się ona w czasie fazy testów jednostkowych. Zasady CI i oraz zasady tworzenia testów znajdziesz w moich poprzednich postach.  sd









Gradle :
uzupełniam sekcje sourceSet  o itTest

Oczywiście to się wiąże z utworzeniem odpowiednich katalogów :)
Następnie w sekcji dependencies dodaje :
Został do dodania tylko odpowiedni task, który będzie wyzwalał test.
Wynik (testuje na konsoli : gradle test i gradle itTest):

Maven :
Tworze profil : dzięki temu mogę np puszczać integration test z zwykłymi testami lub je blokować.
Podpinam źródła aby były ładnie widoczne w eclipse, a robię to tak (build helper)
Integration test : surfire plugin + failSafe plugin (odpowiada za uruchomienie testów integracyjnych)  : 

Odpalam testy poleceniami :  
   1. mvn integration-test -  uruchamia integracyjne
   2. mvn verify - sprawdza, czy testy  integracyjne zostały wykonane prawidłowo
   3. mvn test  - jednostkowe zwykłe.


Ważne jest odpowiednie zrozumienie faz :

pre-integration-test: w tej fazie możemy ustawić i przygotować odpowiednio zasoby.
integration-test: failsafe : odpalamy testy
post-integration-test: zwalnianie zasobów, czyszczenie


verify: failsafe odpala wszystkie  powyższe cele w swojej hierarchii. Normalne użycie bez przygotowanego profilu (jak to zrobić ->  patrz powyżej ), że zostaną odpalone zarówno testy jednostkowe jak i integracyjne.


Tip : mvn verify to dobra praktyka. Pozwala upewnić się, że post-integration-test przeprowadzi jeszcze fazę czyszczenia.

Różnica pomiędzy Surfire a failSafe jest taka, że ten pierwszy przerywa build jeśli test się nie wykona, failSafe pozwala na kontynuowania budowania do fazy czyszczenia.



Możemy przyjąć również inną strategię różnicowania testów, zamiast  rozdzielać testy do różnych zasobów (katalogów  - taką wersję ja polecam) zastosować strategię nazewnictwa np poprzez dodanie prefixu lub suffixu IT.



Posumowanie : Narzędzia te zostały stworzone dla Ciebie żeby Ci pomóc łatwiej zarządzać tym całym burdelem (czytaj procesem wytwarzania i budowy). Warto poświęcić trochę czasu i je odpowiednio skonfigurować to zaoszczędzi Ci czasu i nerwów na przyszłość. Określenie strategii testów jest bardzo ważne. Testy zawsze są nieodłączną częścią życia każdego projektów.

Pisanie dobrych testów nie jest proste. Zainwestowany czas w tę tematykę na pewno przyniesie wymierne korzyści zarówno dla projektu ja i może dla kieszeni. Patrz na tendencję na rynku pracy i jakiś skillów oczekują pracowawcy a zrozumiesz o czym mówię.




środa, 15 października 2014

Problem&Solution

Problem&Solution -  to codzienne problemy i próby ich rozwiązania...
Dziś  trafiłem natrafiłem na następujący wyjątek podczas podnoszenia wersji Springa i jego całego stack'u w projekcie bazującym na Spring Rest + Hateoas :



Problem 1 :
Exception :  Could not instantiate bean class [org.springframework.data.domain.Pageable]


Solution:
add @EnableSpringDataWebSupport annotation


Poniżej kawałek kodu który przestał serwować odpowiednie dane :
Czas rozwiązania : 2 min + stackoverflow.:)


Problem 2.
Podniesienie springdata-neo4j z wersji 3.0.0 na : 3.2.0
Spowodowało, iż SpringData Neo4j przestał widzieć obiekty domenowe....
Solution :
Wskazanie mapowania w konstruktorze....
Czas rozwiązania : 5 min + stackoverflow. + google:)

Dispel your security concerns - Spring Security part2 (mongoDB,Thymeleaf,boot)

Spring Security konfiguracja część 2. 
Rozwiewanie wątpliwości ;)
Wstęp do tematu znajdziesz w tym poście.
Kata na dzisiaj: (szybka implementacja)
Zadanie : Spring Security  - Custom web
page  + model domenowy w MongoDB
Chronimy URL + stosujemy CSRF.
Web - ThymeLeaf + webjars (bootstrap ,jquery)
Pamiętaj : 
Security to cross-cutting concern - nie mieszaj implementacji bezpieczeństwa z implementacją businesową.
TIP : Opieraj się na AOP, DI czy Sevlet filters


Po cholerę to piszę ?....
Jeśli porywasz się na implementację aplikacji wystawionej w sieci bez pomocy frameworka typu Spring Security to masz dużo fantazji, a może czasu na stworzenie własnych rozwiązań. Może treść czy dane, które serwujesz są po prostu gówno warte ?:). Problemy security są złożone a własna implementacja zabezpieczeń problematyczna - testowanie trudne. Tak czy inaczej bez odpowiedniego frameworka wspierającego Security znajdziesz się w dupie ....

Wystarczy spojrzeć na OWASP. by zrozumieć co Cię czeka...
Teraz spójrz na Spring Security reference. (a oferuje dużo :))

Kiedyś CSRF pisałem z palca. Teraz mam to out-of-the-box w Spring-Security.
TIP  : Pamiętaj, że CSRF protection jest włączone z default przy konfiguracji Java Config. Aby bo wyłączyć użyj :
 

OWASP Top Ten

1. Injection - Criteria API , JPQL Binding, QueryDSL, Spring JDBCTemplate,Escaping, WhiteListing
2. Cross-Site Scripting (XSS) - Spring Security 3.2 upper, th:text, JSR 303 hibernate validator @SafeHtml
3. Broken Authentication and Session Management - Spring Security, session-management
4. Insecure Direct Object References
5. Cross-Site Request Forgery (CSRF) - Spring Security 3.2 upper - domyślnie
low session timeout, random generated token, again login in case of sensitive sites
6. Security Misconfiguration- configure logging, exception handling, right security configuration policy
7. Insecure Cryptographic Storage - Spring Security np : OpenId, Jasypt,Spring Security crypto, never log any sensitive data uncrypted , encrypt db for sensitive data , choose right crypt algorithm, change keys and passwords periodically
8. Failure to Restrict URL Access - Spring Security
9. Insufficient Transport Layer Protection - Spring Security, secure session cookie
10. Unvalidated Redirects and Forwards- avoid redirects wherever possible, validate target URL
 
Tip : rozważ użycie HDIV !!- o tym w następnych postach

Ale .... Zaczniemy od bardzo fajnego features'a z Gradle.
czyli Resolution.

Generalnie chodzi o upewnienie się, że pobierzemy odpowiednie wersje zależności :

Przykład z dokumentacji Gradle :
Płynie powracamy do Spring Security configuration  :
http auto-config="true" - włączenie uwieżytelniania korzystającego z formularzy (włączenie łańcucha filtrów) - typowa domyślna konfiguracja dla Web

use-expression="true" -  włączenie wyrażeń SpEl dla Springa, przydatne np w JSP

create-session={} - session fixaction attack

form-login default-target-url="/welcome.html" - przekierowanie na danego URL'a po udanej autentykacji.

authentication-failure-url - przekierowanie na danego URL'a po nieudanej akcji autentykacji

remember-me - włączona opcja zapamiętywania

logout logout-success-url="/welcome.html" - konfiguracja operacji wylogowania - przekierowanie na danego URL'a po udanej akcji wylogowania

authentication-manager - manager uwierzytelniania wpółgra z authentication-provider

authentication-provider - dostawca uwierzytelnienia podpinamy tu jakąś logikę np DAO
Może to być dowolna interpretacje UserDetailsService czyli np implementacja w pamięci dostarczona przez Spring-Security czyli InMemoryDaoImpl


Http Basic Authentication ->  użyj : <http-basic />

Form Based Login -> użyj <form-login /> z default Spring Security wygeneruje dla Ciebie prosty formularz który znajdziesz pod URL'em /spring_security_login

Ok, spróbujemy to zrobić za pomocą JavaConfig. -> Czyli Start..:)
Na sam początek może startowy przykład z dokumentacji Spring Security:

Po kolei :
1.Upewniam się , że żaden request nie przejdzie przez filtry jeśli użytkownik nie będzie zalogowany.
2. Zezwalam na autentykacje przez form based login
3. Zezwalam na autentykacje przez HTTP Basic
Tyle. To jest bardzo podstawowa konfiguracja i dobrze właśnie z niej wyjść.

Zaczynam od potrzebnych zależności () :
Konfiguracja security :

Zawsze możesz customize'ować na kształt konfiguracji poniżej :

Konfiguracja mongoDB :

Konfiguracja dao :
Konfiguracja thymeLeaf :
Konfiguracja szyfrowania (teraz szyfruje tylko hasło w bazie, o zaawansowanych metodach szyfrowania - jasypt przeczytasz w następnych postach:) )
Model domenowy jest prosty : pamiętaj o UserDetails impl 

Db populate:


 








Potrzebuje impl UserServiceDetailsImpl aby podłączyć ją do authentication-managera
W celu podcięcia jakieś funkcjonalności zawsze używaj handlerów (np logowanie zdarzeń do bazy czy inne mierniki). Przykładowe handlery są poniżej :
Mechanizm logowania i wylogowania z CRSF w thymeleaf wyglądają jak poniżej :
Webjars w Thymeleaf :
Krótki post opisujący jak możesz za modelować sobie proste security.
Jeśli chcesz zabezpieczyć metody biznesowe - proszę :

Szybki Test

Testujemy Web :)



Po zalogowaniu :












Wszystko wygląda prosto. Ale wbrew pozorom można popełnić kilka błędów.
Taki PoC stworzyć jednak można szybko. Security oparte na formularzu jest jak widać proste - ale dla wprawionych. Konfiguracja w Xml wydaje się być bardziej przejrzysta niż JavaConfig DSL w wydaniu Spring Security. My jednak konsekwentnie odchodzimy na ile to możliwe od Xml'a.

Na koniec kolejny fajny feature:

Kod do posta znajdziesz tutaj;)

czwartek, 2 października 2014

Quick@Easy cache added



Problem : Spring Data + JPA + Second level Cache
Rozwiązanie : dodać hibernate-cache do dependency
 Zaleta : Wykorzystanie cache second level w celu zwiększenia wydajności aplikacji

Problem2 : Monitoring
Rozwiązanie2 : dodać hibernate-jmx do dependency włączyć obsługę JMX w springu
Zaleta2 : Wiem co się dzieje + eliminacja bottlenecks w aplikacji. Ułatwienie znalezienia problemu N+1 



Ogólne korzyści z użycia cache w Twojej aplikacji są oczywiste : 
   - redukcja zapytań do db
   - redukcja tworzenia obiektów
   - redukcja użycia CPU omijamy często powtórną serializację (poprawny wyjściowy format danych)
   - redukcja ruchu na kablu 

Charakterystyka ehcache : (Hibernate korzysta z niego domyślnie Easy Hibernate Cache)

Zalety : 
  - łatwość impl
  - sprawdza się w większości przypadków
  - wbudowany alg eksmisji
  - wbudowane statystyki i dostęp przez JMX
  - możliwa replikacja i dystrybucja danych
  - kontrola wykorzystania sterty
  - łatwa i rozbudowana konfiguracja regionów
  - szybkość działania

Przykład konfiguracji :

Teraz musimy powiedzieć ehcache'owi jak skonfigurować regiony, strategię i politykę ....
Startuje od projektu z poprzedniego posta czyli JPA + Spring Data. Pierwsze co muszę zrobić to powiedzieć jak chce skonfigurować cache :


Krótkie objaśnienie :
W celu określenia polityki cache stosuje się plik ehcache.xml.
timeToIdleSeconds - określa ważność w sekundach od momentu pobrania ostatniego elementu z bufora
timeToIdleLiveSecond - określa ważność w sekundach od momentu umieszczenia w buforze
maxElementsInMemory - max liczba elementów przechowywana w pamięci
overflowToDisk - buforowanie z użyciem dysku twardego
eternal - true -> elementy w cache nigdy nie wygasają (timeToIdealSeconds, timeToLiveSeconds)


Odpalam aplikację i widzę :
Problem : Unable to resolve name [org.hibernate.cache.ehcache.EhCacheRegionFactory] as strategy [org.hibernate.cache.spi.RegionFactory]

org.hibernate.HibernateException: could not instantiate RegionFactory [org.hibernate.cache.ehcache.EhCacheRegionFactory] 

No tak brakuje jakiś zależności, więc dodaje na szybko:
Już lepiej...


Trochę teorii na temat cache - hibernate :
L1:
 - dotyczy encji
 - Cache L1 jest domyślnie włączony zawsze :)
 - skojarzony z sesją Hibernate , (JPA entityManager)
 - optymalizacja wąskiej przestrzeni pracy
 - pobieranie po id,
 -  zwielokrotnienie find()  - jeden select w SQL (is dirty pattern)
 -  zwieloktornienie merge - ale operacja Update  (is dirty pattern)
 L2 :
  - cache dotyczy encji lub kolekcji
  - skojarzony z fabryką sesji (JPA EntityManagerFactory)
  - cache dla całej kolekcji czy grafu zapytania find()
  - najpierw następuje sprawdzenie w L1 w następnej kolejności w L2

Problem : Kiedy użyć L2 , a kiedy nie ?
  Tak : 
   - odciążenie bazy - poprawa wydajności
   - sprawdza się dla zapytań często wykonywach
   - sprawdza się doskonale jak każdy cache dla obiektów rzadko lub wcale nie modyfikowanych np słowniki

  Nie : 
   - dla dużych zbiorów danych będzie to zabójstwo OutOfMemoryException
   - słabe rozwiązanie dla encji często lub współbieżnie modyfikowanych

Strategie : 

Read-only - Najbardziej wydajna : encje są często czytane ale nigdy nie są modyfikowane -> słowniki
Nonstrict read-write : encje są rzadko modyfikowane
Read-write  : Większy narzut encje są modyfikowane

Teraz płynnie przychodzimy przez konfiguracją wszystkich pozostałych warstw aplikacji :
Encja : 
Repository :
Konfiguracja EntityManager'a :
Test :
Pytanie czy naprawdę działa ?
Teraz jeszcze jeden bajer chce podłączyć JMX i zobaczyć te statystyki na konsoli :
Aby to zadziałało potrzebuje następnych dependecies (jmx + ehcache):
Wynik : używam hibernate-jconsole :) - polecam ...


















Tyle :) Kod po posta - > tutaj Uwaga : pod branch'em cache ;)

środa, 1 października 2014

Quick&Easy .... Spring Data + sql audit

Nowy cykl postów 'Quick&Easy' czyli jeszcze mniej pisania i więcej ukierunkowania na dany problem.
Dziś odgrzewam starego kotleta, ale może nie wszyscy mają świadomość jak to działa czy jak to zrobić.
Problem : szybka konfiguracja JPA + Spring Data + audyt dla zapytań natywnych SQL
Rozwiązanie : p4spy lub log4jdbc
Zaleta : Analiza natywnych zapytań SQL po przetransformowaniu przez ORM'a
Wiemy co tak naprawę robi aplikacja.


Ok lecimy:
Potrzebuje pulę połączeń bo nie chcę katować bazy.

Widok na pule z jcosole wygląda tak :



































oraz startowe ustawienia :

Super teraz trzeba by zrobić proxy na wybrany dataSource - łatwizna
Przydałoby się powiedzieć wybranemu loggerowi co i jak ma logować ....logback wydaje się być najbardziej odpowiednim wyborem (co to jest opisywałem tutaj)

Testujemy :

Wynik śledzenia SQL'a "
Podczas gdy hibernate.show.sql=true daje mi coś na kształt :
Kod do posta tutaj ->