(file) Return to WQLOperationRequestDispatcher.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Server

  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 mike    1.36     Array<CIMInstance>& a = enr->getNamedInstances();
 49              
 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 mike    1.36             else a.remove(i);
 64 kumpf   1.24         }
 65                      catch (...)
 66                      {
 67 mike    1.36             a.remove(i);
 68 kumpf   1.24         }
 69                  }
 70 schuur  1.1  }
 71              
 72              void WQLOperationRequestDispatcher::handleQueryResponseAggregation(
 73 kumpf   1.24     OperationAggregate* poA)
 74 schuur  1.1  {
 75 kumpf   1.24     PEG_METHOD_ENTER(TRC_DISPATCHER,
 76 kumpf   1.28         "WQLOperationRequestDispatcher::handleQueryResponseAggregation");
 77 kumpf   1.24 
 78                  Uint32 numberResponses = poA->numberResponses();
 79 kumpf   1.39 
 80 marek   1.30     PEG_TRACE((
 81                      TRC_DISPATCHER,
 82 marek   1.32         Tracer::LEVEL4,
 83 kumpf   1.28         "WQLOperationRequestDispatcher::ExecQuery Response - "
 84 marek   1.30             "Name Space: %s  Class name: %s Response Count: %u",
 85                      (const char*) poA->_nameSpace.getString().getCString(),
 86                      (const char*) poA->_className.getString().getCString(),
 87                      numberResponses));
 88 kumpf   1.24 
 89                  if (numberResponses == 0)
 90                      return;
 91 schuur  1.1  
 92 kumpf   1.24     CIMResponseMessage* response = poA->getResponse(0);
 93                  CIMExecQueryResponseMessage* toResponse = 0;
 94                  Uint32 startIndex = 0;
 95                  Uint32 endIndex = numberResponses - 1;
 96                  Boolean manyResponses = true;
 97                  if (response->getType() == CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE)
 98                  {
 99 kumpf   1.29         // Create an ExecQuery response from an EnumerateInstances request
100 kumpf   1.24         CIMRequestMessage* request = poA->getRequest();
101                      AutoPtr<CIMExecQueryResponseMessage> query(
102                          new CIMExecQueryResponseMessage(
103                              request->messageId,
104                              CIMException(),
105                              request->queueIds.copyAndPop(),
106                              Array<CIMObject>()));
107                      query->syncAttributes(request);
108 aruran.ms 1.17         toResponse = query.release();
109 kumpf     1.24     }
110                    else
111                    {
112                        toResponse = (CIMExecQueryResponseMessage*) response;
113                        manyResponses = false;
114                    }
115 brian.campbell 1.10 
116 kumpf          1.24     // Work backward and delete each response off the end of the array
117                         for (Uint32 i = endIndex; i >= startIndex; i--)
118                         {
119                             if (manyResponses)
120                                 response = poA->getResponse(i);
121 schuur         1.1  
122 kumpf          1.24         if (response->getType() == CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE)
123                             {
124                                 // convert enumerate instances responses to exec query responses
125                                 applyQueryToEnumeration(response, poA->_query);
126                                 CIMEnumerateInstancesResponseMessage* fromResponse =
127                                     (CIMEnumerateInstancesResponseMessage*) response;
128                                 CIMClass cimClass;
129                     
130                                 Boolean clsRead=false;
131 mike           1.36             Array<CIMInstance>& a = fromResponse->getNamedInstances();
132                                 for (Uint32 j = 0, m = a.size();
133 kumpf          1.24                  j < m; j++)
134                                 {
135 mike           1.36                 CIMObject co=CIMObject(a[j]);
136 kumpf          1.24                 CIMObjectPath op=co.getPath();
137                                     const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
138                                     if (kbs.size() == 0)
139                                     {     // no path set why ?
140                                         if (clsRead == false)
141                                         {
142                                             cimClass = _repository->getClass(
143                                                 poA->_nameSpace, op.getClassName(),
144                                                 false,true,false, CIMPropertyList());
145                                             clsRead=true;
146                                         }
147 mike           1.36                     op = a[j].buildPath(cimClass);
148 kumpf          1.24                 }
149                                     op.setNameSpace(poA->_nameSpace);
150                                     op.setHost(System::getHostName());
151                                     co.setPath(op);
152                                     if (manyResponses)
153                                         toResponse->cimObjects.append(co);
154                                 }
155                             }
156                             else
157                             {
158                                 CIMExecQueryResponseMessage* fromResponse =
159                                     (CIMExecQueryResponseMessage*) response;
160                                 CIMClass cimClass;
161                                 Boolean clsRead=false;
162                                 for (Uint32 j = 0, m = fromResponse->cimObjects.size(); j < m; j++)
163                                 {
164                                     CIMObject co=fromResponse->cimObjects[j];
165                                     CIMObjectPath op=co.getPath();
166                                     const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
167                                     if (kbs.size()==0)
168                                     {     // no path set why ?
169 kumpf          1.24                     if (clsRead==false)
170                                         {
171                                             cimClass = _repository->getClass(
172                                                 poA->_nameSpace,op.getClassName(),
173                                                 false,true,false, CIMPropertyList());
174                                             clsRead=true;
175                                         }
176                                         op = CIMInstance(fromResponse->cimObjects[j]).buildPath(
177                                             cimClass);
178                                     }
179                                     op.setNameSpace(poA->_nameSpace);
180                                     op.setHost(System::getHostName());
181                                     co.setPath(op);
182                                     if (manyResponses)
183                                         toResponse->cimObjects.append(co);
184                                 }
185                             }
186                     
187                             if (manyResponses)
188                                 poA->deleteResponse(i);
189                     
190 kumpf          1.24         if (i == 0)
191                                 break;
192                         } // for all responses in response list
193                     
194                         // if we started with an enumerateInstances repsonse, then add it to overall
195                         if ((startIndex == 0) && manyResponses)
196                             poA->appendResponse(toResponse);
197 schuur         1.1  
198 kumpf          1.24     PEG_METHOD_EXIT();
199                     }
200 schuur         1.1  
201                     void WQLOperationRequestDispatcher::handleQueryRequest(
202 kumpf          1.24     CIMExecQueryRequestMessage* request)
203 schuur         1.1  {
204 kumpf          1.21     PEG_METHOD_ENTER(TRC_DISPATCHER,
205 kumpf          1.28         "WQLOperationRequestDispatcher::handleQueryRequest");
206 kumpf          1.21 
207 kumpf          1.24     Boolean exception=false;
208                         AutoPtr<WQLSelectStatement> selectStatement(new WQLSelectStatement());
209                         AutoPtr<WQLQueryExpressionRep> qx;
210                         CIMException cimException;
211                         CIMName className;
212                     
213                         if (request->queryLanguage!="WQL")
214                         {
215                             cimException = PEGASUS_CIM_EXCEPTION(
216                                 CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED, request->queryLanguage);
217                             exception=true;
218                         }
219                         else
220                         {
221                             try
222                             {
223                                 WQLParser::parse(request->query, *selectStatement.get());
224                                 className = selectStatement->getClassName();
225                                 qx.reset(new WQLQueryExpressionRep("WQL", selectStatement.get()));
226                                 selectStatement.release();
227                             }
228 kumpf          1.24         catch (ParseError&)
229                             {
230                                 cimException =
231                                     PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
232                                 exception=true;
233                             }
234                             catch (MissingNullTerminator&)
235                             {
236                                 cimException =
237                                     PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
238                                 exception = true;
239                             }
240                     
241                             if (exception == false)
242                             {
243 kumpf          1.27             if (!_checkExistenceOfClass(request->nameSpace, className))
244                                 {
245                                     cimException = PEGASUS_CIM_EXCEPTION(
246                                         CIM_ERR_INVALID_CLASS, className.getString());
247 kumpf          1.24                 exception = true;
248 kumpf          1.27             }
249 kumpf          1.24         }
250                         }
251 schuur         1.1  
252 kumpf          1.21     if (exception)
253                         {
254                             CIMResponseMessage* response = request->buildResponse();
255                             response->cimException = cimException;
256 schuur         1.1  
257 kumpf          1.21         _enqueueResponse(request, response);
258 schuur         1.1          PEG_METHOD_EXIT();
259                             return;
260                         }
261                     
262                         //
263                         // Get names of descendent classes:
264                         //
265                         Array<ProviderInfo> providerInfos;
266                     
267                         // This gets set by _lookupAllInstanceProviders()
268                         Uint32 providerCount;
269                     
270 kumpf          1.24     try
271                         {
272 chip           1.12         providerInfos =
273                                 _lookupAllInstanceProviders(
274                                     request->nameSpace,
275                                     className,
276                                     providerCount);
277 schuur         1.1      }
278 kumpf          1.33     catch (CIMException& e)
279 kumpf          1.24     {
280 schuur         1.1          // Return exception response if exception from getSubClasses
281 kumpf          1.21         CIMResponseMessage* response = request->buildResponse();
282 kumpf          1.33         response->cimException = e;
283 schuur         1.1  
284 kumpf          1.21         _enqueueResponse(request, response);
285 schuur         1.1          PEG_METHOD_EXIT();
286                             return;
287                         }
288                     
289                         // Test for "enumerate too Broad" and if so, execute exception.
290                         // This limits the number of provider invocations, not the number
291                         // of instances returned.
292 kumpf          1.24     if (providerCount > _maximumEnumerateBreadth)
293 schuur         1.1      {
294 marek          1.31         PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL1,
295 kumpf          1.25             "ERROR: Enumerate operation too broad for class %s.  "
296                                     "Limit = %u, providerCount = %u",
297                                 (const char*)request->className.getString().getCString(),
298                                 _maximumEnumerateBreadth,
299                                 providerCount));
300 schuur         1.1  
301 kumpf          1.21         CIMResponseMessage* response = request->buildResponse();
302                             response->cimException =
303                                 PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED, MessageLoaderParms(
304 kumpf          1.28                 "Server.WQLOperationRequestDispatcher.QUERY_REQ_TOO_BROAD",
305                                     "The query request is too broad."));
306 schuur         1.1  
307 kumpf          1.21         _enqueueResponse(request, response);
308 schuur         1.1          PEG_METHOD_EXIT();
309                             return;
310                         }
311                     
312                         // If no provider is registered and the repository isn't the default,
313                         // return CIM_ERR_NOT_SUPPORTED
314                         if ((providerCount == 0) && !(_repository->isDefaultInstanceProvider()))
315                         {
316 thilo.boehm    1.34         PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL2,
317                                 "CIM_ERROR_NOT_SUPPORTED for %s",
318                                 (const char*)request->className.getString().getCString()));
319 schuur         1.1  
320 kumpf          1.21         CIMResponseMessage* response = request->buildResponse();
321                             response->cimException =
322                                 PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY);
323 schuur         1.1  
324 kumpf          1.21         _enqueueResponse(request, response);
325                             PEG_METHOD_EXIT();
326 schuur         1.1          return;
327                         }
328                     
329                         // We have instances for Providers and possibly repository.
330                         // Set up an aggregate object and save a copy of the original request.
331                     
332 kumpf          1.24     OperationAggregate* poA= new OperationAggregate(
333 schuur         1.1          new CIMExecQueryRequestMessage(*request),
334 kumpf          1.24             request->getType(),
335                                 request->messageId,
336                                 request->queueIds.top(),
337                                 className, CIMNamespaceName(),
338                                 qx.release(),
339                                 "WQL");
340 schuur         1.1  
341                         // Set the number of expected responses in the OperationAggregate
342                         Uint32 numClasses = providerInfos.size();
343                         poA->_aggregationSN = cimOperationAggregationSN++;
344                         poA->_nameSpace=request->nameSpace;
345                     
346                         if (_repository->isDefaultInstanceProvider())
347 brian.campbell 1.10     {
348 kumpf          1.24         // Loop through providerInfos, forwarding requests to repository
349                             for (Uint32 i = 0; i < numClasses; i++)
350                             {
351                                 ProviderInfo& providerInfo = providerInfos[i];
352                     
353                                 // this class is registered to a provider - skip
354                                 if (providerInfo.hasProvider)
355                                     continue;
356                     
357                                 // If this class does not have a provider
358                     
359 kumpf          1.25             PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
360                                     "Routing ExecQuery request for class %s to the "
361                                         "repository.  Class # %u of %u, aggregation SN %u.",
362                                     (const char*)providerInfo.className.getString().getCString(),
363 mike           1.26                 (unsigned int)(i + 1),
364                                     (unsigned int)(numClasses),
365                                     (unsigned int)(poA->_aggregationSN)));
366 kumpf          1.24 
367 kumpf          1.29             // Create an EnumerateInstances response from an ExecQuery request
368 kumpf          1.24             AutoPtr<CIMEnumerateInstancesResponseMessage> response(
369                                     new CIMEnumerateInstancesResponseMessage(
370                                         request->messageId,
371                                         CIMException(),
372 mike           1.36                     request->queueIds.copyAndPop()));
373 kumpf          1.24             response->syncAttributes(request);
374                     
375                                 try
376                                 {
377                                     // Enumerate instances only for this class
378 mike           1.36                 response->setNamedInstances(
379 kumpf          1.24                     _repository->enumerateInstancesForClass(
380                                             request->nameSpace,
381 mike           1.36                         providerInfo.className));
382 kumpf          1.24             }
383 kumpf          1.33             catch (CIMException& e)
384 kumpf          1.24             {
385 kumpf          1.33                 response->cimException = e;
386 kumpf          1.24             }
387 kumpf          1.33             catch (Exception& e)
388 kumpf          1.24             {
389                                     response->cimException = PEGASUS_CIM_EXCEPTION(
390 kumpf          1.33                     CIM_ERR_FAILED, e.getMessage());
391 kumpf          1.24             }
392                                 catch (...)
393                                 {
394                                     response->cimException = PEGASUS_CIM_EXCEPTION(
395                                         CIM_ERR_FAILED, String::EMPTY);
396                                 }
397                     
398                                 poA->appendResponse(response.release());
399                             } // for all classes and derived classes
400                     
401                             Uint32 numberResponses = poA->numberResponses();
402                             Uint32 totalIssued = providerCount + (numberResponses > 0 ? 1 : 0);
403                             poA->setTotalIssued(totalIssued);
404                     
405                             if (numberResponses > 0)
406                             {
407                                 handleEnumerateInstancesResponseAggregation(poA);
408                                 CIMResponseMessage* response = poA->removeResponse(0);
409                                 _forwardRequestForAggregation(
410 venkat.puvvada 1.35                 getQueueId(),
411 kumpf          1.24                 String(),
412                                     new CIMExecQueryRequestMessage(*request),
413                                     poA, response);
414                             }
415 brian.campbell 1.10     } // if isDefaultInstanceProvider
416 kumpf          1.24     else
417                         {
418                             // Set the number of expected responses in the OperationAggregate
419                             poA->setTotalIssued(providerCount);
420                         }
421 schuur         1.1  
422                         // Loop through providerInfos, forwarding requests to providers
423                         for (Uint32 i = 0; i < numClasses; i++)
424                         {
425                             // If this class has a provider
426 kumpf          1.24         ProviderInfo& providerInfo = providerInfos[i];
427 schuur         1.1  
428 kumpf          1.24         // this class is NOT registered to a provider - skip
429                             if (!providerInfo.hasProvider)
430                                 continue;
431 chip           1.12 
432 kumpf          1.25         PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
433                                 "Routing ExecQuery request for class %s to "
434                                     "service \"%s\" for control provider \"%s\".  "
435                                     "Class # %u of %u, aggregation SN %u.",
436                                 (const char*)providerInfo.className.getString().getCString(),
437 venkat.puvvada 1.35             lookup(providerInfo.serviceId)->getQueueName(),
438 kumpf          1.25             (const char*)providerInfo.controlProviderName.getCString(),
439 mike           1.26             (unsigned int)(i + 1),
440                                 (unsigned int)numClasses,
441                                 (unsigned int)(poA->_aggregationSN)));
442 kumpf          1.24 
443                             ProviderIdContainer* providerIdContainer =
444                                 providerInfo.providerIdContainer.get();
445                     
446                             if (providerInfo.hasNoQuery)
447                             {
448                                 OperationContext* context = &request->operationContext;
449                                 const OperationContext::Container* container = 0;
450                                 container = &context->get(IdentityContainer::NAME);
451                                 const IdentityContainer& identityContainer =
452                                     dynamic_cast<const IdentityContainer&>(*container);
453                     
454                                 AutoPtr<CIMEnumerateInstancesRequestMessage> enumReq(
455                                     new CIMEnumerateInstancesRequestMessage(
456                                         request->messageId,
457                                         request->nameSpace,
458                                         providerInfo.className,
459 kumpf          1.40                     false,false,false,
460 kumpf          1.24                     CIMPropertyList(),
461                                         request->queueIds,
462                                         request->authType,
463                                         identityContainer.getUserName()));
464                     
465                                 context = &enumReq->operationContext;
466                                 if (providerIdContainer)
467                                     context->insert(*providerIdContainer);
468                                 context->insert(identityContainer);
469                                 _forwardRequestForAggregation(
470 venkat.puvvada 1.35                  providerInfo.serviceId,
471 kumpf          1.24                  providerInfo.controlProviderName,
472                                      enumReq.release(), poA);
473                             }
474                             else
475                             {
476                                 AutoPtr<CIMExecQueryRequestMessage> requestCopy(
477                                     new CIMExecQueryRequestMessage(*request));
478                     
479                                 OperationContext* context = &request->operationContext;
480                                 if (providerIdContainer)
481                                     context->insert(*providerIdContainer);
482                     
483                                 requestCopy->operationContext = *context;
484                                 requestCopy->className = providerInfo.className;
485                     
486                                 _forwardRequestForAggregation(
487 venkat.puvvada 1.35                 providerInfo.serviceId,
488 kumpf          1.24                 providerInfo.controlProviderName,
489                                     requestCopy.release(), poA);
490                             }
491 brian.campbell 1.10     } // for all classes and derived classes
492 schuur         1.1  
493 kumpf          1.24     PEG_METHOD_EXIT();
494 schuur         1.1  }
495                     
496                     PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2