You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Il ciclo di vita inizia quando il client richiede un riferimento al bean. Il container crea una nuova istanza.
Alla creazione, vengono anche iniettate le dipendenze richieste
Se l'istanza appena creata ha un metodo annotato con @PostConstruct, il container lo invoca.
Invocazioni dei metodi da parte dei client
Il container invoca il metodo annotato con @PreDestroy, se esiste, e termina il ciclo di vita dell'istanza del bean.
Le Transizioni per gli Stateful
Il ciclo di vita inizia quando il client richiede un riferimento al bean. Il container crea una nuova istanza.
Alla creazione, vengono anche iniettate le dipendenze richieste
Se l'istanza appena creata ha un metodo annotato con @PostConstruct, il container lo invoca.
Invocazioni dei metodi da parte dei client
Se il client resta in idle per un certo periodo di tempo, il container invoca il metodo @PrePassivate e rende passivo il bean in uno storage permanente
Se un client invoca un bean <>, il container lo attiva riportandolo in memoria ed invoca il metodo annotato con @PostActivate, se esiste.
Se un client non invoca il bean all'interno del session timeout period, il container lo elimina.
Alternativamente al passo 7, se un client chiama un metodo annotato con @Remove, il container invocherà il metodo annotato con @PreDestroy, se esiste e termina il ciclo di vita del bean.
Obiettivo: controllare l'accesso al codice di business
L'autenticazione è gestita dal layer di presentazione (web) o dall'applicazione client.
che poi passano l'utente al layer EJB
che deve verificare se ha accesso al possibile metodo, basato su ruolo
L'autorizzazione può avvenire in maniera dichiarativa (dall'EJB Container) oppure da programma, attraverso Java Authentication and Authorization Service (JAAS API)
Autorizzazione Dichiarativa
Definita usando annotazioni oppure XML Deployment Descriptor.
Richiede di:
definire ruoli
assegnare permessi ai metodi
cambiare temporaneamente una security identity
@Stateless@RolesAllowed({"user", "employee", "admin"}) // Definisce i ruoli autorizzati per accedere a questo EJBpublicclassItemEJB {
@PersistenceContext(unitName = "chapter08PU") // Inietta l'EntityManager per gestire le operazioni di persistenzaprivateEntityManagerem;
/** * Trova un libro in base al suo ID. * @param id L'ID del libro da cercare. * @return Il libro trovato, oppure null se non esiste. */publicBookfindBookById(Longid) {
returnem.find(Book.class, id); // Utilizza l'EntityManager per cercare il libro nel database
}
/** * Crea un nuovo libro nel database. * @param book L'oggetto Book da persistere. * @return Il libro creato, con eventuali modifiche apportate dal database (ad esempio, ID generato). */publicBookcreateBook(Bookbook) {
em.persist(book); // Persistente il nuovo libro nel databasereturnbook; // Restituisce l'oggetto Book appena creato
}
/** * Elimina un libro dal database. * Solo gli utenti con ruolo "admin" possono eseguire questa operazione. * @param book L'oggetto Book da eliminare. */@RolesAllowed("admin") // Assegna permessi specifici per il metodo deleteBookpublicvoiddeleteBook(Bookbook) {
em.remove(em.merge(book)); // Rimuove il libro dal database dopo averlo unito (merge) per garantire che sia gestito dall'EntityManager
}
}
Autorizzazione Programmatica
Permette una grana più fine nel controllo:
ad esempio, per blocchi di programma oppure per uno specifico utente.
Si usano direttamente le API di Java Authentication and Authorization Service (JAAS)
Interfaccia java.security.Principal insieme al contesto del JavaBean
L'interfaccia SessionContext offre metodi per verificare che se:
chi chiama il metodo ha un certo ruolo
oppure verifica l'utente stesso
@Stateless// Indica che questo EJB è stateless (senza stato)publicclassItemEJB {
@PersistenceContext(unitName = "chapter08PU") // Inietta l'EntityManager per gestire le operazioni di persistenzaprivateEntityManagerem;
@Resource// Inietta il contesto della sessione, utile per la gestione della sicurezzaprivateSessionContextctx;
/** * Elimina un libro dal database. * Solo gli utenti con ruolo "admin" possono eseguire questa operazione. * @param book L'oggetto Book da eliminare. */publicvoiddeleteBook(Bookbook) {
// Verifica se l'utente chiamante ha il ruolo "admin"if (!ctx.isCallerInRole("admin")) {
thrownewSecurityException("Only admins are allowed"); // Lancia un'eccezione se non ha il ruolo necessario
}
em.remove(em.merge(book)); // Rimuove il libro dal database
}
/** * Crea un nuovo libro nel database. * Assegna un valore al campo "createdBy" in base al ruolo dell'utente. * @param book L'oggetto Book da persistere. * @return Il libro creato, con eventuali modifiche apportate dal database. */publicBookcreateBook(Bookbook) {
// Controlla se l'utente ha il ruolo "employee" e non è un adminif (ctx.isCallerInRole("employee") && !ctx.isCallerInRole("admin")) {
book.setCreatedBy("employee only"); // Imposta il creatore come "employee only"
} elseif (ctx.getCallerPrincipal().getName().equals("paul")) {
book.setCreatedBy("special user"); // Imposta il creatore come "special user" se l'utente è "paul"
}
em.persist(book); // Persistente il nuovo libro nel databasereturnbook; // Restituisce l'oggetto Book appena creato
}
}
Transazioni
I dati sono cruciali per il business e vanno mantenuti in maniera coerente.
ad esempio: quando si fa un bonifico bancario, i soldi dal conto di uno vanno inseriti nel conto dell'altro, come un'unica operazione.
Una transazione rappresenta un insieme di operazioni logiche che devono essere realizzate come una singola unità di lavoro.
Le operazioni vanno ovviamente realizzate separatamente e, se vanno tutte a buon fine, la transazione va a buon fine (commit)
Altrimenti si deve riportare tutto a com'era prima che iniziasse la transazione (rollback)
Proprietà ACID: Atomicità, Cosistenza, Isolamento e Durabilità.
Transazioni Locali in JTA
Transazioni Distribuite
Esempio semplice di applicazione su una risorsa singola (DB)
Transaction Manager(TM): componente core che gestisce le operazioni, informa il RM chi partecipa nella transazione
Resource Manager(RM): responsabile della gestione delle risorse e della loro registrazione con il transaction manager.
driver, risorse JMS...
Risorsa: persistent storage da cui leggere o scrivere
DB, messaggi...
Quando ci sono più risorse coinvolte, ad esempio diversi DB
Coordinamento usando EXtended Architecture (XA) per Distributed Transaction Processing
JTA supporta XA (eterogeneità vendor)
Tecnica del two-phase commit: step di preparazione
Transazioni Distribuite
Supponiamo di effettuare un bonifico.
prelevo 1000€ dal primo conto: transazione completata con successo
accredito sul secondo conto: transazione fallita
è necessario annullare la transazione sul conto che è stato addebitato.
Bisogna usare il two-phase commit per evitare queste inconsistenze!
Two Phase Commit
Durante la fase 1, ogni Resource Manager viene notificato con un comando "prepare" che un commit sta per essere eseguito
Se tutti dichiarano che sono "prepared", la transazione può avvenire ed ai resource manager viene chiesto di fare commit nella seconda fase
Container-Managed Transactions
Delega completa della gestione delle transazioni al container
Il programmatore non sviluppa codice JTA
I servizi vengono forniti ai session beans
Gli EJB sono per loro natura transazionali: configuration by exception
@Stateless// Indica che questo EJB è stateless (senza stato)publicclassItemEJB {
@PersistenceContext(unitName = "chapter09PU") // Inietta l'EntityManager per gestire le operazioni di persistenzaprivateEntityManagerem;
@Inject// Inietta un'altra EJB, InventoryEJB, per gestire l'inventarioprivateInventoryEJBinventory;
/** * Trova tutti i libri nel database. * @return Una lista di oggetti Book trovati. */publicList<Book> findBooks() {
// Crea una query tipizzata per trovare tutti i libriTypedQuery<Book> query = em.createNamedQuery("FIND_ALL", Book.class);
returnquery.getResultList(); // Restituisce la lista dei risultati
}
/** * Crea un nuovo libro nel database e lo aggiunge all'inventario. * @param book L'oggetto Book da persistere. * @return Il libro creato, con eventuali modifiche apportate dal database. */publicBookcreateBook(Bookbook) {
em.persist(book); // Persistente il nuovo libro nel databaseinventory.addItem(book); // Aggiunge il libro all'inventario tramite l'EJB InventoryEJBreturnbook; // Restituisce l'oggetto Book appena creato
}
}
Bean-Managed Transactions
@Stateless// Indica che questo EJB è stateless (senza stato)@TransactionManagement(TransactionManagementType.BEAN) // Gestione delle transazioni a livello di beanpublicclassInventoryEJB {
@PersistenceContext(unitName = "chapter09PU") // Inietta l'EntityManager per gestire le operazioni di persistenzaprivateEntityManagerem;
@Resource// Inietta l'oggetto UserTransaction per gestire le transazioni manualmenteprivateUserTransactionut;
/** * Gestisce la vendita di un articolo, aggiornando lo stock e inviando notifiche. * @param item L'oggetto Item da elaborare. */publicvoidoneItemSold(Itemitem) {
try {
ut.begin(); // Inizia una nuova transazioneitem.decreaseAvailableStock(); // Diminuisce lo stock disponibile dell'articolosendShippingMessage(); // Invia un messaggio di spedizione// Controlla il livello di inventario dell'articoloif (inventoryLevel(item) == 0) {
ut.rollback(); // Se lo stock è a zero, annulla la transazione
} else {
ut.commit(); // Altrimenti, conferma la transazione
}
} catch (Exceptione) {
ut.rollback(); // In caso di eccezione, annulla la transazione
}
sendInventoryAlert(); // Invia un avviso sull'inventario, indipendentemente dall'esito della transazione
}
}