OSDN Git Service

FIRST REPOSITORY
[eos/hostdependOTHERS.git] / I386LINUX / util / I386LINUX / doc / mico / examples / pi / README
1                 Notes to Portable Interceptors
2                 ------------------------------
3                 
4 1. How to use
5 According to specification (orbos/99-12-02) this implementation based on,
6 "Portable Interceptors are hooks into the ORB through which ORB services
7 can intercept the normal flow of execution of the ORB". As far as interceptors
8 are becoming standardized, it is becoming possible to create standardized
9 services e.g. Security Service, Transaction Service etc. based on Portable
10 Interceptors (PI) which can be used with any ORB.
11 Rules for creation any service based on PI described below.
12 In current submission we have 3 types of interceptors - Client Interceptor,
13 Server Interceptor and IOR Interceptor.
14
15 1.1. Registering Interceptors.
16 Interceptors are intended to be a means by which ORB services gain access
17 to ORB processing, effectively becoming part of the ORB. Since Interceptors
18 are part of the ORB, when ORB_init() returns an ORB, the Interceptors shall
19 have been registered. An Interceptor is registering an assotiated ORBInitializer
20 object which implements the ORBInitializer interface. When ORB is initializing,
21 it calls each registered ORBInitializer, passing it an ORBInitInfo object,
22 which is used to register its Interceptor(s).
23 In our examples (see poa, poa2, client.cc, server.cc) we implemented this
24 interface as MyInitializer class. Using this class it is possible to register
25 any number of any kind of interceptors and every interceptor is some service
26 we need for this ORB.
27 Simple example:
28
29 class MyInitializer : virtual public PortableInterceptor::ORBInitializer
30 {
31   public:
32         MyInitializer() {}
33     ~MyInitializer() {}
34
35     virtual void pre_init( PortableInterceptor::ORBInitInfo_ptr info ) {
36         // register server interceptor(s)       
37         MyServerInterceptor * interceptor = new MyServerInterceptor("MyServerInterceptor");
38         info->add_server_request_interceptor(interceptor);
39         MyServerInterceptor * interceptor2 = new MyServerInterceptor("MyServerInterceptor2");
40         info->add_server_request_interceptor(interceptor2);
41         ........
42         // also policy factory(s) if necessary
43         // some initial settings, getting parameters, etc.
44     }
45     
46     virtual void post_init( PortableInterceptor::ORBInitInfo_ptr info ) {
47         // nothing, but you can put any stuff here if necessary
48     }
49 };
50
51 Every initializer is registered using register_orb_initializer() operation,
52 this operation like ORB_init() is not part of any interface and is "global".
53 Also it can not be called after ORB_init() operation.
54 Example:
55
56 int
57 main (int argc, char *argv[])
58 {
59
60   /*
61    * Initialize PI
62    */
63   MyInitializer * ini = new MyInitializer;
64   PortableInterceptor::register_orb_initializer(ini);
65
66   /*
67    * Initialize the ORB
68    */
69
70   CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
71   ..................................................
72   do whatever...
73   .............
74 }
75
76
77 1.2. Service implementation (for Request Interceptors).
78 To be able to implement some kind of service based on PI we have to derive
79 our service from Server or Client PI and implement its main methods. Simple
80 example for server:
81
82 class MyServerInterceptor : virtual public PortableInterceptor::ServerRequestInterceptor
83 {
84         string nm;
85         
86   public:
87         
88         MyServerInterceptor() {
89                 nm = "";
90         }
91         MyServerInterceptor(char * name) {      
92                 nm = name;
93         }
94         
95         char* name() {
96                 return (char *)nm.c_str();
97         }
98
99         void receive_request_service_contexts( PortableInterceptor::ServerRequestInfo_ptr ri ) {
100         
101                 // put your service stuff here
102         }
103     
104         void receive_request( PortableInterceptor::ServerRequestInfo_ptr ri ) {
105                 
106                 // put your service stuff here
107         }
108
109         void send_reply( PortableInterceptor::ServerRequestInfo_ptr ri ) {
110
111                 // put your service stuff here
112         }
113
114         void send_exception( PortableInterceptor::ServerRequestInfo_ptr ri ) {
115
116                 // put your service stuff here
117         }
118
119         void send_other( PortableInterceptor::ServerRequestInfo_ptr ri ) {
120
121                 // put your service stuff here
122         }
123         
124 };
125
126 Service based on Client PI looks similar.
127
128 Every method implements what we (our service) want to do on appropriate interception
129 point. After our service has been registered, ORB will call every method of every
130 registered service in appropriate interception point. Rules for using standard
131 paramenter which is filled in by ORB on every interception point (PortableInterceptor::
132 ServerRequestInfo or PortableInterceptor::ClientRequestInfo) and what kind of information
133 we can get/put from/to ORB using this parameter described in tables 5-2 p.5-50,51
134 and 5-1 p.5-46,47 respectively. See specification for detailed description of interception
135 points flow for Client and Server Interceptors.
136
137 1.3. IOR Interceptor
138 Like described in Specification the IOR Interceptor is used to establish tagged components
139 in the profile(s) within an IOR.
140 The IOR Interceptor is registered like any other interceptor (see above) using
141 ORBInitializer object. To be able to implement service based on this interceptor we have
142 to do the following (simple example):
143
144 class MyIORInterceptor : virtual public PortableInterceptor::IORInterceptor
145 {
146         string nm;
147         
148         public:
149         
150         MyIORInterceptor() {
151                 nm = "";
152         }
153         MyIORInterceptor(char * name) { 
154                 nm = name;
155         }
156         
157         char* name() {
158                 return (char *)nm.c_str();
159         }
160         
161         void establish_components(PortableInterceptor::IORInfo_ptr info) {
162          
163          // use IORInfo object for your service needs
164          // e.g. obtain effective policy (see below "Notes about POA policies")
165         CORBA::Policy_ptr pol;
166         try {
167         pol = info->get_effective_policy((CORBA::PolicyType)111111);
168         } catch (...) {
169         cout << "Exception occured..." << endl;
170         return;
171         }
172         cout << "PolicyType = " << pol->policy_type() << endl;
173         }
174 };
175
176 Example of using "like IOR Interceptor" service you can find in poa2/server.cc.
177 Operation establish_components() is guaranteed to be called at least once for each
178 distinct set of server policies, i.e. once per POA creation in our case.
179
180 Notes about POA policies. According to Specification: "The POA shall preserve
181 Policies whose types have been registered via PortableInterceptor::OrbInintInfo::
182 register_policy_factory() even if the POA itself does not know about those policies."
183 So now we can create our own policy factories, create our own policies and register
184 those policies with POA during creation and can obtain those policies from interceptors
185 in appropriate interception points.
186 Simple example of using own policies (see poa2/server.cc):
187 .........
188 ///////////////////////////
189 // My Policy
190
191 class MyPolicy : virtual public CORBA::Policy
192 {
193         CORBA::PolicyType pt;
194         
195   public:
196         MyPolicy() {
197                 pt = (CORBA::PolicyType)111111;
198         }
199         ~MyPolicy() {}
200         
201         CORBA::PolicyType policy_type() {
202                 return pt;
203         }
204         CORBA::Policy_ptr copy() {
205                 return _duplicate(this);
206         }
207         void destroy() {}
208 };
209         
210 ///////////////////////////
211 // My Policy Factory
212
213 class MyPolicyFactory : virtual public PortableInterceptor::PolicyFactory
214 {
215   public:       
216         MyPolicyFactory() {}
217         ~MyPolicyFactory() {}
218         
219         CORBA::Policy_ptr create_policy( CORBA::PolicyType type, const CORBA::Any& value ) {
220                 if (type != (CORBA::PolicyType)111111)
221                         mico_throw(CORBA::PolicyError());
222                 return new MyPolicy;
223         }
224 };      
225
226
227
228 class MyInitializer : virtual public PortableInterceptor::ORBInitializer
229 {
230   public:
231         MyInitializer() {}
232     ~MyInitializer() {}
233
234     virtual void pre_init( PortableInterceptor::ORBInitInfo_ptr info ) {
235         // register request server interceptor(s)       
236         MyServerInterceptor * interceptor = new MyServerInterceptor("MyServerInterceptor");
237         info->add_server_request_interceptor(interceptor);
238         // register IOR Interceptor
239         MyIORInterceptor * ior_interceptor = new MyIORInterceptor("MyIORInterceptor");
240         info->add_ior_interceptor(ior_interceptor);
241         // register My Policy Factory
242         MyPolicyFactory * factory = new MyPolicyFactory;
243         info->register_policy_factory((CORBA::PolicyType)111111, factory);
244     }
245     
246     virtual void post_init( PortableInterceptor::ORBInitInfo_ptr info ) {
247         // nothing
248     }
249 };
250
251
252
253 int
254 main (int argc, char *argv[])
255 {
256
257   /*
258    * Initialize PI
259    */
260   
261   MyInitializer * ini = new MyInitializer;
262   PortableInterceptor::register_orb_initializer(ini);
263
264   /*
265    * Initialize the ORB
266    */
267
268   CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
269
270   /*
271    * Obtain a reference to the RootPOA and its Manager
272    */
273
274   CORBA::Object_var poaobj = orb->resolve_initial_references ("RootPOA");
275   PortableServer::POA_var poa = PortableServer::POA::_narrow (poaobj);
276   PortableServer::POAManager_var mgr = poa->the_POAManager();
277
278   /*
279    * The RootPOA has the USE_ACTIVE_OBJECT_MAP_ONLY policy; to register
280    * our ServantManager, we must create our own POA with the
281    * USE_SERVANT_MANAGER policy
282    */
283
284   CORBA::PolicyList pl;
285   pl.length(2);
286   pl[0] = poa->create_request_processing_policy (PortableServer::USE_SERVANT_MANAGER);
287
288   //////////////////////////////////////////////////////////////
289   // test our policy factory, create MyPolicy and add it to POA,
290   // interceptor will be able to obtain this policy
291   /////////////////////////////////////////////////////////////
292
293   CORBA::Any any; // for this example we don't need
294   pl[1] = orb->create_policy((CORBA::PolicyType)111111, any);
295   //
296   PortableServer::POA_var mypoa = poa->create_POA ("MyPOA", mgr, pl);
297   .............
298   continue.....
299   .............
300 }
301
302 2. Notes about current implementation.
303 2.1. Specification.
304
305 2.1.1. Table 5-2, p. 5-50,51
306 last row, first 2 columns - I would say "no", "no" instead of "yes", "yes" because
307 at those points it is impossible (at least for this orb), because orb request has
308 only 1 service context list both for receive and reply and at those points we have
309 only "receive service context" and we can't do anything with reply service context.
310 Also IMHO it is not necessary at those interception points because we don't send to
311 client anything yet, what for we need to add something to "reply service context"?
312
313 2.1.2. Same table, "get_server_policy" row "receive_request_service_contexts" column -
314 I would say "no" instead of "yes", because we don't have OA at this point yet and
315 we can't get policy and IMHO we don't need any policy here.
316
317 2.1.3. Misprint on page 9-70 - IDL description of ORBInitInfo interface,
318 .......
319 void resolve_initial_references(...)....
320 .......
321 But if it doesn't return something it is useless :-)
322 I would say
323 ......
324 Object resolve_initial_references(...)....
325 ......
326
327 2.2. MICO ORB.
328 Some problems with Codec - for _this_ orb it is almost useless, because _this_ orb
329 doesn't use approach with TaggedComponents and TaggedProfiles, it uses Components and
330 Profiles "as is" not encoded, all this stuff encoded at last stage in GIOP::Codec
331 when message is assemled, so I had to do some "triks" to convert this stuff back
332 and forth for conformance with spec.
333 Also we don't have ANY implementation for components and profiles, but Codec works 
334 with ANY only.
335
336 Anyway I implemented it, it works but we don't need it for _this_ orb.
337