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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2