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