BookStore #gradle - Enterprise Application, Git, EJB, EAP ...users.nik.uni-obuda.hu › ... ›...
Transcript of BookStore #gradle - Enterprise Application, Git, EJB, EAP ...users.nik.uni-obuda.hu › ... ›...
BookStore #gradleEnterprise Application, Git, EJB, EAP/EAS, Logging,PostgreSQL/MySQL, JPA, Integration testing
Óbudai Egyetem, Java Enterprise EditionMűszaki Informatika szakLabor 3
Bedők Dávid2018-01-17v1.1
Bedők Dávid (UNI-OBUDA) BookStore (template.tex) 2018-01-17 v1.1 1 / 110
EAS - Domain struktúra
Bedők Dávid (UNI-OBUDA) BookStore (eas-domains.tex) 2018-01-17 v1.1 2 / 110
EAS - Deployment struktúra
Bedők Dávid (UNI-OBUDA) BookStore (eas-domain.tex) 2018-01-17 v1.1 3 / 110
BookLightEgyszerűsített könyvesbolt
Feladat : hozzunk létre egy alkalmazást, mely egy könyvesbolt könyveineklekérdezésére alkalmas.A feladatot két részletben valósítjuk meg. Első körben a persistence rétegetmock-olni/fake-elni fogjuk.
Alkalmazandó technikák:
. Java Enterprise Edition 6• EJB API 3.1• Servlet API 3.0.1• JPA 2.0
. JBoss 6.4 / WebLogic 12.1.3
Bedők Dávid (UNI-OBUDA) BookStore (booklight.tex) 2018-01-17 v1.1 4 / 110
In medias resTeszteljük le a fejlesztési környezetünket� �1 > cd [GIT]\ gradle\jboss\booklight\2 > gradle clean build3 ..4 BUILD SUCCESSFUL� �Új EAR csomag:[GIT]\gradle\jboss\booklight\build\libs\booklight.ear� �1 > cd [JBOSS -HOME]\bin2 > standalone .[bat|sh]� �Másoljuk be az elkészült booklight.ear állományt a[JBOSS-HOME]\standalone\deployments könyvtárba.http://localhost:8080/bl-weblayer/BookPing� �BookStub [isbn =978 -0441172719 , author=Frank Herbert , title=Dune ,category=SCIFI , price =3500.0 , numberOfPages =896]� �Bedők Dávid (UNI-OBUDA) BookStore (in-medias-res-gradle.tex) 2018-01-17 v1.1 5 / 110
IsmeretszerzésBookLight
. Projekt hierarchia létrehozása
. Enterprise JavaBean (ejb) alapok mint business layer
. Egyszerű servlet mint weblayer
. Mockolt adatok mint persistence layer
Enterprise Application Servers (EAS). RedHat JBoss 6.4. Oracle WebLogic 12.1.3
Bedők Dávid (UNI-OBUDA) BookStore (knowledge.tex) 2018-01-17 v1.1 6 / 110
Másik EAS választásának lehetősége
A JavaEE-ben megvalósított alkalmazások minden olyan Java alkalmazásszerveren futnak, melyek az adott verziójú JavaEE-t támogatják. Ez az át-járhatóság tovább erősíti a Java egyébként is cross-platform tulajdonságát(bár attól hogy egy nyelv cross-platform, még nem lenne természetes ekkorakomplexitású alkalmazások mozgatása AS-ek között).
A feladatot két különböző EAS-ra fogjuk elkészíteni/deploy-olni.
Bedők Dávid (UNI-OBUDA) BookStore (multiple-eas.tex) 2018-01-17 v1.1 7 / 110
Cross-Platform Java
Bedők Dávid (UNI-OBUDA) BookStore (cross-platform.tex) 2018-01-17 v1.1 8 / 110
Repository
[gradle|maven]\jboss\booklight� �1 > gradle clean build� �Megjegyzés : a gradle build-je ear plugin esetén ear-t, war plugin ese-tén war-t, java plugin esetén compile-t fog végrehajtani (ezek mind függ-nek a build-től).
Bedők Dávid (UNI-OBUDA) BookStore (repository-booklight-gradle.tex) 2018-01-17 v1.1 9 / 110
Git alapokLokális módosítások eldobása
A blueprint repository frissítése (Git pull) szükséges, ha az origin/master(branch) változott. E művelet előtt a lokális változásainkat el kell dobni.
Working copy kiválasztása (root könyvtárban)� �1 > git checkout .� �Lokális módosítások eldobása� �1 > git reset --hard� �Új állományok/könyvtárak eldobása� �1 > git clean -fd� �Változások leszedése a master-ről� �1 > git pull� �
Bedők Dávid (UNI-OBUDA) BookStore (git-basics.tex) 2018-01-17 v1.1 10 / 110
GitExtensionsGit grafikus eszköz Windows OS-hez
http://gitextensions.github.io/https://github.com/gitextensions
Verzió: 2.50.02OS: Windows (NIX esetén Mono 5.0 szükséges)
Grafikus felületet biztosít a Git parancsok végrehajtásához. Nem csak eszköz,tanítja is a kiadott parancsokat.A Git használat nem lineáris, és ugyanaz a feladat többféleképpen is meg-oldható. Minden külső eszköz használata e végett magában foglal némi koc-kázatot (nem biztos hogy a tool azt hajtja végre, amit mi szeretnénk).Alapfunkciók esetén szinte kockázatmentes.
Bedők Dávid (UNI-OBUDA) BookStore (git-gitextensions.tex) 2018-01-17 v1.1 11 / 110
SourceTreeOS független modern Git GUI
https://www.sourcetreeapp.com/
Verzió: 2.6.3aOS: Windows / Mac OS
Elegáns, modern felület, néhol kicsit körülményes (pl. git log/blame esetén),felületét szokni kell, de azt követően hatékony eszköz. Windows rendszerekenkorábban lassú volt. Nem tanítja a git parancsokat, mint pl. a GitExtensions.
Bedők Dávid (UNI-OBUDA) BookStore (git-sourcetree.tex) 2018-01-17 v1.1 12 / 110
Git Commit és PushÚj fejlesztések/hibajavítások megosztása
Állapot lekérdezése:� �1 > git status� �Stage� �1 > git add [FILENAME]� �Commit (-a/–all, -m/–message)� �1 > git commit -a -m "[ COMMIT_MESSAGE ]"� �Változások felküldése a master-re� �1 > git push� �
Bedők Dávid (UNI-OBUDA) BookStore (git-commit.tex) 2018-01-17 v1.1 13 / 110
Enterprise Gradle projectHierarchical Multi-project
Több project, hierarchiába szervezve. WebLayer
• gradle java és war plugin → war• EAR web module
. EJBService• gradle java → jar• EAR ejb module
. Root project• gradle ear plugin → ear
Bedők Dávid (UNI-OBUDA) BookStore (javaee-project-gradle.tex) 2018-01-17 v1.1 14 / 110
WAR - Web application ARchive
Könyvtár struktúraMETA-INF/
MANIFEST.MFWEB-INF/
classes/hu/
qwaevisz/demo/
Lorem.classIpsum.class
lib/dummy.jar
web.xmlindex.htmllogo.jpgbase.css� �1 <web -app version="3.0" xmlns="http: //java.sun.com/xml/ns/javaee"2 xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance"3 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web -app_3_0.xsd">4 [...]5 </web -app>� �
web.xml
Bedők Dávid (UNI-OBUDA) BookStore (war.tex) 2018-01-17 v1.1 15 / 110
public resources (alkönyvtárakba elhelyezhetőek)
web application deployment descriptor
EAR - Enterprise ARchive
Könyvtár struktúraMETA-INF/
MANIFEST.MFapplication.xml
lib/dummy.jar
xyz.jarabc.war� �1 <?xml version="1.0"?>2 <application xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp: //java.sun.com/xml/ns/javaee/application_6.xsd"xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance" version="6">
3 <display -name>sample </display -name>4 <module >5 <ejb>xyz.jar</ejb>6 </module >7 <module >8 <web>9 <web -uri>abc.war</web -uri>
10 <context -root>abcwebapp </context -root>11 </web>12 </module >13 <library -directory >lib</library -directory >14 </application >� �
application.xmlBedők Dávid (UNI-OBUDA) BookStore (ear.tex) 2018-01-17 v1.1 16 / 110
3rd party library
Multi-project könyvtár struktúra létrehozásaEgyszerűsített könyvesbolt
Könyvtár struktúrabooklight/
bl-ejbservice/src/
main/java/resources/
META-INF/ejb-jar.xml
build.gradlebl-weblayer/
src/main/
java/webapp/
WEB-INF/web.xml
build.gradlebuild.gradlesettings.gradle
Bedők Dávid (UNI-OBUDA) BookStore (multi-project.tex) 2018-01-17 v1.1 17 / 110
EJB module - Deployment Descriptorejb-jar.xml
src | main | resources | META-INF | ejb-jar.xml� �1 <ejb -jar xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance"2 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http: //java.sun.com/xml/ns/javaee/ejb -jar_3_0.xsd"3 version="3.0">45 </ejb -jar>� �
ejb-jar.xml
Kötelező elem?Bár a Gradle és a JBoss nem követeli meg az üres ejb-jar.xml jelenlétét a classpath-on, ér-demes szerepeltetni az átjárhatóság végett (pl. Maven megköveteli a jelenlétét). A deploymentdescriptor -ban definiálható szabályok jelentős részét ma már annotációk segítségével a forráskód-ban helyezzük el. A leíró xml precedenciája mindig magasabb (felül lehet írni az annotációk általszabályozott elemeket).
Bedők Dávid (UNI-OBUDA) BookStore (ejb-jar.tex) 2018-01-17 v1.1 18 / 110
Root EAR projectGradle EAR plugin
� �1 apply plugin: ’eclipse ’2 apply plugin: ’ear ’34 dependencies {5 deploy project(’bl -ejbservice ’)6 deploy project(path: ’bl-weblayer ’, configuration: ’archives ’)7 }� �
build.gradle� �1 include ’bl-ejbservice ’2 include ’bl-weblayer ’� �
settings.gradle
Bedők Dávid (UNI-OBUDA) BookStore (gradle-root-project.tex) 2018-01-17 v1.1 19 / 110
Project project(String path)Project project(String path, String configuration)
Az ear plugin dependency configuration lehetőségei : deploy és earlib.
EJB Service subprojectGradle Java plugin
� �1 apply plugin: ’eclipse ’2 apply plugin: ’java ’34 repositories { mavenCentral () }56 jar { archiveName ’bl-ejbservice.jar ’ }78 dependencies {9 compile group: ’javax ’, name:’javaee -api ’, version :’6.0’
10 }� �build.gradle
Bedők Dávid (UNI-OBUDA) BookStore (gradle-ejbservice-project.tex) 2018-01-17 v1.1 20 / 110
Pontosan ez az alapértelmezettérték, így elhagyható a teljesblokk.
WebLayer subproject
� �1 apply plugin: ’eclipse ’2 apply plugin: ’java ’3 apply plugin: ’war ’45 repositories { mavenCentral () }67 war { archiveName ’bl-weblayer.war ’ }89 dependencies {
10 providedCompile project(’:bl -ejbservice ’)11 providedCompile group: ’javax ’, name:’javaee -api ’, version :’6.0’12 }� �
build.gradle
Bedők Dávid (UNI-OBUDA) BookStore (gradle-weblayer-project.tex) 2018-01-17 v1.1 21 / 110
A war plugin dependency configuration lehetőségei :
. providedCompile : kell a fordításhoz, de a con-tainer biztosítja
. providedRuntime : a container biztosítja
Használható a java plugin compile dc-je is : kell a for-dításhoz, de a container nem biztosítja (az war artifactWEB-INF\lib könyvtárába fog kerülni).
A " :" jelentése egy project neve előtt azt jelzi, hogy a projectet a rootproject-től kiindulva kell keresni (absolute elérés lesz, nem pedig relative).
Enterprise JavaBeans
. Szerveroldali üzleti komponensek (back-end services)
. JSR19, JSR152, JSR220, JSR318, JSR345
. IBM (1997), majd Sun Microsystems (1999)
. Egyfajta "best-practice" annak érdekében, hogy az üzleti értéket"kelljen csak" lefejleszteni, ne a "tipikus" keret dolgokat (boilerplateelemeket).
• Tranzakciókezelés• Konkurrenciakezelés• Aszinkron metódushívás• Eseménykezelés• Java Message Service integráció (Message Driven Beans)• Perzisztencia integráció támogatása (de már nem része a perstence az
EJB specifikációnak). Verziók
• EJB1.x: minden "remote"• EJB2.x: nagyon "kényelmetlen", túlbonyolított• EJB3.x: a Spring Framework és a Hibernate tapasztalatai alapján
újraalkotott elképzelés (POJO-kal dolgozik mint a Spring FW és szakítaz entity bean-ekkel (inkább támogatja a perzisztens réteget, nemmegvalósítja))
Bedők Dávid (UNI-OBUDA) BookStore (ejb.tex) 2018-01-17 v1.1 22 / 110
EJB típusok
. Session Beans• Stateless SB (SLSB)
◦ Állapotmentes• Stateful SB (SFSB)
◦ Állapottartó◦ Aktiválás/Passziválás◦ Fontos a szerializálhatóság
• Singleton SB (SSB)◦ "Egyke"
. Message Driven Beans (MDB)• Üzenetvezérelt• Elsősorban aszinkron feldolgozás• Nincs kliens interface
. Entity Beans• Deprecated, EJB 3.x-től a JPA helyettesíti
Bedők Dávid (UNI-OBUDA) BookStore (ejb-types.tex) 2018-01-17 v1.1 23 / 110
Business Layer
Definiáljunk néhány üzleti metódust:
. ISBN1 alapján egy könyv adatainak biztosítása• BookStub getBook ( String isbn )
. Keresési feltételek alapján a feltételnek megfelelő könyvek adatainakkinyerése• List<BookStub> getBooks ( BookCriteria criteria )
. FacadeException : ha az üzleti kérés nem teljesíthető
Definiáljunk az ezekhez szükséges DTO2-kat:
. BookStub: isbn (String), author (String), title (String), category(BookCategoryStub), price (double), numberOfPages (int)
. BookCategoryStub: SCIFI, LITERATURE, HISTORICAL, PHILOSOPHY
. BookCriteria: author (String), title (String), minPrice (int),maxPrice (int)
1 International Standard Book Number2Data Transfer Object
Bedők Dávid (UNI-OBUDA) BookStore (business-layer.tex) 2018-01-17 v1.1 24 / 110
Domain osztályok - Könyv kategóriák� �1 package hu.qwaevisz.booklight.ejbservice.domain;2 public enum BookCategoryStub {34 SCIFI("Sci -Fi"),5 LITERATURE("Literature"),6 HISTORICAL("Historical"),7 PHILOSOPHY("Philosophy");89 private final String label;
1011 private BookCategoryStub(String label) {12 this.label = label;13 }1415 public String getLabel () {16 return this.label;17 }18 public String getName () {19 return this.name();20 }21 }� �
BookCategoryStub.javaBedők Dávid (UNI-OBUDA) BookStore (domain-bookcategorystub.tex) 2018-01-17 v1.1 25 / 110
Domain osztályok - Könyv� �1 package hu.qwaevisz.booklight.ejbservice.domain;2 public class BookStub {3 private String isbn;4 private String author;5 private String title;6 private BookCategoryStub category;7 private double price;8 private int numberOfPages;9
10 public BookStub(String isbn , String author , String title ,BookCategoryStub category , double price , int numberOfPages){
11 this.isbn = isbn;12 this.author = author;13 this.title = title;14 this.category = category;15 this.price = price;16 this.numberOfPages = numberOfPages;17 }18 [...]19 }� �
BookStub.javaBedők Dávid (UNI-OBUDA) BookStore (domain-bookstub.tex) 2018-01-17 v1.1 26 / 110
Domain osztályok - Keresési feltételek
� �1 package hu.qwaevisz.booklight.ejbservice.domain;23 public class BookCriteria {45 private String author;6 private String title;7 private BookCategoryStub category;8 private int minimumPrice;9 private int maximumPrice;
1011 public BookCriteria () {12 }1314 [...]15 }� �
BookCriteria.java
Bedők Dávid (UNI-OBUDA) BookStore (domain-bookcriteria.tex) 2018-01-17 v1.1 27 / 110
Domain osztályok - Dobható üzleti kivétel
� �1 package hu.qwaevisz.booklight.ejbservice.exception;23 public class FacadeException extends Exception {45 private static final long serialVersionUID = 1L;67 public FacadeException(String message) {8 super(message);9 }
1011 public FacadeException(String message , Throwable cause) {12 super(message , cause);13 }1415 }� �
FacadeException.java
Bedők Dávid (UNI-OBUDA) BookStore (facadeexception.tex) 2018-01-17 v1.1 28 / 110
Stateless Session BeanLocal interface
� �1 package hu.qwaevisz.booklight.ejbservice.facade;23 import java.util.List;4 import javax.ejb.Local;5 import hu.qwaevisz.booklight.ejbservice.domain.BookCriteria;6 import hu.qwaevisz.booklight.ejbservice.domain.BookStub;7 import hu.qwaevisz.booklight.ejbservice.exception.FacadeException;89 @Local
10 public interface BookFacade {1112 BookStub getBook(String isbn) throws FacadeException;1314 List <BookStub > getBooks(BookCriteria criteria) throws FacadeException;15 }� �
BookFacade.java
@Remote : költséges és lassú (hálózati hívás, serializáció), RMI, eredeti kon-cepció csak ezt támogatta, különböző JVM-ek között használjuk@Local : olcsó és gyors, azonos JVM-en belül (elsősorban adott EAR-onbelül)
Bedők Dávid (UNI-OBUDA) BookStore (bookfacade.tex) 2018-01-17 v1.1 29 / 110
Stateless Session BeanImplementation
� �1 package hu.qwaevisz.booklight.ejbservice.facade;23 [...]45 @Stateless(mappedName = "ejb/bookFacade")6 public class BookFacadeImpl implements BookFacade {78 @Override9 public BookStub getBook(String isbn) throws FacadeException {
10 return new BookStub(isbn , "Frank Herbert", "Dune", BookCategoryStub.SCIFI , 3500,896);
11 }1213 @Override14 public List <BookStub > getBooks(BookCriteria criteria) throws FacadeException {15 List <BookStub > stubs = new ArrayList <BookStub >();16 stubs.add(new BookStub("978 -0441172719", "Frank Herbert", "Dune",
BookCategoryStub.SCIFI , 3500, 896));17 stubs.add(new BookStub("978 -0684824710", "Daniel C. Dennett", "Darwin ’s dangerous
idea", BookCategoryStub.PHILOSOPHY , 4500, 586));18 return stubs;19 }2021 }� �
BookFacadeImpl.java
Bedők Dávid (UNI-OBUDA) BookStore (bookfacadeimpl.tex) 2018-01-17 v1.1 30 / 110
Mock implementáció(literálokat ad vissza)
Stateless Session Bean@Stateless annotáció
@Stateless : Stateless Session Bean EJB típus definiálása. name : ejb neve
• JNDI lookup során használatos• alapértelmezetten az unqualified name (pl. : BookFacadeImpl)
. mappedName : global JNDI név• gyártó specifikus (vendor specific)
. description : leírás
Bedők Dávid (UNI-OBUDA) BookStore (slsb.tex) 2018-01-17 v1.1 31 / 110
ServletEgyelőre csak tesztelési célból
� �1 package hu.qwaevisz.booklight.weblayer.servlet;2 [...]3 @WebServlet("/BookPing")4 public class BookPingServlet extends HttpServlet {56 @EJB7 private BookFacade facade;89 @Override
10 protected void doGet(HttpServletRequest request , HttpServletResponse response) throwsServletException , IOException {
11 response.setCharacterEncoding("UTF -8");12 final PrintWriter out = response.getWriter ();13 try {14 final BookStub book = this.facade.getBook("978 -0441172719");15 out.println(book.toString ());16 } catch (final FacadeException e) {17 out.println(e.getLocalizedMessage ());18 }19 out.close();20 }21 }� �
BookPingServlet.java
Bedők Dávid (UNI-OBUDA) BookStore (bookpingservlet.tex) 2018-01-17 v1.1 32 / 110
EJB proxy inject-álása@EJB annotáció
@EJB : Session Bean proxy beszúrása. Csak az EJB "érdekszférájában" használható
• Minden EJB ide tartozik• Minden Servlet ide tartozik (@WebServlet)• stb..
. beanName vagy lookup : az EJB feloldásához használhatóattribútumok• A kettő közül egy időben csak az egyik használható• Ha csak egy implementáció van, akkor alkalmazáson belül egyik
attribútumot sem kell használni (típus alapján megtalálja acontainer a megfelelőt).
• beanName : A Session bean name értékére refereál• lookup : A Session bean JNDI nevére refereál
Bedők Dávid (UNI-OBUDA) BookStore (ejbannotation.tex) 2018-01-17 v1.1 33 / 110
Webalkalmazás fejlesztés alapjai Java nyelvenServletek és JPS-k
Az Óbudai Egyetem "Modern programozási nyelvek" laborjának ide vonat-kozó részei szükséges és elégséges feltétele a jelen labor során bemutatottfrontend fejlesztésnek.
A tárgy nem hivatalos oldala:http://users.nik.uni-obuda.hu/bedok.david/jse.html
A tárgy hivatalos oldala:http://users.nik.uni-obuda.hu/java/
Bedők Dávid (UNI-OBUDA) BookStore (servlets-ref.tex) 2018-01-17 v1.1 34 / 110
Red Hat® JBoss® MiddlewareEnterprise Application Platform
http://www.jboss.org/Install : unzipEnterprise JavaBeans Open Source Software → EJBoss
→ JBoss (az EJB® Sun trademark volt)JEE 7 compliant verzió: v7.0.0 (2016.05.10.)JEE 6 compliant verzió: v6.4.0 (2015.04.15.)Kereskedelmi termék!Standalone / Domain modeTartalma: https://access.redhat.com/articles/112673
. RESTEasy - 2.3.10.Final
. Hibernate Core - 4.2.18.Final
. Hibernate JPA 2.0 API - 1.0.1.Final
. JSF2 - 2.1.28.Final
. HornetQ - 2.3.25.Final (EAP 7.x → JBoss A-MQ)
. JBoss Logging - 3.1.4.GA
. JAXB - 2.2.5-redhat-9
. Apache Web Server - 2.2.26
. ...Bedők Dávid (UNI-OBUDA) BookStore (jboss.tex) 2018-01-17 v1.1 35 / 110
Red Hat® WildFly® MiddlewareEnterprise Application Platform
http://wildfly.org/Install : unzipJEE 7 compliant verzió: v11.0.0.Final (2017.10.23.)JEE 7 compliant verzió: v10.1.0.Final (2016.08.19.)JEE 7 compliant verzió: v8.0.0.Final (2014.02.11.)A JBoss ingyenes változata.Standalone / Domain mode
JBoss vs. WildFlyA két alkalmazásszerver gyakorlati használata közel megegyezik, ha valaki azegyikkel dolgozott már, a másik vonatkozásában nem fog váratlan nehézsé-gekbe belefutni.
Bedők Dávid (UNI-OBUDA) BookStore (wildfly.tex) 2018-01-17 v1.1 36 / 110
JBoss - Standalone modeServer instance kezelése
Standalone mód ([JBOSS-HOME]\standalone):. \configuration\standalone.xml. \deployments. logs\server.log
Standalone mód elindítása (standalone.xml):� �1 > cd [JBOSS -HOME]\bin2 > standalone .[bat|sh]� �Standalone mód elindítása (custom.xml használata):� �1 > [JBOSS -HOME]\bin\standalone .[bat|sh] custom.xml� �Standalone server instance leállítása:� �1 > [JBOSS -HOME]/bin/jboss -cli.[bat|sh] --connect command =: shutdown� �
Bedők Dávid (UNI-OBUDA) BookStore (jboss-standalone.tex) 2018-01-17 v1.1 37 / 110
Oracle® WebLogic® ServerEnterprise Application Server
http://www.oracle.com/technetwork/middleware/weblogic/
JEE 7 compliant verzió: v12.2.1.3JEE 6 compliant verzió: v12.1.3Kereskedelmi termék!Az Oracle felvásárlását megelőzően a BEA terméke volt.
A JavaEE mellett a Spring Framework-öt is támogatja (a SF számára egyApache Tomcat® is legtöbbször elégséges).
Bedők Dávid (UNI-OBUDA) BookStore (weblogic.tex) 2018-01-17 v1.1 38 / 110
Oracle® WebLogic® ServerTelepítés
. Unzip (wls1213_dev_update3.zip)• pl. : c:\work\wls12130\
. Környezeti változó:• MW_HOME → c:\work\wls12130\
. Telepítő futtatása (Run as Administrator)• [MW_HOME]\configure.cmd• Do you want to configure a new Domain? Yes (Y)• username: weblogic• password: AlmafA1#
. WebLogic Server Administration Console• http://localhost:7001/console
Bedők Dávid (UNI-OBUDA) BookStore (weblogic-install.tex) 2018-01-17 v1.1 39 / 110
Oracle® WebLogic® ServerDomain elindítása
Domain elindítása:� �1 > [MW_HOME ]\ user_projects\domains\mydomain\startWebLogic.cmd� �Domain leállítása:
. WebLogic Server Administration Console-ról illetve a console ablakterminálása (Ctrl+C)• Environment | Servers | Control tab
◦ select “myserver” → Shutdown∗ When work completes vagy∗ Force Shutdown now
Bedők Dávid (UNI-OBUDA) BookStore (weblogic-start.tex) 2018-01-17 v1.1 40 / 110
Oracle® WebLogic® ServerApplication deploy
. WebLogic Server Administration Console• Deployments | Install..
◦ Browse EAR◦ Ezt követően lehet ugyanezen path-ról egy-két kattintássalfrissíteni az alkalmazást (redeploy)
A WebLogic gazdag statisztikákat kezel, monitorozza a futó komponenseket.Érdemes az Admin Console-on megvizsgálni a lehetőségeket.
Autodeploy könyvtár:[MW_HOME]\user_projects\domains\mydomain\autodeploy\
Megjegyzés : az auto deploy-olt alkalmazások nem törölhetőek/frissíthetőekA Deployments alól (a autodeploy könyvtárból kell kezelnünk ezt is).
Bedők Dávid (UNI-OBUDA) BookStore (weblogic-deploy.tex) 2018-01-17 v1.1 41 / 110
JBoss - DeployAlkalmazás telepítése
[gradle|maven]\jboss\booklight\build\libs\booklight.ear
Másolás ide: [JBOSS-HOME]\standalone\deployments\� �09:14:13 ,505 INFO [org.jboss.as.server.deployment] (MSC service thread 1-6)JBAS015876: Starting deployment of "booklight.ear" (runtime -name: "booklight.ear")09:14:13 ,533 INFO [org.jboss.as.server.deployment] (MSC service thread 1-6)JBAS015973: Starting subdeployment (runtime -name: "bl-ejbservice.jar")09:14:13 ,534 INFO [org.jboss.as.server.deployment] (MSC service thread 1-5)JBAS015973: Starting subdeployment (runtime -name: "bl-weblayer.war")09:14:13 ,577 INFO[org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSCservice thread 1-1) JNDI bindings for session bean named BookFacadeImpl in deploymentunit subdeployment "bl -ejbservice.jar" of deployment "booklight.ear" are as follows:
java:global/booklight/bl-ejbservice/BookFacadeImpl!hu.qwaevisz.booklight.ejbservice.facade.BookFacadejava:app/bl-ejbservice/BookFacadeImpl!hu.qwaevisz.booklight.ejbservice.facade.BookFacadejava:module/BookFacadeImpl!hu.qwaevisz.booklight.ejbservice.facade.BookFacadejava:global/booklight/bl-ejbservice/BookFacadeImpljava:app/bl-ejbservice/BookFacadeImpljava:module/BookFacadeImpl
09:14:13 ,646 INFO [org.jboss.web] (ServerService Thread Pool -- 11) JBAS018210:Register web context: /bl-weblayer09:14:13 ,739 INFO [org.jboss.as.server] (DeploymentScanner -threads - 2) JBAS015859:Deployed "booklight.ear" (runtime -name : "booklight.ear")� �
server.log
Bedők Dávid (UNI-OBUDA) BookStore (jboss-deploy.tex) 2018-01-17 v1.1 42 / 110
TesztServlet kipróbálása
http://localhost:8080/bl-weblayer/BookPing� �BookStub [isbn =978 -0441172719 , author=Frank Herbert , title=Dune ,category=SCIFI , price =3500.0 , numberOfPages =896]� �
Bedők Dávid (UNI-OBUDA) BookStore (booklight-test.tex) 2018-01-17 v1.1 43 / 110
BookLight → BookStoreProject átalakítása
A BookStore project teljes egészében tartalmazza a BookLight funkcio-nalitását, azonban az egyértelműség végett a projekt és a csomagok nevekülönböző.
[gradle|maven]\jboss\bookstore
Innentől kezdve a BookStore gyökere elkészíthető a BookLight alapján, ésa fejlesztés a BookStore projektben folytatható.A BookStore már tartalmazni fogja a data tier réteget (persistence layer).
Bedők Dávid (UNI-OBUDA) BookStore (booklight-to-bookstore.tex) 2018-01-17 v1.1 44 / 110
Root project - RefactorRedundancia csökkentése� �1 [..]2 ext {3 testngVersion = ’6.9.+’4 jeeVersion = ’6.0’5 servletapiVersion = ’3.0.1’6 }78 subprojects {9 apply plugin: ’eclipse ’
10 apply plugin: ’java ’1112 repositories { mavenCentral () }1314 dependencies {15 compile group: ’javax ’, name: ’javaee -api ’, version:
jeeVersion16 testCompile group: ’org.testng ’, name: ’testng ’, version:
testngVersion17 }18 }19 [..]� �
build.gradleBedők Dávid (UNI-OBUDA) BookStore (gradle-root-refactor.tex) 2018-01-17 v1.1 45 / 110
A subprojects {...} blokk minden gyer-mek build script-re érvényes (merge), és léte-zik egy allprojects {...} blokk is, melymind az aktuális (ez esetben a root), minda gyermek scriptekre érvényes.
Subprojects - RefactorEgyedi eltérések meghatározása
bs-ejbservice subproject :� �1 jar { archiveName ’bs-ejbservice.jar ’ }� �
build.gradle
bs-weblayer subproject :� �1 apply plugin: ’war ’23 war { archiveName ’bs-weblayer.war ’ }45 dependencies {6 providedCompile project(’:bs -ejbservice ’)7 providedCompile group: ’javax ’, name: ’javaee -api ’, version:
jeeVersion8 }� �
build.gradle
Bedők Dávid (UNI-OBUDA) BookStore (gradle-subprojects-refactor.tex) 2018-01-17 v1.1 46 / 110
Mivel ez az alapértelmezés, akár üres is lehetne ez a build file.
Apache Log4JNapló készítése 3rd party library segítségével
http://logging.apache.org/log4j/2.x/http://logging.apache.org/log4j/1.2/
Log4j2 verzió: v2.9.1Log4j verzió: v1.2.17
JBoss 6.4 egyelőre a Log4j 1.2.x-et támogatja, a WebLogicalapértelmezetten nem támogatja.
Standard?A JavaEE-nek nem része a Log4J, a standard a JDK Logging-ot tartalmazza(ezt a JBoss és a WebLogic is támogatja természetesen).
Simple Logging Facade for Java (SLF4J): képes elfedni a különbözőlogging megoldásokat, és mindezeket dinamikusan kezelni (java.util.logging,logback, log4j).
Bedők Dávid (UNI-OBUDA) BookStore (log4j.tex) 2018-01-17 v1.1 47 / 110
Apache Log4JFogalmak
. Loggers• Összerendeli a Java csomagot, a log level-t és az appendereket (1
logger N appender)• Egy ún. Root Logger mindig létezik.
. Appenders• Definiálja a log üzenet “pattern”-jét és a logolás típusát (pl. file,
rolling file, e-mail, jms message, stb.).
KonfigurációStandalone alkalmazás esetében log4j(2).xml vagy log4j(2).properties ál-lományban konfiguráljuk. A Jboss esetén a Logging subsystem csomagolja,és a standalone.xml-en keresztül konfiguráljuk.
Bedők Dávid (UNI-OBUDA) BookStore (log4j-concepts.tex) 2018-01-17 v1.1 48 / 110
Apache Log4JNaplózási szintek
. TRACE• Nagyon részletes adatok, csak kivételes esetben érdemes bekapcsolni (pl. cik-
lusmagok belsejének logjai).. DEBUG
• Hibakeresési/fejlesztési szint. Végigkövetik a log üzenetek az üzleti folyama-tokat komponens szinten. A Debug logok segítségével reprodukálható pl. afelhasználó tevékenysége.
. INFO• Azok az üzenetek, melyek minden esetben jelenjenek meg a logban. Különösen
fontos és semmiképpen sem gyakori események írhatóak ki ezen a szinten. Azinfo szintű üzenetek kb. a "hahó, itt vagyok" típusúak, belőlük pl. hibát keresni,reprodukálni nem lehet.
. WARN• Figyelmeztetés. Általában olyan esemény, mely azért nem hiba, mert az al-
kalmazás lekezeli valamilyen módon, vagy pl. a tranzakció végrehajtódik, debizonyos korlátozásokkal.
. ERROR• Hiba. Olyan részletes leírást tartalmazzon, amennyire lehetséges. Ez lesz az az
információ, amit a hibajegy javításakor birtokolni fogunk. Ez alapján kérni kelltudni a reprodukciót (mely során már kérhetünk debug logokat is).
. FATAL• Ritkán alkalmazzuk. Végzetes hiba. Az ügyfelek már az Error esetén is üvölte-
nek, nem érdemes fatális hibákkal ijesztgetni őket.
Bedők Dávid (UNI-OBUDA) BookStore (log4j-levels.tex) 2018-01-17 v1.1 49 / 110
Apache Log4JINFO szintű logolás minta
� �1 public class BookPingServlet extends HttpServlet {23 private static final Logger LOGGER =
Logger.getLogger(BookPingServlet.class);45 @Override6 protected void doGet(HttpServletRequest request ,
HttpServletResponse response) throws ServletException ,IOException {
7 LOGGER.info("Get Book by user");8 [..]9 }
10 }� �BookPingServlet.java
Bedők Dávid (UNI-OBUDA) BookStore (log4j-sample-info.tex) 2018-01-17 v1.1 50 / 110
Apache Log4JDEBUG szintű logolás minta� �1 public class BookFacadeImpl implements BookFacade {23 private static final Logger LOGGER =
Logger.getLogger(BookFacadeImpl.class);45 @Override6 public BookStub getBook(String isbn) {7 if (LOGGER.isDebugEnabled ()) {8 LOGGER.debug("Get Book (isbn: " + isbn + ")");9 }
10 [..]11 }12 }� �
BookFacadeImpl.java
Fontos! Production kódban a DEBUG üzenetek se a teljesítményt, se a memóriát ne terheljék,mivel valós futás közben általában a DEBUG szintet nem naplózzuk. A bemutatott megoldás egylogikai ellenőrzés költségű, míg az alternatív megoldás egy String literált elhelyez a permspace-en.A String összefűzés futását mindenképpen kerüljük el ilyen esetekben (ebből StringBuilder-t készíta fordító, de feleslegesen optimalizálja a sort ha nem naplózzuk).
Bedők Dávid (UNI-OBUDA) BookStore (log4j-sample-debug.tex) 2018-01-17 v1.1 51 / 110
alternatív megoldás (kevesebb kódsor):LOGGER.debug(String.format("Get Book (isbn: %s)", isbn);
JBoss Logging Subsystemstandalone.xml áttekintés
� �1 <server xmlns="urn:jboss:domain:1 .7">2 <extensions >3 <extension module="org.jboss.as.logging"/>4 [..]5 </extensions >6 <management >[..]</management >7 <profile >8 <subsystem xmlns="urn:jboss:domain:logging:1 .5">9 [APPENDERS DETAILS]
10 [LOGGER DETAILS]11 </subsystem >12 [..]13 </profile >14 <interfaces >[..]</interfaces >15 <socket -binding -group>[..]</socket -binding -group>16 </server >� �
standalone.xml
Bedők Dávid (UNI-OBUDA) BookStore (jboss-logging.tex) 2018-01-17 v1.1 52 / 110
JBoss Logging Subsystemstandalone.xml módosítása
� �1 <console -handler name="CONSOLE">[..]</console -handler >2 <periodic -rotating -file -handler
name="FILE">[..]</periodic -rotating -file -handler >34 <logger category="hu.qwaevisz">5 <level name="DEBUG"/>6 </logger >78 <root -logger >9 <level name="INFO"/>
10 <handlers >11 <handler name="CONSOLE"/>12 <handler name="FILE"/>13 </handlers >14 </root -logger >15 <formatter name="PATTERN">[..]</formatter >� �
standalone.xml
Bedők Dávid (UNI-OBUDA) BookStore (jboss-add-logger.tex) 2018-01-17 v1.1 53 / 110
Naplózás WebLogic alattJDK Logging
A Log4J beállításához külön lépések szükségesek (alapértelmezetten nemtámogatja a WebLogic, bár szállít hozzá wrapper-t).Helyette JDK Logging-ot használjunk (JavaEE része, java.util.logging.*).
� �1 import java.util.logging.Level;2 import java.util.logging.Logger;3 [..]4 private static final Logger LOGGER =
Logger.getLogger(BookListController.class.getName ());5 [..]6 LOGGER.info("Get All Books");� �
BookListController.java
Bedők Dávid (UNI-OBUDA) BookStore (weblogic-logging.tex) 2018-01-17 v1.1 54 / 110
JDK Logging vs Log4J
JDK Logging Level Log4J Level JDK Logging sampleFINEST - LOGGER.finest();FINER TRACE LOGGER.finer();FINE DEBUG LOGGER.fine();
CONFIG - LOGGER.config();INFO INFO LOGGER.info();
WARNING WARN LOGGER.warning();SEVERE ERROR LOGGER.severe();
- ERROR -
Ha a hiba mellé a kivételt is szeretnénk továbbadni (ez Log4J eseténegyszerű overload metódus):� �1 LOGGER.log(Level.SEVERE , e.getMessage (), e);� �
Bedők Dávid (UNI-OBUDA) BookStore (logging-compare.tex) 2018-01-17 v1.1 55 / 110
Apache Log4JGradle integráció (root project)
� �1 [..]2 ext {3 [..]4 log4jVersion = ’1.2.17’5 }67 subprojects {8 [..]9
10 dependencies {11 compile group: ’log4j ’, name: ’log4j ’, version: log4jVersion12 [..]13 }1415 }16 [..]� �
build.gradle
Bedők Dávid (UNI-OBUDA) BookStore (log4j-gradle.tex) 2018-01-17 v1.1 56 / 110
PostgreSQLProfesszionális nyílt forráskódú adatbáziskezelő
http://www.postgresql.org/Verzió: v10.0 (2017.10.05.)Verzió: v9.6.5 (2017.09.31.)Telepítés : installerAlapértelmezett adatok: 5432 (port) és postgres (database)Alapértelmezett felhasználó: postgres (user) és root (password)Szerkesztő: pgAdmin III vagy pgAdmin IVKörnyezeti változók:. PSQL_HOME →c:\ProgramFiles\PostgreSQL\9.4. Path módosítása → %Path%;%PSQL_HOME%\bin
Professzionális eszközA mellett, hogy a PostgreSQL hasonlóan professzionális management lehe-tőséggel rendelkezik, mint pl. az Oracle DB vagy a SAP Adaptive ServerEnterprise (korábban Sybase ASE), létezik production környezetben rendszermelyben 4 TB adatot kezel.Bedők Dávid (UNI-OBUDA) BookStore (postgresql.tex) 2018-01-17 v1.1 57 / 110
PostgreSQL - psqlCsatlakozás
Verzió lekérdezése� �1 > psql --version2 psql (PostgreSQL) 9.4.1� �Csatlakozás (CLI)� �1 > psql -d postgres -h localhost -p 5432 -U postgres� �Csatlakozás és utasítások végrehajtása állományból� �1 > psql -d postgres -h localhost -p 5432 -U postgres -f [FILENAME]� �
Bedők Dávid (UNI-OBUDA) BookStore (postgresql-connect.tex) 2018-01-17 v1.1 58 / 110
Oracle MySQLA legnépszerűbb nyílt forráskódú adatbáziskezelő
https://www.mysql.com/Letöltés: https://dev.mysql.com/downloads/A Community verzió ingyenes (GPL).Verzió: v5.7.20Alapértelmezett adatok: 3306 (port)Alapértelmezett felhasználó: root (user) és - (password)Szerkesztő: MySQL WorkbenchKörnyezeti változók:. MYSQL_HOME →c:\ProgramFiles\MySQL\5.7\bin. Path módosítása → %Path%;%MYSQL_HOME%\bin
Népszerű eszközA PHP-s webfejlesztés világában a MySQL szinte nélkülözhetetlen, szinte nincsolyan Shared Hosting szolgáltatás, ahol ne a MySQL lenne elérhető mint perzisztensréteg. Különféle engine-eket támogat, mindegyiknek meg(lehet) a maga előnye/-hátránya. Az InnoDB támogat professzionális használatot (hibái ellenére), viszontpl. role-okat ez sem kezel még.
Bedők Dávid (UNI-OBUDA) BookStore (mysql.tex) 2018-01-17 v1.1 59 / 110
BookStore db scriptekAdatbázis, Szerep és Felhasználó létrehozása
[gradle|maven]\jboss\bookstore\database� �1 CREATE DATABASE bookstoredb;� �
create-database.sql� �1 CREATE ROLE bookstore_role WITH NOSUPERUSER NOCREATEDB
NOCREATEROLE;� �create-role.sql� �
1 CREATE USER bookstore_user;2 ALTER USER bookstore_user PASSWORD ’123 topSECret321 ’;3 GRANT bookstore_role TO bookstore_user;� �
create-user.sql
Bedők Dávid (UNI-OBUDA) BookStore (psql-bookstore-role-user.tex) 2018-01-17 v1.1 60 / 110
BookStore db scriptek futtatásaAdatbázis, Szerep és Felhasználó létrehozása
� �1 > psql -d postgres -h localhost -p 5432 -U postgres -f
create -database.sql23 > psql -d postgres -h localhost -p 5432 -U postgres -f
create -role.sql45 > psql -d postgres -h localhost -p 5432 -U postgres -f
create -user.sql� �Csatlakozás a bookstoredb adatbázishoz a bookstore_user felhasználóval� �1 > psql -d bookstoredb -h localhost -p 5432 -U bookstore_user� �
Bedők Dávid (UNI-OBUDA) BookStore (psql-bookstore-role-user-execute.tex) 2018-01-17 v1.1 61 / 110
BookStore db schemaKönyv és kategóriája� �1 CREATE TABLE bookcategory (2 bookcategory_id INTEGER NOT NULL ,3 bookcategory_name CHARACTER VARYING (100) NOT NULL ,4 CONSTRAINT PK_BOOKCATEGORY_ID PRIMARY KEY (bookcategory_id)5 );67 ALTER TABLE bookcategory OWNER TO postgres;89 CREATE TABLE book (
10 book_id SERIAL NOT NULL ,11 book_isbn CHARACTER VARYING (100) NOT NULL ,12 book_author CHARACTER VARYING (100) NOT NULL ,13 book_title CHARACTER VARYING (100) NOT NULL ,14 book_bookcategory_id INTEGER NOT NULL ,15 book_price REAL NOT NULL ,16 book_number_of_pages INTEGER NOT NULL ,17 CONSTRAINT PK_BOOK_ID PRIMARY KEY (book_id),18 CONSTRAINT FK_BOOK_BOOKCATEGORY FOREIGN KEY (book_bookcategory_id)19 REFERENCES bookcategory (bookcategory_id) MATCH SIMPLE ON UPDATE RESTRICT ON DELETE
RESTRICT20 );2122 ALTER TABLE book OWNER TO postgres;2324 CREATE UNIQUE INDEX UI_BOOK_ISBN ON book USING btree (book_isbn);� �
create-schema.sql
Bedők Dávid (UNI-OBUDA) BookStore (psql-bookstore-schema.tex) 2018-01-17 v1.1 62 / 110
SERIAL : létre fog jönni egybook_book_id_seq nevű dbsequence.
BookStore - grantadatbázis konfiguráció utolsó lépései
� �1 GRANT SELECT , INSERT , UPDATE , DELETE ON bookcategory , book TO
bookstore_role;23 GRANT USAGE , SELECT , UPDATE ON book_book_id_seq TO bookstore_role;� �
grant-access.sql
� �1 > psql -d bookstoredb -h localhost -p 5432 -U postgres -f
create -schema.sql23 > psql -d bookstoredb -h localhost -p 5432 -U postgres -f
grant -access.sql� �
Bedők Dávid (UNI-OBUDA) BookStore (psql-bookstore-grant.tex) 2018-01-17 v1.1 63 / 110
BookStore - AdatfeltöltésKezdeti adatok létrehozása� �1 INSERT INTO bookcategory (bookcategory_id , bookcategory_name)
VALUES (0, ’SCIFI’);2 INSERT INTO bookcategory (bookcategory_id , bookcategory_name)
VALUES (1, ’LITERATURE ’);3 INSERT INTO bookcategory (bookcategory_id , bookcategory_name)
VALUES (2, ’HISTORICAL ’);4 INSERT INTO bookcategory (bookcategory_id , bookcategory_name)
VALUES (3, ’PHILOSOPHY ’);56 INSERT INTO book (book_isbn , book_author , book_title ,
book_bookcategory_id , book_price , book_number_of_pages)VALUES (’978 -0441172719 ’, ’Frank Herbert ’, ’Dune’, 0, 3500,896);
7 [..]� �initial-data.sql
� �1 > psql -d bookstoredb -h localhost -p 5432 -U postgres -f
initial -data.sql� �Bedők Dávid (UNI-OBUDA) BookStore (psql-bookstore-initial.tex) 2018-01-17 v1.1 64 / 110
Adatbázis elérése Java-ban
JDBCJava SE témakörében ez gyakorlatban a java.sql csomag osztályainak hasz-nálatát jelenti. Ezen kívül szükség lesz még a használni kívánt adatbázisJDBC driver-ére (Java DataBase Connectivity, tipikusan egy jar file,mely az ODBC (Open Database Connectivity) driver Java-s változata.� �1 Class.forName("org.postgresql.Driver");2 Connection connection =
DriverManager.getConnection("jdbc:postgresql :// localhost :5432/ bookstoredb","bookstore_user", "123 topSECret321");
34 Statement statement = connection.createStatement ();5 ResultSet rs = statement.executeQuery("SELECT book_id , book_title
FROM book");6 while (rs.next()) {7 long id = rs.getLong("book_id");8 String title = rs.getString("book_title");9 }
10 rs.close();11 statement.close();1213 connection.close();� �
Bedők Dávid (UNI-OBUDA) BookStore (jdbc.tex) 2018-01-17 v1.1 65 / 110
A példakód a hibakezelést teljesen mellőzi. Működő pél-da a shopping projektben megtalálható, de a JPA hasz-nálatához ennek előzetes megismerése nem szükséges. AJDBC ily használatának legnagyobb hátránya a nem type-safe kezelés.
Java Persistence API
Bedők Dávid (UNI-OBUDA) BookStore (jpa.tex) 2018-01-17 v1.1 66 / 110
JBoss - Adatbázis integrációPostgreSQL
. Új module létrehozása: PostgreSQL JDBC driver
. Module regisztrálása a standalone domain-hez
. Database driver regisztrálása a standalone domain-ben
. bookstoredb datasource létrehozása a standalone domain-ben
Bedők Dávid (UNI-OBUDA) BookStore (jboss-database.tex) 2018-01-17 v1.1 67 / 110
JBoss - Új module létrehozásaPostgreSQL JDBC driver számára
environment\modules\org\postgresql\main\
Könyvtár struktúra[JBOSS\_HOME]/modules/
org/ → name directorypostgresql/ → name directory
main/ → slot directorymodule.xml → descriptorpostgresql-42.1.4.jar → JDBC driver https://jdbc.postgresql.org/� �
1 <module xmlns="urn:jboss:module:1 .1" name="org.postgresql">2 <resources >3 <resource -root path="postgresql -42.1.4. jar"/>4 </resources >5 <dependencies >6 <module name="javax.api"/>7 <module name="javax.transaction.api"/>8 </dependencies >9 </module >� �
module.xmlBedők Dávid (UNI-OBUDA) BookStore (jboss-new-module.tex) 2018-01-17 v1.1 68 / 110
JBoss - Module regisztrálásaStandalone domain
[JBOSS_HOME] | standalone | configuration | standalone.xml� �1 <subsystem xmlns="urn:jboss:domain:ee:1 .2">2 <global -modules >3 <module name="org.postgresql" slot="main"/>4 </global -modules >5 [..]6 </subsystem >� �
standalone.xml
Bedők Dávid (UNI-OBUDA) BookStore (jboss-register-module.tex) 2018-01-17 v1.1 69 / 110
JBoss - Database driver regisztrálásaStandalone domain
[JBOSS_HOME] | standalone | configuration | standalone.xml� �1 <subsystem xmlns="urn:jboss:domain:datasources:1 .2">2 <datasources >3 [..]4 <drivers >5 [..]6 <driver name="postgresql" module="org.postgresql">7 <xa-datasource -class>org.postgresql.xa.PGXADataSource </xa -datasource -class>8 </driver >9 </drivers >
10 </datasources >11 </subsystem >� �
standalone.xml
Bedők Dávid (UNI-OBUDA) BookStore (jboss-register-driver.tex) 2018-01-17 v1.1 70 / 110
JBoss - Datasource létrehozásaPostgreSQL bookstoredb adatbázisa számára
[JBOSS_HOME] | standalone | configuration | standalone.xml� �1 <subsystem xmlns="urn:jboss:domain:datasources:1 .2">2 <datasources >3 [..]4 <datasource jndi -name="java:jboss/datasources/bookstoreds"
pool -name="BookStoreDSPool" enabled="true" use -java -context="true">5 <connection -url>jdbc:postgresql: // localhost:5432/bookstoredb </connection -url>6 <driver >postgresql </driver >7 <security >8 <user -name>bookstore_user </user -name>9 <password >123 topSECret321 </password >
10 </security >11 </datasource >12 [..]13 </datasources >14 </subsystem >� �
standalone.xml
Bedők Dávid (UNI-OBUDA) BookStore (jboss-datasource.tex) 2018-01-17 v1.1 71 / 110
JNDI name : java:jboss/datasources/bookstoredsJDBC url : jdbc:postgresql://localhost:5432/bookstoredb
JBoss - DB restart utáni Connection validációBookStore datasource konfiguráció módosítása
[JBOSS_HOME] | standalone | configuration | standalone.xml� �1 <subsystem xmlns="urn:jboss:domain:datasources:1 .2">2 <datasources >3 <datasource jndi -name="java:jboss/datasources/bookstoreds"
pool -name="BookStoreDSPool" enabled="true" use -java -context="true">4 [..]5 <validation >6 <check -valid -connection -sql>SELECT 1</check -valid -connection -sql>7 <validate -on-match >true</validate -on-match >8 <background -validation >false</background -validation >9 </validation >
10 <statement >11 <share -prepared -statements >false</share -prepared -statements >12 </statement >13 </datasource >14 [..]15 </datasources >16 </subsystem >� �
standalone.xml
Bedők Dávid (UNI-OBUDA) BookStore (jboss-datasource-validation.tex) 2018-01-17 v1.1 72 / 110
WebLogic DataSource konfigurálásaServer Administration Console-on keresztül
. PostgreSQL JDBC library hozzáadása a domain classpath-ához• JDBC driver (pl. postgresql-9.4-1201.jdbc41.jar) másolása
ide: [MW\_HOME]\user\_projects\domains\mydomain\lib\• Server újraindítása
. WebLogic Server Administration Console• Services | Data Sources | Configuration tab
◦ New → Generic Data Source∗ Name: bookstoreds∗ JNDI name: jdbc/datasource/bookstoreds∗ Target: "myserver"∗ Database type: PostgreSQL
◦ Next, Next..∗ Database name: bookstoredb∗ Host name: localhost∗ Port: 5432 (default)∗ Database user name: bookstore_user∗ Password: 123topSECret321
◦ Érdemes tesztelni a kapcsolatot a felületen keresztül
Bedők Dávid (UNI-OBUDA) BookStore (weblogic-datasource.tex) 2018-01-17 v1.1 73 / 110
PersistenceÚj subproject
Könyvtár struktúrabookstore/
[..]bs-persistence/
src/main/
java/resources/
META-INF/ejb-jar.xmlpersistence.xml
build.gradle[..]
Bedők Dávid (UNI-OBUDA) BookStore (persistence-project.tex) 2018-01-17 v1.1 74 / 110
Root EAR projectMódosítás
� �1 [..]2 dependencies {3 [..]4 deploy project(’bs -persistence ’)5 }� �
build.gradle� �1 [..]2 include ’bs-persistence ’� �
settings.gradle
Bedők Dávid (UNI-OBUDA) BookStore (gradle-root-persistence.tex) 2018-01-17 v1.1 75 / 110
Persistence subprojectGradle Java plugin
� �1 jar { archiveName ’bs-persistence.jar ’ }� �
build.gradle
JPA implementációJBoss 6.4 runtime a Hibernate 4.3.10.Final-t használja mint JPA imp-lementáció, de mi kizárólag a JPA API-t (szeretnénk) használni fejlesztésközben, ezért nincs szükségünk erre a függőségre:’org.hibernate:hibernate-core:4.3.10.Final’
Bedők Dávid (UNI-OBUDA) BookStore (gradle-persistence-project.tex) 2018-01-17 v1.1 76 / 110
EJB Service subprojectPersistence függőség beállítása
� �1 [..]2 dependencies {3 compile project(’:bs-persistence ’)4 }� �
build.gradle
Függőségekbs-weblayer használja bs-ejbservice-t, hogy elérje a BookFacadeEJB-t.bs-ejbservice használja bs-persistence-t hogy elérje a BookServiceEJB-t.
Bedők Dávid (UNI-OBUDA) BookStore (gradle-ejbservice-modification.tex) 2018-01-17 v1.1 77 / 110
JPA PersistenceDeployment descriptor
hibernate.dialect : megadása nem kötelező, de ajánlott. Segítségével a Hibernate képes lesz PostgreSQLspecifikus natív query-ket is generálni. Ha itt nem adjuk meg, akkor is működni fog a project (a generáltANSI SQL jelen esetben elegendő).
src | main | resources | META-INF | persistence.xml� �1 <persistence xmlns="http://java.sun.com/xml/ns/persistence"2 xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance"3 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"4 version="2.0">5 <persistence -unit name="bs -persistence -unit"
transaction -type="JTA">6 <jta -data -source >java:jboss/datasources/bookstoreds </jta -data -source >7 <properties >8 <property name="hibernate.dialect"
value="org.hibernate.dialect.PostgreSQLDialect"/>9 <property name="hibernate.show_sql" value="true"/>
10 <property name="hibernate.format_sql" value="true"/>11 </properties >12 </persistence -unit>13 </persistence >� �
Bedők Dávid (UNI-OBUDA) BookStore (jboss-jpa-persistence.tex) 2018-01-17 v1.1 78 / 110
Persistence unit neve: bs-persistence-unitJNDI name : java:jboss/datasources/bookstoreds
JPA PersistenceDeployment descriptor
src | main | resources | META-INF | persistence.xml� �1 <?xml version="1.0"?>2 <persistence xmlns="http:// xmlns.jcp.org/xml/ns/persistence"3 xmlns:xsi="http://www.w3.org /2001/ XMLSchema -instance"4 xsi:schemaLocation="http:// xmlns.jcp.org/xml/ns/persistence
http:// xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"5 version="2.1">6 <persistence -unit name="bs -persistence -unit"
transaction -type="JTA">7 <provider >org.eclipse.persistence.jpa.PersistenceProvider </provider >8 <jta -data -source >jdbc/datasource/bookstoreds </jta -data -source >9 <class >hu.qwaevisz.bookstore.persistence.entity.Book</class >
10 <properties >11 <property name="eclipselink.logging.level" value="FINE"/>12 </properties >13 </persistence -unit>14 </persistence >� �
persistence.xml
Bedők Dávid (UNI-OBUDA) BookStore (weblogic-jpa-persistence.tex) 2018-01-17 v1.1 79 / 110
Az Oracle WebLogic a EclipseLink-et (TopLink) használ-ja mint JPA Provider, és a Hibernate beállítása csak úgylehetséges, ha kicseréljük minden függőségével együtt azelemeket (nem javasolt). Viszont a JPA Provider-ek kö-zött is szabadon mozoghatunk a JavaEE világában, egye-dül a descriptorokat kell cserélnünk/finomhangolnunk.
Book entitásIdentification mező
Ha nem adjuk meg a @SequenceGenerator és @GeneratedValue annotációkat, beszúráskor egyorg.hibernate.id.IdentifierGenerationException fogunk kapni, melyben jelzi a Hibernate hogy: "idsfor this class must be manually assigned before calling save()".� �1 package hu.qwaevisz.persistence.entity;23 @Entity4 @Table(name = "book")5 public class Book implements Serializable {67 @Id8 @SequenceGenerator(name = "generatorBook", sequenceName =
"book_book_id_seq", allocationSize = 1)9 @GeneratedValue(strategy = GenerationType.SEQUENCE , generator =
"generatorBook")10 @Column(name = "book_id", nullable = false)11 private Long id;1213 [..]14 }� �
Book.javaBedők Dávid (UNI-OBUDA) BookStore (book-entity-id.tex) 2018-01-17 v1.1 80 / 110
Database table name : book
Database sequence name : book_book_id_seq
Database column name : book_id
Book entitásTovábbi mezők� �1 @Column(name = "book_isbn", nullable = false)2 private String isbn;34 @Column(name = "book_author", nullable = false)5 private String author;67 @Column(name = "book_title", nullable = false)8 private String title;9
1011 @Enumerated(EnumType.ORDINAL)12 @Column(name = "book_bookcategory_id", nullable = false)13 private BookCategory category;1415 @Column(name = "book_price", nullable = false)16 private Double price;1718 @Column(name = "book_number_of_pages", nullable = false)19 private Integer numberOfPages;� �
Book.java
Bedők Dávid (UNI-OBUDA) BookStore (book-entity-fields.tex) 2018-01-17 v1.1 81 / 110
A bookcategory adatbázis szinten egy tábla, ORM szinten viszontegy enum (CRUD műveletek nem értelmezettek rajta).
BookCategoryORM által használt enum
� �1 package hu.qwaevisz.bookstore.persistence.entity.trunk;23 public enum BookCategory {45 SCIFI ,6 LITERATURE ,7 HISTORICAL ,8 PHILOSOPHY;9
10 }� �BookCategory.java
Bedők Dávid (UNI-OBUDA) BookStore (bookcategory.tex) 2018-01-17 v1.1 82 / 110
BookStorePersistence szolgáltatások
. A BookStore alkalmazás két szinten definiál szolgáltatásokat.• A bs-ejbservice project szintjén definiált EJB service-ek a "customer" (meg-
rendelő) igényei szerint alakítandóak.◦ Az interface által megfogalmazott igényekre üzleti use-case-ek születnek.◦ Az interface által használt típusok a stub-ok, melyek technikai szinten
publikusan kifelé nézve.◦ Az interface által használt kivételek technikai szinten publikusak, vagy
publikus hibaüzenetekké alakíthatóak. Technikai részleteket ritkán tar-talmaznak (security).
• A bs-persistence project szintjén definiált EJB service-ek a fejlesztők belsőszabályai alapján, elsősorban technikai követelmények és lehetőségek szerintalakulnak.
◦ Az interface által megfogalmazott igényeket a fejlesztők maguk alakítjákki, egészséges egyensúlyt tartva a redundancia mentes, karbantartható,tiszta és olykor akár future-proof követelmények alapján.
◦ Az interface által használt típusok az entity-k, melyek az alkalmazásbelső használatú DTO-i, kifelé legtöbbször nem publikusak.
◦ Az interface által használt kivételek részletes technikai információkat istartalmazhatnak, legtöbbször ezek a "kliens" oldalon nem jelennek megés nem alakíthatóak közvetlenül publikus hibaüzenetté.
Bedők Dávid (UNI-OBUDA) BookStore (persistence-service.tex) 2018-01-17 v1.1 83 / 110
BookService - Persistence SLSBLocal interface
� �1 package hu.qwaevisz.bookstore.persistence.service;2 [..]3 @Local4 public interface BookService {5 [..]6 Book read(String isbn) throws PersistenceServiceException;78 List <Book > readAll () throws PersistenceServiceException;9 [..]
10 }� �BookService.java
Bedők Dávid (UNI-OBUDA) BookStore (bookservice.tex) 2018-01-17 v1.1 84 / 110
BookService - Persistence SLSBImplementáció
� �1 @Stateless(mappedName = "ejb/bookService")2 @TransactionManagement(TransactionManagementType.CONTAINER)3 @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)4 public class BookServiceImpl implements BookService {56 @PersistenceContext(unitName = "bs -persistence -unit")7 private EntityManager entityManager;89 @Override
10 public Book read(final String isbn) throws PersistenceServiceException {11 Book result = null;12 try {13 result = this.entityManager.createNamedQuery(Book.GET_BY_ISBN ,
Book.class).setParameter("isbn", isbn).getSingleResult ();14 } catch (final Exception e) {15 throw new PersistenceServiceException("Unknown error when fetching Book by ISBN
(" + isbn + ")! " + e.getLocalizedMessage (), e);16 }17 return result;18 }19 [..]20 }� �
BookServiceImpl.java
Bedők Dávid (UNI-OBUDA) BookStore (bookserviceimpl.tex) 2018-01-17 v1.1 85 / 110
JPA Named Query : Book.GET_BY_ISBN ("Book.getByIsbn")Paraméter neve: isbngetSingleResult() : pontosan egy rekord létezik (különben kivételt dob)getResultList() : List<Book> lesz a visszatérési érték
JPA Named QueryJPQL syntax
� �1 @Entity2 @Table(name = "book")3 @NamedQueries(value = { //4 @NamedQuery(name = Book.GET_BY_ISBN , query = "SELECT b FROM
Book b WHERE b.isbn=:isbn"),5 @NamedQuery(name = Book.GET_ALL , query = "SELECT b FROM Book
b ORDER BY b.title"),6 [..]7 })8 public class Book implements Serializable {9
10 public static final String GET_BY_ISBN = "Book.getByIsbn";11 public static final String GET_ALL = "Book.getAll";1213 [..]14 }� �
Book.java
Bedők Dávid (UNI-OBUDA) BookStore (namedquery.tex) 2018-01-17 v1.1 86 / 110
Facade réteg felelősségeEJB Service project (bs-ejbservice)
Bedők Dávid (UNI-OBUDA) BookStore (facade-responsibility.tex) 2018-01-17 v1.1 87 / 110
Könyv lekérdezése ISBN alapjánEJB Service project (bs-ejbservice)
Bedők Dávid (UNI-OBUDA) BookStore (facade-getbookbyisbn.tex) 2018-01-17 v1.1 88 / 110
BookConverterEJB Service project (bs-ejbservice)� �1 @Local2 public interface BookConverter {3 BookStub to(Book book);4 List <BookStub > to(List <Book > books);5 }� �
BookConverter.java
Nagyon jó 3rd party library-k léteznek konverziós célra, pl. MapStruct (http://mapstruct.org/).� �1 @Stateless2 public class BookConverterImpl implements BookConverter {34 @Override5 public BookStub to(Book book) {6 final BookCategoryStub category =
BookCategoryStub.valueOf(book.getCategory ().toString ());7 return new BookStub(book.getIsbn (), book.getAuthor (), book.getTitle (), category ,
book.getPrice (), book.getNumberOfPages ());8 }9 [..]
10 }� �BookConverterImpl.java
Bedők Dávid (UNI-OBUDA) BookStore (bookconverter.tex) 2018-01-17 v1.1 89 / 110
BookFacade módosításaEJB Service project (bs-ejbservice)
� �1 @Stateless(mappedName = "ejb/bookFacade")2 public class BookFacadeImpl implements BookFacade {34 @EJB5 private BookService service;67 @EJB8 private BookConverter converter;9
10 @Override11 public BookStub getBook(String isbn) throws FacadeException {12 try {13 final BookStub stub = this.converter.to(this.service.read(isbn));14 if (LOGGER.isDebugEnabled ()) {15 LOGGER.debug("Get Book by isbn (" + isbn + ") --> " + stub);16 }17 return stub;18 } catch (final PersistenceServiceException e) {19 LOGGER.error(e, e);20 throw new FacadeException(e.getLocalizedMessage ());21 }22 }23 [..]24 }� �
BookFacadeImpl.java
Bedők Dávid (UNI-OBUDA) BookStore (bookfacade-modification.tex) 2018-01-17 v1.1 90 / 110
Megjelenítési réteg továbbfejlesztésebs-weblayer project
A korábbi BookPingServlet mellett készítsünk egy valós megjelenítési réte-get Servlet/JSP alapokon, követve aModell-View-Controller (MVC)tervezést.
. BookController servlet, mely URI paraméterben kapja az ISBN szá-mot, mely alapján lekéri az érintett könyvet, majd a BookStub példánytelhelyezi a HttpServletRequest-ben, és a kérést forward -olja egy JSPlapnak.
. book.jsp által generált servlet, mely kiveszi a HttpServletRequest-ből a BookStub példányát és megjeleníti XHTML tagek ölelésében.
Bedők Dávid (UNI-OBUDA) BookStore (weblayer-improvements.tex) 2018-01-17 v1.1 91 / 110
BookControllerWeblayer project (bs-weblayer)
� �1 package hu.qwaevisz.bookstore.weblayer.servlet;2 [..]3 @WebServlet("/Book")4 public class BookController extends HttpServlet {5 [..]6 @EJB7 private BookFacade facade;89 @Override
10 protected void doGet(HttpServletRequest request , HttpServletResponse response) throwsServletException , IOException {
11 String isbn = request.getParameter("isbn");12 [..]13 try {14 BookStub book = this.facade.getBook(isbn);15 request.setAttribute("book", book);16 } catch (final FacadeException e) {17 LOGGER.error(e, e);18 }19 RequestDispatcher view = request.getRequestDispatcher("book.jsp");20 view.forward(request , response);21 }22 [..]23 }� �
BookController.java
Bedők Dávid (UNI-OBUDA) BookStore (bookcontroller.tex) 2018-01-17 v1.1 92 / 110
book.jspWeblayer project (bs-weblayer)� �1 <%@ page language="java" contentType="text/html; charset=UTF -8" pageEncoding="UTF -8" %>2 <%@ page import="hu.qwaevisz.bookstore.ejbservice.domain.BookStub" %>3 <!DOCTYPE html>4 <html>5 <head>6 <meta http -equiv="Content -Type" content="text/html; charset=UTF -8">7 <title>:: Book ::</title>8 </head>9 <body>
10 <jsp:useBean id="book" class="hu.qwaevisz.bookstore.ejbservice.domain.BookStub"scope="request" />
11 <h1>12 <jsp:getProperty name="book" property="author" />:13 <jsp:getProperty name="book" property="title" />14 </h1>15 <div>16 <label >ISBN: </label>17 <span><jsp:getProperty name="book" property="isbn" /></span>18 </div>19 <div>20 <label >Number of pages: </label>21 <span><jsp:getProperty name="book" property="numberOfPages" /></span>22 </div>23 [..]24 </body>25 </html>� �
book.jsp
Bedők Dávid (UNI-OBUDA) BookStore (book-page.tex) 2018-01-17 v1.1 93 / 110
BookStoreKönyvesbolt webalkalmazás
http://localhost:8080/bs-weblayer/Book?isbn=978-0441172719
További feladatok:. Összes könyv listázása (JPA query, persistence service, facade service,
converter ejb)• Criteria alapján szűrés megvalósítása (opcionális)
. list.jsp és BookListController servlet megvalósítása
. list.jsp és book.jsp összekötése (a controller servlet-ekösszekötése)
. page.css file készítése a weblapokhoz
. ...
Bedők Dávid (UNI-OBUDA) BookStore (bookstore.tex) 2018-01-17 v1.1 94 / 110
BookStore CRUDKönyvesbolt webalkalmazás
A BookStore alkalmazás a lekérdezési lehetőségek mellett teljes CRUD szer-kesztési lehetőséget is tartalmaz. Ennek technikai részleteit JPA szempont-jából később tekintjük át.
A következő néhány slide-on - csupán előzetesen - az érintett műveletek pers-istence oldala lesz olvasható. A megoldás nélkülözi a tranzakció- és hibake-zelést. Mindezek később a school elnevezésű projektben lesznek részletezve.
Bedők Dávid (UNI-OBUDA) BookStore (bookstore-crud.tex) 2018-01-17 v1.1 95 / 110
BookStore - Új könyv rögzítéseKönyvesbolt webalkalmazás
� �1 @Stateless(mappedName = "ejb/bookService")2 public class BookServiceImpl implements BookService {3 [..]4 @PersistenceContext(unitName = "bs -persistence -unit")5 private EntityManager entityManager;67 @Override8 public Book create(final String isbn , final String author , final String title , final
int numberOfPages , final double price , final BookCategory category)9 throws PersistenceServiceException {
10 [..]11 final Book book = new Book(isbn , author , title , numberOfPages , price , category);12 this.entityManager.persist(book);13 [..]14 return book;15 }16 [..]17 }� �
BookServiceImpl.java
Bedők Dávid (UNI-OBUDA) BookStore (bookstore-create.tex) 2018-01-17 v1.1 96 / 110
BookStore - Könyv módosításaKönyvesbolt webalkalmazás
� �1 @Stateless(mappedName = "ejb/bookService")2 public class BookServiceImpl implements BookService {3 [..]4 @PersistenceContext(unitName = "bs -persistence -unit")5 private EntityManager entityManager;67 @Override8 public Book update(final String isbn , final String author , final String title , final
int numberOfPages , final double price , final BookCategory category)9 throws PersistenceServiceException {
10 final Book book = this.read(isbn);11 book.setAuthor(author);12 book.setTitle(title);13 book.setNumberOfPages(numberOfPages);14 book.setPrice(price);15 book.setCategory(category);16 [..]17 return this.entityManager.merge(book);18 }19 [..]20 }� �
BookServiceImpl.java
Bedők Dávid (UNI-OBUDA) BookStore (bookstore-update.tex) 2018-01-17 v1.1 97 / 110
BookStore - Könyv törléseKönyvesbolt webalkalmazás
� �1 @Stateless(mappedName = "ejb/bookService")2 public class BookServiceImpl implements BookService {3 [..]4 @PersistenceContext(unitName = "bs -persistence -unit")5 private EntityManager entityManager;67 @Override8 public void delete(final String isbn) throws PersistenceServiceException {9 this.entityManager.createNamedQuery(Book.REMOVE_BY_ISBN).setParameter("isbn",
isbn).executeUpdate ();10 [..]11 }12 [..]13 }� �
BookServiceImpl.javaA hivatkozott JPQL az alábbi :DELETE FROM Book b WHERE b.isbn=:isbn
Bedők Dávid (UNI-OBUDA) BookStore (bookstore-delete.tex) 2018-01-17 v1.1 98 / 110
TesztelésTesztelés szintjei
A kódolás - mint fejlesztési folyamat - szét nem választható egységet képez a teszteléssel.Jelen diasorozatnak azonban nem scope-ja a kódolást a minden ponton vele együtt járóteszteléssel együtt bemutatni.
. egység vagy komponens- teszt : az objektum-orientált fejlesztésben egy osztály (egyfelelősség) önálló, független tesztjét értjük egység teszt alatt. Minden környezetiés közel minden programozott függőséget (elsősorban az aggregációkat és kom-pozíciókat) ki kell küszöbölni, meg kell kerülni. Célja legtöbbször a programhibákleggyorsabb és legpontosabb felderítése, illetve relatíve magas coverage esetén arefactorálás támogatása.
. integrációs teszt : néhány komponens együttes tesztelése, célja legtöbbször a fejlesz-tés menetének meggyorsítása. Mindig helyben dönthető el, hogy mekkora környezetifüggőséget engedélyezünk a teszt számára.
. system vagy rendszer- teszt: tipikusan a fejlesztők által végzett legmagasabb tesz-telés, melyben a rendszer vagy annak egy önállóan működő része "minden" függősé-gével együtt kerül tesztelésre (itt képke kerülhetnek szimulátorok, melyeket szintjéna fejlesztőknek kell lefejlesztenie).
. end-to-end vagy átvételi- teszt : egy jól működő projektben az end-to-end teszteléstkülön, a fejlesztőktől független csapat végzi. Mérnökökből álló tesztelői (integrációsés verifikációs) csapat automata tesztekben gondolkodik, míg sok helyen végzik ezta szintet manuális lépések segítségével. Webalkalmazás fejlesztés során gyakoriak pl.a Selenium tesztek.
Bedők Dávid (UNI-OBUDA) BookStore (testing.tex) 2018-01-17 v1.1 99 / 110
Perzisztencia tesztelése
. Körülményes egy-egy named query tesztelése miatt deploy-olni és manuálistesztelni (nagyon sok idő, sok elgépelési lehetőség).
. Adatbázis műveletek, named query-k tesztelése nem unit-test felelősség.
. A JPA API használható standalone alkalmazásban is. Ez is egy mód a teszte-lésre, de ez egy elkülönített kódrész lesz, mely automata tesztelésre legtöbb-ször nem alkalmas (de a fejlesztés támogatására igen).
. Talán a legelegánsabb megoldás integration test-eket készíteni a persistenceréteg tesztelésére, melyben a megírt named query-k és entity manager mű-veletek valóban lefutnak az adatbázison, azok hatékonysága és teljesítményemérhető és ellenőrizhető lesz, függetlenül az alkalmazás szervertől (az alkal-mazás szervert kivesszük a tesztelésből, de az adatbázist nem).
. Az integrációs tesztek tipikusan nem futnak az egység tesztekkel együtt, ígya külön futásukat illendő megoldani (többféle megoldás lehetséges).
. A persistence réteg osztályait (ahol értelme van, és nem boilerplate algorit-musok érintettek) természetesen egység tesztekkel le lehet fedni. Az egységtesztelésről a school elnevezésű projekt fog részletesebben foglalkozni.
Bedők Dávid (UNI-OBUDA) BookStore (persistence-testing.tex) 2018-01-17 v1.1 100 / 110
Standalone Persistence Unit az integrációs tesztekhez
src | main | resources | META-INF | persistence.xml� �1 <persistence [..]>2 [..]3 <persistence -unit name="bs -persistence -test -unit" transaction -type="RESOURCE_LOCAL">4 <provider >org.hibernate.jpa.HibernatePersistenceProvider </provider >5 <class >hu.qwaevisz.bookstore.persistence.entity.Book</class >6 <properties >7 <property name="javax.persistence.jdbc.url"
value="jdbc:postgresql: // localhost:5432/bookstoredb" />8 <property name="javax.persistence.jdbc.user" value="bookstore_user" />9 <property name="javax.persistence.jdbc.password" value="123 topSECret321" />
10 <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />1112 <property name="hibernate.dialect"
value="org.hibernate.dialect.PostgreSQLDialect"/>13 <property name="hibernate.show_sql" value="true"/>14 <property name="hibernate.format_sql" value="true"/>1516 <property name="jboss.as.jpa.managed" value="false" />17 </properties >18 </persistence -unit>19 </persistence >� �
persistence.xml
Bedők Dávid (UNI-OBUDA) BookStore (integration-persistence-unit.tex) 2018-01-17 v1.1 101 / 110
A JPA a classpath fix helyén keresi a persistence.xml-t. E miatt ajboss.as.jpa.managed értékét false-ra állítva elérhetjük hogy runtimea JBoss ne foglalkozzon ezzel a standalone persistence unit-tal (Class-NotFound hibát okoz e nélkül). JNDI név helyett most definiálva van aprovider class valamint a csatlakozás adatai. Mivel nincs container aki át-nézné a kódot annotációk után, an entity-ket fel kell sorolni.Persistence unit neve: bs-persistence-test-unit
Integration teszt classpath
Az integrációs tesztek JavaEE container nélkül futnak (pl. gradle/maven/eclipse JVM-je futtatja őket), így nem elégséges csupán a interface-ek/enum-ok halmazát tartalmazófüggőség beállítása. Érdemes a futtató környezet által használt runtime függőségeket fel-sorolni, de a JavaEE szabványos világában akár más runtime környezetet is felépíthetünk.
Szükséges runtime függőségek:. PostgreSQL
• org.postgresql:postgresql:9.4+
. Hibernate• org.hibernate:hibernate-core:4.3.10.Final• org.hibernate:hibernate-entitymanager:4.3.10.Final
. JavaEE 6.0 implementáció• org.jboss.spec:jboss-javaee-6.0:3.0.3.Final• Fontos! Ezzel egy időben nem szabad a classpath-ra tenni a
JavaEE 6.0 API-t (a teszt classpath része a production classpath):◦ javax:javaee-api:6.0
Bedők Dávid (UNI-OBUDA) BookStore (integration-classpath.tex) 2018-01-17 v1.1 102 / 110
Root project - Alprojectek megkülönböztetéseJavaEE 6.0 API leszedése a compile classpath-ról� �1 [ . . ]2 a l l p r o j e c t s {3 r e p o s i t o r i e s {4 [ . . ]5 }6 }7 s u b p r o j e c t s {8 [ . . ]9 dependenc i e s {
10 comp i l e group : ’ l o g4 j ’ , name : ’ l o g 4 j ’ , v e r s i o n : l o g 4 j V e r s i o n11 t e s tComp i l e group : ’ o rg . t e s tng ’ , name : ’ t e s tng ’ , v e r s i o n :
t e s t n gV e r s i o n12 }13 t e s t {14 useTestNG ( )15 }16 }17 c o n f i g u r e ( s u b p r o j e c t s . f i n d A l l { i t . name != ’ bs−p e r s i s t e n c e ’ } ) {18 dependenc i e s {19 comp i l e group : ’ j avax ’ , name : ’ j a vaee−ap i ’ , v e r s i o n : j e eV e r s i o n20 }21 }22 [ . . ]� �
build.gradle
Bedők Dávid (UNI-OBUDA) BookStore (gradle-root-integration.tex) 2018-01-17 v1.1 103 / 110
configure(..) : Az összes alprojektre érvényes, kivéve abs-persistence nevűre, ahol a testCompile-ra felkerül majda Java EE 6.0 implementáció.
Persistence project - Teszt classpath konfigurálásaJavaEE 6.0 implementáció elhelyezése a testCompile classpath-ra
� �1 [ . . ]2 dependenc i e s {3 comp i l eOn ly group : ’ j avax ’ , name : ’ j a vaee−ap i ’ , v e r s i o n : j e eV e r s i o n45 t e s tComp i l e group : ’ o rg . p o s t g r e s q l ’ , name : ’ p o s t g r e s q l ’ , v e r s i o n :
p o s t g r e s q l V e r s i o n6 t e s tComp i l e group : ’ o rg . h i b e r n a t e ’ , name : ’ h i b e r n a t e−core ’ , v e r s i o n :
h i b e r n a t eV e r s i o n7 t e s tComp i l e group : ’ o rg . h i b e r n a t e ’ , name : ’ h i b e r n a t e−ent i t ymanage r ’ ,
v e r s i o n : h i b e r n a t eV e r s i o n8 t e s tComp i l e group : ’ o rg . j b o s s . spec ’ , name : ’ j bo s s−j a vaee −6.0 ’ ,
v e r s i o n : j b o s s j e e 6V e r s i o n9 }
10 [ . . ]� �build.gradle
A compileOnly dependency configuration a java plugin része Gradle 2.12 óta. Így aJavaEE API nem lesz része a testCompile-nak, ami az integrációs teszteket elron-taná. Jó - bár talán kevésbé elegáns megoldás - a compile classpath-ra elhelyeznia JavaEE 6.0 implementációt.
Bedők Dávid (UNI-OBUDA) BookStore (gradle-persistence-integration.tex) 2018-01-17 v1.1 104 / 110
Apache Log4JLokális konfiguráció
src | test | resources | log4j.xml� �1 <?xml version="1.0" encoding="UTF -8" ?>2 <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">3 <log4j:configuration debug="true"4 xmlns:log4j=’http:// jakarta.apache.org/log4j/’>56 <appender name="console" class="org.apache.log4j.ConsoleAppender">7 <layout class="org.apache.log4j.PatternLayout">8 <param name="ConversionPattern"9 value="%d{yyyy -MM -dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
10 </layout >11 </appender >1213 <root>14 <level value="DEBUG" />15 <appender -ref ref="console" />16 </root>1718 </log4j:configuration >� �
log4j.xml
A részletes log nagyon sokat segít a fejlesztésben és a tesztelésben is. És pontosan ezenrészletek miatt lesz nagyon gyors és hatékony pl. a named query-k optimalizálása. Mivelaz integrációs tesztek futása során nincs JavaEE container aki biztosítja a naplózást,nekünk kell ezt is konfigurálnunk.
Bedők Dávid (UNI-OBUDA) BookStore (log4j-integration.tex) 2018-01-17 v1.1 105 / 110
Integrációs tesztElőkészületek
� �1 package hu.qwaevisz.bookstore.persistence.service;2 [..]3 public class BookServiceImplIntegrationTest {45 private static final String PERSISTENCE_UNIT = "bs-persistence -test -unit";67 private BookServiceImpl object;89 @BeforeClass
10 private void setUp () {11 final EntityManagerFactory factory =
Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);12 final EntityManager entityManager = factory.createEntityManager ();1314 this.object = new BookServiceImpl ();15 this.object.setEntityManager(entityManager);16 }1718 [..]1920 @AfterClass21 private void tearDown () {22 this.object.getEntityManager ().close ();23 }24 }� �
BookServiceImplIntegrationTest.java
Bedők Dávid (UNI-OBUDA) BookStore (bookserviceimplintegrationtest-setup.tex)2018-01-17 v1.1 106 / 110
A lokális entityManager "befecskende-zésének" megkerülése miatt egy default/-protected setEntitymanager() mutatormetódust készítenünk kell a productionkódban:-(
Integrációs tesztA read() mögötti named query működésének tesztelése.
Az integration csoportosításra a unit-test-ektől való megkülönböztetésmiatt van szükség.� �1 public class BookServiceImplIntegrationTest {2 [..]3 @Test(groups = "integration")4 private void readSampleBookFromDatabase () throws PersistenceServiceException {5 final Book book = this.object.read("978 -0441172719");6 this.assertBook(book , "978 -0441172719", "Frank Herbert", "Dune",
BookCategory.SCIFI , 896, 3500d);7 }89 private void assertBook(final Book book , final String isbn , final String author ,
final String title , final BookCategory category ,10 final Integer numberOfPages , final double price) {11 Assert.assertEquals(book.getIsbn (), isbn);12 Assert.assertEquals(book.getAuthor (), author);13 Assert.assertEquals(book.getTitle (), title);14 Assert.assertEquals(book.getCategory (), category);15 Assert.assertEquals(book.getNumberOfPages (), numberOfPages);16 Assert.assertEquals(book.getPrice (), price);17 }18 [..]19 }� �
BookServiceImplIntegrationTest.javaBedők Dávid (UNI-OBUDA) BookStore (bookserviceimplintegrationtest-query.tex)2018-01-17 v1.1 107 / 110
Integrációs tesztAdatmanipuláció tranzakcióban
� �1 public class BookServiceImplIntegrationTest {2 [..]3 private static final String NEW_BOOK_ISBN = "42-NEW -BOOK -ISBN";45 @Test(groups = "integration")6 private void createABook () throws PersistenceServiceException {7 if (this.object.exists(NEW_BOOK_ISBN)) {8 this.object.getEntityManager ().getTransaction ().begin();9 this.object.delete(NEW_BOOK_ISBN);
10 this.object.getEntityManager ().getTransaction ().commit ();11 }1213 this.object.getEntityManager ().getTransaction ().begin();14 this.object.create(NEW_BOOK_ISBN , "Lorem Ipsum", "Sample book", 142, 999,
BookCategory.HISTORICAL);15 this.object.getEntityManager ().getTransaction ().commit ();1617 final Book book = this.object.read(NEW_BOOK_ISBN);18 this.assertBook(book , NEW_BOOK_ISBN , "Lorem Ipsum", "Sample book",
BookCategory.HISTORICAL , 142, 999);19 }20 [..]21 }� �
BookServiceImplIntegrationTest.java
Bedők Dávid (UNI-OBUDA) BookStore (bookserviceimplintegrationtest-insert.tex)2018-01-17 v1.1 108 / 110
Itt most nincs EJB container, "ami" gondoskodna a tranzak-ciókról. Ezt nekünk kell megtennünk minden adatmanipulációsesetben! Illetve valamiképpen a rerunable képességről is gon-doskodnunk kell.
TestNG Integration Suitebs-persistence project
� �1 [..]2 test {3 useTestNG {4 // suites ’src/test/resources/testng -unit.xml ’5 suites ’src/test/resources/testng -integration.xml ’6 // excludeGroups ’integration ’7 // includeGroups ’unit ’8 }9 }� �
build.gradle
Többféle megoldás lehetséges az integration tesztek futtatására:. Külön integration project létrehozása (talán a legelegánsabb). Külön konfigurációs profil létrehozása (külön classpath, testng config, stb.). Külön TestNG suite.xml-ek definiálása az egység ill. az integration tesztek
számára (az egyszerűség kedvéért ezt alkalmazzuk). Globálisan kizárni/hozzáadni bizonyos TestNG group-okat a tesztek futásához
Bedők Dávid (UNI-OBUDA) BookStore (gradle-testng-integration.tex) 2018-01-17 v1.1 109 / 110
Integration TestNG suites
src | test | resources | testng-*.xml� �1 <!DOCTYPE suite SYSTEM "http:// testng.org/testng -1.0. dtd" >2 <suite name="integration -test -suite" verbose="1" >3 <test name="bookservice">4 <classes >5 <class name="hu .[..]. service.BookServiceImplIntegrationTest" />6 <class name="hu .[..]. service.BookSearchImplIntegrationTest" />7 </classes >8 </test>9 </suite >� �
testng-integration.xml� �1 <!DOCTYPE suite SYSTEM "http:// testng.org/testng -1.0. dtd" >2 <suite name="unit -test -suite" verbose="1">3 <test name="bookservice">4 <groups >5 <run>6 <exclude name="integration" />7 </run>8 </groups >9 <packages >
10 <package name="hu .[..]. service .*" />11 </packages >12 </test>13 </suite >� �
testng-unit.xml
Bedők Dávid (UNI-OBUDA) BookStore (testng-suites.tex) 2018-01-17 v1.1 110 / 110
Az összes teszt case unit test ami amegadott package-ben megtalálha-tó, kivéve az ami az integrationcsoportba tartozik.