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.1 //
38 //%/////////////////////////////////////////////////////////////////////////////
39
40 #include "BasicProviderManagerRouter.h"
41
42 #include <Pegasus/Common/Config.h>
|
43 se.gupta 1.9 #include <Pegasus/Common/OperationContextInternal.h>
|
44 kumpf 1.1 #include <Pegasus/Common/CIMMessage.h>
45 #include <Pegasus/Common/Tracer.h>
|
46 kumpf 1.12 #include <Pegasus/Common/FileSystem.h>
47 #include <Pegasus/Config/ConfigManager.h>
|
48 kumpf 1.1 #include <Pegasus/ProviderManager2/OperationResponseHandler.h>
49 #include <Pegasus/ProviderManager2/ProviderManagerModule.h>
50 #include <Pegasus/ProviderManager2/ProviderManager.h>
51
52 // ProviderManager library names. Should these be defined elsewhere?
53 #if defined(PEGASUS_OS_OS400)
54 # define LIBRARY_NAME_DEFAULTPM "QSYS/QYCMDFTPVM"
55 # define LIBRARY_NAME_CMPIPM "QSYS/QYCMCMPIPM"
56 # define LIBRARY_NAME_JMPIPM "QSYS/QYCMJMPIPM"
57 #else
58 # define LIBRARY_NAME_DEFAULTPM "DefaultProviderManager"
59 # define LIBRARY_NAME_CMPIPM "CMPIProviderManager"
60 # define LIBRARY_NAME_JMPIPM "JMPIProviderManager"
61 #endif
62
63 PEGASUS_NAMESPACE_BEGIN
64
65 // BEGIN TEMP SECTION
66 class ProviderManagerContainer
67 {
68 public:
69 kumpf 1.1 ProviderManagerContainer()
70 : _manager(0)
71 {
72 }
73
74 ProviderManagerContainer(const ProviderManagerContainer & container)
75 : _manager(0)
76 {
77 *this = container;
78 }
79
80 ProviderManagerContainer(
81 const String& physicalName,
82 const String& logicalName,
83 const String& interfaceName,
|
84 carolann.graves 1.17 PEGASUS_INDICATION_CALLBACK indicationCallback,
85 Boolean subscriptionInitComplete)
|
86 kumpf 1.1 : _manager(0)
87 {
|
88 gs.keenan 1.16 #if defined (PEGASUS_OS_VMS)
89 _physicalName = FileSystem::buildLibraryFileName(physicalName);
90 #else
|
91 kumpf 1.12 _physicalName = ConfigManager::getHomedPath(PEGASUS_DEST_LIB_DIR) +
|
92 kumpf 1.13 String("/") + FileSystem::buildLibraryFileName(physicalName);
|
93 gs.keenan 1.16 #endif
|
94 kumpf 1.1
95 _logicalName = logicalName;
96 _interfaceName = interfaceName;
97
98 _module = ProviderManagerModule(_physicalName);
99 _module.load();
100
101 _manager = _module.getProviderManager(_logicalName);
102 PEGASUS_ASSERT(_manager != 0);
103
104 _manager->setIndicationCallback(indicationCallback);
|
105 carolann.graves 1.17
106 _manager->setSubscriptionInitComplete (subscriptionInitComplete);
|
107 kumpf 1.1 }
108
109 ~ProviderManagerContainer()
110 {
111 _module.unload();
112 }
113
114 ProviderManagerContainer& operator=(
115 const ProviderManagerContainer & container)
116 {
117 if (this == &container)
118 {
119 return *this;
120 }
121
122 _logicalName = container._logicalName;
123 _physicalName = container._physicalName;
124 _interfaceName = container._interfaceName;
125
126 _module = container._module;
127 _manager = container._manager;
128 kumpf 1.1
129 return *this;
130 }
131
132 ProviderManager* getProviderManager()
133 {
134 return _manager;
135 }
136
137 const String& getPhysicalName() const
138 {
139 return _physicalName;
140 }
141
142 const String& getLogicalName() const
143 {
144 return _logicalName;
145 }
146
147 const String& getInterfaceName() const
148 {
149 kumpf 1.1 return _interfaceName;
150 }
151
152 private:
153 String _physicalName;
154 String _logicalName;
155 String _interfaceName;
156
157 ProviderManagerModule _module;
158 ProviderManager* _manager;
159 };
160 // END TEMP SECTION
161
162
163 PEGASUS_INDICATION_CALLBACK BasicProviderManagerRouter::_indicationCallback = 0;
164
165 // Private, unimplemented constructor
166 BasicProviderManagerRouter::BasicProviderManagerRouter()
167 {
168 }
169
170 kumpf 1.1 BasicProviderManagerRouter::BasicProviderManagerRouter(
171 PEGASUS_INDICATION_CALLBACK indicationCallback)
172 {
173 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
174 "BasicProviderManagerRouter::BasicProviderManagerRouter");
175
176 _indicationCallback = indicationCallback;
|
177 carolann.graves 1.17 _subscriptionInitComplete = false;
|
178 kumpf 1.1
179 PEG_METHOD_EXIT();
180 }
181
182 BasicProviderManagerRouter::~BasicProviderManagerRouter()
183 {
184 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
185 "BasicProviderManagerRouter::~BasicProviderManagerRouter");
186 PEG_METHOD_EXIT();
187 }
188
189 Message* BasicProviderManagerRouter::processMessage(Message * message)
190 {
191 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
192 "BasicProviderManagerRouter::processMessage");
193
194 CIMRequestMessage* request = dynamic_cast<CIMRequestMessage *>(message);
195 PEGASUS_ASSERT(request != 0);
196
197 Message* response = 0;
|
198 schuur 1.7 Boolean remoteNameSpaceRequest=false;
|
199 kumpf 1.1
200 //
201 // Retrieve the ProviderManager routing information
202 //
203
204 CIMInstance providerModule;
205
206 if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) ||
|
207 kumpf 1.4 (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE) ||
208 (request->getType() == CIM_INITIALIZE_PROVIDER_REQUEST_MESSAGE))
|
209 kumpf 1.1 {
210 // Provider information is in OperationContext
211 ProviderIdContainer pidc = (ProviderIdContainer)
212 request->operationContext.get(ProviderIdContainer::NAME);
213 providerModule = pidc.getModule();
|
214 schuur 1.7 remoteNameSpaceRequest=pidc.isRemoteNameSpace();
|
215 kumpf 1.1 }
216 else if (dynamic_cast<CIMIndicationRequestMessage*>(request) != 0)
217 {
218 // Provider information is in CIMIndicationRequestMessage
219 CIMIndicationRequestMessage* indReq =
220 dynamic_cast<CIMIndicationRequestMessage*>(request);
|
221 se.gupta 1.9 ProviderIdContainer pidc = indReq->operationContext.get(ProviderIdContainer::NAME);
222 providerModule = pidc.getModule();
|
223 kumpf 1.1 }
224 else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
225 {
226 // Provider information is in CIMEnableModuleRequestMessage
227 CIMEnableModuleRequestMessage* emReq =
228 dynamic_cast<CIMEnableModuleRequestMessage*>(request);
229 providerModule = emReq->providerModule;
230 }
231 else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
232 {
233 // Provider information is in CIMDisableModuleRequestMessage
234 CIMDisableModuleRequestMessage* dmReq =
235 dynamic_cast<CIMDisableModuleRequestMessage*>(request);
236 providerModule = dmReq->providerModule;
237 }
|
238 kumpf 1.6 else if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
|
239 carolann.graves 1.17 (request->getType() ==
240 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) ||
|
241 kumpf 1.6 (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE))
|
242 kumpf 1.1 {
243 // This operation is not provider-specific
244 }
245 else
246 {
247 // Error: Unrecognized message type.
248 PEGASUS_ASSERT(0);
|
249 kumpf 1.6 CIMResponseMessage* resp = request->buildResponse();
|
250 schuur 1.7 resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
|
251 kumpf 1.6 "Unknown message type.");
|
252 kumpf 1.1 response = resp;
253 }
254
255 //
256 // Forward the request to the appropriate ProviderManager(s)
257 //
258
|
259 carolann.graves 1.17 if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
260 (request->getType() ==
261 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE))
|
262 kumpf 1.1 {
|
263 carolann.graves 1.17 _subscriptionInitComplete = true;
264
265 // Send CIMStopAllProvidersRequestMessage or
266 // CIMSubscriptionInitCompleteRequestMessage to all ProviderManagers
|
267 kumpf 1.5 ReadLock tableLock(_providerManagerTableLock);
|
268 kumpf 1.1 for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
269 {
270 ProviderManagerContainer* pmc=_providerManagerTable[i];
271 Message* resp = pmc->getProviderManager()->processMessage(request);
272 if (resp)
273 {
|
274 kumpf 1.3 delete resp;
|
275 kumpf 1.1 }
276 }
|
277 kumpf 1.3
|
278 schuur 1.7 response = request->buildResponse();
|
279 kumpf 1.6 }
280 else if(request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE)
281 {
|
282 schuur 1.7 // Do not need to forward this request to in-process provider
|
283 kumpf 1.6 // managers
|
284 schuur 1.7 response = request->buildResponse();
|
285 kumpf 1.1 }
286 else
287 {
288 // Retrieve the provider interface type
289 String interfaceType;
290 CIMValue itValue = providerModule.getProperty(
291 providerModule.findProperty("InterfaceType")).getValue();
292 itValue.get(interfaceType);
293
294 // Look up the appropriate ProviderManager by InterfaceType
295 ProviderManager* pm = _lookupProviderManager(interfaceType);
|
296 schuur 1.7 if (remoteNameSpaceRequest && !pm->supportsRemoteNameSpaces()) {
297 CIMResponseMessage* resp = request->buildResponse();
298 resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
299 "Remote Namespace operations not supported for interface type "+interfaceType);
300 response = resp;
301 }
302 else response = pm->processMessage(request);
|
303 kumpf 1.1 }
304
305 // preserve message key
306 response->setKey(request->getKey());
307
308 // set HTTP method in response from request
309 response->setHttpMethod(request->getHttpMethod());
310
311 PEG_METHOD_EXIT();
312 return response;
313 }
314
315 // ATTN: May need to add interfaceVersion parameter to further constrain lookup
316 ProviderManager* BasicProviderManagerRouter::_lookupProviderManager(
317 const String& interfaceType)
318 {
319 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
320 "BasicProviderManagerRouter::_lookupProviderManager");
321
322 //
323 // Search for this InterfaceType in the table of loaded ProviderManagers
324 kumpf 1.1 //
325 {
326 ReadLock tableLock(_providerManagerTableLock);
327
328 // find provider manager for specified provider interface type
329 for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
330 {
331 if (interfaceType == _providerManagerTable[i]->getInterfaceName())
332 {
333 ProviderManagerContainer* pmc=_providerManagerTable[i];
334 PEG_METHOD_EXIT();
335 return pmc->getProviderManager();
336 }
337 }
338 }
339
340 //
341 // Load the ProviderManager for this InterfaceType and add it to the table
342 //
343 {
344 WriteLock tableLock(_providerManagerTableLock);
345 kumpf 1.1
346 // ATTN: this section is a temporary solution to populate the list of
347 // enabled provider managers for a given distribution. It includes
348 // another temporary solution for converting a generic file name into
349 // a file name useable by each platform.
350
|
351 se.gupta 1.10 #if defined(PEGASUS_ENABLE_DEFAULT_PROVIDER_MANAGER)
|
352 kumpf 1.1 if (interfaceType == "C++Default")
353 {
354 ProviderManagerContainer* pmc = new ProviderManagerContainer(
355 LIBRARY_NAME_DEFAULTPM, "DEFAULT", "C++Default",
|
356 carolann.graves 1.17 _indicationCallback, _subscriptionInitComplete);
|
357 kumpf 1.1 _providerManagerTable.append(pmc);
358 return pmc->getProviderManager();
359 }
360 #endif
361
|
362 se.gupta 1.11 #if defined(PEGASUS_ENABLE_CMPI_PROVIDER_MANAGER)
|
363 kumpf 1.1 if (interfaceType == "CMPI")
364 {
365 ProviderManagerContainer* pmc = new ProviderManagerContainer(
366 LIBRARY_NAME_CMPIPM, "CMPI", "CMPI", _indicationCallback);
367 _providerManagerTable.append(pmc);
368 return pmc->getProviderManager();
369 }
370 #endif
371
|
372 se.gupta 1.11 #if defined(PEGASUS_ENABLE_JMPI_PROVIDER_MANAGER)
|
373 kumpf 1.1 if (interfaceType == "JMPI")
374 {
375 ProviderManagerContainer* pmc = new ProviderManagerContainer(
376 LIBRARY_NAME_JMPIPM, "JMPI", "JMPI", _indicationCallback);
377 _providerManagerTable.append(pmc);
378 return pmc->getProviderManager();
379 }
380 #endif
381 // END TEMP SECTION
382 }
383
384 // Error: ProviderManager not found for the specified interface type
385 PEGASUS_ASSERT(0);
386 PEG_METHOD_EXIT();
387 return 0;
388 }
389
|
390 kumpf 1.5 Boolean BasicProviderManagerRouter::hasActiveProviders()
|
391 kumpf 1.1 {
392 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
|
393 kumpf 1.5 "BasicProviderManagerRouter::hasActiveProviders");
|
394 kumpf 1.1
|
395 kumpf 1.5 ReadLock tableLock(_providerManagerTableLock);
|
396 kumpf 1.1 for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
397 {
398 ProviderManagerContainer* pmc = _providerManagerTable[i];
|
399 kumpf 1.5 if (pmc->getProviderManager()->hasActiveProviders())
400 {
401 PEG_METHOD_EXIT();
402 return true;
403 }
404 }
405
406 PEG_METHOD_EXIT();
407 return false;
408 }
409
410 void BasicProviderManagerRouter::unloadIdleProviders()
411 {
412 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
413 "BasicProviderManagerRouter::unloadIdleProviders");
414
415 //
416 // Save pointers to the ProviderManagerContainers so we don't hold the
417 // _providerManagerTableLock while unloading idle providers
418 //
419 Array<ProviderManagerContainer*> pmcs;
420 kumpf 1.5 {
421 ReadLock tableLock(_providerManagerTableLock);
422 for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
423 {
424 pmcs.append(_providerManagerTable[i]);
425 }
426 }
427
428 //
429 // Unload idle providers in each of the active ProviderManagers
430 // _providerManagerTableLock while unloading idle providers
431 //
432 for (Uint32 i = 0; i < pmcs.size(); i++)
433 {
434 pmcs[i]->getProviderManager()->unloadIdleProviders();
|
435 kumpf 1.1 }
436
437 PEG_METHOD_EXIT();
438 }
439
440 PEGASUS_NAMESPACE_END
|