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