summaryrefslogtreecommitdiff
path: root/CIAO/DAnCE/NodeApplication/NodeApplication_Impl.h
blob: 46951f18f66fb20e76e4f998d7e850d6d15691d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
//$Id$

/**========================================================
 *
 * @file   NodeApplication_Impl.h
 *
 * @Brief  This file contains the implementation of
 *         the NodeApplication interface.
 *
 * @author Tao Lu <lu@dre.vanderbilt.edu>
 * @author Gan Deng <dengg@dre.vanderbilt.edu>
 *========================================================*/

#ifndef NODEAPPLICATION_IMPL_H
#define NODEAPPLICATION_IMPL_H
#include /**/ "ace/pre.h"

#include "CIAO_NodeApplication_export.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#include "ace/Synch.h"
#include "ace/Synch_Traits.h"
#include "ace/SString.h"
#include "ace/Hash_Map_Manager_T.h"
#include "tao/ORB.h"
#include "ciao/Deployment_NodeApplicationS.h"
#include "ciao/Server_init.h"
#include "ciao/CIAO_common.h"
#include "ciao/Object_Set_T.h"
#include "ciaosvcs/Events/CIAO_EventService_Factory_impl.h"
#include "ciaosvcs/Events/CIAO_Events_Base/CIAO_EventsS.h"

#include "NodeApp_Configurator.h"
#include "Container_Base.h"

using CIAO::Utility::write_IOR;

/**
 *
 * @class NodeApplication_Impl
 *
 * @brief This class implements the NodeApplication interface.
 * This interface is semantically very simillar to container
 * in the old DnC spec. However this class will also be used
 * as a Server for hosting home/component. This way we reduce the
 * complexity of the framework by omitting the componentserver layer.
 *
 * @@TODO add configuration capabilities. Threading is one of them.
 *
 * @@Assumptions:
 * 1. Now the implementation is not thread safe.
 * // @@Gan, the above assumption is _really_ bad. Could you please
 * use the lock in the imeplementation to do some simple
 * prootections.
 **/

namespace CIAO
{
  // @@ Gan, as we discussed before can you please wrap this
  // implementation in a namespace Node_Application or whatever to
  // signify that it belongs to another software piece of CIAO?
  class NODEAPPLICATION_Export NodeApplication_Impl
    : public virtual POA_Deployment::NodeApplication
  {
  public:
    enum Component_State
    {
      NEW_BORN, PRE_ACTIVE, ACTIVE, POST_ACTIVE, PASSIVE, DEACTIVATED
    };

    typedef struct _component_state_info
    {
      Components::CCMObject_var objref_;
      Component_State state_;
    } Component_State_Info;

    NodeApplication_Impl (CORBA::ORB_ptr o,
                          PortableServer::POA_ptr p,
                          NodeApp_Configurator &c,
                          const Static_Config_EntryPoints_Maps* static_entrypts_maps =0);

    /// Default destructor.
    virtual ~NodeApplication_Impl (void);

    /**
     * @method finishLaunch
     *
     * @brief This operation dose 2 things.
     *        1. Get the external connction (facet and Event source)
     *           and connect them to the local receptacle/event sink.
     *        2. If the start augment is true, start the Components.
     * @Note:
     * The connection containes the object ref of the provided object
     * reference (facet/event consumer) of components from other NodeApplications.
     * However the name field stores the name of the port on the local component.
     */
    virtual void
    finishLaunch (const Deployment::Connections & connections,
                  CORBA::Boolean start,
                  CORBA::Boolean add_connection
                  ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       Deployment::StartError,
                       Deployment::InvalidConnection));

    /**
     * @method start
     */
    virtual void
    start (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       Deployment::StartError));

    /*-------------  CIAO specific IDL operations (idl)----------
     *
     *-----------------------------------------------------------*/

    /**
     * @method ciao_preactivate
     */
    virtual void
    ciao_preactivate (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       Deployment::StartError));

    /**
     * @method ciao_postactivate
     */
    virtual void
    ciao_postactivate (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       Deployment::StartError));

    /**
     * @method ciao_passivate
     */
    virtual void
    ciao_passivate (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       Deployment::StopError));

    /// Initialize the NodeApplication
    virtual CORBA::Long init (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException));

    /// Start install homes and components.
    virtual ::Deployment::ComponentInfos *
      install (const ::Deployment::NodeImplementationInfo & node_impl_info
               ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       ::Deployment::UnknownImplId,
                       ::Deployment::ImplEntryPointNotFound,
                       ::Deployment::InstallationFailure,
                       ::Components::InvalidConfiguration));

    /// Install a number of CIAO_Event_Service objects within the NA
    virtual ::Deployment::CIAO_Event_Services *
      install_es (const ::Deployment::ESInstallationInfos & es_infos
                  ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((::CORBA::SystemException,
                       ::Deployment::InstallationFailure));

    /// Get the object reference of the NodeApplicationManager.
    /// This might come in handy later.
    virtual ::CORBA::Object_ptr
    get_node_application_manager (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException));

    /// Access the readonly attribute.
    virtual ::Deployment::Properties *
    properties (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException));

    /// Remove a component instance from the NodeApplication
    virtual void remove_component (const char * inst_name
                                   ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((::CORBA::SystemException,
                       ::Components::RemoveFailure));

    virtual void activate_component (const char * name
                                     ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((::CORBA::SystemException,
                       ::Deployment::StartError));

    virtual void passivate_component (const char * name
                                      ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((::CORBA::SystemException,
                       ::Components::RemoveFailure));

    /// Remove everything inside including all components and homes.
    virtual void remove (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException));

    /// Create a container interface, which will be hosted in this NodeApplication.
    virtual ::Deployment::Container_ptr
      create_container (const ::Deployment::Properties &properties
                        ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       ::Components::CreateFailure,
                       ::Components::InvalidConfiguration));

    /// Remove a container interface.
    virtual void remove_container (::Deployment::Container_ptr cref
                                   ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       ::Components::RemoveFailure));

    /// Get all container object refs
    virtual ::Deployment::Containers * get_containers (
        ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException));

    /*-------------  CIAO specific helper functions (C++)---------
     *
     *-----------------------------------------------------------*/

    /// Get the containing POA.  This operation does *not*
    /// increase the reference count of the POA.
    virtual PortableServer::POA_ptr _default_POA (void);

    /// Return the cached object reference of this NodeApplication object.
    /// This operation does *NOT* increase the reference count.
    ::Deployment::NodeApplication_ptr
    get_objref (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS);

    /*------- CIAO helper functions for pub/sub service -------
     *
     *--------------------------------------------------------*/

    /// Set up a connection using the CIAO_Event_Service, which
    /// is available as a field in the <Deployment::Connection>
    /// struct type.
    /// If <add_or_remove> input parameter is true, then we will
    /// add the event connection, otherwise we will remove the
    /// event connection.
    void build_event_connection (
        const Deployment::Connection & connection,
        bool add_or_remove
        ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((Deployment::InvalidConnection,
                       CORBA::SystemException));

  protected:
    /// If <add_connection> is "false", then we shall "remove"
    /// the connections, otherwise we will add these connections.
    virtual void
    finishLaunch_i (const Deployment::Connections & connections,
                    CORBA::Boolean start,
                    CORBA::Boolean add_connection
                    ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       Deployment::StartError,
                       Deployment::InvalidConnection));
    virtual void
    handle_facet_receptable_connection (
        Components::CCMObject_ptr comp,
        const Deployment::Connection & connection,
        CORBA::Boolean add_connection)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       Deployment::InvalidConnection));

    virtual void
    handle_emitter_consumer_connection (
        Components::CCMObject_ptr comp,
        const Deployment::Connection & connection,
        CORBA::Boolean add_connection)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       Deployment::InvalidConnection));

    virtual void
    handle_publisher_consumer_connection (
        Components::CCMObject_ptr comp,
        const Deployment::Connection & connection,
        CORBA::Boolean add_connection)
      ACE_THROW_SPEC ((CORBA::SystemException,
                       Deployment::InvalidConnection));

    virtual bool
    _is_es_consumer_conn (Deployment::Connection conn);

    virtual bool
    _is_publisher_es_conn (Deployment::Connection conn);

    /// Register the publisher to the CIAO event service
    /// The only fields of <connection> struct used in this method
    /// are: <type>, <event_service>, <instanceName>, <portName>.
    virtual void
    handle_publisher_es_connection (
        Components::CCMObject_ptr comp,
        const Deployment::Connection & connection,
        CORBA::Boolean add_connection)
      ACE_THROW_SPEC ((CORBA::SystemException,
                      Deployment::InvalidConnection));

    /// Register the consumer to the CIAO event service
    virtual void
    handle_es_consumer_connection (
        const Deployment::Connection & connection,
        CORBA::Boolean add_connection)
      ACE_THROW_SPEC ((CORBA::SystemException,
                      Deployment::InvalidConnection));

    /// Create and initialize all the containers
    virtual CORBA::Long create_all_containers (
        const ::Deployment::ContainerImplementationInfos & container_infos
        ACE_ENV_ARG_DECL_WITH_DEFAULTS)
      ACE_THROW_SPEC ((CORBA::SystemException));

    /// Create a "key" for the connection
    virtual ACE_CString *
    create_connection_key (const Deployment::Connection & connection);

    /// To build a map between a component instance and  its container
    typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
                                    Deployment::Container_var,
                                    ACE_Hash<ACE_CString>,
                                    ACE_Equal_To<ACE_CString>,
                                    ACE_Null_Mutex> Component_Container_Map;
    typedef Component_Container_Map::iterator Component_Container_Iterator;
    Component_Container_Map component_container_map_;


    /// To store all created Component objects as well as their lifecycle
    /// states..
    typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
                                    Component_State_Info,
                                    ACE_Hash<ACE_CString>,
                                    ACE_Equal_To<ACE_CString>,
                                    ACE_Null_Mutex> CCMComponent_Map;
    typedef CCMComponent_Map::iterator Component_Iterator;
    CCMComponent_Map component_state_map_;

    /// A Map which stores all the connection cookies
    typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
                                    ::Components::Cookie_var,
                                    ACE_Hash<ACE_CString>,
                                    ACE_Equal_To<ACE_CString>,
                                    ACE_Null_Mutex> Cookie_Map;
    typedef Cookie_Map::iterator Cookie_Map_Iterator;
    Cookie_Map cookie_map_;

    /// Synchronize access to the object set.
    TAO_SYNCH_MUTEX lock_;

    /// Keep a list of managed Container objects.
    Object_Set<Deployment::Container, Deployment::Container_var> container_set_;

    /// Keep a pointer to the managing ORB serving this servant.
    CORBA::ORB_var orb_;

    /// Keep a pointer to the managing POA.
    // @@Gan/Jai, which POA is this? Same as the component POA or a
    // different one. My sense is that its different. Could you please
    //document it?
    PortableServer::POA_var poa_;

    // Configurator for allocating NodeApp resources and policies
    NodeApp_Configurator &configurator_;

    /// Cached properties
    Deployment::Properties properties_;

    /// And a reference to the NodeApplicationManager that created us.
    ::CORBA::Object_var node_app_manager_;

    /// Cache the object reference (of ourselves).
    ::Deployment::NodeApplication_var objref_;

    /// A factory to create CIAO event services
    EventService_Factory_impl es_factory_;

    /// Cache the (NA specific) installation info of all the
    /// CIAO_Event_Services
    typedef ACE_Hash_Map_Manager_Ex<ACE_CString,
                                    ::Deployment::ESInstallationInfos_var,
                                    ACE_Hash<ACE_CString>,
                                    ACE_Equal_To<ACE_CString>,
                                    ACE_Null_Mutex> ES_Installation_Map;
    typedef ES_Installation_Map::iterator ES_Installation_Map_Iterator;
    ES_Installation_Map es_info_map_;

    const Static_Config_EntryPoints_Maps* static_entrypts_maps_;
  private:
    /// Default constructor, noop
    NodeApplication_Impl(void);
  };
}

#if defined (__ACE_INLINE__)
# include "NodeApplication_Impl.inl"
#endif /* __ACE_INLINE__ */

#include /**/ "ace/post.h"
#endif /* NODEAPPLICATION_IMPL_H */