1 xinf.zhao 1.1 //%LICENSE////////////////////////////////////////////////////////////////
2 //
3 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 xinf.zhao 1.1 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 //%////////////////////////////////////////////////////////////////////////////
29
30
31 #include "CQLOperationRequestDispatcher.h"
32
33 #include <Pegasus/Common/AutoPtr.h>
34 #include <Pegasus/Common/QueryExpressionRep.h>
35 #include <Pegasus/Common/StatisticalData.h>
36 #include <Pegasus/Provider/CIMOMHandleQueryContext.h>
37
38 PEGASUS_NAMESPACE_BEGIN
39
40 PEGASUS_USING_STD;
41
42 void CQLOperationRequestDispatcher::applyQueryToEnumeration(
43 xinf.zhao 1.1 CIMResponseMessage* msg,
44 QueryExpressionRep* query)
45 {
46 PEG_METHOD_ENTER(TRC_DISPATCHER,
47 "CQLOperationRequestDispatcher::applyQueryToEnumeration");
48
49 CIMEnumerateInstancesResponseMessage* enr =
50 (CIMEnumerateInstancesResponseMessage*) msg;
51 CQLSelectStatement* qs = ((CQLQueryExpressionRep*)query)->_stmt;
52
53 Array<CIMInstance>& a = enr->getResponseData().getInstances();
54
55 for (int i = a.size() - 1; i >= 0; i--)
56 {
57 try
58 {
59 if (qs->evaluate(a[i]))
60 {
61 //
62 // Specify that missing requested project properties are
63 // allowed to be consistent with clarification from DMTF
64 xinf.zhao 1.1 qs->applyProjection(a[i], true);
65 }
66 else
67 {
68 a.remove(i);
69 }
70 }
71 catch (...)
72 {
73 a.remove(i);
74 }
75 }
76 PEG_METHOD_EXIT();
77 }
78
79 void CQLOperationRequestDispatcher::handleQueryRequest(
80 CIMExecQueryRequestMessage* request)
81 {
82 PEG_METHOD_ENTER(TRC_DISPATCHER,
83 "CQLOperationRequestDispatcher::handleQueryRequest");
84 Boolean exception=false;
85 xinf.zhao 1.1
86 CIMOMHandle _ch;
87 CIMOMHandleQueryContext _queryOrig(request->nameSpace,_ch);
88
89 AutoPtr<CQLSelectStatement> selectStatement(
90 new CQLSelectStatement(request->queryLanguage,
91 request->query,
92 _queryOrig));
93
94 AutoPtr<CQLQueryExpressionRep> qx;
95 CIMException cimException;
96 CIMName className;
97
98 if (request->queryLanguage != "DMTF:CQL")
99 {
100 cimException = PEGASUS_CIM_EXCEPTION(
101 CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED, request->queryLanguage);
102 exception=true;
103 }
104 else
105 {
106 xinf.zhao 1.1 try
107 {
108 CQLParser::parse(request->query, *selectStatement.get());
109
110 Array<CIMObjectPath> classPath =
111 selectStatement->getClassPathList();
112 className = classPath[0].getClassName();
113 qx.reset(
114 new CQLQueryExpressionRep("DMTF:CQL", selectStatement.get()));
115 selectStatement.release();
116 }
117 catch (ParseError&)
118 {
119 cimException =
120 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
121 exception=true;
122 }
123 catch (MissingNullTerminator&)
124 {
125 cimException =
126 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
127 xinf.zhao 1.1 exception = true;
128 }
129
130 if (exception == false)
131 {
132 if (!_checkExistenceOfClass(request->nameSpace, className))
133 {
134 cimException = PEGASUS_CIM_EXCEPTION(
135 CIM_ERR_INVALID_CLASS, className.getString());
136 exception = true;
137 }
138 }
139 }
140
141 if (exception)
142 {
143 CIMResponseMessage* response = request->buildResponse();
144 response->cimException = cimException;
145
146 _enqueueResponse(request, response);
147 PEG_METHOD_EXIT();
148 xinf.zhao 1.1 return;
149 }
150
151 // Get names of descendent classes:
|
152 karl 1.5 ProviderInfoList providerInfos;
|
153 xinf.zhao 1.1
|
154 karl 1.5 // This exception should not be required or we should apply for
155 // all _lookupInstanceProvider Calls.
|
156 xinf.zhao 1.1
157 try
158 {
|
159 karl 1.4 providerInfos = _lookupAllInstanceProviders(
|
160 xinf.zhao 1.1 request->nameSpace,
|
161 karl 1.5 className);
|
162 xinf.zhao 1.1 }
163 catch (CIMException& e)
164 {
165 // Return exception response if exception from getSubClasses
166 CIMResponseMessage* response = request->buildResponse();
167 response->cimException = e;
168
169 _enqueueResponse(request, response);
170 PEG_METHOD_EXIT();
171 return;
172 }
173
174 // If no provider is registered and the repository isn't the default,
175 // return CIM_ERR_NOT_SUPPORTED
|
176 karl 1.5
177 if (_rejectNoProvidersOrRepository(request,
178 providerInfos.providerCount,
179 className))
|
180 xinf.zhao 1.1 {
181 PEG_METHOD_EXIT();
182 return;
183 }
184
185 // We have instances for Providers and possibly repository.
186 // Set up an aggregate object and save a copy of the original request.
187
188 OperationAggregate* poA= new OperationAggregate(
189 new CIMExecQueryRequestMessage(*request),
190 request->getType(),
191 request->messageId,
192 request->queueIds.top(),
193 className, CIMNamespaceName(),
194 qx.release(),
195 "DMTF:CQL");
196
197 // Set the number of expected responses in the OperationAggregate
198 Uint32 numClasses = providerInfos.size();
199 poA->_nameSpace=request->nameSpace;
200 if (_repository->isDefaultInstanceProvider())
201 xinf.zhao 1.1 {
202 // Loop through providerInfos, forwarding requests to repository
203 for (Uint32 i = 0; i < numClasses; i++)
204 {
205 ProviderInfo& providerInfo = providerInfos[i];
206
207 // this class is registered to a provider - skip
208 if (providerInfo.hasProvider)
|
209 karl 1.4 {
|
210 xinf.zhao 1.1 continue;
|
211 karl 1.4 }
|
212 xinf.zhao 1.1
213 // If this class does not have a provider
214
215 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
216 "Routing ExecQuery request for class %s to the "
|
217 karl 1.4 "repository. Class # %u of %u",
218 CSTRING(providerInfo.className.getString()),
219 (i + 1),
220 numClasses ));
|
221 xinf.zhao 1.1
222 // Create an EnumerateInstances response from an ExecQuery request
223 AutoPtr<CIMEnumerateInstancesResponseMessage> response(
224 new CIMEnumerateInstancesResponseMessage(
225 request->messageId,
226 CIMException(),
227 request->queueIds.copyAndPop()));
228 response->syncAttributes(request);
229
230 try
231 {
232 // Enumerate instances only for this class
233 response->getResponseData().setInstances(
234 _repository->enumerateInstancesForClass(
235 request->nameSpace,
236 providerInfo.className));
237 }
238 catch (CIMException& e)
239 {
240 response->cimException = e;
241 }
242 xinf.zhao 1.1 catch (Exception& e)
243 {
244 response->cimException = PEGASUS_CIM_EXCEPTION(
245 CIM_ERR_FAILED, e.getMessage());
246 }
247 catch (...)
248 {
249 response->cimException = PEGASUS_CIM_EXCEPTION(
250 CIM_ERR_FAILED, String::EMPTY);
251 }
252
253 poA->appendResponse(response.release());
254 } // for all classes and derived classes
255
256 Uint32 numberResponses = poA->numberResponses();
|
257 karl 1.5 Uint32 totalIssued = providerInfos.providerCount
258 + (numberResponses > 0 ? 1 : 0);
|
259 xinf.zhao 1.1 poA->setTotalIssued(totalIssued);
260
261 if (numberResponses > 0)
262 {
|
263 marek 1.3 handleOperationResponseAggregation(poA,false,false);
|
264 xinf.zhao 1.1 CIMResponseMessage* response = poA->removeResponse(0);
265 _forwardRequestForAggregation(
266 getQueueId(),
267 String(),
268 new CIMExecQueryRequestMessage(*request),
|
269 karl 1.7 poA, response);
|
270 xinf.zhao 1.1 }
271 } // if isDefaultInstanceProvider
272 else
273 {
274 // Set the number of expected responses in the OperationAggregate
275 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
|
276 karl 1.5 "providerCount:%u",(unsigned int)providerInfos.providerCount));
277 poA->setTotalIssued(providerInfos.providerCount);
|
278 xinf.zhao 1.1 }
279
280 // Loop through providerInfos, forwarding requests to providers
281 for (Uint32 i = 0; i < numClasses; i++)
282 {
283 // If this class has a provider
284 ProviderInfo& providerInfo = providerInfos[i];
285
286 // this class is NOT registered to a provider - skip
287 if (!providerInfo.hasProvider)
|
288 karl 1.7 {
|
289 xinf.zhao 1.1 continue;
|
290 karl 1.7 }
|
291 xinf.zhao 1.1 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
292 "Routing ExecQuery request for class %s to "
293 "service \"%s\" for control provider \"%s\". "
|
294 karl 1.4 "Class # %u of %u",
295 CSTRING(providerInfo.className.getString()),
|
296 xinf.zhao 1.1 lookup(providerInfo.serviceId)->getQueueName(),
|
297 karl 1.4 CSTRING(providerInfo.controlProviderName),
298 (i + 1),
299 numClasses ));
|
300 xinf.zhao 1.1
301 ProviderIdContainer* providerIdContainer =
302 providerInfo.providerIdContainer.get();
303
304 if (providerInfo.hasNoQuery)
305 {
306 OperationContext* context = &request->operationContext;
307 const OperationContext::Container* container = 0;
308 container = &context->get(IdentityContainer::NAME);
309 const IdentityContainer& identityContainer =
310 dynamic_cast<const IdentityContainer&>(*container);
311
312 AutoPtr<CIMEnumerateInstancesRequestMessage> enumReq(
313 new CIMEnumerateInstancesRequestMessage(
314 request->messageId,
315 request->nameSpace,
316 providerInfo.className,
317 false,false,false,
318 CIMPropertyList(),
319 request->queueIds,
320 request->authType,
321 xinf.zhao 1.1 identityContainer.getUserName()));
322
323 context = &enumReq->operationContext;
|
324 karl 1.4
|
325 xinf.zhao 1.1 if (providerIdContainer)
326 context->insert(*providerIdContainer);
|
327 karl 1.4
|
328 xinf.zhao 1.1 context->insert(identityContainer);
|
329 karl 1.4
|
330 xinf.zhao 1.1 _forwardRequestForAggregation(
331 providerInfo.serviceId,
332 providerInfo.controlProviderName,
333 enumReq.release(), poA);
334 }
335 else
336 {
337 AutoPtr<CIMExecQueryRequestMessage> requestCopy(
338 new CIMExecQueryRequestMessage(*request));
339
340 OperationContext* context = &request->operationContext;
|
341 karl 1.4
|
342 xinf.zhao 1.1 if (providerIdContainer)
343 context->insert(*providerIdContainer);
344
345 requestCopy->operationContext = *context;
346 requestCopy->className = providerInfo.className;
347
348 _forwardRequestForAggregation(
349 providerInfo.serviceId,
350 providerInfo.controlProviderName,
351 requestCopy.release(), poA);
352 }
353 } // for all classes and derived classes
354
355 PEG_METHOD_EXIT();
356 }
357
|
358 marek 1.2 PEGASUS_NAMESPACE_END
|