1 martin 1.37 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.38 //
|
3 martin 1.37 // 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 martin 1.38 //
|
10 martin 1.37 // 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 martin 1.38 //
|
17 martin 1.37 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.38 //
|
20 martin 1.37 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.38 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.37 // 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 martin 1.38 //
|
28 martin 1.37 //////////////////////////////////////////////////////////////////////////
|
29 schuur 1.1 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include "WQLOperationRequestDispatcher.h"
|
33 a.arora 1.2 #include <Pegasus/Common/AutoPtr.h>
|
34 kumpf 1.20 #include <Pegasus/Common/StatisticalData.h>
|
35 schuur 1.1
36 PEGASUS_NAMESPACE_BEGIN
37
38 PEGASUS_USING_STD;
39
40 void WQLOperationRequestDispatcher::applyQueryToEnumeration(
|
41 kumpf 1.24 CIMResponseMessage* msg,
42 QueryExpressionRep* query)
|
43 schuur 1.1 {
|
44 kumpf 1.24 CIMEnumerateInstancesResponseMessage* enr =
45 (CIMEnumerateInstancesResponseMessage*) msg;
46 WQLSelectStatement* qs = ((WQLQueryExpressionRep*)query)->_stmt;
|
47 schuur 1.1
|
48 thilo.boehm 1.42 Array<CIMInstance>& a = enr->getResponseData().getInstances();
|
49 mike 1.36
50 for (int i = a.size() - 1; i >= 0; i--)
|
51 kumpf 1.24 {
|
52 mike 1.36 WQLInstancePropertySource ips(a[i]);
|
53 kumpf 1.24 try
54 {
55 if (qs->evaluateWhereClause(&ips))
56 {
57 //
58 // Specify that missing requested project properties are
59 // allowed to be consistent with clarification from DMTF
60 //
|
61 mike 1.36 qs->applyProjection(a[i], true);
|
62 kumpf 1.24 }
|
63 karl 1.49 else
64 {
65 a.remove(i);
66 }
|
67 kumpf 1.24 }
68 catch (...)
69 {
|
70 mike 1.36 a.remove(i);
|
71 kumpf 1.24 }
72 }
|
73 schuur 1.1 }
74
75 void WQLOperationRequestDispatcher::handleQueryRequest(
|
76 kumpf 1.24 CIMExecQueryRequestMessage* request)
|
77 schuur 1.1 {
|
78 kumpf 1.21 PEG_METHOD_ENTER(TRC_DISPATCHER,
|
79 kumpf 1.28 "WQLOperationRequestDispatcher::handleQueryRequest");
|
80 kumpf 1.21
|
81 kumpf 1.24 Boolean exception=false;
82 AutoPtr<WQLSelectStatement> selectStatement(new WQLSelectStatement());
83 AutoPtr<WQLQueryExpressionRep> qx;
84 CIMException cimException;
85 CIMName className;
86
87 if (request->queryLanguage!="WQL")
88 {
89 cimException = PEGASUS_CIM_EXCEPTION(
90 CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED, request->queryLanguage);
91 exception=true;
92 }
93 else
94 {
95 try
96 {
97 WQLParser::parse(request->query, *selectStatement.get());
98 className = selectStatement->getClassName();
99 qx.reset(new WQLQueryExpressionRep("WQL", selectStatement.get()));
100 selectStatement.release();
101 }
102 kumpf 1.24 catch (ParseError&)
103 {
104 cimException =
105 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
106 exception=true;
107 }
108 catch (MissingNullTerminator&)
109 {
110 cimException =
111 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
112 exception = true;
113 }
114
115 if (exception == false)
116 {
|
117 kumpf 1.27 if (!_checkExistenceOfClass(request->nameSpace, className))
118 {
119 cimException = PEGASUS_CIM_EXCEPTION(
120 CIM_ERR_INVALID_CLASS, className.getString());
|
121 kumpf 1.24 exception = true;
|
122 kumpf 1.27 }
|
123 kumpf 1.24 }
124 }
|
125 schuur 1.1
|
126 kumpf 1.21 if (exception)
127 {
128 CIMResponseMessage* response = request->buildResponse();
129 response->cimException = cimException;
|
130 schuur 1.1
|
131 kumpf 1.21 _enqueueResponse(request, response);
|
132 schuur 1.1 PEG_METHOD_EXIT();
133 return;
134 }
135
136 //
137 // Get names of descendent classes:
138 //
|
139 karl 1.47 ProviderInfoList providerInfos;
|
140 schuur 1.1
|
141 kumpf 1.24 try
142 {
|
143 karl 1.46 providerInfos = _lookupAllInstanceProviders(
|
144 chip 1.12 request->nameSpace,
|
145 karl 1.47 className);
|
146 schuur 1.1 }
|
147 kumpf 1.33 catch (CIMException& e)
|
148 kumpf 1.24 {
|
149 schuur 1.1 // Return exception response if exception from getSubClasses
|
150 kumpf 1.21 CIMResponseMessage* response = request->buildResponse();
|
151 kumpf 1.33 response->cimException = e;
|
152 schuur 1.1
|
153 kumpf 1.21 _enqueueResponse(request, response);
|
154 schuur 1.1 PEG_METHOD_EXIT();
155 return;
156 }
157
158 // If no provider is registered and the repository isn't the default,
159 // return CIM_ERR_NOT_SUPPORTED
|
160 karl 1.47
161 if (_rejectNoProvidersOrRepository(request,
162 providerInfos.providerCount,
163 className))
|
164 schuur 1.1 {
|
165 kumpf 1.21 PEG_METHOD_EXIT();
|
166 schuur 1.1 return;
167 }
168
169 // We have instances for Providers and possibly repository.
170 // Set up an aggregate object and save a copy of the original request.
171
|
172 kumpf 1.24 OperationAggregate* poA= new OperationAggregate(
|
173 schuur 1.1 new CIMExecQueryRequestMessage(*request),
|
174 kumpf 1.24 request->getType(),
175 request->messageId,
176 request->queueIds.top(),
177 className, CIMNamespaceName(),
178 qx.release(),
179 "WQL");
|
180 schuur 1.1
181 // Set the number of expected responses in the OperationAggregate
182 Uint32 numClasses = providerInfos.size();
|
183 karl 1.49
|
184 schuur 1.1 poA->_nameSpace=request->nameSpace;
185
186 if (_repository->isDefaultInstanceProvider())
|
187 brian.campbell 1.10 {
|
188 kumpf 1.24 // Loop through providerInfos, forwarding requests to repository
189 for (Uint32 i = 0; i < numClasses; i++)
190 {
191 ProviderInfo& providerInfo = providerInfos[i];
192
193 // this class is registered to a provider - skip
194 if (providerInfo.hasProvider)
|
195 karl 1.47 {
|
196 kumpf 1.24 continue;
|
197 karl 1.47 }
|
198 kumpf 1.24
199 // If this class does not have a provider
200
|
201 kumpf 1.25 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
202 "Routing ExecQuery request for class %s to the "
|
203 karl 1.46 "repository. Class # %u of %u",
204 CSTRING(providerInfo.className.getString()),
205 (i + 1),
206 numClasses ));
|
207 kumpf 1.24
|
208 kumpf 1.29 // Create an EnumerateInstances response from an ExecQuery request
|
209 kumpf 1.24 AutoPtr<CIMEnumerateInstancesResponseMessage> response(
210 new CIMEnumerateInstancesResponseMessage(
211 request->messageId,
212 CIMException(),
|
213 mike 1.36 request->queueIds.copyAndPop()));
|
214 kumpf 1.24 response->syncAttributes(request);
215
216 try
217 {
218 // Enumerate instances only for this class
|
219 thilo.boehm 1.42 response->getResponseData().setInstances(
|
220 kumpf 1.24 _repository->enumerateInstancesForClass(
221 request->nameSpace,
|
222 mike 1.36 providerInfo.className));
|
223 kumpf 1.24 }
|
224 kumpf 1.33 catch (CIMException& e)
|
225 kumpf 1.24 {
|
226 kumpf 1.33 response->cimException = e;
|
227 kumpf 1.24 }
|
228 kumpf 1.33 catch (Exception& e)
|
229 kumpf 1.24 {
230 response->cimException = PEGASUS_CIM_EXCEPTION(
|
231 kumpf 1.33 CIM_ERR_FAILED, e.getMessage());
|
232 kumpf 1.24 }
233 catch (...)
234 {
235 response->cimException = PEGASUS_CIM_EXCEPTION(
236 CIM_ERR_FAILED, String::EMPTY);
237 }
238
239 poA->appendResponse(response.release());
240 } // for all classes and derived classes
241
242 Uint32 numberResponses = poA->numberResponses();
|
243 karl 1.47 Uint32 totalIssued = providerInfos.providerCount
244 + (numberResponses > 0 ? 1 : 0);
|
245 kumpf 1.24 poA->setTotalIssued(totalIssued);
246
247 if (numberResponses > 0)
248 {
|
249 marek 1.45 handleOperationResponseAggregation(poA,false,false);
|
250 kumpf 1.24 CIMResponseMessage* response = poA->removeResponse(0);
251 _forwardRequestForAggregation(
|
252 venkat.puvvada 1.35 getQueueId(),
|
253 kumpf 1.24 String(),
254 new CIMExecQueryRequestMessage(*request),
255 poA, response);
256 }
|
257 brian.campbell 1.10 } // if isDefaultInstanceProvider
|
258 kumpf 1.24 else
259 {
260 // Set the number of expected responses in the OperationAggregate
|
261 karl 1.47 poA->setTotalIssued(providerInfos.providerCount);
|
262 kumpf 1.24 }
|
263 schuur 1.1
264 // Loop through providerInfos, forwarding requests to providers
265 for (Uint32 i = 0; i < numClasses; i++)
266 {
267 // If this class has a provider
|
268 kumpf 1.24 ProviderInfo& providerInfo = providerInfos[i];
|
269 schuur 1.1
|
270 kumpf 1.24 // this class is NOT registered to a provider - skip
271 if (!providerInfo.hasProvider)
272 continue;
|
273 chip 1.12
|
274 kumpf 1.25 PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
275 "Routing ExecQuery request for class %s to "
276 "service \"%s\" for control provider \"%s\". "
|
277 karl 1.46 "Class # %u of %u",
278 CSTRING(providerInfo.className.getString()),
|
279 venkat.puvvada 1.35 lookup(providerInfo.serviceId)->getQueueName(),
|
280 karl 1.46 CSTRING(providerInfo.controlProviderName),
281 (i + 1),
282 numClasses ));
|
283 kumpf 1.24
284 ProviderIdContainer* providerIdContainer =
285 providerInfo.providerIdContainer.get();
286
287 if (providerInfo.hasNoQuery)
288 {
289 OperationContext* context = &request->operationContext;
290 const OperationContext::Container* container = 0;
291 container = &context->get(IdentityContainer::NAME);
292 const IdentityContainer& identityContainer =
293 dynamic_cast<const IdentityContainer&>(*container);
294
295 AutoPtr<CIMEnumerateInstancesRequestMessage> enumReq(
296 new CIMEnumerateInstancesRequestMessage(
297 request->messageId,
298 request->nameSpace,
299 providerInfo.className,
|
300 kumpf 1.40 false,false,false,
|
301 kumpf 1.24 CIMPropertyList(),
302 request->queueIds,
303 request->authType,
304 identityContainer.getUserName()));
305
306 context = &enumReq->operationContext;
|
307 karl 1.46
|
308 kumpf 1.24 if (providerIdContainer)
309 context->insert(*providerIdContainer);
|
310 karl 1.46
|
311 kumpf 1.24 context->insert(identityContainer);
|
312 karl 1.49
|
313 kumpf 1.24 _forwardRequestForAggregation(
|
314 karl 1.49 providerInfo.serviceId,
315 providerInfo.controlProviderName,
316 enumReq.release(), poA);
|
317 kumpf 1.24 }
318 else
319 {
320 AutoPtr<CIMExecQueryRequestMessage> requestCopy(
321 new CIMExecQueryRequestMessage(*request));
322
323 OperationContext* context = &request->operationContext;
|
324 karl 1.46
|
325 kumpf 1.24 if (providerIdContainer)
326 context->insert(*providerIdContainer);
327
328 requestCopy->operationContext = *context;
329 requestCopy->className = providerInfo.className;
330
331 _forwardRequestForAggregation(
|
332 venkat.puvvada 1.35 providerInfo.serviceId,
|
333 kumpf 1.24 providerInfo.controlProviderName,
334 requestCopy.release(), poA);
335 }
|
336 brian.campbell 1.10 } // for all classes and derived classes
|
337 schuur 1.1
|
338 kumpf 1.24 PEG_METHOD_EXIT();
|
339 schuur 1.1 }
340
341 PEGASUS_NAMESPACE_END
|