1 karl 1.11 //%2005////////////////////////////////////////////////////////////////////////
|
2 schuur 1.1 //
|
3 karl 1.8 // 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 schuur 1.1 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.8 // 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.11 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 schuur 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.8 //
|
19 schuur 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: Adrain Schuur (schuur@de.ibm.com)
31 //
32 // Modified By:
|
33 a.arora 1.2 // Amit K Arora, IBM (amita@in.ibm.com) for PEP#101
|
34 se.gupta 1.3 // Seema Gupta (gseema@in.ibm.com) for PEP135
|
35 schuur 1.1 //
36 //%/////////////////////////////////////////////////////////////////////////////
37
38 #include "WQLOperationRequestDispatcher.h"
|
39 a.arora 1.2 #include <Pegasus/Common/AutoPtr.h>
|
40 schuur 1.1
41 PEGASUS_NAMESPACE_BEGIN
42
43 PEGASUS_USING_STD;
44
45
46 void WQLOperationRequestDispatcher::applyQueryToEnumeration(
47 CIMResponseMessage* msg,
48 QueryExpressionRep* query)
49 {
50 CIMEnumerateInstancesResponseMessage *enr=(CIMEnumerateInstancesResponseMessage*)msg;
51 WQLSelectStatement *qs=((WQLQueryExpressionRep*)query)->_stmt;
52
53 for (int i=enr->cimNamedInstances.size()-1; i>=0; i--) {
54 WQLInstancePropertySource ips(enr->cimNamedInstances[i]);
55 try {
56 if (qs->evaluateWhereClause(&ips)) {
57 qs->applyProjection(enr->cimNamedInstances[i]);
58 }
59 else enr->cimNamedInstances.remove(i);
60 }
61 schuur 1.1 catch (...) {
62 enr->cimNamedInstances.remove(i);
63 }
64 }
65 }
66
67
68 void WQLOperationRequestDispatcher::handleQueryResponseAggregation(
69 OperationAggregate* poA)
70 {
|
71 brian.campbell 1.10 PEG_METHOD_ENTER(TRC_DISPATCHER,
72 "CIMOperationRequestDispatcher::handleExecQueryResponse");
|
73 schuur 1.1
|
74 brian.campbell 1.10 Uint32 numberResponses = poA->numberResponses();
75 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
76 "CIMOperationRequestDispatcher::ExecQuery Response - "
77 "Name Space: $0 Class name: $1 Response Count: $2",
78 poA->_nameSpace.getString(),
79 poA->_className.getString(),
80 numberResponses);
81
82 if (numberResponses == 0)
83 return;
84
85 CIMResponseMessage *response = poA->getResponse(0);
86 CIMExecQueryResponseMessage *toResponse = 0;
87 Uint32 startIndex = 0;
88 Uint32 endIndex = numberResponses - 1;
89
90 if (response->getType() == CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE)
91 {
92 CIMRequestMessage &request = *poA->getRequest();
93 AutoPtr<CIMExecQueryResponseMessage> query
94 (new CIMExecQueryResponseMessage(request.messageId,
95 brian.campbell 1.10 CIMException(),
96 request.queueIds.copyAndPop(),
97 Array<CIMObject>()));
98 toResponse = query.release();
99 }
100 else
101 {
102 toResponse = (CIMExecQueryResponseMessage *)response;
103 startIndex = 1;
104 }
|
105 schuur 1.1
|
106 brian.campbell 1.10 // Work backward and delete each response off the end of the array
107 for(Uint32 i = endIndex; i >= startIndex; i--)
108 {
109 response = poA->getResponse(i);
110
111 if (response->getType() == CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE)
112 {
113 // convert enumerate instances responses to exec query responses
114 applyQueryToEnumeration(response, poA->_query);
115 CIMEnumerateInstancesResponseMessage *fromResponse =
116 (CIMEnumerateInstancesResponseMessage *)response;
117 CIMClass cimClass;
118
119 Boolean clsRead=false;
120 for (Uint32 j = 0,m = fromResponse->cimNamedInstances.size(); j<m; j++)
121 {
|
122 schuur 1.1 CIMObject co=CIMObject(fromResponse->cimNamedInstances[j]);
123 CIMObjectPath op=co.getPath();
|
124 brian.campbell 1.10 const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
125 if (kbs.size()==0)
126 { // no path set why ?
127 if (clsRead==false)
128 {
129 cimClass =
130 _repository->getClass(poA->_nameSpace, op.getClassName(),
131 false,true,false, CIMPropertyList());
132 clsRead=true;
133 }
134 op = fromResponse->cimNamedInstances[j].buildPath(cimClass);
|
135 schuur 1.1 }
136 op.setNameSpace(poA->_nameSpace);
137 op.setHost(System::getHostName());
138 co.setPath(op);
|
139 brian.campbell 1.10 toResponse->cimObjects.append(co);
140 }
141 }
142 else
143 {
144 CIMExecQueryResponseMessage *fromResponse =
145 (CIMExecQueryResponseMessage *)response;
146 CIMClass cimClass;
147 Boolean clsRead=false;
148 for (Uint32 j = 0, m = fromResponse->cimObjects.size(); j<m; j++)
149 {
|
150 schuur 1.1 CIMObject co=fromResponse->cimObjects[j];
151 CIMObjectPath op=co.getPath();
|
152 brian.campbell 1.10 const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
153 if (kbs.size()==0)
154 { // no path set why ?
155 if (clsRead==false)
156 {
157 cimClass =
158 _repository->getClass(poA->_nameSpace,op.getClassName(),
159 false,true,false, CIMPropertyList());
160 clsRead=true;
161 }
162 op=CIMInstance(fromResponse->cimObjects[j]).buildPath(cimClass);
|
163 schuur 1.1 }
164 op.setNameSpace(poA->_nameSpace);
165 op.setHost(System::getHostName());
166 co.setPath(op);
|
167 brian.campbell 1.10 toResponse->cimObjects.append(co);
168 }
169 }
170
171 poA->deleteResponse(i);
172 if (i == 0)
173 break;
174 } // for all responses in response list
175
176 // if we started with an enumerateInstances repsonse, then add it to overall
177 if (startIndex == 0)
178 poA->appendResponse(toResponse);
179
180 PEG_METHOD_EXIT();
|
181 schuur 1.1 }
182
183
184
185 void WQLOperationRequestDispatcher::handleQueryRequest(
186 CIMExecQueryRequestMessage* request)
187 {
188 Boolean exception=false;
|
189 a.arora 1.2 AutoPtr<WQLSelectStatement> selectStatement(new WQLSelectStatement());
190 AutoPtr<WQLQueryExpressionRep> qx;
|
191 schuur 1.1 CIMException cimException;
192 CIMName className;
193
194 //if (getenv("CMPI_DEBUG")) asm("int $3");
195 PEG_METHOD_ENTER(TRC_DISPATCHER,
196 "CIMOperationRequestDispatcher::handleExecQueryRequest");
197
198 if (request->queryLanguage!="WQL") {
199 cimException =
200 PEGASUS_CIM_EXCEPTION(CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED, request->queryLanguage);
201 exception=true;
202 }
203 else {
204 try {
|
205 a.arora 1.2 WQLParser::parse(request->query, *selectStatement.get());
|
206 schuur 1.1 className=selectStatement->getClassName();
|
207 a.arora 1.2 qx.reset(new WQLQueryExpressionRep("WQL",selectStatement.get()));
|
208 a.dunfey 1.7 selectStatement.release();
|
209 schuur 1.1 }
|
210 brian.campbell 1.9 catch (ParseError&) {
|
211 schuur 1.1 cimException =
212 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
213 exception=true;
214 }
|
215 brian.campbell 1.9 catch (MissingNullTerminator&) {
|
216 schuur 1.1 cimException =
217 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
218 exception=true;
219 }
220
221 if (exception==false) {
222 _checkExistenceOfClass(request->nameSpace,
223 className,
224 cimException);
225 if (cimException.getCode() != CIM_ERR_SUCCESS)
226 exception=true;
227 }
228 }
229
230 if (exception) {
231 Array<CIMObject> cimObjects;
232
|
233 a.arora 1.2 AutoPtr<CIMExecQueryResponseMessage> response(
|
234 schuur 1.1 new CIMExecQueryResponseMessage(
235 request->messageId,
236 cimException,
237 request->queueIds.copyAndPop(),
|
238 a.arora 1.2 cimObjects));
|
239 schuur 1.1
240 STAT_COPYDISPATCHER_REP
|
241 a.arora 1.2 _enqueueResponse(request, response.release());
|
242 schuur 1.1 PEG_METHOD_EXIT();
243 return;
244 }
245
246 //
247 // Get names of descendent classes:
248 //
249 Array<ProviderInfo> providerInfos;
250
251 // This gets set by _lookupAllInstanceProviders()
252 Uint32 providerCount;
253
254 try {
255 providerInfos = _lookupAllInstanceProviders(request->nameSpace,
256 className,
257 // request->className,
258 providerCount,
259 true);
260 }
261 catch(CIMException& exception) {
262 // Return exception response if exception from getSubClasses
263 schuur 1.1 cimException = exception;
|
264 a.arora 1.2 AutoPtr<CIMExecQueryResponseMessage> response(
|
265 schuur 1.1 new CIMExecQueryResponseMessage(request->messageId,
266 cimException,
267 request->queueIds.copyAndPop(),
|
268 a.arora 1.2 Array<CIMObject>()));
|
269 schuur 1.1
|
270 w.white 1.5 STAT_COPYDISPATCHER_REP
271
|
272 a.arora 1.2 _enqueueResponse(request, response.release());
|
273 schuur 1.1 PEG_METHOD_EXIT();
274 return;
275 }
276
277 // Test for "enumerate too Broad" and if so, execute exception.
278 // This limits the number of provider invocations, not the number
279 // of instances returned.
280 if(providerCount > _maximumEnumerateBreadth)
281 {
282 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
283 "Request-too-broad exception. Namespace: $0 "
284 "Class Name: $1 Limit: $2 ProviderCount: $3",
285 request->nameSpace.getString(),
286 request->className.getString(),
287 _maximumEnumerateBreadth, providerCount);
288
289 PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4,
290 Formatter::format("ERROR Enumerate too broad for class $0. "
291 "Limit = $1, Request = $2",
292 request->className.getString(),
293 _maximumEnumerateBreadth,
294 schuur 1.1 providerCount));
295
296 // l10n
297
|
298 a.arora 1.2 AutoPtr<CIMExecQueryResponseMessage> response(
|
299 schuur 1.1 new CIMExecQueryResponseMessage(request->messageId,
300 PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
301 MessageLoaderParms("Server.CIMOperationRequestDispatcher."
302 "QUERY_REQ_TOO_BROAD", "Query request too Broad")),
303 request->queueIds.copyAndPop(),
|
304 a.arora 1.2 Array<CIMObject>()));
|
305 schuur 1.1
306 STAT_COPYDISPATCHER
307
|
308 a.arora 1.2 _enqueueResponse(request, response.release());
|
309 schuur 1.1 PEG_METHOD_EXIT();
310 return;
311 }
312
313 // If no provider is registered and the repository isn't the default,
314 // return CIM_ERR_NOT_SUPPORTED
315 if ((providerCount == 0) && !(_repository->isDefaultInstanceProvider()))
316 {
317 PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4,
318 "CIM_ERROR_NOT_SUPPORTED for " + request->className.getString());
319
|
320 a.arora 1.2 AutoPtr<CIMExecQueryResponseMessage> response(
|
321 schuur 1.1 new CIMExecQueryResponseMessage(request->messageId,
322 PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY),
323 request->queueIds.copyAndPop(),
|
324 a.arora 1.2 Array<CIMObject>()));
|
325 schuur 1.1
326 STAT_COPYDISPATCHER
327
|
328 a.arora 1.2 _enqueueResponse(request, response.release());
|
329 schuur 1.1 PEG_METHOD_EXIT();
330 return;
331 }
332
333 // We have instances for Providers and possibly repository.
334 // Set up an aggregate object and save a copy of the original request.
335
336 OperationAggregate *poA= new OperationAggregate(
337 new CIMExecQueryRequestMessage(*request),
338 request->getType(),
339 request->messageId,
340 request->queueIds.top(),
|
341 brian.campbell 1.9 className, CIMNamespaceName(),
|
342 a.arora 1.2 qx.release(),
|
343 schuur 1.1 "WQL");
344
345 // Set the number of expected responses in the OperationAggregate
346 Uint32 numClasses = providerInfos.size();
347 poA->_aggregationSN = cimOperationAggregationSN++;
348 poA->_nameSpace=request->nameSpace;
349
350 if (_repository->isDefaultInstanceProvider())
|
351 brian.campbell 1.10 {
352 // Loop through providerInfos, forwarding requests to repository
353 for (Uint32 i = 0; i < numClasses; i++)
354 {
355 ProviderInfo &providerInfo = providerInfos[i];
356
357 // this class is registered to a provider - skip
358 if (providerInfo.hasProvider)
359 continue;
360
361 // If this class does not have a provider
362
363 PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4, Formatter::format
364 ("ExcecQuery Req. class $0 to repository, "
365 "No $1 of $2, SN $3",
366 providerInfo.className.getString(),
367 i, numClasses, poA->_aggregationSN));
368
369 CIMException cimException;
370 Array<CIMInstance> cimInstances;
371 STAT_PROVIDERSTART
372 brian.campbell 1.10
373 try
374 {
375 // Enumerate instances only for this class
376 cimInstances =
377 _repository->enumerateInstancesForClass(
378 request->nameSpace,
379 providerInfo.className,
380 false);
381 }
382 catch(CIMException& exception)
383 {
384 cimException = exception;
385 }
386 catch(Exception& exception)
387 {
388 cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
389 exception.getMessage());
390 }
391 catch(...)
392 {
393 brian.campbell 1.10 cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
394 String::EMPTY);
395 }
396
397 STAT_PROVIDEREND
398
399 AutoPtr<CIMEnumerateInstancesResponseMessage> response
400 (new CIMEnumerateInstancesResponseMessage
401 (request->messageId, cimException, request->queueIds.copyAndPop(),
402 cimInstances));
403
404 STAT_COPYDISPATCHER_REP
405
406 poA->appendResponse(response.release());
407 } // for all classes and derived classes
408
409 Uint32 numberResponses = poA->numberResponses();
410 Uint32 totalIssued = providerCount + (numberResponses > 0 ? 1 : 0);
411 poA->setTotalIssued(totalIssued);
412
413 if (numberResponses > 0)
414 brian.campbell 1.10 {
415 handleEnumerateInstancesResponseAggregation(poA);
416 CIMResponseMessage *response = poA->removeResponse(0);
417 _forwardRequestForAggregation(String(PEGASUS_QUEUENAME_OPREQDISPATCHER),
418 String(),
419 new CIMExecQueryRequestMessage(*request),
420 poA, response);
421 }
422 } // if isDefaultInstanceProvider
423 else
424 {
425 // Set the number of expected responses in the OperationAggregate
426 poA->setTotalIssued(providerCount);
427 }
|
428 schuur 1.1
429 // Loop through providerInfos, forwarding requests to providers
430 for (Uint32 i = 0; i < numClasses; i++)
431 {
432 // If this class has a provider
|
433 brian.campbell 1.10 ProviderInfo &providerInfo = providerInfos[i];
|
434 schuur 1.1
|
435 brian.campbell 1.10 // this class is NOT registered to a provider - skip
436 if (! providerInfo.hasProvider)
437 continue;
438
439 STAT_PROVIDERSTART
440
441 PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4, Formatter::format
442 ("Query Req. class $0 to svc \"$1\" for "
443 "control provider \"$2\", No $3 of $4, SN $5",
444 providerInfo.className.getString(),
445 providerInfo.serviceName,
446 providerInfo.controlProviderName,
447 i, numClasses, poA->_aggregationSN));
448
449 ProviderIdContainer *providerIdContainer =
450 providerInfo.providerIdContainer.get();
451
452 if (providerInfo.hasNoQuery && providerIdContainer)
453 {
454 OperationContext *context = &request->operationContext;
455 const OperationContext::Container *container = 0;
456 brian.campbell 1.10 container = &context->get(IdentityContainer::NAME);
457 const IdentityContainer &identityContainer =
458 dynamic_cast<const IdentityContainer &>(*container);
459
460 CIMEnumerateInstancesRequestMessage *enumReq = new
461 CIMEnumerateInstancesRequestMessage(request->messageId,
462 request->nameSpace,
463 providerInfo.className,
464 false,false,false,false,
465 CIMPropertyList(),
466 request->queueIds,
467 request->authType,
468 identityContainer.getUserName());
469
470 context = &enumReq->operationContext;
471 context->insert(*providerIdContainer);
472 context->insert(identityContainer);
473 _forwardRequestForAggregation(providerInfo.serviceName,
474 providerInfo.controlProviderName,
475 enumReq, poA);
476 }
477 brian.campbell 1.10 else
478 {
479 AutoPtr<CIMExecQueryRequestMessage> requestCopy
480 (new CIMExecQueryRequestMessage(*request));
481
482 requestCopy->className = providerInfo.className;
483
484 _forwardRequestForAggregation(providerInfo.serviceName,
485 providerInfo.controlProviderName,
486 requestCopy.release(), poA);
|
487 schuur 1.1 }
|
488 brian.campbell 1.10
489 STAT_PROVIDEREND
|
490 schuur 1.1
|
491 brian.campbell 1.10 } // for all classes and derived classes
|
492 schuur 1.1
493 PEG_METHOD_EXIT();
|
494 brian.campbell 1.10 return;
|
495 schuur 1.1 }
496
497
498 PEGASUS_NAMESPACE_END
499
|