root/ossiedev/branches/ssayed/devs/src/system/ossie/framework/DomainManager_impl.cpp @ 7853

Revision 7853, 56.9 KB (checked in by shereef, 5 years ago)

DevMgr? still crashes; something is throwing a CF::FileException? right at the end; getting warmer

  • Property svn:eol-style set to native
Line 
1/****************************************************************************
2
3Copyright 2008, Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Core Framework.
6
7OSSIE Core Framework is free software; you can redistribute it and/or modify
8it under the terms of the Lesser GNU General Public License as published by
9the Free Software Foundation; either version 2.1 of the License, or
10(at your option) any later version.
11
12OSSIE Core Framework is distributed in the hope that it will be useful
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15Lesser GNU General Public License for more details.
16
17You should have received a copy of the Lesser GNU General Public License
18along with OSSIE Core Framework; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21****************************************************************************/
22
23/* SCA */
24/* Include files */
25
26#include <iostream>
27#include <string>
28#include <vector>
29
30#include <string.h>
31
32#ifdef HAVE_OMNIEVENTS
33#include "omniEvents.hh"
34#endif
35
36#include "ossie/StandardEvent.h"    // from idl
37
38#include "ossie/debug.h"
39#include "ossie/DomainManager_impl.h"
40#include "ossie/ossieSupport.h"
41
42
43DomainManager_impl::DomainManager_impl (const char *_dmdFile, const char *_rootpath)
44{
45
46    std::string _domainManagerProfile = _dmdFile;
47
48    _numApps = 0;
49
50    _numDevMgrs = 0;
51
52    _applications.length (_numApps);
53
54    _deviceManagers.length (_numDevMgrs);
55
56   
57// Create file manager
58    FileManager_impl *_fileMgrImpl = new FileManager_impl ();
59    _fileMgr = _fileMgrImpl->_this ();
60// Create file system
61    FileSystem_impl *_fileSysImpl = new FileSystem_impl(_rootpath);
62    _fileSys = _fileSysImpl->_this();
63// Mount the file system to the file manager
64    try
65    {
66     _fileMgr->mount("/", _fileSys);
67    } catch( CF::InvalidFileName &_ex ) {
68     std::cout << "[DomainManager::ctor] While mounting File System: " << _ex.msg << "\n";
69     exit(EXIT_FAILURE);
70    } /*catch( CF::InvalidFileSystem &_ex ) {
71     std::cout << "[DomainManager::ctor] While mounting File System: Invalid File System\n";
72     exit(EXIT_FAILURE);
73    } catch( CF::MointPointAlreadyExists &_ex ) {
74     std::cout << "[DomainManager::ctor] While mounting File System: Moint point already exists\n";
75     exit(EXIT_FAILURE);
76    }*/ catch( ... ) { exit(EXIT_FAILURE); }
77// Parse the DMD profile
78    CF::File_var _dmd;
79    try
80    {
81     _dmd = _fileMgr->open( _domainManagerProfile.c_str(), true );
82    } catch( CF::InvalidFileName &_ex ) {
83     std::cout << "[DomainManager::ctor] While opening DMD: " << _ex.msg << "\n";
84     exit(EXIT_FAILURE);
85    } catch( CF::FileException &_ex ) {
86     std::cout << "[DomainManager::ctor] While opening DMD: " << _ex.msg << "\n";
87     exit(EXIT_FAILURE);
88    } catch( ... ) { exit(EXIT_FAILURE); }
89
90    DMDParser _DMDParser ( _dmd  );
91    _dmd->close();
92
93    this->_identifier = _DMDParser.getID();
94
95/// \todo lookup and install any services specified in the DMD
96
97/// \todo Discuss using filename + path directly from xml and screwing with FileSystem
98    CF::FileSystem::FileInformationSequence_var _dmdSoftPkg;
99    try
100    {
101     _dmdSoftPkg = _fileMgr->list (_DMDParser.getDomainManagerSoftPkg ());
102    } catch( CF::InvalidFileName &_ex ) {
103     std::cout << "[DomainManager::ctor] While obtaining File Information Sequence: " << _ex.msg << "\n";
104     exit(EXIT_FAILURE);
105    } catch( CF::FileException &_ex ) {
106     std::cout << "[DomainManager::ctor] While obtaining File Information Sequence: " << _ex.msg << "\n";
107     exit(EXIT_FAILURE);
108    } catch( ... ) { exit(EXIT_FAILURE); }
109
110    CF::File_var _spd;
111    try
112    {
113     _spd = _fileMgr->open( _DMDParser.getDomainManagerSoftPkg(), true );
114    } catch( CF::InvalidFileName &_ex ) {
115     std::cout << "[DomainManager::ctor] While opening SPD: " << _ex.msg << "\n";
116     exit(EXIT_FAILURE);
117    } catch( CF::FileException &_ex ) {
118     std::cout << "[DomainManager::ctor] While opening SPD: " << _ex.msg << "\n";
119     exit(EXIT_FAILURE);
120    }
121    SPDParser _DM_SPD_Parser ( _spd );
122    _spd->close();
123
124
125/*******************************************************
126
127At some point, memory has to be added to the system,
128where the domainmanager recalls the last configuration
129
130*******************************************************/
131
132//      create Incoming Domain Management and Outgoing Domain Management event channels
133    createEventChannels ();
134
135    // Create the event channel conusmer object to send events to
136#ifdef HAVE_OMNIEVENTS
137    ODM_Channel_consumer = connectEventChannel(ODM_channel);
138#endif
139}
140
141
142DomainManager_impl::~DomainManager_impl ()
143{
144  /// \todo uncomment    destroyEventChannels ();
145
146    DEBUG(1, DomMgr, "Domain Manager destructor called")
147
148/**************************************************
149 *    Save current state for configuration recall   *
150 *    this is not supported by this version          *
151 **************************************************/
152
153    unsigned int i;
154    for (i=0; i<_pendingConnections.size(); i++)
155    {
156        delete _pendingConnections[i];
157    }
158
159    for (i=0; i<_registeredDevices.size();i++)
160    {
161        delete _registeredDevices[i];
162    }
163
164    for (i=0; i<_registeredServices.size();i++)
165    {
166        delete _registeredServices[i];
167    }
168}
169
170char *
171DomainManager_impl::identifier (void)
172throw (CORBA::SystemException)
173{
174    return CORBA::string_dup(_identifier.c_str());
175}
176
177
178char *
179DomainManager_impl::domainManagerProfile (void)
180throw (CORBA::SystemException)
181{
182    return CORBA::string_dup(_domainManagerProfile.c_str());
183}
184
185
186CF::FileManager_ptr DomainManager_impl::fileMgr (void) throw (CORBA::
187SystemException)
188{
189
190    return CF::FileManager::_duplicate(_fileMgr);
191}
192
193
194CF::DomainManager::ApplicationFactorySequence *
195DomainManager_impl::applicationFactories (void) throw (CORBA::
196SystemException)
197{
198  CF::DomainManager::ApplicationFactorySequence_var result = new CF::DomainManager::ApplicationFactorySequence(_applicationFactories);
199
200  return result._retn();
201}
202
203
204CF::DomainManager::ApplicationSequence *
205DomainManager_impl::applications (void) throw (CORBA::SystemException)
206{
207
208  CF::DomainManager::ApplicationSequence_var result = new CF::DomainManager::ApplicationSequence(_applications);
209  return result._retn();
210}
211
212
213CF::DomainManager::DeviceManagerSequence *
214DomainManager_impl::deviceManagers (void) throw (CORBA::SystemException)
215{
216
217  CF::DomainManager::DeviceManagerSequence_var result = new CF::DomainManager::DeviceManagerSequence(_deviceManagers);
218  return result._retn();
219}
220
221
222void
223DomainManager_impl::registerDeviceManager (CF::DeviceManager_ptr deviceMgr)
224throw (CORBA::SystemException, CF::InvalidObjectReference, CF::InvalidProfile,
225CF::DomainManager::RegisterError)
226{
227
228    if (CORBA::is_nil (deviceMgr))
229    {
230//writeLogRecord(FAILURE_ALARM,invalid reference input parameter.);
231
232        throw (CF::
233            InvalidObjectReference
234            ("Cannot register Device. DeviceMgr is a nil reference."));
235    }
236
237//      add device manager to list
238
239    addDeviceMgr (CF::DeviceManager::_duplicate (deviceMgr));
240
241    ossieSupport::sendObjAdded_event(_identifier.c_str(), deviceMgr->identifier(), deviceMgr->label(), (CORBA::Object_var) NULL, StandardEvent::DEVICE_MANAGER);
242
243//      mount filesystem under "/DomainName1/<deviceMgr.label>"
244
245    string mountPoint = "/";
246    mountPoint += deviceMgr->label();
247    try
248    {
249     _fileMgr->mount (mountPoint.c_str(), deviceMgr->fileSys ());
250    } catch( CF::InvalidFileName &_ex ) {
251     std::cout << "[DomainManager::registerDeviceManager] While mounting DevMgr FileSys: " << _ex.msg << "\n";
252     exit(EXIT_FAILURE);
253    } catch( ... ) {
254     std::cout << "[DomainManager::registerDeviceManager] While mounting DevMgr FileSys: Unknown Exception\n";
255     exit(EXIT_FAILURE);
256    }
257
258//      add all devices under device manager to registereddevice att.
259//      associate input deviceMgr with registeredDevices
260    addDeviceMgrDevices (deviceMgr);
261
262//      add all services under device manager to registeredservices
263//      associate input deviceMgr with registeredservices
264    addDeviceMgrServices (deviceMgr);
265
266//NOTE: The SCA V2.2 describes that all service connections should be established at this point.
267//That step has been performed by the registerDevice operation (called by addDeviceMgrDevices) and by
268//registerService ( called by addDeviceMgrServices).
269//The registerDevice function establish all the connections requiered for the registering device and stores
270//any connection when the requested service is not registered yet.
271//The registerService function will establish any pending connection with the registering service.
272//These two functions together will establish all service connections required.
273
274//Note: In the event of an internal error that prevents the device Mgr registration from success, the
275//RegisterError exception shuld be raised and a FAILURE_ALARM log record written to a DomainManagerÂs Log
276}
277
278
279void
280DomainManager_impl::addDeviceMgr (CF::DeviceManager_ptr deviceMgr)
281{
282
283    if (!deviceMgrIsRegistered (deviceMgr))
284    {
285        _deviceManagers.length (_deviceManagers.length () + 1);
286        _deviceManagers[_deviceManagers.length () - 1] = deviceMgr;
287    }
288}
289
290
291void
292DomainManager_impl::addDeviceMgrDevices (CF::DeviceManager_ptr deviceMgr)
293{
294    CF::DeviceSequence * devices;
295    devices = deviceMgr->registeredDevices ();
296
297//Call registerDevice for each device in the DeviceMgr
298    for (unsigned int i = 0; i < devices->length (); i++)
299    {
300        CF::Device_ptr _dev = (*devices)[i];      //(CF::Device_ptr)&devices[i];
301        registerDevice (_dev, deviceMgr);
302    }
303//The registerDevice operation will try to establish any service connections specified in the
304//deviceMgr's DCD for each device.
305}
306
307
308void
309DomainManager_impl::addDeviceMgrServices (CF::DeviceManager_ptr deviceMgr)
310{
311    CF::DeviceManager::ServiceSequence *services;
312    services = deviceMgr->registeredServices ();
313
314//Call registerService for each service in the DeviceMgr
315    for (unsigned int i = 0; i < services->length (); i++ )
316    {
317//(CF::Device_ptr)&devices[i];
318        CF::DeviceManager::ServiceType _serv = (*services)[i];
319        registerService ( _serv.serviceObject, deviceMgr, _serv.serviceName);
320    }
321
322//The registerDeviceManager operation shall add the input deviceMgrÂs registeredServices and
323//each registeredServiceÂs names to the DomainManager. The registerDeviceManager operation
324//associates the input deviceMgrÂs with the input deviceMgrÂs registeredServices in the
325//DomainManager in order to support the unregisterDeviceManager operation.
326
327//Note: The registerService operation will establish any pending connection for the registering service
328}
329
330
331void
332DomainManager_impl::unregisterDeviceManager (CF::DeviceManager_ptr deviceMgr)
333throw (CORBA::SystemException, CF::InvalidObjectReference,
334CF::DomainManager::UnregisterError)
335{
336//The unregisterDeviceManager operation shall raise the CF InvalidObjectReference when the
337//input parameter DeviceManager contains an invalid reference to a DeviceManager interface.
338//      make sure that the pointer is valid
339    if (CORBA::is_nil (deviceMgr))
340    {
341/*writeLogRecord(FAILURE_ALARM,invalid reference input parameter.); */
342
343        throw (CF::
344            InvalidObjectReference
345            ("[DomainManager::unregisterDeviceManager] Cannot unregister Device. DeviceMgr is a nil reference."));
346        return;
347    }
348
349//NOTE: All disconnections of service event channels are performed by unregisterDevice
350//(called by removeDeviceMgrDevices)
351
352//release all device(s) and service(s)
353    removeDeviceMgrDevices (deviceMgr);
354
355    removeDeviceMgrServices (deviceMgr);
356
357//The unregisterDeviceManager operation shall unmount all DeviceManagerÂs FileSystems from
358//its File Manager.
359//Unmount filesystem from "/DomainName1/<deviceMgr.label>"
360    string mountPoint = "/";
361    mountPoint += _identifier;
362    mountPoint += "/";
363    mountPoint += deviceMgr->label();
364
365    _fileMgr->unmount (mountPoint.c_str());
366
367//The unregisterDeviceManager operation shall unregister a DeviceManager component from the
368//DomainManager.
369    removeDeviceMgr (deviceMgr);
370
371//Write log record upon successful registration of Device Manager
372/*writeLogRecord(ADMINISTRATIVE_EVENT, successful unregistration of DeviceManager); */
373
374//The unregisterDeviceManager operation shall, upon successful unregistration, send an event to
375//the Outgoing Domain Management event channel with event data consisting of a
376//DomainManagementObjectRemovedEventType. The event data will be populated as follows:
377//      1. The producerId shall be the identifier attribute of the DomainManager.
378//      2. The sourceId shall be the identifier attribute of the unregistered DeviceManager.
379//      3. The sourceName shall be the label attribute of the unregistered DeviceManager.
380//      4. The sourceCategory shall be DEVICE_MANAGER.
381
382
383/// \todo Fix event sending
384//    StandardEvent::DomainManagementObjectRemovedEventType _objRemovedEvent;
385
386//    _objRemovedEvent.producerId = CORBA::string_dup (this->_identifier);
387
388//    _objRemovedEvent.sourceId = CORBA::string_dup (deviceMgr->identifier ());
389
390//    _objRemovedEvent.sourceName = CORBA::string_dup (deviceMgr->label ());
391
392//    _objRemovedEvent.sourceCategory = StandardEvent::DEVICE_MANAGER;
393
394//    CORBA::Any _anyObjRemovedEvent;
395
396//    _anyObjRemovedEvent <<= _objRemovedEvent;
397
398//    sendEventToOutgoingChannel (_anyObjRemovedEvent);
399
400//Note: In the event of an internal error that prevents the deviceMgr unregistration from success, the
401//RegisterError exception shuld be raised and a FAILURE_ALARM log record written to a DomainManagerÂs Log
402}
403
404
405void
406DomainManager_impl::removeDeviceMgrDevices (CF::DeviceManager_ptr deviceMgr)
407{
408//The unregisterDeviceManager operation shall release all device(s) associated with
409//the DeviceManager that is being unregistered.
410    CF::DeviceSequence * devices;
411    devices = deviceMgr->registeredDevices ();
412
413//Call unregisterDevice for each device in the DeviceMgr
414    for (unsigned int i = 0; i < devices->length (); i++)
415    {
416        CF::Device_ptr _dev = (*devices)[i];
417        unregisterDevice (_dev);
418    }
419
420}
421
422
423void
424DomainManager_impl::removeDeviceMgrServices (CF::DeviceManager_ptr deviceMgr)
425{
426//The unregisterDeviceManager operation shall release all service(s) associated with
427//the DeviceManager that is being unregistered.
428    CF::DeviceManager::ServiceSequence* services;
429    services = deviceMgr->registeredServices ();
430
431//Call unregisterDevice for each device in the DeviceMgr
432    for (unsigned int i = 0; i < services->length (); i++)
433    {
434        unregisterService ( (*services)[i].serviceObject, (*services)[i].serviceName );
435    }
436
437}
438
439
440void
441DomainManager_impl::removeDeviceMgr (CF::DeviceManager_ptr deviceMgr)
442{
443//Look for registeredDeviceMgr in _deviceManagers
444//if deviceMgr is not registered, do nothing
445    for (unsigned int i = 0; i < _deviceManagers.length (); i++)
446    {
447        if (strcmp (_deviceManagers[i]->label (), deviceMgr->label ()) == 0)
448        {
449//_deviceManagers.remove(i);
450            for (unsigned int j = i; j < _deviceManagers.length () - 1; j++)
451            {
452                _deviceManagers[j] = _deviceManagers[j + 1];
453            }
454            _deviceManagers.length (_deviceManagers.length () - 1);
455            break;
456        }
457    }
458
459}
460
461
462void
463DomainManager_impl::registerDevice (CF::Device_ptr registeringDevice,
464CF::DeviceManager_ptr registeredDeviceMgr)
465throw (CORBA::SystemException, CF::InvalidObjectReference, CF::InvalidProfile,
466CF::DomainManager::DeviceManagerNotRegistered,
467CF::DomainManager::RegisterError)
468{
469//Verify they are not a nil reference
470    if (CORBA::is_nil (registeringDevice)
471        || CORBA::is_nil (registeredDeviceMgr))
472    {
473/*writeLogRecord(FAILURE_ALARM,invalid reference input parameter.); */
474        throw (CF::
475            InvalidObjectReference
476            ("[DomainManager::registerDevice] Cannot register Device. Either Device or DeviceMgr is a nil reference."));
477    }
478
479//Verify that input is a registered DeviceManager
480    if (!deviceMgrIsRegistered (registeredDeviceMgr))
481    {
482/*writeLogRecord(FAILURE_ALARM,the device could not register because the DeviceManager is not registered with the DomainManager.); */
483
484        throw CF::DomainManager::DeviceManagerNotRegistered ();
485    }
486
487//Add registeringDevice and its attributes to domain manager
488    if (storeDeviceInDomainMgr (registeringDevice, registeredDeviceMgr) !=
489        NULL_ERROR)
490    {
491/*writeLogRecord(FAILURE_ALARM,the registeringDevice has an invalid profile.); */
492//The registerDevice operation shall raise the CF InvalidProfile exception when:
493//      1. The Device's SPD file and the SPDÂs referenced files do not exist or cannot be processed
494//      due to the file not being compliant with XML syntax, or
495//      2. The DeviceÂs SPD does not reference allocation properties.
496//              throw( CF::InvalidProfile() );
497        throw CF::InvalidProfile ();
498    }
499
500//Check the DCD for connections and establish them
501    establishServiceConnections(registeringDevice, registeredDeviceMgr);
502
503    ossieSupport::sendObjAdded_event(_identifier.c_str(), registeringDevice->identifier(), registeringDevice->label(), (CORBA::Object_var) NULL, StandardEvent::DEVICE);
504
505//write a log record when registration is successful
506/*writeLogRecord(ADMINISTRATIVE_EVENT,the device has successfully registered with the DomainManager); */
507
508//NOTE: This function only checks that the input references are valid and the device manager is registered.
509//No other sanity test is performed. In the event of any internal error that impedes a succesful registration,
510// a FAILURE_ALARM log record should be written and the RegisterError exception should be raised
511}
512
513
514//This function adds the registeringDevice and its atributes to the DomainMgr.
515//if the device already exists it does nothing
516DomainManager_impl::ErrorCode DomainManager_impl::storeDeviceInDomainMgr (CF::
517Device_ptr
518registeringDevice,
519CF::
520DeviceManager_ptr
521registeredDeviceMgr)
522{
523    ErrorCode parserResult;
524
525//check if device is already registered
526    if (deviceIsRegistered (registeringDevice))
527    {
528        return NULL_ERROR;                        //if registeringDevice exists already, do nothing
529    }
530//If this part is reached, the registering device has to be added
531//Get read-only attributes from registeringDevice
532    DeviceNode *
533        newDeviceNode = new DeviceNode;
534
535    newDeviceNode->devicePtr = registeringDevice;
536    newDeviceNode->devMgrPtr = registeredDeviceMgr;
537    newDeviceNode->label = CORBA::string_dup (registeringDevice->label ());
538    newDeviceNode->softwareProfile =
539        CORBA::string_dup (registeringDevice->softwareProfile ());
540
541//parse and get device properties from SPD
542    parserResult = getDeviceProperties (*newDeviceNode);
543    if (parserResult != NULL_ERROR)
544    {
545//There was an error
546        return parserResult;
547    }
548    else
549    {
550//add registeringDevice to DomainManager's registeredDevices
551        _registeredDevices.push_back (newDeviceNode);
552        return NULL_ERROR;
553    }
554}
555
556
557DomainManager_impl::ErrorCode DomainManager_impl::
558getDeviceProperties (DeviceNode & registeringDeviceNode)
559{
560/*PRFProperty parsedProperties;
561   //parse SPD
562   SPDParser SPDFile( registeringDeviceNode.softwareProfile );
563
564   if( SPDFile.isScaCompliant() )
565   {
566   //Parse PRF file to get device's properties
567   PRFParser PRFFile( SPDFile.getPRFFile() );
568   parsedProperties = PRFFile.getProperties();
569   //store properties in registeringDeviceNode
570   CORBA::Any anyVar;
571for(int i = 0; i < parsedProperties.size(); i++)
572{
573registeringDeviceNode.properties[i].id = CORBA::string_dup( parsedProperties[i]->getID() );
574ORB_WRAP::anyType( parsedProperties[i]->getType(), parsedProperties[i]->getValue(), anyVar );
575registeringDeviceNode.properties[i].value = anyVar;
576}
577//return result
578return NULL_ERROR;
579}
580else
581{
582return NOT_SCA_COMPLIANT;
583} */
584    return NULL_ERROR;
585}
586
587
588//This function adds the registeringService and its name to the DomainMgr.
589//if the service already exists it does nothing
590void
591DomainManager_impl::storeServiceInDomainMgr (CORBA::Object_ptr registeringService, CF::DeviceManager_ptr registeredDeviceMgr,const char * name)
592{
593//check if device is already registered
594    if (serviceIsRegistered (name))
595    {
596        return ;                                  //if registeringDevice exists already, do nothing
597    }
598//If this part is reached, the registering device has to be added
599//Get read-only attributes from registeringDevice
600    ServiceNode* newServiceNode = new ServiceNode;
601
602    newServiceNode->objectPtr = registeringService;
603    newServiceNode->devMgrPtr = registeredDeviceMgr;
604    newServiceNode->name = CORBA::string_dup (name);
605
606//add registeringService to DomainManager's registeredServices
607    _registeredServices.push_back (newServiceNode);
608}
609
610
611//This function removes the registeringService and its name to the DomainMgr.
612//if the service already exists it does nothing
613void
614DomainManager_impl::removeServiceFromDomainMgr (CORBA::Object_ptr registeringService, const char * name)
615{
616    vector<ServiceNode*>::iterator p = _registeredServices.begin ();
617//check if service is already registered
618    while (p != _registeredServices.end ())
619    {
620        ServiceNode* _tmp = *p;
621        if (strcmp (name, _tmp->name) == 0)
622        {
623            _registeredServices.erase (p);
624            return;                               //unregisteringDevice has been removed
625        }
626        else
627        {
628            p++;
629        }
630    }
631//If this part is reached, unregisteringDevice was not registered
632    return;
633
634}
635
636
637void
638DomainManager_impl::unregisterDevice (CF::Device_ptr unregisteringDevice)
639throw (CORBA::SystemException, CF::InvalidObjectReference,
640CF::DomainManager::UnregisterError)
641{
642//verify valid reference for a device
643
644    if (CORBA::is_nil (unregisteringDevice)
645        || !deviceIsRegistered (unregisteringDevice))
646    {
647/*writeLogRecord(FAILURE_ALARM,Device reference is not valid); */
648
649//The unregisterDevice operation shall raise the CF InvalidObjectReference exception when the
650//input parameter contains an invalid reference to a Device interface.
651        throw (CF::
652            InvalidObjectReference
653            ("Cannot Unregister Device. Invalid reference"));
654        return;
655    }
656
657
658    ///\todo Figure out what should go and what should be implemented
659
660//disconnect the DeviceÂs consumers and producers Event Service event channel based upon the software profile.
661//The unregisterDevice operation may destroy the Event Service event channel when no more consumers and
662//producers are connected to it.
663//    disconectEventService ();
664
665//The unregisterDevice operation shall release (client-side CORBA release) the
666//unregisteringDevice from the Domain Manager.
667    removeDeviceFromDomainMgr (unregisteringDevice);
668
669/*writeLogRecord(ADMINISTRATIVE_EVENT, Device was successfuly unregistered); */
670
671//The unregisterDevice operation shall, upon successful Device unregistration, send an event to the
672//Outgoing Domain Management event channel with event data consisting of a
673//DomainManagementObjectRemovedEventType. The event data will be populated as follows:
674//1. The producerId shall be the identifier attribute of the DomainManager.
675//2. The sourceId shall be the identifier attribute of the unregistered Device.
676//3. The sourceName shall be the lable attribute of the unregistered Device.
677//4. The sourceCategory shall be DEVICE.
678
679/// \todo Fix event sending
680
681//    StandardEvent::DomainManagementObjectRemovedEventType _objRemovedEvent;
682
683//    _objRemovedEvent.producerId = CORBA::string_dup (this->_identifier);
684
685//_objRemovedEvent.sourceId = CORBA::string_dup( unregisteringDevice->identifier() );//Devices don't have identifiers
686
687//    _objRemovedEvent.sourceName =
688//        CORBA::string_dup (unregisteringDevice->label ());
689
690//    _objRemovedEvent.sourceCategory = StandardEvent::DEVICE;
691
692//    CORBA::Any _anyObjRemovedEvent;
693
694//    _anyObjRemovedEvent <<= _objRemovedEvent;
695
696//    sendEventToOutgoingChannel (_anyObjRemovedEvent);
697
698//NOTE: This function only checks that the input reference is valid.
699//No other sanity test is performed. In the event of any internal error that impedes a succesful unregistration,
700// a FAILURE_ALARM log record should be written and the UnregisterError exception should be raised
701}
702
703
704//This function removes the registeringDevice and its atributes from the DomainMgr.
705//if the device doesn't exist, it does nothing
706void
707DomainManager_impl::removeDeviceFromDomainMgr (CF::
708Device_ptr unregisteringDevice)
709{
710    vector < DeviceNode * >::iterator p = _registeredDevices.begin ();
711//check if device is already registered
712    while (p != _registeredDevices.end ())
713    {
714        DeviceNode *_tmp = *p;
715        if (!strcmp (unregisteringDevice->label (), _tmp->devicePtr->label ()))
716        {
717            _registeredDevices.erase (p);
718            return;                               //unregisteringDevice has been removed
719        }
720        else
721        {
722            p++;
723        }
724    }
725
726//If this part is reached, unregisteringDevice was not registered
727    return;
728
729}
730
731
732//This function returns TRUE if the input registeredDevice is contained in the _registeredDevices
733bool DomainManager_impl::deviceIsRegistered (CF::Device_ptr registeredDevice)
734{
735    for (unsigned int i = 0; i < _registeredDevices.size (); i++)
736    {
737        registeredDevice->label ();
738        _registeredDevices[i]->devicePtr->label ();
739        if (strcmp
740            (_registeredDevices[i]->devicePtr->label (),
741            registeredDevice->label ()) == 0)
742        {
743            return true;
744        }
745    }
746    return false;
747}
748
749
750bool DomainManager_impl::serviceIsRegistered (const char *serviceName)
751{
752    for (unsigned int i = 0; i < _registeredServices.size (); i++)
753    {
754        if (strcmp (_registeredServices[i]->name, serviceName) == 0)
755        {
756            return true;
757        }
758    }
759    return false;
760}
761
762
763//This function returns TRUE if the input registeredDeviceMgr is contained in the _deviceManagers list attribute
764bool
765DomainManager_impl::deviceMgrIsRegistered (CF::
766DeviceManager_ptr
767registeredDeviceMgr)
768{
769//Look for registeredDeviceMgr in _deviceManagers
770    for (unsigned int i = 0; i < _deviceManagers.length (); i++)
771    {
772        if (strcmp
773            (_deviceManagers[i]->identifier (),
774            registeredDeviceMgr->identifier ()) == 0)
775        {
776            return true;
777        }
778    }
779    return false;
780}
781
782
783void
784DomainManager_impl::establishServiceConnections (CF::Device_ptr registeringDevice, CF::DeviceManager_ptr registeredDeviceMgr)
785{
786//There are no services for this release. This determination may change though.
787
788//Parse DCD. Obtain all software profiles from deviceManager's fileSys
789
790//The registerDeviceManager operation shall perform the connections specified in the connections
791//element of the deviceMgrÂs Device Configuration Descriptor (DCD) file. If the
792//DeviceManagerÂs DCD describes a connection for a service that has not been registered with the
793//DomainManager, the registerDeviceManager operation shall establish any pending connection
794//when the service registers with the DomainManager by the registerDeviceManager operation.
795
796//get DCD's connections
797
798    DCDParser _dcdParser( _fileMgr->open( registeredDeviceMgr->deviceConfigurationProfile(), true ) );
799
800    std::vector<Connection*>* _connection = _dcdParser.getConnections();
801
802    for( int _numConnections = _connection->size() - 1; _numConnections >= 0; _numConnections-- )
803    {
804        UsesPort* _usesPortParser = (*_connection)[ _numConnections ]->getUsesPort();
805
806        FindBy* _findUsesPortBy = _usesPortParser->getFindBy();
807
808        ProvidesPort* _providesPortParser = NULL;
809
810        FindBy* _findProvidesPortBy = NULL;
811
812//ComponentSupportInterface* _componentSuppInterface = NULL:
813
814        if( (*_connection)[ _numConnections ]->isProvidesPort() )
815            _providesPortParser = (*_connection)[ _numConnections ]->getProvidesPort();
816        else if( (*_connection)[ _numConnections ]->isFindBy() )
817            _findProvidesPortBy = (*_connection)[ _numConnections ]->getFindBy();
818// else if( _connection[ _numConnections ]->isComponentSupportedInterface() )
819        else
820        {
821//throw an exception?
822        }
823
824//get the connections that involve this device
825        int deviceIsUsing = -1;
826        if( !strcmp( _usesPortParser->getID(), registeringDevice->label() ) ) deviceIsUsing = 1;
827        else if( !strcmp( _providesPortParser->getID(), registeringDevice->label() ) ) deviceIsUsing = 0;
828
829        char serviceName[128];
830        if( deviceIsUsing >= 0)
831        {
832//verify that the service is registered
833            if(deviceIsUsing)
834            {
835                strcpy( serviceName, _providesPortParser->getID() );
836            }
837            else
838            {
839                strcpy( serviceName, _usesPortParser->getID() );
840            }
841            if( serviceIsRegistered( serviceName ) )
842            {
843//get object pointers
844//establish the connection
845                CORBA::Object_var _usesObj;
846
847                CORBA::Object_var _providesObj;
848
849                if( _providesPortParser != NULL )
850                    _findProvidesPortBy = _providesPortParser->getFindBy();
851
852                if( _findUsesPortBy->isFindByNamingService() )
853                {
854                    while( CORBA::is_nil( _usesObj ) )
855                        ///\todo When services are implemented fix this                        _usesObj = _orb_wrap->lookup( _findUsesPortBy->getFindByNamingServiceName() );
856                        ;
857                }
858
859                if( _findProvidesPortBy->isFindByNamingService() )
860                {
861                    while( CORBA::is_nil( _providesObj ) )
862                        ///\todo When services are implemented fix this                        _providesObj = _orb_wrap->lookup( _findProvidesPortBy->getFindByNamingServiceName() );
863                        ;
864                }
865
866                CF::PortSupplier_ptr _usesPort = CF::PortSupplier::_narrow( _usesObj );
867
868                CF::Port_ptr _port = CF::Port::_narrow( _usesPort->getPort( _usesPortParser->getID() ) );
869
870                _port->connectPort( _providesObj, CORBA::string_dup( (*_connection)[ _numConnections ]->getID() ) );
871
872                CORBA::release(_usesPort);
873                CORBA::release(_port);
874            }
875            else
876            {
877                _pendingConnections.push_back(new Connection( *(*_connection)[ _numConnections ] ));
878            }
879        }
880    }
881
882//For connections established for a CORBA Event ServiceÂs event channel, the
883//registerDeviceManager operation shall connect a CosEventComm PushConsumer or
884//PushSupplier object to the event channel as specified in the DCDÂs domainfinder element. If the
885//event channel does not exist, the registerDeviceManager operation shall create the event
886//channel.
887/*connectToEventChannel(); */
888
889}
890
891
892void
893DomainManager_impl::establishPendingServiceConnections (const char * serviceName)
894{
895    for (int _numConnections = _pendingConnections.size () - 1; _numConnections >= 0; _numConnections--)
896    {
897        UsesPort* _usesPortParser = _pendingConnections[ _numConnections ]->getUsesPort ();
898
899        FindBy* _findUsesPortBy = _usesPortParser->getFindBy ();
900
901        ProvidesPort* _providesPortParser = NULL;
902
903        FindBy* _findProvidesPortBy = NULL;
904
905//ComponentSupportInterface* _componentSuppInterface = NULL:
906
907        if (_pendingConnections[ _numConnections ]->isProvidesPort ())
908            _providesPortParser = _pendingConnections[ _numConnections ]->getProvidesPort ();
909        else if ( _pendingConnections[ _numConnections ]->isFindBy ())
910            _findProvidesPortBy = _pendingConnections[ _numConnections ]->getFindBy ();
911// else if( _connection[ _numConnections ]->isComponentSupportedInterface() )
912        else
913        {
914//throw an exception?
915        }
916
917//get the connections that involve this device
918        if (!strcmp (_usesPortParser->getID (), serviceName) ||
919            !strcmp (_providesPortParser->getID (), serviceName))
920        {
921
922//get object pointers
923//establish the connection
924            CORBA::Object_var _usesObj;
925
926            CORBA::Object_var _providesObj;
927
928            if (_providesPortParser != NULL)
929                _findProvidesPortBy = _providesPortParser->getFindBy ();
930
931            if (_findUsesPortBy->isFindByNamingService ())
932            {
933                while (CORBA::is_nil (_usesObj))
934                    ///\todo When services are implemented fix this                    _usesObj = _orb_wrap->lookup ( _findUsesPortBy->getFindByNamingServiceName ());
935                    ;
936            }
937
938            if (_findProvidesPortBy->isFindByNamingService ())
939            {
940                while (CORBA::is_nil (_providesObj))
941                    ///\todo When services are implemented fix this                    _providesObj = _orb_wrap->lookup (_findProvidesPortBy->getFindByNamingServiceName ());
942                    ;
943            }
944
945            CF::PortSupplier_ptr _usesPort = CF::PortSupplier::_narrow (_usesObj);
946
947            CF::Port_ptr _port = CF::Port::_narrow (_usesPort->getPort (_usesPortParser->getID ()));
948
949            _port->connectPort (_providesObj, CORBA::string_dup (_pendingConnections[ _numConnections ]->getID ()));
950
951            CORBA::release(_usesPort);
952            CORBA::release(_port);
953        }
954    }
955
956}
957
958
959void
960DomainManager_impl::disconnectThisService (const char * serviceName)
961{
962//search registered devices to obtain the deviceManager of this service
963    CF::DeviceManager_ptr devMgr;
964    for (unsigned int i = 0; i < _registeredServices.size (); i++ )
965        if (!strcmp (serviceName, _registeredServices[i]->name))
966            devMgr = _registeredServices[i]->devMgrPtr;
967
968//get the DCD
969    DCDParser _dcdParser ( _fileMgr->open( devMgr->deviceConfigurationProfile (), true ) );
970
971//parse connections of this DCD
972    std::vector<Connection*>* _connection = _dcdParser.getConnections ();
973
974//Find the connections that involve this service
975//disconnect the ports the are using this service
976    for (int _numConnections = _connection->size () - 1; _numConnections >= 0; _numConnections--)
977    {
978        UsesPort* _usesPortParser = (*_connection)[ _numConnections ]->getUsesPort ();
979
980        FindBy* _findUsesPortBy = _usesPortParser->getFindBy ();
981
982        ProvidesPort* _providesPortParser = NULL;
983
984        FindBy* _findProvidesPortBy = NULL;
985
986//ComponentSupportInterface* _componentSuppInterface = NULL:
987
988        if ((*_connection)[ _numConnections ]->isProvidesPort ())
989            _providesPortParser = (*_connection)[ _numConnections ]->getProvidesPort ();
990        else if ((*_connection)[ _numConnections ]->isFindBy ())
991            _findProvidesPortBy = (*_connection)[ _numConnections ]->getFindBy ();
992// else if ( _connection[ _numConnections ]->isComponentSupportedInterface ())
993        else
994        {
995//throw an exception?
996        }
997
998//get the connections that involve this device
999        if (!strcmp (_providesPortParser->getID (), serviceName))
1000        {
1001            CORBA::Object_var _usesObj = CORBA::Object::_nil ();
1002
1003            if (_findUsesPortBy->isFindByNamingService ())
1004                {
1005                    while (CORBA::is_nil (_usesObj))
1006                        ///\todo When services are implemented fix this                    _usesObj = _orb_wrap->lookup (_findUsesPortBy->getFindByNamingServiceName ());
1007                        ;
1008                }
1009           
1010            CF::PortSupplier_ptr _usesPort = CF::PortSupplier::_narrow (_usesObj);
1011
1012            CF::Port_ptr _port = CF::Port::_narrow (_usesPort->getPort (_usesPortParser->getID ()));
1013
1014            _port->disconnectPort (CORBA::string_dup ((*_connection)[ _numConnections ]->getID ()));
1015
1016//store this connection in pendingConnections so it is established
1017//again when this service registers again
1018            _pendingConnections.push_back ( new Connection ( *(*_connection)[ _numConnections ]));
1019            CORBA::release(_usesPort);
1020            CORBA::release(_port);
1021        }
1022    }
1023}
1024
1025
1026
1027
1028
1029/*void DomainManager_impl::writeLogRecord(CF::LogLevelType logLevelType)
1030{
1031    //There are no services considered in this release
1032}*/
1033
1034//      METHOD:         installApplication
1035//      PURPOSE:        verify that all application file dependencies are available within
1036//                              the domain managers file manager
1037//      EXCEPTIONS:
1038//              --              InvalidProfile
1039//              --              InvalidFileName
1040//              --              ApplicationInstallationError
1041
1042void
1043DomainManager_impl::installApplication (const char *profileFileName)
1044throw (CORBA::SystemException, CF::InvalidProfile, CF::InvalidFileName,
1045CF::DomainManager::ApplicationInstallationError)
1046{
1047// NOTE: the <softwareassembly> name attribute is the name of the App Factory
1048//               that is currently installed because it is the installed factory that
1049//               provides the value of profileFileName
1050    DEBUG(1, DomMgr, "Entering installApplication")
1051  try {
1052    // check the profile ends with .sad.xml, warn if it doesn't
1053    if ((strstr (profileFileName, ".sad.xml")) == NULL)
1054        std::cerr << "File " << profileFileName << " should end with .sad.xml." << std::endl;
1055
1056    this->validate (profileFileName);
1057 
1058/// \todo verify that SAD conforms to DTD by allowing parser to throw an exception
1059//               then the DomainManager throws a CF::InvalidProfile if the SAD does not conform
1060    SADParser *sadParser = new SADParser ( _fileMgr->open( profileFileName, true ) );
1061
1062// check if application factory already exists for this profile
1063    for (unsigned int i = 0; i < appFact_servants.size(); i++)
1064    {
1065      if (!strcmp(sadParser->getID (), appFact_servants[i]->identifier()))
1066        {
1067            delete sadParser;
1068            return;
1069        }
1070    }
1071
1072// query the SAD for all ComponentPlacement's
1073    std::vector < SADComponentPlacement * >*sadComponents =
1074        sadParser->getComponents ();
1075
1076// query each ComponentPlacement for its SPD file
1077//sadComponents.begin();
1078    std::vector < SADComponentPlacement * >::iterator _iterator = sadComponents->begin ();
1079
1080    while (_iterator != sadComponents->end ())
1081    {
1082        this->validateSPD ( sadParser->getSPDById( (*_iterator)->getFileRefId() ) );
1083        ++_iterator;
1084    }
1085
1086    appFact_servants.push_back(new ApplicationFactory_impl (profileFileName, &_applications));
1087
1088    unsigned int appFactIndex = appFact_servants.size()-1;
1089
1090    _applicationFactories.length(appFactIndex+1); ///\todo Preallocate based on number of apps in init()
1091    _applicationFactories[appFactIndex] = appFact_servants[appFactIndex]->_this();
1092
1093    ossieSupport::sendObjAdded_event(_identifier.c_str(), sadParser->getID(), sadParser->getName(), (CORBA::Object_var) NULL, StandardEvent::APPLICATION_FACTORY);
1094
1095
1096    delete sadParser;
1097
1098  } catch (CF::FileException ex) {
1099    throw CF::DomainManager::ApplicationInstallationError (CF::CFEBADF, ex.msg);
1100  }
1101
1102    DEBUG(1, DomMgr, "Leaving installApplication")
1103}
1104
1105
1106void
1107DomainManager_impl::uninstallApplication (const char *applicationId)
1108throw (CORBA::SystemException, CF::DomainManager::InvalidIdentifier,
1109CF::DomainManager::ApplicationUninstallationError)
1110{
1111// NOTE: applicationId is the value of the <softwareassembly> name attribute
1112//               for the App Factory's SAD profile
1113
1114    int appNum = -1;
1115
1116    {    ///\bug Figure out MSVC flags to corectly scope for loops
1117        for (unsigned int i = 0; i < appFact_servants.size(); i++)
1118        {
1119            if (strcmp (applicationId,
1120                appFact_servants[i]->identifier ()) == 0)
1121            {
1122                appNum = i;
1123                break;
1124            }
1125        }
1126    }
1127
1128    if (appNum == -1)
1129        throw CF::DomainManager::InvalidIdentifier ();
1130
1131    SADParser sadParser ( _fileMgr->open( appFact_servants[appNum]->softwareProfile (), true ) );
1132
1133// remove all files associated with the Application
1134    std::vector < SADComponentPlacement * >*sadComponents =
1135        sadParser.getComponents ();
1136
1137    std::vector < SADComponentPlacement * >::iterator _iterator =
1138        sadComponents->begin ();
1139
1140    while (_iterator != sadComponents->end ())
1141    {
1142//this->removeSPD( (*_iterator)->getSPDFile() );  // technically, this is supposed to happen
1143// however, we don't think so, so we took it out.
1144        ++_iterator;
1145    }
1146    ///\todo Finish vectorization of uninstallApplication if double free fixed
1147    //    installedApplicationFactories.erase(appNum);
1148
1149// if SUCCESS, write an ADMINISTRATIVE_EVENT to the DomainMgr's Log
1150
1151// send event to Outgoing Domain Management channel consisting of:
1152// DomainManager identifier attribute
1153// this->_identifier
1154// uninstalled AppFactory identifier
1155// sadParser.getId()
1156// uninstalled AppFactory name
1157// sadParser.getName()
1158// uninstalled AppFactory IOR
1159// ask the ORB
1160// sourceCategory = APPLICATION_FACTORY
1161// StandardEvent enumeration
1162
1163/// \todo Fix event sending
1164
1165//    StandardEvent::DomainManagementObjectRemovedEventType _objRemovedEvent;
1166
1167//    _objRemovedEvent.producerId = CORBA::string_dup (this->_identifier);
1168
1169//    _objRemovedEvent.sourceId = CORBA::string_dup (sadParser.getID ());
1170
1171//    _objRemovedEvent.sourceName = CORBA::string_dup (sadParser.getName ());
1172
1173//    _objRemovedEvent.sourceCategory = StandardEvent::APPLICATION_FACTORY;
1174
1175//    CORBA::Any _anyObjRemovedEvent;
1176
1177//    _anyObjRemovedEvent <<= _objRemovedEvent;
1178
1179//    sendEventToOutgoingChannel (_anyObjRemovedEvent);
1180}
1181
1182
1183void
1184DomainManager_impl::registerWithEventChannel (CORBA::
1185Object_ptr registeringObject,
1186const char *registeringId,
1187const char *eventChannelName)
1188throw (CORBA::SystemException, CF::InvalidObjectReference,
1189CF::DomainManager::InvalidEventChannelName,
1190CF::DomainManager::AlreadyConnected)
1191{
1192#if 0 ///\todo uncommment
1193// connect input registeringObject to an event channel as specified by the eventChannelName
1194// Narrow the object to the CosEventComm::PushConsumer interface
1195    CosEventComm::PushConsumer_var consumer =
1196        CosEventComm::PushConsumer::_narrow (registeringObject);
1197
1198    if (CORBA::is_nil (consumer))
1199    {
1200// Raise the CF::InvalidObjectReference exception
1201//std::cerr << "Invalid PushConsumer Object Reference" << std::endl;
1202        throw CF::InvalidObjectReference ();
1203    }
1204
1205// Get the ConsumerAdmin object from the event channel
1206    CosEventChannelAdmin::ConsumerAdmin_var consumerAdmin;
1207
1208// Any registerWithEventChannel request received should be for the ODM_Channel only.
1209    if (strcmp (eventChannelName, "ODM_Channel") == 0)
1210        consumerAdmin = _odmEventChannel->for_consumers ();
1211    else if (strcmp (eventChannelName, "IDM_Channel") == 0)
1212        consumerAdmin = _idmEventChannel->for_consumers ();
1213    else
1214    {
1215// Raise the CF::InvalidEventChannelName exception
1216//std::cerr << "Invalid Event Channel Name: " << eventChannelName << std::endl;
1217        throw CF::DomainManager::InvalidEventChannelName ();
1218    }
1219
1220    CosEventChannelAdmin::ProxyPushSupplier_var supplier =
1221        consumerAdmin->obtain_push_supplier ();
1222
1223// Connect to the Push supplier: Raises AlreadyConnected
1224    supplier->connect_push_consumer (consumer);
1225#endif
1226}
1227
1228
1229void
1230DomainManager_impl::unregisterFromEventChannel (const char *unregisteringId,
1231const char *eventChannelName)
1232throw (CORBA::SystemException, CF::DomainManager::InvalidEventChannelName,
1233CF::DomainManager::NotConnected)
1234{
1235#if 0 /// \todo uncomment
1236// Any registerWithEventChannel request received should be for the IDM_Channel only.
1237    if (!(strcmp (eventChannelName, "IDM_Channel") == 0))
1238    {
1239// Raise the CF::InvalidEventChannelName exception
1240//std::cerr << "Invalid Event Channel Name: " << eventChannelName << std::endl;
1241        throw CF::DomainManager::InvalidEventChannelName ();
1242    }
1243
1244// Get the ConsumerAdmin object from the event channel
1245    CosEventChannelAdmin::ConsumerAdmin_var consumerAdmin =
1246        _idmEventChannel->for_consumers ();
1247
1248    CosEventChannelAdmin::ProxyPushSupplier_var supplier =
1249        consumerAdmin->obtain_push_supplier ();
1250
1251// Connect to the Push supplier: Raises NotConnected
1252
1253// get the reference from the "unregisteringId"
1254
1255    CORBA::Object_var obj = ORB_WRAP::orb->string_to_object (unregisteringId);
1256
1257    if (CORBA::is_nil (obj.in ()))    {
1258//std::cerr << "Object " << unregisteringId << " is invalid!!" << std::endl;
1259        throw CF::InvalidObjectReference ();
1260    }
1261
1262    CosEventComm::PushConsumer_var consumer =
1263        CosEventComm::PushConsumer::_narrow (obj.in ());
1264
1265    consumer->disconnect_push_consumer ();
1266#endif
1267}
1268
1269
1270void DomainManager_impl::registerService(
1271CORBA::Object_ptr registeringService,
1272CF::DeviceManager_ptr registeredDeviceMgr,
1273const char * name)
1274throw (
1275CF::DomainManager::RegisterError,
1276CF::DomainManager::DeviceManagerNotRegistered,
1277CF::InvalidObjectReference,
1278CORBA::SystemException)
1279{
1280//The registerService operation shall verify the input registeringService and registeredDeviceMgr
1281//are valid object references.
1282
1283//Verify they are not a nil reference
1284    if ( CORBA::is_nil(registeringService) || CORBA::is_nil(registeredDeviceMgr) )
1285    {
1286//The registerService operation shall raise the CF InvalidObjectReference exception when input
1287//parameters registeringService or registeredDeviceMgr contains an invalid reference.
1288
1289/*writeLogRecord(FAILURE_ALARM,invalid reference input parameter.);*/
1290        throw( CF::InvalidObjectReference("Cannot register Service. Either registeringService or DeviceMgr is a nil reference.") );
1291    }
1292
1293//The registerService operation shall verify the input registeredDeviceMgr has been previously
1294//registered with the DomainManager.
1295
1296//Verify that input is a registered DeviceManager
1297    if (!deviceMgrIsRegistered (registeredDeviceMgr))
1298    {
1299//The registerService operation shall raise a DeviceManagerNotRegistered exception when the
1300//input registeredDeviceMgr parameter is not a nil reference and is not registered with the
1301//DomainManager.
1302
1303/*writeLogRecord(FAILURE_ALARM,the service could not register because
1304the DeviceManager is not registered with the DomainManager.);*/
1305//throw( CF::DomainManager::DeviceManagerNotRegistered() );
1306    }
1307
1308//The registerService operation shall add the registeringServices object reference and the
1309//registeringServices name to the DomainManager, if the name for the type of service being
1310//registered does not exist within the DomainManager. However, if the name of the registering
1311//service is a duplicate of a registered service of the same type, then the new service shall not be
1312//registered with the DomainManager.
1313
1314//The registerService operation shall associate the input registeringService parameter with the
1315//input registeredDeviceMgr parameter in the DomainManagers, when the registeredDeviceMgr
1316//parameter indicates a DeviceManager registered with the DomainManager.
1317
1318//Add registeringService and its name to domain manager
1319    storeServiceInDomainMgr(registeringService, registeredDeviceMgr, name);
1320
1321//The registerService operation shall, upon successful service registration, establish any pending
1322//connection requests for the registeringService. The registerService operation shall, upon
1323//successful service registration, write an ADMINISTRATIVE_EVENT log record to a
1324//DomainManagers Log.
1325
1326    establishPendingServiceConnections(name);
1327
1328//The registerService operation shall, upon unsuccessful service registration, write a
1329//FAILURE_ALARM log record to a DomainManagers Log.
1330
1331//The registerService operation shall, upon successful service registration, send an event to the
1332//Outgoing Domain Management event channel with event data consisting of a
1333//DomainManagementObjectAddedEventType. The event data will be populated as follows:
1334//1. The producerId shall be the identifier attribute of the DomainManager.
1335//2. The sourceId shall be the identifier attribute from the componentinstantiation element
1336//associated with the registered service.
1337//3. The sourceName shall be the input name parameter for the registering service.
1338//4. The sourceIOR shall be the registered service object reference.
1339//5. The sourceCategory shall be SERVICE.
1340
1341//The registerService operation shall raise the RegisterError exception when an internal error
1342//exists which causes an unsuccessful registration.
1343}
1344
1345
1346void DomainManager_impl::unregisterService(CORBA::Object_ptr unregisteringService,const char * name)
1347throw (CF::DomainManager::UnregisterError, CF::InvalidObjectReference,CORBA::SystemException)
1348{
1349
1350//The unregisterService operation shall raise the CF InvalidObjectReference exception when the
1351//input parameter contains an invalid reference to a Service interface.
1352    if( CORBA::is_nil(unregisteringService) || !serviceIsRegistered(name) )
1353    {
1354/*writeLogRecord(FAILURE_ALARM,Device reference is not valid);*/
1355
1356//The unregisterDevice operation shall raise the CF InvalidObjectReference exception when the
1357//input parameter contains an invalid reference to a Device interface.
1358        throw( CF::InvalidObjectReference("Cannot Unregister Service. Invalid reference") );
1359        return;
1360    }
1361
1362//The unregisterService operation shall remove the unregisteringService entry specified by the
1363//input name parameter from the DomainManager.
1364
1365//The unregisterService operation shall release (client-side CORBA release) the
1366//unregisteringService from the DomainManager.
1367
1368    disconnectThisService(name);
1369
1370    removeServiceFromDomainMgr(unregisteringService, name);
1371
1372//The unregisterService operation shall, upon the successful unregistration of a Service, write an
1373//ADMINISTRATIVE_EVENT log record to a DomainManagers Log.
1374
1375//The unregisterService operation shall, upon unsuccessful unregistration of a Service, write a
1376//FAILURE_ALARM log record to a DomainManagers Log.
1377
1378//The unregisterService operation shall, upon successful service unregistration, send an event to
1379//the Outgoing Domain Management event channel with event data consisting of a
1380//DomainManagementObjectRemovedEventType. The event data will be populated as follows:
1381//1. The producerId shall be the identifier attribute of the DomainManager.
1382//2. The sourceId shall be the ID attribute from the componentinstantiation element
1383//associated with the unregistered service.
1384//3. The sourceName shall be the input name parameter for the unregistering service.
1385//4. The sourceCategory shall be SERVICE.
1386
1387//The unregisterService operation shall raise the UnregisterError exception when an internal error
1388//exists which causes an unsuccessful unregistration.
1389
1390}
1391
1392
1393void
1394DomainManager_impl::validate (const char *_profile)
1395{
1396    if (_profile == NULL)
1397        return;
1398
1399// verify the application's SAD exists in DomainManager FileSystem
1400    if (!_fileMgr->exists (_profile)) {
1401      string msg = "File ";
1402      msg += _profile;
1403      msg += " does not exist.";
1404
1405      throw CF::FileException (CF::CFENOENT, msg.c_str());
1406    }
1407}
1408
1409
1410void
1411DomainManager_impl::validateSPD (const char *_spdProfile, int _cnt)
1412{
1413  if (_spdProfile == NULL)
1414    return;
1415
1416  /// \todo Figure out checks for xml conforming to dtd, through suitable exception if it doesn't. Possibly CF::InvalidProfile
1417
1418  try
1419    {
1420      this->validate (_spdProfile);
1421   
1422      // check the filename ends with the extension given in the spec
1423      if ((strstr (_spdProfile, ".spd.xml")) == NULL)
1424          std::cerr << "File " << _spdProfile << " should end with .spd.xml" << std::endl;
1425     
1426      SPDParser spdParser ( _fileMgr->open( _spdProfile, true ) );
1427
1428      // query SPD for PRF
1429      this->validate (spdParser.getPRFFile ());
1430   
1431      // check the file name ends with the extension given in the spec
1432      if ((strstr (spdParser.getPRFFile (), ".prf.xml")) == NULL && strlen(spdParser.getPRFFile()))
1433          std::cerr << "File " << spdParser.getPRFFile() << " should end in .prf.xml." << std::endl;
1434
1435      PRFParser prfParser ( _fileMgr->open( spdParser.getPRFFile (), true ) );
1436
1437      // query SPD for SCD
1438      this->validate (spdParser.getSCDFile ());
1439
1440      // Check the filename ends with  the extension given in the spec
1441      if ((strstr (spdParser.getSCDFile (), ".scd.xml")) == NULL)
1442          std::cerr << "File " << spdParser.getSCDFile() << " should end with .scd.xml." << std::endl;
1443 
1444
1445      SCDParser scdParser ( _fileMgr->open( spdParser.getSCDFile (), true ) );
1446
1447      /// \todo Figure out if this should go: this->validateSPD( spdParser.getSPDFile(), ++_cnt );
1448
1449    } catch (CF::InvalidFileName ex) {
1450      throw CF::DomainManager::ApplicationInstallationError (CF::CFEBADF, ex.msg);
1451    }
1452
1453}
1454
1455
1456void
1457DomainManager_impl::removeSPD (const char *_spdProfile, int _cnt)
1458{
1459    if (_spdProfile == NULL)
1460        return;
1461
1462    SPDParser *_spdParser = new SPDParser ( _fileMgr->open( _spdProfile, true ) );
1463
1464    try
1465    {
1466        _fileMgr->remove (_spdParser->getPRFFile ());
1467    }
1468    catch (CF::InvalidFileName &)
1469    {
1470// TODO: write FAILURE_ALARM
1471// TODO: output the error message from the invalid file name
1472
1473        delete _spdParser;
1474        _spdParser = NULL;
1475
1476        throw CF::DomainManager::ApplicationUninstallationError (CF::CFEBADF,
1477            "[DomainManager:removeSPD] invalid PRF file");
1478    }
1479    catch (CF::FileException &)
1480    {
1481// TODO: write FAILURE_ALARM
1482// TODO: output the error message from the file exception
1483
1484        delete _spdParser;
1485        _spdParser = NULL;
1486
1487        throw CF::DomainManager::ApplicationUninstallationError (CF::CFEBADF,
1488            "[DomainManager:removeSPD] PRF file exception");
1489    }
1490
1491    try
1492    {
1493        _fileMgr->remove (_spdParser->getSCDFile ());
1494    }
1495    catch (CF::InvalidFileName &)
1496    {
1497// TODO: write FAILURE_ALARM
1498// TODO: output the error message from the invalid file name
1499
1500        delete _spdParser;
1501        _spdParser = NULL;
1502
1503        throw CF::DomainManager::ApplicationUninstallationError (CF::CFEBADF,
1504            "[DomainManager:removeSPD] invalid SCD file");
1505    }
1506    catch (CF::FileException &)
1507    {
1508// TODO: write FAILURE_ALARM
1509// TODO: output the error message from the file exception
1510
1511        delete _spdParser;
1512        _spdParser = NULL;
1513
1514        throw CF::DomainManager::ApplicationUninstallationError (CF::CFEBADF,
1515            "[DomainManager:removeSPD] SCD file exception");
1516    }
1517
1518    removeSPD (_spdParser->getSPDFile (), ++_cnt);
1519
1520    delete _spdParser;
1521    _spdParser = NULL;
1522
1523    try
1524    {
1525        _fileMgr->remove (_spdProfile);
1526    }
1527    catch (CF::InvalidFileName &)
1528    {
1529/// \todo write FAILURE_ALARM
1530/// \todo output the error message from the invalid file name
1531        throw CF::DomainManager::ApplicationUninstallationError (CF::CFEBADF,
1532            "[DomainManager:removeSPD] invalid SPD file");
1533    }
1534    catch (CF::FileException &)
1535    {
1536/// \todo write FAILURE_ALARM
1537/// \todo output the error message from the file exception
1538        throw CF::DomainManager::ApplicationUninstallationError (CF::CFEBADF,
1539            "[DomainManager:removeSPD] SPD file exception");
1540    }
1541}
1542
1543
1544void DomainManager_impl::createEventChannels (void)
1545{
1546  // This code is very likely omniEvent specific. See pp -- in --.
1547  /// \todo break into smaller chuncks and make error handling better
1548  /// \todo Have this routine take the Event Channel name as an argument and return the object
1549
1550
1551  // Get the Name Service root context
1552#ifdef HAVE_OMNIEVENTS
1553  CORBA::Object_var obj = ORB_WRAP::orb->resolve_initial_references("NameService");
1554  CosNaming::NamingContext_var rootContext = CosNaming::NamingContext::_nil();
1555
1556  rootContext = CosNaming::NamingContext::_narrow(obj);
1557  if (CORBA::is_nil(rootContext))
1558    throw CORBA::OBJECT_NOT_EXIST();
1559 
1560  // Find the object reference for the Event Channel factory
1561  CosNaming::Name name;
1562  name.length(1);
1563  name[0].id = CORBA::string_dup("EventChannelFactory");
1564
1565
1566  obj = rootContext->resolve(name);
1567
1568  omniEvents::EventChannelFactory_var factory = omniEvents::EventChannelFactory::_narrow(obj);
1569
1570  if (CORBA::is_nil(factory))
1571    throw CORBA::OBJECT_NOT_EXIST();  /// \todo throw something better
1572
1573  // Check that object support EventChannel object interface
1574  CosLifeCycle::Key key;
1575  key.length(1);
1576  key[0].id = CORBA::string_dup("EventChannel");
1577  key[0].kind = CORBA::string_dup("object interface");
1578
1579  if (!factory->supports(key)) {
1580      std::cerr << "Factory does not support Event Channel interface, dying" << std::endl;
1581    exit (-1);
1582  }
1583
1584  // Create the IDM Event Channel Object
1585  CosLifeCycle::Criteria criteria; // I think this passes options to the channel PJB
1586
1587  CORBA::Object_var IDM_channelObj = factory->create_object(key, criteria);
1588  if (CORBA::is_nil(IDM_channelObj))
1589    exit(-1);
1590
1591  IDM_channel = CosEventChannelAdmin::EventChannel::_narrow(IDM_channelObj);
1592  if (CORBA::is_nil(IDM_channel))
1593    exit (-1);
1594
1595  CosNaming::Name idm_name;
1596
1597  ORB_WRAP::getCosName (idm_name, "/DomainName1/IDM_Channel");
1598  rootContext->rebind(idm_name, IDM_channel.in());
1599
1600  // Create the ODM Event Channel object
1601
1602  CORBA::Object_var ODM_channelObj = factory->create_object(key, criteria);
1603  if (CORBA::is_nil(ODM_channelObj))
1604    exit(-1);
1605
1606  ODM_channel = CosEventChannelAdmin::EventChannel::_narrow(ODM_channelObj);
1607  if (CORBA::is_nil(ODM_channel))
1608    exit (-1);
1609
1610  CosNaming::Name odm_name;
1611
1612  ORB_WRAP::getCosName (odm_name, "/DomainName1/ODM_Channel");
1613
1614
1615  rootContext->rebind(odm_name, ODM_channel.in());
1616#endif
1617}
1618
1619
1620#ifdef HAVE_OMNIEVENTS
1621CosEventChannelAdmin::ProxyPushConsumer_var DomainManager_impl::connectEventChannel(CosEventChannelAdmin::EventChannel_var eventChannel)
1622{
1623
1624  /// \todo Add exception handling
1625  CosEventChannelAdmin::SupplierAdmin_var supplier_admin;
1626
1627  supplier_admin = eventChannel->for_suppliers();
1628
1629  CosEventChannelAdmin::ProxyPushConsumer_var proxy_consumer;
1630
1631  proxy_consumer = supplier_admin->obtain_push_consumer();
1632
1633  return proxy_consumer;
1634}
1635
1636DomainManagerEventHandler::DomainManagerEventHandler (DomainManager_impl *
1637_dmn)
1638{
1639    _dmnMgr = _dmn;
1640}
1641
1642
1643void
1644DomainManagerEventHandler::push (const CORBA::Any & _any)
1645throw (CORBA::SystemException, CosEventComm::Disconnected)
1646{
1647    _dmnMgr->_applications[0] = CF::Application::_nil ();
1648}
1649
1650
1651void
1652DomainManagerEventHandler::disconnect_push_consumer ()
1653throw (CORBA::SystemException)
1654{
1655    CORBAOBJ _obj = ORB_WRAP::orb->resolve_initial_references ("POACurrent");
1656
1657    PortableServer::Current_var _current =
1658        PortableServer::Current::_narrow (_obj);
1659
1660    PortableServer::POA_var _poa = _current->get_POA ();
1661
1662    PortableServer::ObjectId_var _oid = _current->get_object_id ();
1663
1664    _poa->deactivate_object (_oid);
1665}
1666#endif
1667
Note: See TracBrowser for help on using the browser.