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