1 chip 1.1 //%/////////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000 - 2003 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
14 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 chip 1.1 //==============================================================================
23 //
24 // Author: Chip Vincent (cvincent@us.ibm.com)
25 //
26 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
27 // (carolann_graves@hp.com)
28 // Mike Day, IBM (mdday@us.ibm.com)
29 // Karl Schopmeyer(k.schopmeyer@opengroup.org) - Fix associators.
30 // Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include "ProviderManagerService.h"
35
36 #include <Pegasus/Common/Config.h>
37 #include <Pegasus/Common/Constants.h>
38 #include <Pegasus/Common/CIMMessage.h>
39 #include <Pegasus/Common/Tracer.h>
40 #include <Pegasus/Common/Logger.h>
41
42 #include <Pegasus/Common/Destroyer.h>
43 chip 1.1
44 PEGASUS_NAMESPACE_BEGIN
45
46 ProviderManagerService::ProviderManagerService(void)
47 : MessageQueueService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP)
48 {
49 }
50
51 ProviderManagerService::ProviderManagerService(ProviderRegistrationManager * providerRegistrationManager)
52 : MessageQueueService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP)
53 {
54 try
55 {
56 ProviderManagerModule module("DefaultProviderManager");
57
58 // ATTN: ensure module loaded
59 module.load();
60
61 // ATTN: ensure entry point returned valid response
62 ProviderManager * manager = module.getProviderManager("Default");
63
64 chip 1.1 // ATTN: only set the hacked/cached provider registration manager pointer after the module
65 // has loaded.
66 manager->setProviderRegistrationManager(providerRegistrationManager);
67
68 _providerManagers.append(Pair<ProviderManager *, ProviderManagerModule>(manager, module));
69 }
70 catch(...)
71 {
72 }
73 }
74
75 ProviderManagerService::~ProviderManagerService(void)
76 {
77 }
78
79 Boolean ProviderManagerService::messageOK(const Message * message)
80 {
81 PEGASUS_ASSERT(message != 0);
82
83 /*
84 Boolean rc = false;
85 chip 1.1
86 switch(message->getType())
87 {
88 case CIM_GET_INSTANCE_REQUEST_MESSAGE:
89 case CIM_ENUMERATE_INSTANCES_REQUEST_MESSAGE:
90 case CIM_ENUMERATE_INSTANCE_NAMES_REQUEST_MESSAGE:
91 case CIM_CREATE_INSTANCE_REQUEST_MESSAGE:
92 case CIM_MODIFY_INSTANCE_REQUEST_MESSAGE:
93 case CIM_DELETE_INSTANCE_REQUEST_MESSAGE:
94 case CIM_GET_PROPERTY_REQUEST_MESSAGE:
95 case CIM_SET_PROPERTY_REQUEST_MESSAGE:
96 case CIM_INVOKE_METHOD_REQUEST_MESSAGE:
97 case CIM_ENABLE_INDICATION_SUBSCRIPTION_REQUEST_MESSAGE:
98 case CIM_MODIFY_INDICATION_SUBSCRIPTION_REQUEST_MESSAGE:
99 case CIM_DISABLE_INDICATION_SUBSCRIPTION_REQUEST_MESSAGE:
100 rc = true;
101
102 break;
103 default:
104 rc = false;
105
106 chip 1.1 break;
107 }
108
109 return(rc);
110 */
111
112 return(MessageQueueService::messageOK(message));
113 }
114
115 void ProviderManagerService::handleEnqueue(void)
116 {
117 Message * message = dequeue();
118
119 handleEnqueue(message);
120 }
121
122 void ProviderManagerService::handleEnqueue(Message * message)
123 {
124 PEGASUS_ASSERT(message != 0);
125
126 //*FIXME* Markus
127 chip 1.1 // catch response messages that should never appear here
128
129 // if (message->getType() == CIM_ENUMERATE_INSTANCE_NAMES_RESPONSE_MESSAGE)
130 // abort(); // handle double provider callback !
131
132 AsyncLegacyOperationStart * asyncRequest;
133
134 if(message->_async != NULL)
135 {
136 asyncRequest = static_cast<AsyncLegacyOperationStart *>(message->_async);
137 }
138 else
139 {
140 asyncRequest = new AsyncLegacyOperationStart(
141 get_next_xid(),
142 0,
143 this->getQueueId(),
144 message,
145 this->getQueueId());
146 }
147
148 chip 1.1 _handle_async_request(asyncRequest);
149 }
150
151 void ProviderManagerService::_handle_async_request(AsyncRequest * request)
152 {
153 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
154 "ProviderManagerService::_handle_async_request");
155
156 PEGASUS_ASSERT((request != 0) && (request->op != 0));
157
158 if(request->getType() == async_messages::ASYNC_LEGACY_OP_START)
159 {
160 request->op->processing();
161
162 _incomingQueue.enqueue(request->op);
163
164 _thread_pool->allocate_and_awaken((void *)this, ProviderManagerService::handleCimOperation);
165 }
166 else
167 {
168 // pass all other operations to the default handler
169 chip 1.1 MessageQueueService::_handle_async_request(request);
170 }
171
172 PEG_METHOD_EXIT();
173
174 return;
175 }
176
177 /*
178 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL ProviderManagerService::handleServiceOperation(void * arg) throw()
179 {
180 // get the service from argument
181 ProviderManagerService * service = reinterpret_cast<ProviderManagerService *>(arg);
182
183 PEGASUS_ASSERT(service != 0);
184
185 // get message from service queue
186 Message * message = service->_incomingQueue.dequeue();
187
188 PEGASUS_ASSERT(message != 0);
189
190 chip 1.1 if(service->_incomingQueue.size() == 0)
191 {
192 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
193 "ProviderManagerService::handleCimOperation() called with no op node in queue" );
194
195 PEG_METHOD_EXIT();
196
197 // thread started with no message in queue.
198 return(PEGASUS_THREAD_RETURN(1));
199 }
200
201 AsyncOpNode * op = service->_incomingQueue.dequeue();
202
203 PEGASUS_ASSERT(op != 0 );
204
205 if(op->_request.count() == 0)
206 {
207 MessageQueue * queue = MessageQueue::lookup(op->_source_queue);
208
209 PEGASUS_ASSERT(queue != 0);
210
211 chip 1.1 PEG_METHOD_EXIT();
212
213 // no request in op node
214 return(PEGASUS_THREAD_RETURN(1));
215 }
216
217 return(0);
218 }
219 */
220
221 PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL ProviderManagerService::handleCimOperation(void * arg) throw()
222 {
223 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "ProviderManagerService::handleCimOperation");
224
225 // get the service from argument
226 ProviderManagerService * service = reinterpret_cast<ProviderManagerService *>(arg);
227
228 PEGASUS_ASSERT(service != 0);
229
230 if(service->_incomingQueue.size() == 0)
231 {
232 chip 1.1 PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
233 "ProviderManagerService::handleCimOperation() called with no op node in queue" );
234
235 PEG_METHOD_EXIT();
236
237 // thread started with no message in queue.
238 return(PEGASUS_THREAD_RETURN(1));
239 }
240
241 AsyncOpNode * op = service->_incomingQueue.dequeue();
242
243 PEGASUS_ASSERT(op != 0 );
244
245 if(op->_request.count() == 0)
246 {
247 MessageQueue * queue = MessageQueue::lookup(op->_source_queue);
248
249 PEGASUS_ASSERT(queue != 0);
250
251 PEG_METHOD_EXIT();
252
253 chip 1.1 // no request in op node
254 return(PEGASUS_THREAD_RETURN(1));
255 }
256
257 AsyncRequest * request = static_cast<AsyncRequest *>(op->_request.next(0));
258
259 PEGASUS_ASSERT(request != 0);
260
261 if(request->getType() != async_messages::ASYNC_LEGACY_OP_START)
262 {
263 // reply with NAK
264
265 PEG_METHOD_EXIT();
266
267 return(PEGASUS_THREAD_RETURN(0));
268 }
269
270 Message * legacy = static_cast<AsyncLegacyOperationStart *>(request)->get_action();
271
272 if(legacy != 0)
273 {
274 chip 1.1 Destroyer<Message> xmessage(legacy);
275
276 // Set the client's requested language into this service thread.
277 // This will allow functions in this service to return messages
278 // in the correct language.
279 CIMMessage * msg = dynamic_cast<CIMMessage *>(legacy);
280
281 if(msg != 0)
282 {
283 AcceptLanguages * langs = new AcceptLanguages(msg->acceptLanguages);
284
285 Thread::setLanguages(langs);
286 }
287 else
288 {
289 Thread::clearLanguages();
290 }
291
292 // only pass valid message types to provider managers
293 switch(legacy->getType())
294 {
295 chip 1.1 case CIM_GET_INSTANCE_REQUEST_MESSAGE:
296 case CIM_ENUMERATE_INSTANCES_REQUEST_MESSAGE:
297 case CIM_ENUMERATE_INSTANCE_NAMES_REQUEST_MESSAGE:
298 case CIM_CREATE_INSTANCE_REQUEST_MESSAGE:
299 case CIM_MODIFY_INSTANCE_REQUEST_MESSAGE:
300 case CIM_DELETE_INSTANCE_REQUEST_MESSAGE:
301 case CIM_EXEC_QUERY_REQUEST_MESSAGE:
302 case CIM_ASSOCIATORS_REQUEST_MESSAGE:
303 case CIM_ASSOCIATOR_NAMES_REQUEST_MESSAGE:
304 case CIM_REFERENCES_REQUEST_MESSAGE:
305 case CIM_REFERENCE_NAMES_REQUEST_MESSAGE:
306 case CIM_GET_PROPERTY_REQUEST_MESSAGE:
307 case CIM_SET_PROPERTY_REQUEST_MESSAGE:
308 case CIM_INVOKE_METHOD_REQUEST_MESSAGE:
309 case CIM_CREATE_SUBSCRIPTION_REQUEST_MESSAGE:
310 case CIM_MODIFY_SUBSCRIPTION_REQUEST_MESSAGE:
311 case CIM_DELETE_SUBSCRIPTION_REQUEST_MESSAGE:
312 case CIM_ENABLE_INDICATIONS_REQUEST_MESSAGE:
313 case CIM_DISABLE_INDICATIONS_REQUEST_MESSAGE:
314 case CIM_DISABLE_MODULE_REQUEST_MESSAGE:
315 case CIM_ENABLE_MODULE_REQUEST_MESSAGE:
316 chip 1.1 case CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE:
317 case CIM_CONSUME_INDICATION_REQUEST_MESSAGE:
318 service->handleCimRequest(op, legacy);
319 break;
320
321 default:
322 // unsupported messages are ignored
323 break;
324 }
325 }
326
327 PEG_METHOD_EXIT();
328
329 return(PEGASUS_THREAD_RETURN(0));
330 }
331
332 void ProviderManagerService::handleCimRequest(AsyncOpNode * op, const Message * message) throw()
333 {
334 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "ProviderManagerService::handleCimRequest");
335
336 // ATTN: ensure message is a request???
337 chip 1.1 CIMMessage * request = dynamic_cast<CIMMessage *>(const_cast<Message *>(message));
338
339 // get request from op node
340 AsyncRequest * async = static_cast<AsyncRequest *>(op->_request.next(0));
341
342 PEGASUS_ASSERT((request != 0) && (async != 0));
343
344 Message * response = 0;
345
346 // find provider manager
347 // ATTN: implement efficient lookup
348 ProviderManager * manager = _providerManagers[0].first;
349
350 try
351 {
352 // forward request
353 response = manager->processMessage(request);
354 }
355 catch(...)
356 {
357 // ATTN: create response with error message
358 chip 1.1 }
359
360 // preserve message key
361 response->setKey(request->getKey());
362
363 // set HTTP method in response from request
364 response->setHttpMethod(request->getHttpMethod());
365
366 AsyncLegacyOperationResult * async_result =
367 new AsyncLegacyOperationResult(
368 async->getKey(),
369 async->getRouting(),
370 op,
371 response);
372
373 _complete_op_node(op, ASYNC_OPSTATE_COMPLETE, 0, 0);
374
375 PEG_METHOD_EXIT();
376 }
377
378 void ProviderManagerService::unload_idle_providers(void)
379 chip 1.1 {
380 }
381
382 PEGASUS_NAMESPACE_END
|