Definito a partire dallo standard CORBA 2.3.
Il POA ha, tra le sue responsabilità, quella di gestire il ciclo di vita degli oggetti CORBA.
Le strategie di gestione oggetti possono essere predisposte dal programmatore.
IL POA ha una struttura gerarchica.
Il rootPOA rappresenta la radice della gerarchia (struttura ad albero), dal quale si possono eventualmente creare altri POA.
Esso viene creato e gestito direttamente dall’ORB, risultando sempre disponibile a un’applicazione servente.
Il riferimento al rootPOA viene restituito dall’ORB con l’operazione resolve_initial_references
(“RootPOA
“)
All’interno di ogni POA, la corrispondenza oggetto CORBA – Servant viene gestita mediante un’apposita tabella, denominata Active Object Map (AOM).
Tale tabella contiene le corrispondenze tra l’identificativo dell’oggetto servente (nella forma di un Servant) e il suo object reference.
Ad ogni POA possono essere associati due oggetti:
Le politiche di un POA svolgono un ruolo importante nella definizione del comportamento del POA stesso, relativamente alla gestione degli oggetti CORBA e alle strategie di elaborazione delle richieste.
Il rootPOA possiede il proprio insieme di politiche predefinite e non modificabili.
Il programmatore lato servente può comunque predisporre uno o più POA, assegnandone i comportamenti che meglio soddisfano i requisiti dell’applicazione.
La creazione di più POA nell’ambito di un’applicazione servente può essere utile per un eventuale partizionamento dell’applicazione servente in più gruppi di oggetti serventi.
L’interfaccia PortableServer::POA
fornisce i metodi per la creazione di oggetti di tipo Policy, denominati policy factories.
Gli oggettiPolicy
definiti sono raccolti in un array e forniti come parametro d’ingresso al metodo create_POA()
, al fine di creare un POA con le politiche prescelte.
Retention policy
Indica l’utilizzo o meno dell’AOM, per la memorizzazione delle corrispondenze object reference- oggetti serventi.
Un POA, carente di un AOM, dovrà obbligatoriamente utilizzare un Servant Locator o un Default Servant.
La politica di retention è definita mediante l’utilizzo del metodo create_servant_retention_policy() sull’oggetto POA. A tale metodo si fornisce uno dei seguenti argomenti:
Request processing policy
Indica la modalità di reperimento degli oggetti serventi per l’elaborazione delle richieste ad essi indirizzate. Qui di seguito si illustrano le quattro opzioni configurabili con la politica in oggetto:
Tale politica viene definita mediante l’invocazione sull’oggetto POA del metodo create_request_processing_policy()
, al quale si fornisce uno dei seguenti argomenti:
USE_ACTIVE_OBJECT_MAP_ONLY
(lo smistamento delle richieste avviene solo per gli oggetti serventi registrati nell’AOM);USE_SERVANT_MANAGER
(indica l’utilizzo di un Servant Manager, cioè di un oggetto associato al POA che ha la responsabilità di reperire l’oggetto servente, a cui è indirizzata una richiesta di servizio);USE_DEFAULT_SERVANT
(le richieste destinate ad oggetti serventi non reperibili dal POA, o perché l’oggetto servente non è presente nell’AOM o perché è stata configurata la politica di NON_RETAIN, saranno destinate ad un apposito oggetto, denominato DefaultServant).Determina la persistenza degli object reference, cioè la capacità di mantenere validi gli object reference anche al di fuori del contesto dell’applicazione servente in cui gli oggetti CORBA sono stati creati
Un oggetto CORBA, caratterizzato da un object reference persistente può essere riferito da un oggetto cliente attraverso successive attivazioni del POA o successive esecuzioni dell’applicazione servente.
La politica di lifespan viene definita mediante l’utilizzo del metodo create_lifespan_policy() al quale si fornisce uno dei seguenti argomenti:
TRANSIENT
PERSISTENT
Indica la modalità di assegnazione dell’object Id, cioè se l’assegnazione è a carico dell’utente (USER_ID
) o del POA (SYSTEM_ID
).
Viene definita mediante l’utilizzo del metodo create_id_assignment_policy()
al quale si fornisce uno dei seguenti argomenti:
SYSTEM_ID
. è il POA ad avere la responsabilità di generare l’identificativo dell’oggetto servente. Tale politica è utile soprattutto per gli oggetti transienti, avendo questi ultimi un ciclo di vita minore di quello del POA in cui sono registrati.USER_ID
. Tale politica conferisce al programmatore la responsabilità dell’assegnazione dell’object Id. Tale politica è utile soprattutto nel caso in cui l’oggetto registrato sia persistente.Indica la possibilità per un oggetto servente di essere associato, mediante il processo di incarnation, a più di un oggetto CORBA.
Viene definita mediante l’utilizzo del metodo create_id_uniqueness_policy()
, al quale si fornisce uno dei seguenti argomenti:
UNIQUE_ID
. Ad ogni oggetto servente è associato un identificativo univoco all’interno del POA dove è registratoMULTIPLE_ID
. Un medesimo oggetto servente può essere registrato in un POA con più identificativi.Indica la tipologia di gestione dei thread adottata dal POA per l’elaborazione delle richieste provenienti dall’ORB.
Viene definita mediante l’utilizzo del metodo create_thread_policy()
al quale si fornisce uno dei seguenti argomenti:
ORB_CTRL_MODEL
. Secondo tale politica, l’ORB sarà in grado di elaborare le richieste in maniera concorrente, mediante l’utilizzo di più thread. In tal caso l’ORB sarà responsabile dell’assegnazione delle richieste ai thread;SINGLE_THREAD_MODEL
. Tale politica indica una modalità di elaborazione delle richieste di tipo single-threaded: cioè le richieste sono elaborate in maniera sequenziale.Indica la modalità di attivazione di un oggetto CORBA.
Viene definita mediante l’utilizzo del metodo create_implicit_activation_policy()
al quale si fornisce uno dei seguenti argomenti:
IMPLICIT_ACTIVATION
. Indica la modalità di attivazione implicita: l’associazione (object reference, Object Id, Servant) è realizzata in un sol passoNO_IMPLICIT_ACTIVATION
. Indica la modalità di attivazione esplicita: viene prima realizzata l’associazione (Object Id, Servant) e, poi, quella (object reference, Object Id).La modalità di attivazione implicita di un oggetto CORBA avviene mediante l’invocazione dei seguenti metodi:
org.omg.CORBA.Object _this_object();
org.omg.CORBA.Object servant_to_reference(Servant s).
La modalità di attivazione esplicita degli oggetti si esplica in due fasi. Nella prima fase si realizza l’associazione object Id e il Servant, mediante l’invocazione, sull’oggetto POA, di uno dei seguenti metodi:
byte [] activate_object(Servant p) throws ServantAlreadyActive, WrongPolicy;
void activate_object_with_id(byte[]id, Servant p) throws ServantAlreadyActive, ObjectAlreadyActive, WrongPolicy.
Una volta registrato l’oggetto servente nel POA, il programmatore dovrà ottenere l’object reference assegnato mediante l’invocazione di uno dei tre metodi di seguito descritti:
org.omg.CORBA.Object id_to_reference(byte[]) throws ObjectNoActive, WrongPolicy;
org.omg.CORBA.Object create_reference_with_id(byte[] oid,String intf) throws WrongPolicy;
org.omg.CORBA.Object _this_object().
La configurazione di un POA è, in linea generale, il risultato di una combinazione delle politiche precedentemente analizzate.
Non tutte le combinazione possibili sono valide, in quanto i valori di alcune politiche vincolano la scelta di altri:
NON_RETAIN
richiede, per quanto riguarda la politica relativa all’elaborazione delle richieste, la configurazione dei valori USE_DEFAULT_SERVANT
oppureUSE_SERVANT_MANAGER
;SYSTEM_ID
e la politica di retention al valoreRETAIN
;USE_ACTIVE_OBJECT_MAP_ONLY
richiede la configurazione della politica di retention sul valore RETAIN
, altrimenti le attivazioni degli oggetti sul POA non verranno memorizzate in maniera permanente sull’AOM;MULTIPLE_ID
, in maniera tale che molteplici oggetti CORBA possano essere associati al medesimo oggetto servente (il Default Servant).Ha il compito di incapsulare lo stato di elaborazione delle richieste dei POA da esso gestiti.
L’associazione di un POAManager ad un particolare POA avviene all’atto della sua creazione, proprio nel momento in cui si fornisce il POAManager come parametro d’ingresso al metodo create_POA()
.
Più POA possono condividere lo stesso POAManager
L’associazione di un POAManager ad un particolare POA avviene all’atto della sua creazione, proprio nel momento in cui si fornisce il POAManager come parametro d’ingresso al metodo create_POA()
.
Gli stati del POAManager sono quattro:
E’ una classe concepita per supportare il POA nelle modalità di gestione (attivazione/disattivazione) dinamica degli oggetti serventi.
Le configurazioni possibili sono essenzialmente due e si definiscono mediante due politiche, Request Processing e Servant Retention.
Il tipo ServantManager è definito in CORBA mediante un’interfaccia IDL, priva di operazioni, che funge da classe base per due diverse specializzazioni: ServantActivator
e ServantLocator
.
Attivazione
Il POA può ottenere il servente attivando il metodo incarnate() sul ServantActivator. L’associazione del servente con l’oggetto CORBA consiste nella registrazione della coppia ObjectId-Servant presso l’AOM. Realizzata l’associazione, il POA può utilizzare il servente senza l’intermediazione del ServantActivator (l’identificativo del servente è già presente nell’AOM).
Disattivazione
Durante il suo ciclo di vita un POA può ricevere delle richieste che comportano, direttamente o indirettamente, la disattivazione di oggetti CORBA da esso gestiti.
L’attivazione e la disattivazione avvengono mediante l’invocazione dei metodi presenti nella interfaccia del ServantActivator
.
Il suo utilizzo è consigliato nei casi in cui il numero di oggetti CORBA da mantenere attivi sia troppo elevato e/o la frequenza di utilizzo sia molto bassa.
Al fine di rendere più efficiente l’utilizzo delle risorse di sistema è possibile attivare gli oggetti immediatamente prima del loro uso e disattivarli subito dopo.
L’attivazione e disattivazione sono eseguite mediante l’invocazione dei due metodi preinvoke()
e postinvoke()
.
E’ utile in quei casi in cui si debba implementare la classe servente in maniera tale che vi sia un unico Servant in grado di gestire le richieste per più oggetti CORBA.
Il programmatore può realizzare la classe servente secondo una tecnica che prevede la realizzazione di una classe, derivata dallo skeleton, che, come ogni classe servente, fornisce l’implementazione dei metodi definiti nell’interfaccia IDL.
All’arrivo di una richiesta, tale classe dovrà recuperare l’object Id dell’oggetto servente a cui è destinata la richiesta. A tale scopo la piattaforma fornisce un particolare oggetto, denominato Current, il quale fornisce l’Object Id contenuto nella richiesta.
Gli oggetti di tipo Current sono forniti dall’ORB tramite il metodo resolve_initial_references("POACurrent").
Esso è definito dalla seguente interfaccia IDL:
module PortableServer{
interface Current: CORBA::Current{
exception NoContext();
POA get_POA() raises (NoContext);
ObjectID get_object_id() raises (NoContext);
};
};
Per utilizzare un DefaultServant occorre:
USE_DEFAULT_SERVANT
;set_servant(Servant servant)
.2. La modellazione a oggetti e il linguaggio UML (richiami)
3. Generalità su Java e la programmazione ad oggetti
6. Regole di traduzione da UML a Java/C++
7. Programmazione multi-thread
8. Sincronizzazione tra thread
9. Programmazione client-server con socket TCP/IP (Java networkin...
10. Programmazione di applicazioni client-server: il Pattern Proxy...
12. Design Patterns
13. Pattern architetturali - Esempi
14. Design pattern creazionali. Esempi
15. Design pattern strutturali. Esempi
16. Introduzione alle tecnologie middleware
17. Modelli di middleware: RPC, MOM, TP, TS