1 karl 1.15 //%2005////////////////////////////////////////////////////////////////////////
|
2 kumpf 1.1 //
|
3 karl 1.14 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 kumpf 1.1 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.14 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.15 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 kumpf 1.1 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to
14 // deal in the Software without restriction, including without limitation the
15 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 // sell copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
|
18 karl 1.14 //
|
19 kumpf 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
20 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
21 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
23 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //==============================================================================
29 //
30 // Author: Chip Vincent (cvincent@us.ibm.com)
31 // Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
32 //
|
33 se.gupta 1.9 // Modified By: Seema Gupta(gseema@in.ibm.com) for PEP135
|
34 gs.keenan 1.16 // Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com)
|
35 carolann.graves 1.17 // Carol Ann Krug Graves, Hewlett-Packard Company
36 // (carolann_graves@hp.com)
|
37 kumpf 1.24 // Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#2619, #2685,#3354
|
38 j.alex 1.26 // John Alex, IBM (johnalex@us.ibm.com) - Bug#2290
|
39 kumpf 1.1 //
40 //%/////////////////////////////////////////////////////////////////////////////
41
42 #include "BasicProviderManagerRouter.h"
43
44 #include <Pegasus/Common/Config.h>
|
45 se.gupta 1.9 #include <Pegasus/Common/OperationContextInternal.h>
|
46 kumpf 1.1 #include <Pegasus/Common/CIMMessage.h>
47 #include <Pegasus/Common/Tracer.h>
|
48 kumpf 1.24 #include <Pegasus/Common/Logger.h>
|
49 kumpf 1.12 #include <Pegasus/Common/FileSystem.h>
50 #include <Pegasus/Config/ConfigManager.h>
|
51 kumpf 1.1 #include <Pegasus/ProviderManager2/OperationResponseHandler.h>
52 #include <Pegasus/ProviderManager2/ProviderManagerModule.h>
53 #include <Pegasus/ProviderManager2/ProviderManager.h>
54
55 // ProviderManager library names. Should these be defined elsewhere?
56 #if defined(PEGASUS_OS_OS400)
|
57 humberto 1.19 # define LIBRARY_NAME_DEFAULTPM "QSYS/QYCMPMDE00"
|
58 kumpf 1.1 # define LIBRARY_NAME_CMPIPM "QSYS/QYCMCMPIPM"
59 # define LIBRARY_NAME_JMPIPM "QSYS/QYCMJMPIPM"
60 #else
61 # define LIBRARY_NAME_DEFAULTPM "DefaultProviderManager"
62 # define LIBRARY_NAME_CMPIPM "CMPIProviderManager"
63 # define LIBRARY_NAME_JMPIPM "JMPIProviderManager"
64 #endif
65
66 PEGASUS_NAMESPACE_BEGIN
67
68 // BEGIN TEMP SECTION
69 class ProviderManagerContainer
70 {
71 public:
72 ProviderManagerContainer()
73 : _manager(0)
74 {
75 }
76
77 ProviderManagerContainer(const ProviderManagerContainer & container)
78 : _manager(0)
79 kumpf 1.1 {
80 *this = container;
81 }
82
83 ProviderManagerContainer(
84 const String& physicalName,
85 const String& logicalName,
86 const String& interfaceName,
|
87 carolann.graves 1.17 PEGASUS_INDICATION_CALLBACK indicationCallback,
88 Boolean subscriptionInitComplete)
|
89 kumpf 1.1 : _manager(0)
90 {
|
91 gs.keenan 1.16 #if defined (PEGASUS_OS_VMS)
|
92 carson.hovey 1.25 _physicalName = ConfigManager::getInstance()->getCurrentValue("providerDir") +
93 String("/") + FileSystem::buildLibraryFileName(physicalName) + String(".exe");
|
94 humberto 1.19 #elif defined (PEGASUS_OS_OS400)
|
95 chuck 1.20 _physicalName = physicalName;
|
96 gs.keenan 1.16 #else
|
97 kumpf 1.12 _physicalName = ConfigManager::getHomedPath(PEGASUS_DEST_LIB_DIR) +
|
98 kumpf 1.13 String("/") + FileSystem::buildLibraryFileName(physicalName);
|
99 gs.keenan 1.16 #endif
|
100 kumpf 1.1
101 _logicalName = logicalName;
102 _interfaceName = interfaceName;
103
104 _module = ProviderManagerModule(_physicalName);
|
105 kumpf 1.24 Boolean moduleLoaded = _module.load();
|
106 kumpf 1.1
|
107 kumpf 1.24 if (moduleLoaded)
108 {
109 _manager = _module.getProviderManager(_logicalName);
110 }
111 else
112 {
113 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
114 "ProviderManagerModule load failed.");
115 }
116
117 if (_manager == 0)
118 {
119 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
120 "Failed to load ProviderManager \"" + _physicalName + "\".");
121
122 Logger::put_l(
123 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
124 "ProviderManager.BasicProviderManagerRouter."
125 "PROVIDERMANAGER_LOAD_FAILED",
126 "Failed to load the Provider Manager for interface type \"$0\""
127 " from library \"$1\".",
128 kumpf 1.24 _interfaceName, _physicalName);
129
130 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
131 "ProviderManager.BasicProviderManagerRouter."
132 "PROVIDERMANAGER_LOAD_FAILED",
133 "Failed to load the Provider Manager for interface type \"$0\""
134 " from library \"$1\".",
135 _interfaceName, _physicalName));
136 }
|
137 kumpf 1.1
138 _manager->setIndicationCallback(indicationCallback);
|
139 carolann.graves 1.17
140 _manager->setSubscriptionInitComplete (subscriptionInitComplete);
|
141 kumpf 1.1 }
142
143 ~ProviderManagerContainer()
144 {
|
145 joyce.j 1.23 delete _manager;
|
146 kumpf 1.1 _module.unload();
147 }
148
149 ProviderManagerContainer& operator=(
150 const ProviderManagerContainer & container)
151 {
152 if (this == &container)
153 {
154 return *this;
155 }
156
157 _logicalName = container._logicalName;
158 _physicalName = container._physicalName;
159 _interfaceName = container._interfaceName;
160
161 _module = container._module;
162 _manager = container._manager;
163
164 return *this;
165 }
166
167 kumpf 1.1 ProviderManager* getProviderManager()
168 {
169 return _manager;
170 }
171
172 const String& getPhysicalName() const
173 {
174 return _physicalName;
175 }
176
177 const String& getLogicalName() const
178 {
179 return _logicalName;
180 }
181
182 const String& getInterfaceName() const
183 {
184 return _interfaceName;
185 }
186
187 private:
188 kumpf 1.1 String _physicalName;
189 String _logicalName;
190 String _interfaceName;
191
192 ProviderManagerModule _module;
193 ProviderManager* _manager;
194 };
195 // END TEMP SECTION
196
197
198 PEGASUS_INDICATION_CALLBACK BasicProviderManagerRouter::_indicationCallback = 0;
199
200 // Private, unimplemented constructor
201 BasicProviderManagerRouter::BasicProviderManagerRouter()
202 {
203 }
204
205 BasicProviderManagerRouter::BasicProviderManagerRouter(
206 PEGASUS_INDICATION_CALLBACK indicationCallback)
207 {
208 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
209 kumpf 1.1 "BasicProviderManagerRouter::BasicProviderManagerRouter");
210
211 _indicationCallback = indicationCallback;
|
212 carolann.graves 1.17 _subscriptionInitComplete = false;
|
213 kumpf 1.1
214 PEG_METHOD_EXIT();
215 }
216
217 BasicProviderManagerRouter::~BasicProviderManagerRouter()
218 {
219 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
220 "BasicProviderManagerRouter::~BasicProviderManagerRouter");
|
221 joyce.j 1.21 /* Clean up the provider managers */
222 for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
223 {
224 ProviderManagerContainer* pmc=_providerManagerTable[i];
225 delete pmc;
226 }
|
227 kumpf 1.1 PEG_METHOD_EXIT();
228 }
229
230 Message* BasicProviderManagerRouter::processMessage(Message * message)
231 {
232 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
233 "BasicProviderManagerRouter::processMessage");
234
235 CIMRequestMessage* request = dynamic_cast<CIMRequestMessage *>(message);
236 PEGASUS_ASSERT(request != 0);
237
238 Message* response = 0;
|
239 schuur 1.7 Boolean remoteNameSpaceRequest=false;
|
240 kumpf 1.1
241 //
242 // Retrieve the ProviderManager routing information
243 //
244
245 CIMInstance providerModule;
246
247 if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) ||
|
248 kumpf 1.4 (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE) ||
|
249 kumpf 1.24 (request->getType() == CIM_INITIALIZE_PROVIDER_REQUEST_MESSAGE))
|
250 kumpf 1.1 {
251 // Provider information is in OperationContext
252 ProviderIdContainer pidc = (ProviderIdContainer)
253 request->operationContext.get(ProviderIdContainer::NAME);
254 providerModule = pidc.getModule();
|
255 kumpf 1.24 remoteNameSpaceRequest=pidc.isRemoteNameSpace();
|
256 kumpf 1.1 }
257 else if (dynamic_cast<CIMIndicationRequestMessage*>(request) != 0)
258 {
259 // Provider information is in CIMIndicationRequestMessage
260 CIMIndicationRequestMessage* indReq =
261 dynamic_cast<CIMIndicationRequestMessage*>(request);
|
262 kumpf 1.24 ProviderIdContainer pidc = indReq->operationContext.get(ProviderIdContainer::NAME);
263 providerModule = pidc.getModule();
|
264 kumpf 1.1 }
265 else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
266 {
267 // Provider information is in CIMEnableModuleRequestMessage
268 CIMEnableModuleRequestMessage* emReq =
269 dynamic_cast<CIMEnableModuleRequestMessage*>(request);
270 providerModule = emReq->providerModule;
271 }
272 else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
273 {
274 // Provider information is in CIMDisableModuleRequestMessage
275 CIMDisableModuleRequestMessage* dmReq =
276 dynamic_cast<CIMDisableModuleRequestMessage*>(request);
277 providerModule = dmReq->providerModule;
278 }
|
279 kumpf 1.6 else if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
|
280 kumpf 1.24 (request->getType() ==
|
281 carolann.graves 1.17 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) ||
|
282 kumpf 1.24 (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE))
|
283 kumpf 1.1 {
284 // This operation is not provider-specific
285 }
286 else
287 {
288 // Error: Unrecognized message type.
289 PEGASUS_ASSERT(0);
|
290 kumpf 1.6 CIMResponseMessage* resp = request->buildResponse();
|
291 schuur 1.7 resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
|
292 kumpf 1.6 "Unknown message type.");
|
293 kumpf 1.1 response = resp;
294 }
295
296 //
297 // Forward the request to the appropriate ProviderManager(s)
298 //
299
|
300 carolann.graves 1.17 if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
|
301 kumpf 1.24 (request->getType() ==
|
302 carolann.graves 1.17 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE))
|
303 kumpf 1.1 {
|
304 carolann.graves 1.17 _subscriptionInitComplete = true;
305
|
306 kumpf 1.24 // Send CIMStopAllProvidersRequestMessage or
|
307 carolann.graves 1.17 // CIMSubscriptionInitCompleteRequestMessage to all ProviderManagers
|
308 kumpf 1.5 ReadLock tableLock(_providerManagerTableLock);
|
309 kumpf 1.1 for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
310 {
311 ProviderManagerContainer* pmc=_providerManagerTable[i];
312 Message* resp = pmc->getProviderManager()->processMessage(request);
313 if (resp)
314 {
|
315 kumpf 1.3 delete resp;
|
316 kumpf 1.1 }
317 }
|
318 kumpf 1.3
|
319 schuur 1.7 response = request->buildResponse();
|
320 kumpf 1.6 }
321 else if(request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE)
322 {
|
323 schuur 1.7 // Do not need to forward this request to in-process provider
|
324 kumpf 1.6 // managers
|
325 schuur 1.7 response = request->buildResponse();
|
326 kumpf 1.1 }
327 else
328 {
329 // Retrieve the provider interface type
330 String interfaceType;
331 CIMValue itValue = providerModule.getProperty(
332 providerModule.findProperty("InterfaceType")).getValue();
333 itValue.get(interfaceType);
334
|
335 kumpf 1.24 ProviderManager* pm = 0;
336 Boolean gotError = false;
337 try
338 {
339 // Look up the appropriate ProviderManager by InterfaceType
340 pm = _lookupProviderManager(interfaceType);
341 }
342 catch (const CIMException& e)
343 {
344 CIMResponseMessage* cimResponse = request->buildResponse();
345 cimResponse->cimException = e;
346 response = cimResponse;
347 gotError = true;
348 }
349
350 if (remoteNameSpaceRequest && !pm->supportsRemoteNameSpaces())
351 {
352 CIMResponseMessage* resp = request->buildResponse();
353 resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
354 "Remote Namespace operations not supported for interface type "
355 + interfaceType);
356 kumpf 1.24 response = resp;
357 gotError = true;
358 }
359
360 if (!gotError)
361 {
362 response = pm->processMessage(request);
363 }
|
364 kumpf 1.1 }
365
366 // preserve message key
367 // set HTTP method in response from request
|
368 j.alex 1.26 // set closeConnect
369 ((CIMResponseMessage *)response)->syncAttributes(request);
|
370 kumpf 1.1
371 PEG_METHOD_EXIT();
372 return response;
373 }
374
375 // ATTN: May need to add interfaceVersion parameter to further constrain lookup
376 ProviderManager* BasicProviderManagerRouter::_lookupProviderManager(
377 const String& interfaceType)
378 {
379 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
380 "BasicProviderManagerRouter::_lookupProviderManager");
381
382 //
383 // Search for this InterfaceType in the table of loaded ProviderManagers
384 //
385 {
386 ReadLock tableLock(_providerManagerTableLock);
387
388 // find provider manager for specified provider interface type
389 for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
390 {
391 kumpf 1.1 if (interfaceType == _providerManagerTable[i]->getInterfaceName())
392 {
393 ProviderManagerContainer* pmc=_providerManagerTable[i];
394 PEG_METHOD_EXIT();
395 return pmc->getProviderManager();
396 }
397 }
398 }
399
400 //
401 // Load the ProviderManager for this InterfaceType and add it to the table
402 //
403 {
404 WriteLock tableLock(_providerManagerTableLock);
405
406 // ATTN: this section is a temporary solution to populate the list of
407 // enabled provider managers for a given distribution. It includes
408 // another temporary solution for converting a generic file name into
409 // a file name useable by each platform.
410
|
411 se.gupta 1.10 #if defined(PEGASUS_ENABLE_DEFAULT_PROVIDER_MANAGER)
|
412 kumpf 1.1 if (interfaceType == "C++Default")
413 {
414 ProviderManagerContainer* pmc = new ProviderManagerContainer(
415 LIBRARY_NAME_DEFAULTPM, "DEFAULT", "C++Default",
|
416 carolann.graves 1.17 _indicationCallback, _subscriptionInitComplete);
|
417 kumpf 1.1 _providerManagerTable.append(pmc);
418 return pmc->getProviderManager();
419 }
420 #endif
421
|
422 se.gupta 1.11 #if defined(PEGASUS_ENABLE_CMPI_PROVIDER_MANAGER)
|
423 kumpf 1.1 if (interfaceType == "CMPI")
424 {
425 ProviderManagerContainer* pmc = new ProviderManagerContainer(
|
426 kumpf 1.18 LIBRARY_NAME_CMPIPM, "CMPI", "CMPI", _indicationCallback,
427 _subscriptionInitComplete);
|
428 kumpf 1.1 _providerManagerTable.append(pmc);
429 return pmc->getProviderManager();
430 }
431 #endif
432
|
433 se.gupta 1.11 #if defined(PEGASUS_ENABLE_JMPI_PROVIDER_MANAGER)
|
434 kumpf 1.1 if (interfaceType == "JMPI")
435 {
436 ProviderManagerContainer* pmc = new ProviderManagerContainer(
|
437 kumpf 1.18 LIBRARY_NAME_JMPIPM, "JMPI", "JMPI", _indicationCallback,
438 _subscriptionInitComplete);
|
439 kumpf 1.1 _providerManagerTable.append(pmc);
440 return pmc->getProviderManager();
441 }
442 #endif
443 // END TEMP SECTION
444 }
445
446 // Error: ProviderManager not found for the specified interface type
447 PEGASUS_ASSERT(0);
448 PEG_METHOD_EXIT();
449 return 0;
450 }
451
|
452 kumpf 1.5 Boolean BasicProviderManagerRouter::hasActiveProviders()
|
453 kumpf 1.1 {
454 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
|
455 kumpf 1.5 "BasicProviderManagerRouter::hasActiveProviders");
|
456 kumpf 1.1
|
457 kumpf 1.5 ReadLock tableLock(_providerManagerTableLock);
|
458 kumpf 1.1 for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
459 {
460 ProviderManagerContainer* pmc = _providerManagerTable[i];
|
461 kumpf 1.5 if (pmc->getProviderManager()->hasActiveProviders())
462 {
463 PEG_METHOD_EXIT();
464 return true;
465 }
466 }
467
468 PEG_METHOD_EXIT();
469 return false;
470 }
471
472 void BasicProviderManagerRouter::unloadIdleProviders()
473 {
474 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
475 "BasicProviderManagerRouter::unloadIdleProviders");
476
477 //
478 // Save pointers to the ProviderManagerContainers so we don't hold the
479 // _providerManagerTableLock while unloading idle providers
480 //
481 Array<ProviderManagerContainer*> pmcs;
482 kumpf 1.5 {
483 ReadLock tableLock(_providerManagerTableLock);
484 for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
485 {
486 pmcs.append(_providerManagerTable[i]);
487 }
488 }
489
490 //
491 // Unload idle providers in each of the active ProviderManagers
492 // _providerManagerTableLock while unloading idle providers
493 //
494 for (Uint32 i = 0; i < pmcs.size(); i++)
495 {
496 pmcs[i]->getProviderManager()->unloadIdleProviders();
|
497 kumpf 1.1 }
498
499 PEG_METHOD_EXIT();
500 }
501
502 PEGASUS_NAMESPACE_END
|