166d233497df0c6299d1f14cffa9fd978d8d5a10
[tpot/pegasus/.git] / src / Pegasus / ControlProviders / ProviderRegistrationProvider / ProviderRegistrationProvider.cpp
1 //%/////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
14 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Yi Zhou (yi_zhou@hp.com)
25 //
26 // Modified By: Chip Vincent (cvincent@us.ibm.com)
27 //              Nitin Upasani, Hewlett-Packard Company (Nitin_Upasani@hp.com)
28 //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
29 //              Carol Ann Krug Graves, Hewlett-Packard Company
30 //                  (carolann_graves@hp.com)
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include "ProviderRegistrationProvider.h"
35
36 #include <Pegasus/Common/PegasusVersion.h>
37 #include <Pegasus/Common/XmlWriter.h>
38 #include <Pegasus/Common/Constants.h>
39 #include <Pegasus/Common/CIMMessage.h>
40 #include <Pegasus/Common/OperationContext.h>
41 #include <Pegasus/Common/System.h>
42
43 PEGASUS_NAMESPACE_BEGIN
44
45 /**
46    The name of the CapabilityID property for provider capabilities class
47 */
48 static const CIMName _PROPERTY_CAPABILITYID  = CIMName ("CapabilityID");
49
50 /**
51    Module status
52 */
53 static const Uint16 _MODULE_OK        = 2;
54
55 /**
56    stopping provider method
57 */
58 static const CIMName _STOP_PROVIDER     = CIMName ("Stop");
59
60 /**
61    starting provider method
62 */
63 static const CIMName _START_PROVIDER   = CIMName ("Start");
64
65 /**
66    Provider status
67 */
68 static const Uint16 _MODULE_STOPPING   = 9;
69
70 static const Uint16 _MODULE_STOPPED   = 10;
71
72 ProviderRegistrationProvider::ProviderRegistrationProvider(
73     ProviderRegistrationManager * providerRegistrationManager)  
74     :_id(peg_credential_types::PROVIDER)
75 {
76     _providerRegistrationManager = providerRegistrationManager;
77
78     _controller = &(ModuleController::get_client_handle(_id, &_client_handle));
79     if(_client_handle == NULL)
80         throw UninitializedObjectException();
81 }
82
83 ProviderRegistrationProvider::~ProviderRegistrationProvider(void)       
84 {
85     if (_providerRegistrationManager)
86     {
87         delete _providerRegistrationManager;
88     }
89
90     if (_client_handle)
91     {
92         delete _client_handle;
93     }
94
95 }
96
97 void ProviderRegistrationProvider::initialize(CIMOMHandle & cimom)
98 {
99     // This method should not be called because this is a control provider
100     // and is not dynamically loaded through the provider manager
101 }
102
103 void ProviderRegistrationProvider::terminate(void)
104 {
105 }
106
107 // get registered provider
108 void ProviderRegistrationProvider::getInstance(
109     const OperationContext & context,
110     const CIMObjectPath & instanceReference,
111     const Boolean includeQualifiers,
112     const Boolean includeClassOrigin,
113     const CIMPropertyList & propertyList,
114     InstanceResponseHandler & handler)
115 {
116
117     if(!instanceReference.getNameSpace().equal (PEGASUS_NAMESPACENAME_INTEROP))
118     {
119         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
120             instanceReference.getNameSpace().getString());
121     }
122
123     // ensure the class existing in the specified namespace
124     CIMName className = instanceReference.getClassName();
125
126     if(!className.equal (PEGASUS_CLASSNAME_PROVIDER) &&
127        !className.equal (PEGASUS_CLASSNAME_PROVIDERCAPABILITIES) &&
128        !className.equal (PEGASUS_CLASSNAME_PROVIDERMODULE))
129     {
130         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
131             className.getString());
132     }
133
134     // begin processing the request
135     handler.processing();
136
137     CIMInstance instance;
138
139     try
140     {
141         instance = _providerRegistrationManager->getInstance(instanceReference);
142     }
143     catch(CIMException& e)
144     {
145         throw (e);
146     }
147
148     handler.deliver(instance);
149
150     // complete processing the request
151     handler.complete();
152 }
153
154 // get all registered providers
155 void ProviderRegistrationProvider::enumerateInstances(
156     const OperationContext & context,
157     const CIMObjectPath & classReference,
158     const Boolean includeQualifiers,
159     const Boolean includeClassOrigin,
160     const CIMPropertyList & propertyList,
161     InstanceResponseHandler & handler)
162 {
163     if(!classReference.getNameSpace().equal (PEGASUS_NAMESPACENAME_INTEROP))
164     {
165         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
166             classReference.getNameSpace().getString());
167     }
168
169     // ensure the class existing in the specified namespace
170     CIMName className = classReference.getClassName();
171
172     if(!className.equal (PEGASUS_CLASSNAME_PROVIDER) &&
173        !className.equal (PEGASUS_CLASSNAME_PROVIDERCAPABILITIES) &&
174        !className.equal (PEGASUS_CLASSNAME_PROVIDERMODULE))
175     {
176         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
177             className.getString());
178     }
179
180     // begin processing the request
181     handler.processing();
182
183     Array<CIMInstance> enumInstances;
184
185     try
186     {
187         enumInstances = _providerRegistrationManager->enumerateInstances(classReference);
188     }
189     catch(CIMException& e)
190     {
191         throw (e);
192     }
193
194     handler.deliver(enumInstances);
195
196     // complete processing the request
197     handler.complete();
198 }
199
200 // get all registered provider names
201 void ProviderRegistrationProvider::enumerateInstanceNames(
202     const OperationContext & context,
203     const CIMObjectPath & classReference,
204     ObjectPathResponseHandler & handler)
205 {
206     if(!classReference.getNameSpace().equal (PEGASUS_NAMESPACENAME_INTEROP))
207     {
208         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
209             classReference.getNameSpace().getString());
210     }
211
212     // ensure the class existing in the specified namespace
213     CIMName className = classReference.getClassName();
214
215     if(!className.equal (PEGASUS_CLASSNAME_PROVIDER) &&
216        !className.equal (PEGASUS_CLASSNAME_PROVIDERCAPABILITIES) &&
217        !className.equal (PEGASUS_CLASSNAME_PROVIDERMODULE))
218     {
219         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
220             className.getString());
221     }
222
223     // begin processing the request
224     handler.processing();
225
226     Array<CIMObjectPath> enumInstanceNames;
227
228     // get all instance names from repository
229     try
230     {
231         enumInstanceNames =
232             _providerRegistrationManager->enumerateInstanceNames(classReference);
233     }
234     catch(CIMException& e)
235     {
236         throw (e);
237     }
238
239     handler.deliver(enumInstanceNames);
240
241     // complete processing the request
242     handler.complete();
243 }
244
245 // change properties for the registered provider
246 // only support to change property of Namespaces, property of
247 // SupportedProperties, and property of SupportedMethods
248 void ProviderRegistrationProvider::modifyInstance(
249         const OperationContext & context,
250         const CIMObjectPath & instanceReference,
251         const CIMInstance & instanceObject,
252         const Boolean includeQualifiers,
253         const CIMPropertyList & propertyList,
254         ResponseHandler & handler)
255 {
256     // get userName and only privileged user can execute this operation
257     String userName;
258     try
259     {
260         IdentityContainer container = context.get(IdentityContainer::NAME);
261         userName = container.getUserName();
262     }
263     catch (...)
264     {
265         userName = String::EMPTY;
266     }
267
268     if ((userName != String::EMPTY) && !System::isPrivilegedUser(userName))
269     {
270         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ACCESS_DENIED,
271             "You must have superuser privilege to modify the registration.");   
272     }
273
274     if(!instanceReference.getNameSpace().equal (PEGASUS_NAMESPACENAME_INTEROP))
275     {
276         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
277             instanceReference.getNameSpace().getString());
278     }
279
280     //
281     // only support to modify the instance of PG_ProviderCapabilities
282     //
283     if (!instanceReference.getClassName().equal 
284         (PEGASUS_CLASSNAME_PROVIDERCAPABILITIES))
285     {
286         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
287             instanceReference.getClassName().getString());
288     }
289
290     //
291     // only can modify the property of Namespaces, property of
292     // SupportedProperties, and property of SupportedMethods
293     //
294     if (propertyList.isNull())
295     {
296         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
297             "Only can modify Namespaces, SupportedProperties, and SupportedMethods.");
298     }
299
300     Array<CIMName> propertyArray = propertyList.getPropertyNameArray();
301     for (Uint32 i=0; i<propertyArray.size(); i++)
302     {
303         if (!propertyArray[i].equal (_PROPERTY_NAMESPACES) &&
304             !propertyArray[i].equal (_PROPERTY_SUPPORTEDPROPERTIES) &&
305             !propertyArray[i].equal (_PROPERTY_SUPPORTEDMETHODS))
306         {
307             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
308                 propertyArray[i].getString());
309         }
310     }
311
312     // begin processing the request
313     handler.processing();
314
315     try
316     {
317         _providerRegistrationManager->modifyInstance(instanceReference,
318             instanceObject, includeQualifiers, propertyArray);
319     }
320     catch(CIMException& e)
321     {
322         throw (e);
323     }
324
325     // complete processing the request
326     handler.complete();
327 }
328
329 // register a provider
330 void ProviderRegistrationProvider::createInstance(
331     const OperationContext & context,
332     const CIMObjectPath & instanceReference,
333     const CIMInstance & instanceObject,
334     ObjectPathResponseHandler & handler)
335 {
336     // get userName and only privileged user can execute this operation
337     String userName;
338     try
339     {
340         IdentityContainer container = context.get(IdentityContainer::NAME);
341         userName = container.getUserName();
342     }
343     catch (...)
344     {
345         userName = String::EMPTY;
346     }
347
348     if ((userName != String::EMPTY) && !System::isPrivilegedUser(userName))
349     {
350         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ACCESS_DENIED,
351             "You must have superuser privilege to register providers.");        
352     }
353
354     CIMName className = instanceReference.getClassName();
355     CIMNamespaceName nameSpace = instanceReference.getNameSpace();
356
357     CIMObjectPath returnReference;
358
359     CIMInstance instance = instanceObject;
360
361     if(!nameSpace.equal (PEGASUS_NAMESPACENAME_INTEROP))
362     {
363         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
364             nameSpace.getString());
365     }
366
367     // ensure the class existing in the specified namespace
368     if(!className.equal (PEGASUS_CLASSNAME_PROVIDER) &&
369        !className.equal (PEGASUS_CLASSNAME_PROVIDERCAPABILITIES) &&
370        !className.equal (PEGASUS_CLASSNAME_PROVIDERMODULE))
371     {
372         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
373             className.getString());
374     }
375
376     //
377     // Check all required properties are set
378     //
379     if (className.equal (PEGASUS_CLASSNAME_PROVIDERMODULE))
380     {
381         //
382         // Name, Version, InterfaceType, InterfaceVersion, and Location
383         // properties must be set
384         // OperationalStatus property needs to be set. If not, set to default
385         //
386         if (instanceObject.findProperty(_PROPERTY_PROVIDERMODULE_NAME) ==
387             PEG_NOT_FOUND)
388         {
389             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
390                 "Missing Name which is required property in PG_ProviderModule class.");
391         }
392
393         if (instanceObject.findProperty(_PROPERTY_VENDOR) == PEG_NOT_FOUND)
394         {
395             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
396                 "Missing Vendor which is required property in PG_ProviderModule class.");
397         }
398
399         if (instanceObject.findProperty(_PROPERTY_VERSION) == PEG_NOT_FOUND)
400         {
401             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
402                 "Missing Version which is required property in PG_ProviderModule class.");
403         }
404
405         Uint32 ifcTypeIndex =
406             instanceObject.findProperty(_PROPERTY_INTERFACETYPE);
407         if (ifcTypeIndex == PEG_NOT_FOUND)
408         {
409             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
410                 "Missing InterfaceType which is required property in PG_ProviderModule class.");
411         }
412         String ifcTypeString;
413         instanceObject.getProperty(ifcTypeIndex).getValue().
414             get(ifcTypeString);
415         if (ifcTypeString != "C++Default" || ifcTypeString != "CMPI" )
416         {
417             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
418                 "Unsupported InterfaceType value: \"" + ifcTypeString + "\"");
419         }
420
421         Uint32 ifcVersionIndex =
422             instanceObject.findProperty(_PROPERTY_INTERFACEVERSION);
423         if (ifcVersionIndex == PEG_NOT_FOUND)
424         {
425             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
426                 "Missing InterfaceVersion which is required property in PG_ProviderModule class.");
427         }
428         String ifcVersionString;
429         instanceObject.getProperty(ifcVersionIndex).getValue().
430             get(ifcVersionString);
431         if ((ifcVersionString != "2.1.0") &&
432             (ifcVersionString != "2.2.0"))
433         {
434             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
435                 "Unsupported InterfaceVersion value: \"" + ifcVersionString +
436                     "\"");
437         }
438
439         if (instanceObject.findProperty(_PROPERTY_LOCATION) == PEG_NOT_FOUND)
440         {
441             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
442                 "Missing Location which is required property in PG_ProviderModule class.");
443         }
444
445         if (instanceObject.findProperty(_PROPERTY_OPERATIONALSTATUS) == 
446             PEG_NOT_FOUND)
447         {
448             Array<Uint16> _operationalStatus;
449             _operationalStatus.append(_MODULE_OK);
450             instance.addProperty (CIMProperty
451                 (_PROPERTY_OPERATIONALSTATUS, _operationalStatus));
452         }
453     }
454     else if (className.equal (PEGASUS_CLASSNAME_PROVIDERCAPABILITIES))
455     {
456         //
457         // ProviderModuleName, ProviderName, InstanceID, ClassName,
458         // Namespaces, and ProviderType properties must be set
459         //
460
461         if (instanceObject.findProperty(_PROPERTY_PROVIDERMODULENAME) ==
462             PEG_NOT_FOUND)
463         {
464             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
465                 "Missing ProviderModuleName which is required property in PG_ProviderCapabilities class.");
466         }
467
468         if (instanceObject.findProperty(_PROPERTY_PROVIDERNAME) == 
469             PEG_NOT_FOUND)
470         {
471             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
472                 "Missing ProviderName which is required property in PG_ProviderCapabilities class.");
473         }
474
475         if (instanceObject.findProperty(_PROPERTY_CAPABILITYID) == 
476             PEG_NOT_FOUND)
477         {
478             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
479                 "Missing CapabilityID which is required property in PG_ProviderCapabilities class.");
480         }
481
482         if (instanceObject.findProperty(_PROPERTY_CLASSNAME) == PEG_NOT_FOUND)
483         {
484             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
485                 "Missing ClassName which is required property in PG_ProviderCapabilities class.");
486         }
487
488         if (instanceObject.findProperty(_PROPERTY_NAMESPACES) == PEG_NOT_FOUND)
489         {
490             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
491                 "Missing Namespaces which is required property in PG_ProviderCapabilities class.");
492         }
493
494         if (instanceObject.findProperty(_PROPERTY_PROVIDERTYPE) == PEG_NOT_FOUND)
495         {
496             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
497                 "Missing ProviderType which is required property in PG_ProviderCapabilities class.");
498         }
499     }
500     else // PEGASUS_CLASSNAME_PROVIDER
501     {
502         //
503         // Name and ProviderModuleName properties must be set
504         //
505         if (instanceObject.findProperty(_PROPERTY_PROVIDER_NAME) == PEG_NOT_FOUND)
506         {
507             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
508                 "Missing Name which is required property in PG_Provider class.");
509         }
510         
511         if (instanceObject.findProperty(_PROPERTY_PROVIDERMODULENAME) == 
512             PEG_NOT_FOUND)
513         {
514             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
515                 "Missing ProviderModuleName which is required property in PG_Provider class.");
516         }
517     }
518
519     // begin processing the request
520     handler.processing();
521         
522     try
523     {
524         returnReference =
525             _providerRegistrationManager->createInstance(instanceReference, instance);
526     }
527     catch(CIMException& e)
528     {
529         throw (e);
530     }
531
532     handler.deliver(returnReference);
533
534     // complete processing request
535     handler.complete();
536 }
537
538 // Unregister a provider
539 void ProviderRegistrationProvider::deleteInstance(
540     const OperationContext & context,
541     const CIMObjectPath & instanceReference,
542     ResponseHandler & handler)
543 {
544     // get userName and only privileged user can execute this operation
545     String userName;
546     try
547     {
548         IdentityContainer container = context.get(IdentityContainer::NAME);
549         userName = container.getUserName();
550     }
551     catch (...)
552     {
553         userName = String::EMPTY;
554     }
555
556     if ((userName != String::EMPTY) && !System::isPrivilegedUser(userName))
557     {
558         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ACCESS_DENIED,
559             "You must have superuser privilege to unregister providers.");      
560     }
561
562     if(!instanceReference.getNameSpace().equal (PEGASUS_NAMESPACENAME_INTEROP))
563     {
564         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
565             instanceReference.getNameSpace().getString());
566     }
567
568     CIMName className = instanceReference.getClassName();
569
570     // ensure the class existing in the specified namespace
571     if(!className.equal (PEGASUS_CLASSNAME_PROVIDER) &&
572        !className.equal (PEGASUS_CLASSNAME_PROVIDERCAPABILITIES) &&
573        !className.equal (PEGASUS_CLASSNAME_PROVIDERMODULE))
574     {
575         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
576             className.getString());
577     }
578
579     // begin processing the request
580     handler.processing();
581
582     String moduleName;
583     Boolean moduleFound = false;
584     Array<CIMKeyBinding> keys = instanceReference.getKeyBindings();
585
586     //
587     // disable provider before delete provider 
588     // registration if the class is PG_Provider
589     //
590     if (className.equal (PEGASUS_CLASSNAME_PROVIDER))
591     {
592         // get module name from reference
593
594         for(Uint32 i=0; i<keys.size() ; i++)
595         {
596             if(keys[i].getName().equal (_PROPERTY_PROVIDERMODULENAME))
597             {
598                 moduleName = keys[i].getValue();
599                 moduleFound = true;
600             }
601         }
602
603         // if _PROPERTY_PROVIDERMODULENAME key not found
604         if( !moduleFound)
605         {
606             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
607                 "key ProviderModuleName was not found");
608         }
609
610         // 
611         // disable the provider 
612         //
613         try
614         {
615              //
616              // if the provider disable failed
617              //
618              if (_disableModule(instanceReference, moduleName, true) == -1)
619              {
620                  throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
621                      "disable the provider failed.");
622              }
623         }
624         catch(CIMException&)
625         {
626             throw;
627         }
628     }
629
630     //
631     // disable provider module before remove provider registration
632     // if the class is PG_ProviderModule 
633     //
634
635     if (className.equal (PEGASUS_CLASSNAME_PROVIDERMODULE))
636     {
637         // get module name from reference
638
639         for(Uint32 i=0; i<keys.size() ; i++)
640         {
641             if(keys[i].getName().equal (_PROPERTY_PROVIDERMODULE_NAME))
642             {
643                 moduleName = keys[i].getValue();
644                 moduleFound = true;
645             }
646         }
647
648         // if _PROPERTY_PROVIDERMODULE_NAME key not found
649         if( !moduleFound)
650         {
651         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
652                 "key Name was not found");
653         }
654
655         // 
656         // disable the provider module
657         //
658         try
659         {
660             //
661             // if the provider module disable failed
662             //
663             if (_disableModule(instanceReference, moduleName, false) == -1)
664             {
665                  throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
666                      "disable the provider module failed.");
667             }
668         }
669         catch(CIMException& e)
670         {
671             throw (e);
672         }
673     }
674
675     try
676     {
677         _providerRegistrationManager->deleteInstance(instanceReference);
678     }
679     catch(CIMException& e)
680     {
681         throw (e);
682     }
683
684     // complete processing the request
685     handler.complete();
686 }
687
688 // Block a provider, unblock a provider, and stop a provider
689 void ProviderRegistrationProvider::invokeMethod(
690     const OperationContext & context,
691     const CIMObjectPath & objectReference,
692     const CIMName & methodName,
693     const Array<CIMParamValue> & inParameters,
694     MethodResultResponseHandler & handler)
695 {
696     // get userName and only privileged user can execute this operation
697     String userName;
698     try
699     {
700         IdentityContainer container = context.get(IdentityContainer::NAME);
701         userName = container.getUserName();
702     }
703     catch (...)
704     {
705         userName = String::EMPTY;
706     }
707
708     if ((userName != String::EMPTY) && !System::isPrivilegedUser(userName))
709     {
710         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_ACCESS_DENIED,
711             "You must have superuser privilege to disable or enable providers.");       
712     }
713
714     if(!objectReference.getNameSpace().equal (PEGASUS_NAMESPACENAME_INTEROP))
715     {
716         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, 
717             objectReference.getNameSpace().getString());
718     }
719
720     String moduleName;
721     Boolean moduleFound = false;
722
723     // get module name from reference
724     Array<CIMKeyBinding> keys = objectReference.getKeyBindings();
725
726     for(Uint32 i=0; i<keys.size() ; i++)
727     {
728         if(keys[i].getName().equal (_PROPERTY_PROVIDERMODULE_NAME))
729         {
730             moduleName = keys[i].getValue();
731             moduleFound = true;
732         }
733     }
734
735     // if _PROPERTY_PROVIDERMODULE_NAME key not found
736     if( !moduleFound)
737     {
738         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED,
739                 "key Name was not found");
740     }
741
742     handler.processing();
743
744     Sint16 ret_value;
745
746     if(methodName.equal(_STOP_PROVIDER))
747     {
748         // disable module
749         try
750         {
751              ret_value =  _disableModule(objectReference, moduleName, false);
752         }
753         catch(CIMException& e)
754         {
755              throw (e);
756         }
757
758         CIMValue retValue(ret_value);
759         handler.deliver(retValue);
760         handler.complete();
761         return;
762     }
763     else if(methodName.equal(_START_PROVIDER))
764     {
765         //
766         // get module status
767         //
768         Array<Uint16> _OperationalStatus =
769             _providerRegistrationManager->getProviderModuleStatus( moduleName);
770
771         for (Uint32 i = 0; i<_OperationalStatus.size(); i++)
772         {
773             // retValue equals 1 if module is already enabled
774             if (_OperationalStatus[i] == _MODULE_OK)
775             {
776                 ret_value = 1;
777                 CIMValue retValue(ret_value);
778                 handler.deliver(retValue);
779                 handler.complete();
780                 return;
781             }
782
783             // retValue equals 2 if module is stopping
784             // at this stage, module can not be started
785             if (_OperationalStatus[i] == _MODULE_STOPPING)
786             {
787                 ret_value = 2;
788                 CIMValue retValue(ret_value);
789                 handler.deliver(retValue);
790                 handler.complete();
791                 return;
792             }
793         }
794
795         // get module instance
796         CIMInstance mInstance = 
797             _providerRegistrationManager->getInstance(objectReference);
798
799         //
800         // get provider manager service
801         //
802         MessageQueueService * _service = _getProviderManagerService();
803
804         if (_service != NULL)
805         {
806             // create CIMEnableModuleRequestMessage
807             CIMEnableModuleRequestMessage * enable_req =
808                 new CIMEnableModuleRequestMessage(
809                     XmlWriter::getNextMessageId (),
810                     mInstance,
811                     QueueIdStack(_service->getQueueId()));
812
813             Array<Uint16> _opStatus;
814             _opStatus = _sendEnableMessageToProviderManager(enable_req);
815
816             for (Uint32 i = 0; i<_opStatus.size(); i++)
817             {
818                 if (_opStatus[i] == _MODULE_OK)
819                 {
820                     // module was enabled successfully
821                     ret_value = 0;
822                     CIMValue retValue(ret_value);
823                     handler.deliver(retValue);
824                     handler.complete();
825                     return;
826                 }
827             }
828         }
829
830         // enable failed
831         ret_value = -1;
832         CIMValue retValue(ret_value);
833         handler.deliver(retValue);
834         handler.complete();
835         return;
836     }
837     else
838     {
839         throw PEGASUS_CIM_EXCEPTION(CIM_ERR_METHOD_NOT_AVAILABLE, String::EMPTY);
840     }
841 }
842
843 // get provider manager service
844 MessageQueueService * ProviderRegistrationProvider::_getProviderManagerService()
845 {
846     MessageQueue * queue = MessageQueue::lookup(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);
847     MessageQueueService * _service = dynamic_cast<MessageQueueService *>(queue);
848
849     return(_service);
850 }
851
852 ProviderRegistrationProvider & ProviderRegistrationProvider::operator=(const ProviderRegistrationProvider & handle)
853 {
854     if(this == &handle)
855     {
856         return(*this);
857     }
858
859     return(*this);
860 }
861
862 Array<Uint16> ProviderRegistrationProvider::_sendDisableMessageToProviderManager(
863         CIMDisableModuleRequestMessage * disable_req)
864 {
865     MessageQueueService * _service = _getProviderManagerService();
866     Uint32 _queueId = _service->getQueueId();
867
868     callback_data *cb_data = new callback_data(this);
869
870     // create request envelope
871     AsyncLegacyOperationStart * asyncRequest =
872         new AsyncLegacyOperationStart (
873             _service->get_next_xid(),
874             NULL,
875             _queueId,
876             disable_req,
877             _queueId);
878
879     AsyncReply * asyncReply = _controller->ClientSendWait(*_client_handle,
880                                                           _queueId,
881                                                           asyncRequest);
882     CIMDisableModuleResponseMessage * response =
883         reinterpret_cast<CIMDisableModuleResponseMessage *>(
884              (static_cast<AsyncLegacyOperationResult *>(asyncReply))->get_result());
885     if (response->cimException.getCode() != CIM_ERR_SUCCESS)
886     {
887         CIMException e = response->cimException;
888         delete asyncRequest;
889         delete asyncReply;
890         delete response;
891         throw (e);
892     }
893
894     Array<Uint16> operationalStatus = response->operationalStatus;
895
896     delete asyncRequest;
897     delete asyncReply;
898     delete response;
899
900     return(operationalStatus);
901 }
902
903 Array<Uint16> ProviderRegistrationProvider::_sendEnableMessageToProviderManager(
904         CIMEnableModuleRequestMessage * enable_req)
905 {
906     MessageQueueService * _service = _getProviderManagerService();
907     Uint32 _queueId = _service->getQueueId();
908
909     callback_data *cb_data = new callback_data(this);
910
911     // create request envelope
912     AsyncLegacyOperationStart * asyncRequest =
913         new AsyncLegacyOperationStart (
914             _service->get_next_xid(),
915             NULL,
916             _queueId,
917             enable_req,
918             _queueId);
919
920     AsyncReply * asyncReply = _controller->ClientSendWait(*_client_handle,
921                                                           _queueId,
922                                                           asyncRequest);
923     CIMEnableModuleResponseMessage * response =
924         reinterpret_cast<CIMEnableModuleResponseMessage *>(
925              (static_cast<AsyncLegacyOperationResult *>(asyncReply))->get_result());
926     if (response->cimException.getCode() != CIM_ERR_SUCCESS)
927     {
928         CIMException e = response->cimException;
929         delete asyncRequest;
930         delete asyncReply;
931         delete response;
932         throw (e);
933     }
934
935     Array<Uint16> operationalStatus = response->operationalStatus;
936
937     delete asyncRequest;
938     delete asyncReply;
939     delete response;
940
941     return(operationalStatus);
942 }
943
944 // send termination message to subscription service
945 void ProviderRegistrationProvider::_sendTerminationMessageToSubscription(
946     const CIMObjectPath & ref, const String & moduleName,
947     const Boolean disableProviderOnly)
948 {
949     CIMInstance instance;
950     String _moduleName;
951     Array<CIMInstance> instances;
952
953     if (!disableProviderOnly)
954     {
955         CIMObjectPath reference("", PEGASUS_NAMESPACENAME_INTEROP,
956             PEGASUS_CLASSNAME_PROVIDER, ref.getKeyBindings());
957
958         Array<CIMObjectPath> instanceNames =
959             _providerRegistrationManager->enumerateInstanceNames(reference);
960
961         // find all the instances which have same module name as moduleName
962         for (Uint32 i = 0, n=instanceNames.size(); i < n; i++)
963         {
964             //
965             // get provider module name from reference
966             //
967
968             Array<CIMKeyBinding> keys = instanceNames[i].getKeyBindings();
969
970             for(Uint32 j=0; j < keys.size(); j++)
971             {
972                 if(keys[j].getName().equal (_PROPERTY_PROVIDERMODULENAME))
973                 {
974                     _moduleName = keys[j].getValue();
975                 }
976             }
977
978             if (String::equalNoCase(moduleName, _moduleName))
979             {
980                 reference.setKeyBindings(keys);
981                 instance = _providerRegistrationManager->getInstance(reference);
982                 instances.append(instance);
983             }
984         }
985     }
986     else
987     {
988             instance = _providerRegistrationManager->getInstance(ref);
989             instances.append(instance);
990     }
991
992     //
993     // get indication server queueId
994     //
995     MessageQueueService * _service = _getIndicationService();
996
997     if (_service != NULL)
998     {
999         Uint32 _queueId = _service->getQueueId();
1000
1001         CIMNotifyProviderTerminationRequestMessage * termination_req =
1002             new CIMNotifyProviderTerminationRequestMessage(
1003                 XmlWriter::getNextMessageId (),
1004                 instances,
1005                 QueueIdStack(_service->getQueueId()));
1006
1007         // create request envelope
1008         AsyncLegacyOperationStart * asyncRequest =
1009             new AsyncLegacyOperationStart (
1010                 _service->get_next_xid(),
1011                 NULL,
1012                 _queueId,
1013                 termination_req,
1014                 _queueId);
1015
1016         if( false  == _controller->ClientSendForget(
1017                            *_client_handle,
1018                            _queueId,
1019                            asyncRequest))
1020         {
1021             delete asyncRequest;
1022             throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, String::EMPTY);
1023         }
1024     }
1025 }
1026
1027 // get indication service
1028 MessageQueueService * ProviderRegistrationProvider::_getIndicationService()
1029 {
1030     MessageQueue * queue = MessageQueue::lookup(
1031         PEGASUS_QUEUENAME_INDICATIONSERVICE);
1032
1033     MessageQueueService * _service =
1034         dynamic_cast<MessageQueueService *>(queue);
1035     return(_service);
1036 }
1037
1038 // disable provider module, return 0 if module is disabled successfully,
1039 // return 1 if module is already disabled, otherwise, return -1
1040 Sint16 ProviderRegistrationProvider::_disableModule(
1041     const CIMObjectPath & objectReference, 
1042     const String & moduleName,
1043     Boolean disableProviderOnly)
1044 {
1045         //
1046         // get module status
1047         //
1048         Array<Uint16> _OperationalStatus =
1049             _providerRegistrationManager->getProviderModuleStatus( moduleName);
1050
1051         for (Uint32 i = 0; i<_OperationalStatus.size(); i++)
1052         {
1053             // retValue equals 1 if module is already disabled
1054             if (_OperationalStatus[i] == _MODULE_STOPPED ||
1055                 _OperationalStatus[i] == _MODULE_STOPPING)
1056             {
1057                 return (1);
1058             }
1059         }
1060
1061         CIMInstance instance;
1062         Array<CIMInstance> instances;
1063         CIMInstance mInstance;
1064         String _moduleName;
1065         Uint16 providers;
1066         CIMObjectPath providerRef;
1067
1068         // disable a provider module or delete a provider module
1069         if (!disableProviderOnly)
1070         {
1071             providerRef = CIMObjectPath(objectReference.getHost(),
1072                                  objectReference.getNameSpace(),
1073                                  PEGASUS_CLASSNAME_PROVIDER,
1074                                  objectReference.getKeyBindings());
1075
1076             // get module instance
1077             mInstance = 
1078                 _providerRegistrationManager->getInstance(objectReference);
1079
1080         }
1081         else // disable a provider
1082         {
1083             // get module instance
1084             Array <CIMKeyBinding> moduleKeyBindings;
1085             moduleKeyBindings.append (CIMKeyBinding
1086                 (_PROPERTY_PROVIDERMODULE_NAME, moduleName, 
1087                  CIMKeyBinding::STRING)); 
1088
1089             CIMObjectPath moduleRef(objectReference.getHost(),
1090                                     objectReference.getNameSpace(),
1091                                     PEGASUS_CLASSNAME_PROVIDERMODULE,
1092                                     moduleKeyBindings);
1093                                     
1094             mInstance = 
1095                 _providerRegistrationManager->getInstance(moduleRef);
1096         }
1097
1098         if (!disableProviderOnly)
1099         {
1100             // get all provider instances which have same module name as 
1101             // moduleName
1102             Array<CIMObjectPath> instanceNames = 
1103                 _providerRegistrationManager->enumerateInstanceNames(providerRef);
1104
1105             for(Uint32 i = 0, n=instanceNames.size(); i < n; i++)
1106             {
1107                 //
1108                 // get provider module name from reference
1109                 //
1110
1111                 Array<CIMKeyBinding> keys = instanceNames[i].getKeyBindings();
1112
1113                 for(Uint32 j=0; j < keys.size(); j++)
1114                 {
1115                     if(keys[j].getName().equal (_PROPERTY_PROVIDERMODULENAME))
1116                     {
1117                         _moduleName = keys[j].getValue();
1118                     }
1119                 }
1120
1121                 if (String::equalNoCase(_moduleName, moduleName))
1122                 {
1123                     providerRef.setKeyBindings(keys);
1124                     instance = _providerRegistrationManager->getInstance
1125                         (providerRef);
1126                     instances.append(instance);
1127                 }
1128
1129             }
1130         }
1131         else
1132         {
1133             instances.append(_providerRegistrationManager->getInstance
1134                  (objectReference));
1135         }
1136
1137         //
1138         // get provider manager service
1139         //
1140         MessageQueueService * _service = _getProviderManagerService();
1141
1142         if (_service != NULL)
1143         {
1144             // create CIMDisableModuleRequestMessage
1145             CIMDisableModuleRequestMessage * disable_req =
1146                 new CIMDisableModuleRequestMessage(
1147                     XmlWriter::getNextMessageId (),
1148                     mInstance,
1149                     instances,
1150                     disableProviderOnly,
1151                     QueueIdStack(_service->getQueueId()));
1152
1153             Array<Uint16> _opStatus =
1154                 _sendDisableMessageToProviderManager(disable_req);
1155
1156             if (!disableProviderOnly) // disable provider module
1157             {
1158                 for (Uint32 i = 0; i<_opStatus.size(); i++)
1159                 {
1160                     // module was disabled successfully
1161                     if (_opStatus[i] == _MODULE_STOPPED)
1162                     {
1163                         // send termination message to subscription service
1164                         _sendTerminationMessageToSubscription(objectReference,
1165                                 moduleName, false);
1166                         return (0);
1167                     }
1168                 }
1169             }
1170             else // disable provider
1171             {
1172                 _sendTerminationMessageToSubscription(objectReference,
1173                         moduleName, true);
1174                 return (0);
1175             }
1176         }
1177
1178         // disable failed
1179         return (-1);
1180 }
1181
1182 PEGASUS_NAMESPACE_END