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