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_DEFAULTPM "DefaultProviderManager"
64 # define LIBRARY_NAME_CMPIPM "CMPIProviderManager"
65 # define LIBRARY_NAME_JMPIPM "JMPIProviderManager"
66 #endif
67
68 PEGASUS_NAMESPACE_BEGIN
69
70 // BEGIN TEMP SECTION
71 class ProviderManagerContainer
72 {
73 public:
74 ProviderManagerContainer()
75 : _manager(0)
76 {
77 }
78
79 ProviderManagerContainer(const ProviderManagerContainer & container)
80 : _manager(0)
81 kumpf 1.1 {
82 *this = container;
83 }
84
85 ProviderManagerContainer(
86 const String& physicalName,
87 const String& logicalName,
88 const String& interfaceName,
|
89 kumpf 1.28.2.1 PEGASUS_INDICATION_CALLBACK_T indicationCallback,
90 PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,
|
91 carolann.graves 1.17 Boolean subscriptionInitComplete)
|
92 kumpf 1.1 : _manager(0)
93 {
|
94 gs.keenan 1.16 #if defined (PEGASUS_OS_VMS)
|
95 carson.hovey 1.25 _physicalName = ConfigManager::getInstance()->getCurrentValue("providerDir") +
96 String("/") + FileSystem::buildLibraryFileName(physicalName) + String(".exe");
|
97 humberto 1.19 #elif defined (PEGASUS_OS_OS400)
|
98 chuck 1.20 _physicalName = physicalName;
|
99 gs.keenan 1.16 #else
|
100 kumpf 1.12 _physicalName = ConfigManager::getHomedPath(PEGASUS_DEST_LIB_DIR) +
|
101 kumpf 1.13 String("/") + FileSystem::buildLibraryFileName(physicalName);
|
102 gs.keenan 1.16 #endif
|
103 kumpf 1.1
104 _logicalName = logicalName;
105 _interfaceName = interfaceName;
106
107 _module = ProviderManagerModule(_physicalName);
|
108 kumpf 1.24 Boolean moduleLoaded = _module.load();
|
109 kumpf 1.1
|
110 kumpf 1.24 if (moduleLoaded)
111 {
112 _manager = _module.getProviderManager(_logicalName);
113 }
114 else
115 {
116 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
117 "ProviderManagerModule load failed.");
118 }
119
120 if (_manager == 0)
121 {
122 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
123 "Failed to load ProviderManager \"" + _physicalName + "\".");
124
125 Logger::put_l(
126 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
127 "ProviderManager.BasicProviderManagerRouter."
128 "PROVIDERMANAGER_LOAD_FAILED",
129 "Failed to load the Provider Manager for interface type \"$0\""
130 " from library \"$1\".",
131 kumpf 1.24 _interfaceName, _physicalName);
132
133 throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
134 "ProviderManager.BasicProviderManagerRouter."
135 "PROVIDERMANAGER_LOAD_FAILED",
136 "Failed to load the Provider Manager for interface type \"$0\""
137 " from library \"$1\".",
138 _interfaceName, _physicalName));
139 }
|
140 kumpf 1.1
141 _manager->setIndicationCallback(indicationCallback);
|
142 kumpf 1.28.2.1 _manager->setResponseChunkCallback(responseChunkCallback);
|
143 carolann.graves 1.17
144 _manager->setSubscriptionInitComplete (subscriptionInitComplete);
|
145 kumpf 1.1 }
146
147 ~ProviderManagerContainer()
148 {
|
149 joyce.j 1.23 delete _manager;
|
150 kumpf 1.1 _module.unload();
151 }
152
153 ProviderManagerContainer& operator=(
154 const ProviderManagerContainer & container)
155 {
156 if (this == &container)
157 {
158 return *this;
159 }
160
161 _logicalName = container._logicalName;
162 _physicalName = container._physicalName;
163 _interfaceName = container._interfaceName;
164
165 _module = container._module;
166 _manager = container._manager;
167
168 return *this;
169 }
170
171 kumpf 1.1 ProviderManager* getProviderManager()
172 {
173 return _manager;
174 }
175
176 const String& getPhysicalName() const
177 {
178 return _physicalName;
179 }
180
181 const String& getLogicalName() const
182 {
183 return _logicalName;
184 }
185
186 const String& getInterfaceName() const
187 {
188 return _interfaceName;
189 }
190
191 private:
192 kumpf 1.1 String _physicalName;
193 String _logicalName;
194 String _interfaceName;
195
196 ProviderManagerModule _module;
197 ProviderManager* _manager;
198 };
199 // END TEMP SECTION
200
201
|
202 kumpf 1.28.2.1 PEGASUS_INDICATION_CALLBACK_T
203 BasicProviderManagerRouter::_indicationCallback = 0;
204
205 PEGASUS_RESPONSE_CHUNK_CALLBACK_T
206 BasicProviderManagerRouter::_responseChunkCallback = 0;
|
207 kumpf 1.1
208 BasicProviderManagerRouter::BasicProviderManagerRouter(
|
209 kumpf 1.28.2.1 PEGASUS_INDICATION_CALLBACK_T indicationCallback,
210 PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback)
|
211 kumpf 1.1 {
212 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
213 "BasicProviderManagerRouter::BasicProviderManagerRouter");
214
215 _indicationCallback = indicationCallback;
|
216 kumpf 1.28.2.1 _responseChunkCallback = responseChunkCallback;
|
217 carolann.graves 1.17 _subscriptionInitComplete = false;
|
218 kumpf 1.1
219 PEG_METHOD_EXIT();
220 }
221
222 BasicProviderManagerRouter::~BasicProviderManagerRouter()
223 {
224 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
225 "BasicProviderManagerRouter::~BasicProviderManagerRouter");
|
226 joyce.j 1.21 /* Clean up the provider managers */
227 for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
228 {
229 ProviderManagerContainer* pmc=_providerManagerTable[i];
230 delete pmc;
231 }
|
232 kumpf 1.1 PEG_METHOD_EXIT();
233 }
234
235 Message* BasicProviderManagerRouter::processMessage(Message * message)
236 {
237 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
238 "BasicProviderManagerRouter::processMessage");
239
240 CIMRequestMessage* request = dynamic_cast<CIMRequestMessage *>(message);
241 PEGASUS_ASSERT(request != 0);
242
243 Message* response = 0;
|
244 schuur 1.7 Boolean remoteNameSpaceRequest=false;
|
245 kumpf 1.1
246 //
247 // Retrieve the ProviderManager routing information
248 //
249
250 CIMInstance providerModule;
251
252 if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) ||
|
253 kumpf 1.4 (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE) ||
|
254 kumpf 1.24 (request->getType() == CIM_INITIALIZE_PROVIDER_REQUEST_MESSAGE))
|
255 kumpf 1.1 {
256 // Provider information is in OperationContext
257 ProviderIdContainer pidc = (ProviderIdContainer)
258 request->operationContext.get(ProviderIdContainer::NAME);
259 providerModule = pidc.getModule();
|
260 kumpf 1.24 remoteNameSpaceRequest=pidc.isRemoteNameSpace();
|
261 kumpf 1.1 }
262 else if (dynamic_cast<CIMIndicationRequestMessage*>(request) != 0)
263 {
264 // Provider information is in CIMIndicationRequestMessage
265 CIMIndicationRequestMessage* indReq =
266 dynamic_cast<CIMIndicationRequestMessage*>(request);
|
267 kumpf 1.24 ProviderIdContainer pidc = indReq->operationContext.get(ProviderIdContainer::NAME);
268 providerModule = pidc.getModule();
|
269 kumpf 1.1 }
270 else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
271 {
272 // Provider information is in CIMEnableModuleRequestMessage
273 CIMEnableModuleRequestMessage* emReq =
274 dynamic_cast<CIMEnableModuleRequestMessage*>(request);
275 providerModule = emReq->providerModule;
276 }
277 else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
278 {
279 // Provider information is in CIMDisableModuleRequestMessage
280 CIMDisableModuleRequestMessage* dmReq =
281 dynamic_cast<CIMDisableModuleRequestMessage*>(request);
282 providerModule = dmReq->providerModule;
283 }
|
284 kumpf 1.6 else if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
|
285 kumpf 1.24 (request->getType() ==
|
286 carolann.graves 1.17 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) ||
|
287 kumpf 1.24 (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE))
|
288 kumpf 1.1 {
289 // This operation is not provider-specific
290 }
291 else
292 {
293 // Error: Unrecognized message type.
294 PEGASUS_ASSERT(0);
|
295 kumpf 1.6 CIMResponseMessage* resp = request->buildResponse();
|
296 schuur 1.7 resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
|
297 kumpf 1.6 "Unknown message type.");
|
298 kumpf 1.1 response = resp;
299 }
300
301 //
302 // Forward the request to the appropriate ProviderManager(s)
303 //
304
|
305 carolann.graves 1.17 if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
|
306 kumpf 1.24 (request->getType() ==
|
307 carolann.graves 1.17 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE))
|
308 kumpf 1.1 {
|
309 carolann.graves 1.17 _subscriptionInitComplete = true;
310
|
311 kumpf 1.24 // Send CIMStopAllProvidersRequestMessage or
|
312 carolann.graves 1.17 // CIMSubscriptionInitCompleteRequestMessage to all ProviderManagers
|
313 kumpf 1.5 ReadLock tableLock(_providerManagerTableLock);
|
314 kumpf 1.1 for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
315 {
316 ProviderManagerContainer* pmc=_providerManagerTable[i];
317 Message* resp = pmc->getProviderManager()->processMessage(request);
318 if (resp)
319 {
|
320 kumpf 1.3 delete resp;
|
321 kumpf 1.1 }
322 }
|
323 kumpf 1.3
|
324 schuur 1.7 response = request->buildResponse();
|
325 kumpf 1.6 }
326 else if(request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE)
327 {
|
328 schuur 1.7 // Do not need to forward this request to in-process provider
|
329 kumpf 1.6 // managers
|
330 schuur 1.7 response = request->buildResponse();
|
331 kumpf 1.1 }
332 else
333 {
334 // Retrieve the provider interface type
335 String interfaceType;
336 CIMValue itValue = providerModule.getProperty(
337 providerModule.findProperty("InterfaceType")).getValue();
338 itValue.get(interfaceType);
339
|
340 kumpf 1.24 ProviderManager* pm = 0;
341 Boolean gotError = false;
342 try
343 {
344 // Look up the appropriate ProviderManager by InterfaceType
345 pm = _lookupProviderManager(interfaceType);
346 }
347 catch (const CIMException& e)
348 {
349 CIMResponseMessage* cimResponse = request->buildResponse();
350 cimResponse->cimException = e;
351 response = cimResponse;
352 gotError = true;
353 }
354
355 if (remoteNameSpaceRequest && !pm->supportsRemoteNameSpaces())
356 {
357 CIMResponseMessage* resp = request->buildResponse();
358 resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
359 "Remote Namespace operations not supported for interface type "
360 + interfaceType);
361 kumpf 1.24 response = resp;
362 gotError = true;
363 }
364
365 if (!gotError)
366 {
367 response = pm->processMessage(request);
368 }
|
369 kumpf 1.1 }
370
371 // preserve message key
372 // set HTTP method in response from request
|
373 j.alex 1.26 // set closeConnect
374 ((CIMResponseMessage *)response)->syncAttributes(request);
|
375 kumpf 1.1
376 PEG_METHOD_EXIT();
377 return response;
378 }
379
380 // ATTN: May need to add interfaceVersion parameter to further constrain lookup
381 ProviderManager* BasicProviderManagerRouter::_lookupProviderManager(
382 const String& interfaceType)
383 {
384 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
385 "BasicProviderManagerRouter::_lookupProviderManager");
386
387 //
388 // Search for this InterfaceType in the table of loaded ProviderManagers
389 //
390 {
391 ReadLock tableLock(_providerManagerTableLock);
392
393 // find provider manager for specified provider interface type
394 for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
395 {
396 kumpf 1.1 if (interfaceType == _providerManagerTable[i]->getInterfaceName())
397 {
398 ProviderManagerContainer* pmc=_providerManagerTable[i];
399 PEG_METHOD_EXIT();
400 return pmc->getProviderManager();
401 }
402 }
403 }
404
405 //
406 // Load the ProviderManager for this InterfaceType and add it to the table
407 //
408 {
409 WriteLock tableLock(_providerManagerTableLock);
410
411 // ATTN: this section is a temporary solution to populate the list of
412 // enabled provider managers for a given distribution. It includes
413 // another temporary solution for converting a generic file name into
414 // a file name useable by each platform.
415
|
416 se.gupta 1.10 #if defined(PEGASUS_ENABLE_DEFAULT_PROVIDER_MANAGER)
|
417 kumpf 1.1 if (interfaceType == "C++Default")
418 {
419 ProviderManagerContainer* pmc = new ProviderManagerContainer(
|
420 kumpf 1.28.2.1 LIBRARY_NAME_DEFAULTPM,
421 "DEFAULT",
422 "C++Default",
423 _indicationCallback,
424 _responseChunkCallback,
425 _subscriptionInitComplete);
|
426 kumpf 1.1 _providerManagerTable.append(pmc);
427 return pmc->getProviderManager();
428 }
429 #endif
430
|
431 se.gupta 1.11 #if defined(PEGASUS_ENABLE_CMPI_PROVIDER_MANAGER)
|
432 kumpf 1.1 if (interfaceType == "CMPI")
433 {
434 ProviderManagerContainer* pmc = new ProviderManagerContainer(
|
435 kumpf 1.28.2.1 LIBRARY_NAME_CMPIPM,
436 "CMPI",
437 "CMPI",
438 _indicationCallback,
439 _responseChunkCallback,
|
440 kumpf 1.18 _subscriptionInitComplete);
|
441 kumpf 1.1 _providerManagerTable.append(pmc);
442 return pmc->getProviderManager();
443 }
444 #endif
445
|
446 se.gupta 1.11 #if defined(PEGASUS_ENABLE_JMPI_PROVIDER_MANAGER)
|
447 mark.hamzy 1.28.2.2 if ( interfaceType == "JMPI"
448 || interfaceType == "JMPIExperimental"
449 )
|
450 kumpf 1.1 {
451 ProviderManagerContainer* pmc = new ProviderManagerContainer(
|
452 kumpf 1.28.2.1 LIBRARY_NAME_JMPIPM,
|
453 mark.hamzy 1.28.2.2 interfaceType,
454 interfaceType,
|
455 kumpf 1.28.2.1 _indicationCallback,
456 _responseChunkCallback,
|
457 kumpf 1.18 _subscriptionInitComplete);
|
458 kumpf 1.1 _providerManagerTable.append(pmc);
459 return pmc->getProviderManager();
460 }
461 #endif
462 // END TEMP SECTION
463 }
464
465 // Error: ProviderManager not found for the specified interface type
466 PEGASUS_ASSERT(0);
467 PEG_METHOD_EXIT();
468 return 0;
469 }
470
|
471 kumpf 1.5 Boolean BasicProviderManagerRouter::hasActiveProviders()
|
472 kumpf 1.1 {
473 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
|
474 kumpf 1.5 "BasicProviderManagerRouter::hasActiveProviders");
|
475 kumpf 1.1
|
476 kumpf 1.5 ReadLock tableLock(_providerManagerTableLock);
|
477 kumpf 1.1 for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
478 {
479 ProviderManagerContainer* pmc = _providerManagerTable[i];
|
480 kumpf 1.5 if (pmc->getProviderManager()->hasActiveProviders())
481 {
482 PEG_METHOD_EXIT();
483 return true;
484 }
485 }
486
487 PEG_METHOD_EXIT();
488 return false;
489 }
490
491 void BasicProviderManagerRouter::unloadIdleProviders()
492 {
493 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
494 "BasicProviderManagerRouter::unloadIdleProviders");
495
496 //
497 // Save pointers to the ProviderManagerContainers so we don't hold the
498 // _providerManagerTableLock while unloading idle providers
499 //
500 Array<ProviderManagerContainer*> pmcs;
501 kumpf 1.5 {
502 ReadLock tableLock(_providerManagerTableLock);
503 for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
504 {
505 pmcs.append(_providerManagerTable[i]);
506 }
507 }
508
509 //
510 // Unload idle providers in each of the active ProviderManagers
511 // _providerManagerTableLock while unloading idle providers
512 //
513 for (Uint32 i = 0; i < pmcs.size(); i++)
514 {
515 pmcs[i]->getProviderManager()->unloadIdleProviders();
|
516 kumpf 1.1 }
517
518 PEG_METHOD_EXIT();
519 }
520
521 PEGASUS_NAMESPACE_END
|