1 karl 1.19 //%2006////////////////////////////////////////////////////////////////////////
|
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 karl 1.19 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 schuur 1.1 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.19 //
|
21 schuur 1.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #include "WQLOperationRequestDispatcher.h"
|
35 a.arora 1.2 #include <Pegasus/Common/AutoPtr.h>
|
36 kumpf 1.20 #include <Pegasus/Common/StatisticalData.h>
|
37 schuur 1.1
38 PEGASUS_NAMESPACE_BEGIN
39
40 PEGASUS_USING_STD;
41
42
43 void WQLOperationRequestDispatcher::applyQueryToEnumeration(
44 CIMResponseMessage* msg,
45 QueryExpressionRep* query)
46 {
47 CIMEnumerateInstancesResponseMessage *enr=(CIMEnumerateInstancesResponseMessage*)msg;
48 WQLSelectStatement *qs=((WQLQueryExpressionRep*)query)->_stmt;
49
50 for (int i=enr->cimNamedInstances.size()-1; i>=0; i--) {
51 WQLInstancePropertySource ips(enr->cimNamedInstances[i]);
52 try {
|
53 carolann.graves 1.16 if (qs->evaluateWhereClause(&ips))
54 {
55 //
56 // Specify that missing requested project properties are allowed
57 // to be consistent with clarification from DMTF
58 //
59 qs->applyProjection(enr->cimNamedInstances[i], true);
|
60 schuur 1.1 }
61 else enr->cimNamedInstances.remove(i);
62 }
63 catch (...) {
64 enr->cimNamedInstances.remove(i);
65 }
66 }
67 }
68
69
70 void WQLOperationRequestDispatcher::handleQueryResponseAggregation(
71 OperationAggregate* poA)
72 {
|
73 brian.campbell 1.10 PEG_METHOD_ENTER(TRC_DISPATCHER,
74 "CIMOperationRequestDispatcher::handleExecQueryResponse");
|
75 schuur 1.1
|
76 brian.campbell 1.10 Uint32 numberResponses = poA->numberResponses();
77 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
78 "CIMOperationRequestDispatcher::ExecQuery Response - "
79 "Name Space: $0 Class name: $1 Response Count: $2",
80 poA->_nameSpace.getString(),
81 poA->_className.getString(),
82 numberResponses);
83
84 if (numberResponses == 0)
85 return;
86
87 CIMResponseMessage *response = poA->getResponse(0);
88 CIMExecQueryResponseMessage *toResponse = 0;
89 Uint32 startIndex = 0;
90 Uint32 endIndex = numberResponses - 1;
|
91 konrad.r 1.14 Boolean manyResponses = true;
|
92 brian.campbell 1.10 if (response->getType() == CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE)
93 {
|
94 kumpf 1.21 CIMRequestMessage* request = poA->getRequest();
95 AutoPtr<CIMExecQueryResponseMessage> query(
96 new CIMExecQueryResponseMessage(request->messageId,
|
97 aruran.ms 1.17 CIMException(),
|
98 kumpf 1.21 request->queueIds.copyAndPop(),
|
99 aruran.ms 1.17 Array<CIMObject>()));
|
100 kumpf 1.21 query->syncAttributes(request);
|
101 aruran.ms 1.17 toResponse = query.release();
|
102 brian.campbell 1.10 }
103 else
104 {
105 toResponse = (CIMExecQueryResponseMessage *)response;
|
106 konrad.r 1.14 manyResponses = false;
|
107 brian.campbell 1.10 }
|
108 schuur 1.1
|
109 brian.campbell 1.10 // Work backward and delete each response off the end of the array
110 for(Uint32 i = endIndex; i >= startIndex; i--)
111 {
|
112 konrad.r 1.14 if (manyResponses)
113 response = poA->getResponse(i);
|
114 brian.campbell 1.10
115 if (response->getType() == CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE)
116 {
117 // convert enumerate instances responses to exec query responses
118 applyQueryToEnumeration(response, poA->_query);
119 CIMEnumerateInstancesResponseMessage *fromResponse =
120 (CIMEnumerateInstancesResponseMessage *)response;
121 CIMClass cimClass;
122
123 Boolean clsRead=false;
124 for (Uint32 j = 0,m = fromResponse->cimNamedInstances.size(); j<m; j++)
125 {
|
126 schuur 1.1 CIMObject co=CIMObject(fromResponse->cimNamedInstances[j]);
127 CIMObjectPath op=co.getPath();
|
128 brian.campbell 1.10 const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
129 if (kbs.size()==0)
130 { // no path set why ?
131 if (clsRead==false)
132 {
|
133 chip 1.12 cimClass =
|
134 brian.campbell 1.10 _repository->getClass(poA->_nameSpace, op.getClassName(),
135 false,true,false, CIMPropertyList());
136 clsRead=true;
137 }
|
138 chip 1.12 op = fromResponse->cimNamedInstances[j].buildPath(cimClass);
|
139 schuur 1.1 }
140 op.setNameSpace(poA->_nameSpace);
141 op.setHost(System::getHostName());
142 co.setPath(op);
|
143 konrad.r 1.14 if (manyResponses)
|
144 brian.campbell 1.10 toResponse->cimObjects.append(co);
145 }
146 }
147 else
148 {
149 CIMExecQueryResponseMessage *fromResponse =
150 (CIMExecQueryResponseMessage *)response;
151 CIMClass cimClass;
152 Boolean clsRead=false;
153 for (Uint32 j = 0, m = fromResponse->cimObjects.size(); j<m; j++)
154 {
|
155 schuur 1.1 CIMObject co=fromResponse->cimObjects[j];
156 CIMObjectPath op=co.getPath();
|
157 brian.campbell 1.10 const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
158 if (kbs.size()==0)
159 { // no path set why ?
160 if (clsRead==false)
161 {
|
162 chip 1.12 cimClass =
|
163 brian.campbell 1.10 _repository->getClass(poA->_nameSpace,op.getClassName(),
164 false,true,false, CIMPropertyList());
165 clsRead=true;
166 }
|
167 chip 1.12 op=CIMInstance(fromResponse->cimObjects[j]).buildPath(cimClass);
|
168 schuur 1.1 }
169 op.setNameSpace(poA->_nameSpace);
170 op.setHost(System::getHostName());
171 co.setPath(op);
|
172 konrad.r 1.14 if (manyResponses)
|
173 brian.campbell 1.10 toResponse->cimObjects.append(co);
174 }
175 }
|
176 konrad.r 1.14 if (manyResponses)
177 poA->deleteResponse(i);
|
178 brian.campbell 1.10 if (i == 0)
179 break;
180 } // for all responses in response list
181
182 // if we started with an enumerateInstances repsonse, then add it to overall
|
183 konrad.r 1.14 if ((startIndex == 0) && manyResponses)
|
184 brian.campbell 1.10 poA->appendResponse(toResponse);
185
186 PEG_METHOD_EXIT();
|
187 schuur 1.1 }
188
189
190
191 void WQLOperationRequestDispatcher::handleQueryRequest(
192 CIMExecQueryRequestMessage* request)
193 {
|
194 kumpf 1.21 PEG_METHOD_ENTER(TRC_DISPATCHER,
195 "CIMOperationRequestDispatcher::handleExecQueryRequest");
196
|
197 schuur 1.1 Boolean exception=false;
|
198 a.arora 1.2 AutoPtr<WQLSelectStatement> selectStatement(new WQLSelectStatement());
199 AutoPtr<WQLQueryExpressionRep> qx;
|
200 schuur 1.1 CIMException cimException;
201 CIMName className;
202
203 if (request->queryLanguage!="WQL") {
204 cimException =
205 PEGASUS_CIM_EXCEPTION(CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED, request->queryLanguage);
206 exception=true;
207 }
208 else {
209 try {
|
210 a.arora 1.2 WQLParser::parse(request->query, *selectStatement.get());
|
211 schuur 1.1 className=selectStatement->getClassName();
|
212 a.arora 1.2 qx.reset(new WQLQueryExpressionRep("WQL",selectStatement.get()));
|
213 a.dunfey 1.7 selectStatement.release();
|
214 schuur 1.1 }
|
215 brian.campbell 1.9 catch (ParseError&) {
|
216 schuur 1.1 cimException =
217 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
218 exception=true;
219 }
|
220 brian.campbell 1.9 catch (MissingNullTerminator&) {
|
221 schuur 1.1 cimException =
222 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
223 exception=true;
224 }
225
226 if (exception==false) {
227 _checkExistenceOfClass(request->nameSpace,
228 className,
229 cimException);
230 if (cimException.getCode() != CIM_ERR_SUCCESS)
231 exception=true;
232 }
233 }
234
|
235 kumpf 1.21 if (exception)
236 {
237 CIMResponseMessage* response = request->buildResponse();
238 response->cimException = cimException;
|
239 schuur 1.1
|
240 kumpf 1.21 _enqueueResponse(request, response);
|
241 schuur 1.1 PEG_METHOD_EXIT();
242 return;
243 }
244
245 //
246 // Get names of descendent classes:
247 //
248 Array<ProviderInfo> providerInfos;
249
250 // This gets set by _lookupAllInstanceProviders()
251 Uint32 providerCount;
252
253 try {
|
254 chip 1.12 providerInfos =
255 _lookupAllInstanceProviders(
256 request->nameSpace,
257 className,
258 providerCount);
|
259 schuur 1.1 }
260 catch(CIMException& exception) {
261 // Return exception response if exception from getSubClasses
|
262 kumpf 1.21 CIMResponseMessage* response = request->buildResponse();
263 response->cimException = exception;
|
264 schuur 1.1
|
265 kumpf 1.21 _enqueueResponse(request, response);
|
266 schuur 1.1 PEG_METHOD_EXIT();
267 return;
268 }
269
270 // Test for "enumerate too Broad" and if so, execute exception.
271 // This limits the number of provider invocations, not the number
272 // of instances returned.
273 if(providerCount > _maximumEnumerateBreadth)
274 {
275 Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
276 "Request-too-broad exception. Namespace: $0 "
277 "Class Name: $1 Limit: $2 ProviderCount: $3",
278 request->nameSpace.getString(),
279 request->className.getString(),
280 _maximumEnumerateBreadth, providerCount);
281
282 PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4,
283 Formatter::format("ERROR Enumerate too broad for class $0. "
284 "Limit = $1, Request = $2",
285 request->className.getString(),
286 _maximumEnumerateBreadth,
287 schuur 1.1 providerCount));
288
|
289 kumpf 1.21 CIMResponseMessage* response = request->buildResponse();
290 response->cimException =
291 PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED, MessageLoaderParms(
292 "Server.CIMOperationRequestDispatcher.QUERY_REQ_TOO_BROAD",
293 "Query request too Broad"));
|
294 schuur 1.1
|
295 kumpf 1.21 _enqueueResponse(request, response);
|
296 schuur 1.1 PEG_METHOD_EXIT();
297 return;
298 }
299
300 // If no provider is registered and the repository isn't the default,
301 // return CIM_ERR_NOT_SUPPORTED
302 if ((providerCount == 0) && !(_repository->isDefaultInstanceProvider()))
303 {
304 PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4,
305 "CIM_ERROR_NOT_SUPPORTED for " + request->className.getString());
306
|
307 kumpf 1.21 CIMResponseMessage* response = request->buildResponse();
308 response->cimException =
309 PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY);
|
310 schuur 1.1
|
311 kumpf 1.21 _enqueueResponse(request, response);
312 PEG_METHOD_EXIT();
|
313 schuur 1.1 return;
314 }
315
316 // We have instances for Providers and possibly repository.
317 // Set up an aggregate object and save a copy of the original request.
318
319 OperationAggregate *poA= new OperationAggregate(
320 new CIMExecQueryRequestMessage(*request),
321 request->getType(),
322 request->messageId,
323 request->queueIds.top(),
|
324 brian.campbell 1.9 className, CIMNamespaceName(),
|
325 a.arora 1.2 qx.release(),
|
326 schuur 1.1 "WQL");
327
328 // Set the number of expected responses in the OperationAggregate
329 Uint32 numClasses = providerInfos.size();
330 poA->_aggregationSN = cimOperationAggregationSN++;
331 poA->_nameSpace=request->nameSpace;
332
333 if (_repository->isDefaultInstanceProvider())
|
334 brian.campbell 1.10 {
335 // Loop through providerInfos, forwarding requests to repository
336 for (Uint32 i = 0; i < numClasses; i++)
337 {
338 ProviderInfo &providerInfo = providerInfos[i];
|
339 chip 1.12
|
340 brian.campbell 1.10 // this class is registered to a provider - skip
341 if (providerInfo.hasProvider)
342 continue;
343
344 // If this class does not have a provider
|
345 chip 1.12
|
346 brian.campbell 1.10 PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4, Formatter::format
347 ("ExcecQuery Req. class $0 to repository, "
348 "No $1 of $2, SN $3",
349 providerInfo.className.getString(),
350 i, numClasses, poA->_aggregationSN));
|
351 chip 1.12
|
352 kumpf 1.21 AutoPtr<CIMEnumerateInstancesResponseMessage> response(
|
353 kumpf 1.22 new CIMEnumerateInstancesResponseMessage(
354 request->messageId,
355 CIMException(),
356 request->queueIds.copyAndPop(),
357 Array<CIMInstance>()));
358 response->syncAttributes(request);
|
359 brian.campbell 1.10
360 try
361 {
362 // Enumerate instances only for this class
|
363 kumpf 1.21 response->cimNamedInstances =
|
364 brian.campbell 1.10 _repository->enumerateInstancesForClass(
|
365 kumpf 1.23 request->nameSpace,
366 providerInfo.className);
|
367 brian.campbell 1.10 }
368 catch(CIMException& exception)
369 {
|
370 kumpf 1.21 response->cimException = exception;
|
371 brian.campbell 1.10 }
372 catch(Exception& exception)
373 {
|
374 kumpf 1.21 response->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
|
375 brian.campbell 1.10 exception.getMessage());
376 }
377 catch(...)
378 {
|
379 kumpf 1.21 response->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
|
380 brian.campbell 1.10 String::EMPTY);
381 }
|
382 chip 1.12
|
383 brian.campbell 1.10 poA->appendResponse(response.release());
384 } // for all classes and derived classes
385
386 Uint32 numberResponses = poA->numberResponses();
387 Uint32 totalIssued = providerCount + (numberResponses > 0 ? 1 : 0);
388 poA->setTotalIssued(totalIssued);
|
389 chip 1.12
|
390 brian.campbell 1.10 if (numberResponses > 0)
391 {
392 handleEnumerateInstancesResponseAggregation(poA);
393 CIMResponseMessage *response = poA->removeResponse(0);
394 _forwardRequestForAggregation(String(PEGASUS_QUEUENAME_OPREQDISPATCHER),
|
395 chip 1.12 String(),
|
396 brian.campbell 1.10 new CIMExecQueryRequestMessage(*request),
397 poA, response);
398 }
399 } // if isDefaultInstanceProvider
400 else
401 {
402 // Set the number of expected responses in the OperationAggregate
403 poA->setTotalIssued(providerCount);
404 }
|
405 schuur 1.1
406 // Loop through providerInfos, forwarding requests to providers
407 for (Uint32 i = 0; i < numClasses; i++)
408 {
409 // If this class has a provider
|
410 brian.campbell 1.10 ProviderInfo &providerInfo = providerInfos[i];
|
411 schuur 1.1
|
412 brian.campbell 1.10 // this class is NOT registered to a provider - skip
413 if (! providerInfo.hasProvider)
414 continue;
415
416 PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4, Formatter::format
417 ("Query Req. class $0 to svc \"$1\" for "
418 "control provider \"$2\", No $3 of $4, SN $5",
419 providerInfo.className.getString(),
420 providerInfo.serviceName,
421 providerInfo.controlProviderName,
422 i, numClasses, poA->_aggregationSN));
|
423 chip 1.12
424 ProviderIdContainer *providerIdContainer =
|
425 brian.campbell 1.10 providerInfo.providerIdContainer.get();
426
|
427 konrad.r 1.13 if (providerInfo.hasNoQuery)
|
428 brian.campbell 1.10 {
429 OperationContext *context = &request->operationContext;
430 const OperationContext::Container *container = 0;
431 container = &context->get(IdentityContainer::NAME);
|
432 chip 1.12 const IdentityContainer &identityContainer =
|
433 brian.campbell 1.10 dynamic_cast<const IdentityContainer &>(*container);
434
|
435 konrad.r 1.14 AutoPtr<CIMEnumerateInstancesRequestMessage> enumReq
436 (new CIMEnumerateInstancesRequestMessage(request->messageId,
|
437 brian.campbell 1.10 request->nameSpace,
438 providerInfo.className,
439 false,false,false,false,
440 CIMPropertyList(),
441 request->queueIds,
442 request->authType,
|
443 konrad.r 1.14 identityContainer.getUserName()));
|
444 chip 1.12
|
445 brian.campbell 1.10 context = &enumReq->operationContext;
|
446 konrad.r 1.13 if (providerIdContainer)
447 context->insert(*providerIdContainer);
|
448 brian.campbell 1.10 context->insert(identityContainer);
449 _forwardRequestForAggregation(providerInfo.serviceName,
450 providerInfo.controlProviderName,
|
451 konrad.r 1.14 enumReq.release(), poA);
|
452 brian.campbell 1.10 }
453 else
454 {
455 AutoPtr<CIMExecQueryRequestMessage> requestCopy
456 (new CIMExecQueryRequestMessage(*request));
457
|
458 konrad.r 1.14 OperationContext *context = &request->operationContext;
459 if (providerIdContainer)
460 context->insert(*providerIdContainer);
461
462 requestCopy->operationContext = *context;
|
463 brian.campbell 1.10 requestCopy->className = providerInfo.className;
|
464 konrad.r 1.14
|
465 brian.campbell 1.10 _forwardRequestForAggregation(providerInfo.serviceName,
466 providerInfo.controlProviderName,
467 requestCopy.release(), poA);
|
468 schuur 1.1 }
|
469 chip 1.12
|
470 brian.campbell 1.10 } // for all classes and derived classes
|
471 schuur 1.1
472 PEG_METHOD_EXIT();
|
473 brian.campbell 1.10 return;
|
474 schuur 1.1 }
475
476
477 PEGASUS_NAMESPACE_END
478
|