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