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