Library [email protected] 2010 – August 2010
www.ericgerlofsma.nl
Contents• Creating a Library Session Bean
1. Current situation2. Desired new situation3. IF project for connecting the front-end4. EJB project for business logic5. JAAS project for authentication6. Client project for testing the EJB7. JSF project for deploying the ABC-Library
Current Situation UML(1)public interface LibraryManagerIF
HashSet<Customer> allCustomers(); HashSet<Book> allBooks(); HashSet<Book> allBooks(String name) String addCredits(String name, int credits) String lend(String title, String name) String newBook(String title) String newCustomer(String name) String removeBook(String title) String removeCustomer(String name) String unlend(String title)
public interface LibraryManagerimplements
Current Situation UML(2)public class Book private static HashMap<String, Book> books = new HashMap<String, Book>();
static Book findBook(String title) static void removeBook(String title) static HashSet<Book> allBooks()
private String title = null;private Customer lendTo = null;
Book(String newTitle)public String getTitle()Customer getLendTo()void setLendTo(Customer customer)
public class Customer private static HashMap<String, Customer> customers = new HashMap<String, Customer>();
static Customer findCustomer(String name) static void removeCustomer(String name) static HashSet<Customer> allCustomers()
private String name = null;private int credits = 0;private HashSet<Book> books = new HashSet<Book>(); Customer(String newName)public String getName()int getCredits()void setCredits(int newCredits)HashSet<Book> getBooks()void addBook(Book book)void removeBook(Book book)
Current Situation UML(3)public class LibraryAdmin
public LibraryAdmin()public static String[] check(String usr, String pwd)
class LibraryPrincipal
public static final String MANAGER = "manager";public static final String ADMINISTRATOR = "administrator";public static final String CASHIER = "cashier"; private static HashMap<String, LibraryPrincipal> principals = new HashMap<String, LibraryPrincipal>(); static LibraryPrincipal findLibraryPrincipal(String name)
private String name = null;private String password = null;private String[] roles = null; LibraryPrincipal(String newName, String newPassword, String[] newRoles)String getName()String getPassword()String[] getRoles()
Current Situation• The given ABC-Library-Model has no real database!
• It’s “java-database” is implemented by HashMap attributes in the Book & Customer classes. • The 6 Library classes are packed in a jar-file and becomes an integral part of the JBoss lib.
• This package is to be used by a MVC (JSF) frontend.
• There is no Authentication and Confidentiality yet!• No separate logging!• ABC-Library should be a separate module in Jboss and not part of JBoss? • Adding a database is a JBoss Service.
conf
C:\jboss-5.1.0.GA\server\default
data deploy deployers lib log tmp work
ABC-Library.jar
ABC-LibraryIF.jar
ABC-Library-EJB.jar
Desired New Situation UML
LibraryManagerBean
LibraryManagerIF
Book
Customer
conf
C:\jboss-5.1.0.GA\server\default
data deploy deployers lib log tmp work
ABC-Library-JAAS.sarABC-Library-EJB.jarABC-Library-IF.jar
implements
ABC-Library-Client
LibraryAdminBean
CustomerDAO
LibraryPrincipal
Log
BookDAO
Main
ABC-Library-JAAS
LoginModule
New Situation • Create Interace projectEJB means creating a Stateless Session Bean.
• It’s convenient to make 5 projects: 1. IF project 2. EJB project3. JAAS project 4. Client project 5. JSF project
• The IF project is part of all other projects.
• The minimum testable configuration is IF, EJB and JAAS.
• After a successful test we create(copy) the front-end project, remove the model ABC-Library.jar and make a connection to the enterprise back-end.
IF Project.1. Create in eclipse a new java-project
2. Create a new directories “src”
3. Set project properties:1. Java Build Path2. Source = “src”3. Default output folder = “classes”
4. Copy from model to “src”: LibraryManagerIF
5. Change Book→BookDAO and Customer → CustomerDAO
6. Create serializable data classes BookDAO and CustomerDAO
7. Update a copy an old build,xml file for deploying IF
IF Project.1. Create in eclipse a new java-project
2. Create a new directory “src”
3. Set project properties:1. Java Build Path2. Source = “src”3. Default output folder = “classes”
4. Copy from model to “src”: LibraryManagerIF5. Create a new interface LibraryAdminIF
6. Change Book→BookDAO and Customer → CustomerDAO
7. Create serializable data classes BookDAO and CustomerDAO
8. Update a copy an old build,xml file for deploying IF
Bean Interfaces.package efg.library.IF;import javax.ejb.Local;
@Localpublic interface LibraryAdminIF{ String[] check(String usr, String pwd);}
package efg.library.IF;import java.security.Principal;import java.util.HashSet;import javax.ejb.Remote;
@Remotepublic interface LibraryManagerIF{ Principal getPrincipal(); HashSet<CustomerDAO> allCustomers(); HashSet<BookDAO> allBooks(); HashSet<String> allBooks(String name) throws Exception; String addCredits(String name, int credits) throws Exception; String lend(String title, String name) throws Exception; String newBook(String title) throws Exception; String newCustomer(String name) throws Exception; String removeBook(String title) throws Exception; String removeCustomer(String name) throws Exception; String unlend(String title) throws Exception;}
By defaultall methods are public
DAO Data Access Object.public class BookDAO implements Serializable{ private static final long serialVersionUID = 1847273866441754398L; private String title = null; private String lendTo = null; public void setTitle (String newTitle) { title = newTitle; } public void setLendTo(String newLendTo){ lendTo = newLendTo; } public String getTitle() { return title; } public String getLendTo(){ return lendTo; }}
public class CustomerDAO implements Serializable{ private static final long serialVersionUID = 2403140518716476898L; private String name = null; private int credits = 0; private HashSet<String> titles = new HashSet<String>(); public void setName( String newName) { name = newName; } public void setCredits(int newCredits) { credits = newCredits; } public void addTitle (String newTitle) { titles.add(newTitle); } public void setBooks (HashSet<String> newTitles) { titles = newTitles; } public String getName() { return name; } public int getCredits() { return credits;} public HashSet<String> getBooks() { return titles; }}
build.xml IF Project.<project name="P1-ABC-Library-IF" basedir="." default="package" >
<property environment="env"/> <property name="jboss.home" value="${env.JBOSS_HOME}"/> <property name="jboss.server" value="${jboss.home}/server/default"/> <property name="jboss.deploy" value="${jboss.server}/deploy/efg"/>
<target name="package"> <delete file="${ant.project.name}.jar"/> <jar destfile="${ant.project.name}.jar" basedir="jar"/> <copy file="${ant.project.name}.jar" todir="${jboss.deploy}"/> </target>
</project>
EJB Project.1. Create in eclipse a new java-project
2. Create a new directory: “src”
3. Set project properties:1. Java Build Path2. Source = “src”3. Default output folder = “classes”4. Project = Interface project5. External jar = jboss-ejb3x.jar
4. Copy from model to src: LibraryManager →LibaryManagerBean
5. Add Annotations to LibraryManagerBean
6. Add one new public method: Principal getPrincipal()
7. Update a copy an old build.xml file for deploying
LibraryManagerBean@Stateless@Interceptors(efg.library.Log.class)@SecurityDomain("ABC-Library-Security-Domain")public class LibraryManagerBean implements LibraryManagerIF{ @Resource private EJBContext context = null; @RolesAllowed({"cashier","administrator","manager"}) public Principal getPrincipal() { return context.getCallerPrincipal(); }
@RolesAllowed({"cashier","administrator","manager"}) public HashSet<BookDAO> allBooks() { return Book.allBooks(); }
. . . etc @RolesAllowed before every method
LibraryAdminBeanpackage efg.library;import javax.ejb.Stateless;import efg.library.IF.LibraryAdminIF;
@Statelesspublic class LibraryAdminBean implements LibraryAdminIF{ public LibraryAdminBean() { System.out.println("LibraryAdmin()"); } public String[] check(String usr, String pwd) { System.out.println("LibraryAdmin.check("+usr+", "+pwd+")"); LibraryPrincipal principal = LibraryPrincipal.findLibraryPrincipal(usr); if (principal != null && pwd.equals(principal.getPassword())) { return principal.getRoles(); } return null; }}
EJB Project - build.xml<project name="P1-ABC-Library-EJB" basedir="." default="package" > <property environment="env"/> <property name="jboss.home" value="${env.JBOSS_HOME}"/> <property name="jboss.server" value="${jboss.home}/server/default"/> <property name="jboss.deploy" value="${jboss.server}/deploy/efg"/> <target name="package"> <delete file="${ant.project.name}.jar"/> <jar destfile="${ant.project.name}.jar"> <fileset dir="classes"/> <fileset dir="jar"/> </jar> <copy file="${ant.project.name}.jar" todir="${jboss.deploy}"/> </target>
</project>
EJB JNDI viewjava:comp namespace of the component jboss.j2ee:jar=P1-ABC-Library-EJB.jar,name=LibraryAdminBean,service=EJB3 :
+- EJBContext (class: javax.ejb.EJBContext) +- TransactionSynchronizationRegistry[link -> java:TransactionSynchronizationRegistry] (class: javax.naming.LinkRef) +- UserTransaction (class: org.jboss.ejb3.tx.UserTransactionImpl) +- env (class: org.jnp.interfaces.NamingContext) +- ORB[link -> java:/JBossCorbaORB] (class: javax.naming.LinkRef)
Global JNDI Namespace+- LibraryAdminBean (class: org.jnp.interfaces.NamingContext) | +- local (class: Proxy for: efg.library.IF.LibraryAdminIF) | +- local-efg.library.IF.LibraryAdminIF (class: Proxy for: efg.library.IF.LibraryAdminIF)
+- LibraryManagerBean (class: org.jnp.interfaces.NamingContext) | +- remote (class: Proxy for: efg.library.IF.LibraryManagerIF) | +- remote-efg.library.IF.LibraryManagerIF (class: Proxy for: efg.library.IF.LibraryManagerIF)
JAAS Projectpublic boolean login() throws LoginException { try { InitialContext ctx = new InitialContext(); LibraryAdminIF libraryAdmin = (LibraryAdminIF)ctx.lookup("LibraryAdmin/local"); String[] myroles = libraryAdmin.check(username, password); if (myroles != null) { roles = new MyGroup("Roles"); for (int i=0; i<myroles.length; i++) { roles.addMember(new MyPrincipal(myroles[i])); } callerPrincipal = new MyGroup("CallerPrincipal"); callerPrincipal.addMember(new MyPrincipal(username)); ret = succeeded = true; } } catch (NamingException ne) { ret = succeeded = false; } return ret; }
Client Project (1)import java.util.HashSet;
import efg.library.IF.BookDAO;import efg.library.IF.CustomerDAO;import efg.library.IF.LibraryManagerIF;
import javax.naming.InitialContext;import org.jboss.security.client.SecurityClient;import org.jboss.security.client.SecurityClientFactory;
public class Main{ public static void main(String[] args) throws Exception { InitialContext ctx = new InitialContext(); LibraryManagerIF manager = (LibraryManagerIF)ctx.lookup("LibraryManager/remote"); System.out.println("librarymanager="+manager); SecurityClient securityClient = SecurityClientFactory.getSecurityClient(); securityClient.setSimple("henk", "geheim"); securityClient.login(); printBooks(manager); printCustomers(manager); manager.addCredits("Eric", 1); printCustomers(manager); securityClient.logout();
Client Project (2) securityClient.setSimple("john", "geheim"); securityClient.login(); printBooks(manager); manager.newBook("aapje"); printBooks(manager); printCustomers(manager); manager.newCustomer("aapje"); printCustomers(manager); manager.removeCustomer("aapje"); printCustomers(manager); securityClient.logout(); securityClient.setSimple("fred", "geheim"); securityClient.login(); printCustomers(manager); manager.lend("aapje", "Eric"); printCustomers(manager); securityClient.logout(); securityClient.setSimple("john", "geheim"); securityClient.login(); printBooks(manager); manager.removeBook("aapje"); printBooks(manager); securityClient.logout(); }
Client Project (3) private static void printBooks(LibraryManagerIF manager) { HashSet<BookDAO> books = manager.allBooks(); for (BookDAO book : books) { System.out.println(book.getTitle()); } System.out.println("----------------------------------------------"); } private static void printCustomers(LibraryManagerIF manager) { HashSet<CustomerDAO> customers = manager.allCustomers(); for (CustomerDAO customer : customers) { System.out.print(customer.getName()+", "+customer.getCredits()); HashSet<String> books = customer.getBooks(); for (String title : books) { System.out.print(", "+title); } System.out.println(); } System.out.println("----------------------------------------------"); }}
Do TESTING for first milestone.
Deploy IFDeploy JAASDeploy EJB
do Client-test
JSF Project
Inject a connector to EJB Backend
@EJB(mappedName="LibraryManager/remote")private LibraryManagerIF libraryManager = null;
JSF Project LibraryAccessBean public String doLogin() { boolean[] render = { . . . } session.setAttribute("render", render); try { SecurityClient securityClient = SecurityClientFactory.getSecurityClient(); securityClient.setSimple(usr, pwd); securityClient.login(); Principal principal = libraryManager.getPrincipal(); String name = principal.getName(); securityClient.logout(); boolean[] menu = null; if (name.equals("eric")) { menu = . . . } else if (name.equals("fred")) { menu = . . . } else if (name.equals("john")) { menu = . . . } else if (name.equals("henk")) { menu = . . . } session.setAttribute("menu", menu); } catch (Exception e) { setException(e.getMessage()); return "LibraryAccess"; } return "LibraryManager"; }
JSF Project LibraryManagerBeanpublic void doNewBook(ActionEvent ae) { if (title.equals("")) { FacesContext ctx = FacesContext.getCurrentInstance(); ctx.addMessage( "subview-choice:subview-new-book:form-new-book:input-new-book“ , new FacesMessage(" title is a required field")); return; } try { securityClient.setSimple(usr, pwd); securityClient.login(); setMessage(libraryManager.newBook(title)); title=""; securityClient.logout(); } catch (Exception e) { setException(e.getMessage()); } }
Do TESTING for second milestone.
Deploy JSF
do Browser-test
More steps to do.1. Use the Jboss database service
Top Related