(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 kumpf   1.24     for (int i = enr->cimNamedInstances.size() - 1; i >= 0; i--)
 51                  {
 52                      WQLInstancePropertySource ips(enr->cimNamedInstances[i]);
 53                      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                              qs->applyProjection(enr->cimNamedInstances[i], true);
 62                          }
 63                          else enr->cimNamedInstances.remove(i);
 64                      }
 65                      catch (...)
 66                      {
 67                          enr->cimNamedInstances.remove(i);
 68                      }
 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 marek   1.30     
 80                  PEG_TRACE((
 81                      TRC_DISPATCHER,
 82                      Tracer::LEVEL3,
 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                                 for (Uint32 j = 0, m = fromResponse->cimNamedInstances.size();
132                                      j < m; j++)
133                                 {
134                                     CIMObject co=CIMObject(fromResponse->cimNamedInstances[j]);
135                                     CIMObjectPath op=co.getPath();
136                                     const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
137                                     if (kbs.size() == 0)
138                                     {     // no path set why ?
139                                         if (clsRead == false)
140                                         {
141                                             cimClass = _repository->getClass(
142                                                 poA->_nameSpace, op.getClassName(),
143 kumpf          1.24                             false,true,false, CIMPropertyList());
144                                             clsRead=true;
145                                         }
146                                         op = fromResponse->cimNamedInstances[j].buildPath(cimClass);
147                                     }
148                                     op.setNameSpace(poA->_nameSpace);
149                                     op.setHost(System::getHostName());
150                                     co.setPath(op);
151                                     if (manyResponses)
152                                         toResponse->cimObjects.append(co);
153                                 }
154                             }
155                             else
156                             {
157                                 CIMExecQueryResponseMessage* fromResponse =
158                                     (CIMExecQueryResponseMessage*) response;
159                                 CIMClass cimClass;
160                                 Boolean clsRead=false;
161                                 for (Uint32 j = 0, m = fromResponse->cimObjects.size(); j < m; j++)
162                                 {
163                                     CIMObject co=fromResponse->cimObjects[j];
164 kumpf          1.24                 CIMObjectPath op=co.getPath();
165                                     const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
166                                     if (kbs.size()==0)
167                                     {     // no path set why ?
168                                         if (clsRead==false)
169                                         {
170                                             cimClass = _repository->getClass(
171                                                 poA->_nameSpace,op.getClassName(),
172                                                 false,true,false, CIMPropertyList());
173                                             clsRead=true;
174                                         }
175                                         op = CIMInstance(fromResponse->cimObjects[j]).buildPath(
176                                             cimClass);
177                                     }
178                                     op.setNameSpace(poA->_nameSpace);
179                                     op.setHost(System::getHostName());
180                                     co.setPath(op);
181                                     if (manyResponses)
182                                         toResponse->cimObjects.append(co);
183                                 }
184                             }
185 kumpf          1.24 
186                             if (manyResponses)
187                                 poA->deleteResponse(i);
188                     
189                             if (i == 0)
190                                 break;
191                         } // for all responses in response list
192                     
193                         // if we started with an enumerateInstances repsonse, then add it to overall
194                         if ((startIndex == 0) && manyResponses)
195                             poA->appendResponse(toResponse);
196 schuur         1.1  
197 kumpf          1.24     PEG_METHOD_EXIT();
198                     }
199 schuur         1.1  
200                     void WQLOperationRequestDispatcher::handleQueryRequest(
201 kumpf          1.24     CIMExecQueryRequestMessage* request)
202 schuur         1.1  {
203 kumpf          1.21     PEG_METHOD_ENTER(TRC_DISPATCHER,
204 kumpf          1.28         "WQLOperationRequestDispatcher::handleQueryRequest");
205 kumpf          1.21 
206 kumpf          1.24     Boolean exception=false;
207                         AutoPtr<WQLSelectStatement> selectStatement(new WQLSelectStatement());
208                         AutoPtr<WQLQueryExpressionRep> qx;
209                         CIMException cimException;
210                         CIMName className;
211                     
212                         if (request->queryLanguage!="WQL")
213                         {
214                             cimException = PEGASUS_CIM_EXCEPTION(
215                                 CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED, request->queryLanguage);
216                             exception=true;
217                         }
218                         else
219                         {
220                             try
221                             {
222                                 WQLParser::parse(request->query, *selectStatement.get());
223                                 className = selectStatement->getClassName();
224                                 qx.reset(new WQLQueryExpressionRep("WQL", selectStatement.get()));
225                                 selectStatement.release();
226                             }
227 kumpf          1.24         catch (ParseError&)
228                             {
229                                 cimException =
230                                     PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
231                                 exception=true;
232                             }
233                             catch (MissingNullTerminator&)
234                             {
235                                 cimException =
236                                     PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
237                                 exception = true;
238                             }
239                     
240                             if (exception == false)
241                             {
242 kumpf          1.27             if (!_checkExistenceOfClass(request->nameSpace, className))
243                                 {
244                                     cimException = PEGASUS_CIM_EXCEPTION(
245                                         CIM_ERR_INVALID_CLASS, className.getString());
246 kumpf          1.24                 exception = true;
247 kumpf          1.27             }
248 kumpf          1.24         }
249                         }
250 schuur         1.1  
251 kumpf          1.21     if (exception)
252                         {
253                             CIMResponseMessage* response = request->buildResponse();
254                             response->cimException = cimException;
255 schuur         1.1  
256 kumpf          1.21         _enqueueResponse(request, response);
257 schuur         1.1          PEG_METHOD_EXIT();
258                             return;
259                         }
260                     
261                         //
262                         // Get names of descendent classes:
263                         //
264                         Array<ProviderInfo> providerInfos;
265                     
266                         // This gets set by _lookupAllInstanceProviders()
267                         Uint32 providerCount;
268                     
269 kumpf          1.24     try
270                         {
271 chip           1.12         providerInfos =
272                                 _lookupAllInstanceProviders(
273                                     request->nameSpace,
274                                     className,
275                                     providerCount);
276 schuur         1.1      }
277 kumpf          1.24     catch (CIMException& exception)
278                         {
279 schuur         1.1          // Return exception response if exception from getSubClasses
280 kumpf          1.21         CIMResponseMessage* response = request->buildResponse();
281                             response->cimException = exception;
282 schuur         1.1  
283 kumpf          1.21         _enqueueResponse(request, response);
284 schuur         1.1          PEG_METHOD_EXIT();
285                             return;
286                         }
287                     
288                         // Test for "enumerate too Broad" and if so, execute exception.
289                         // This limits the number of provider invocations, not the number
290                         // of instances returned.
291 kumpf          1.24     if (providerCount > _maximumEnumerateBreadth)
292 schuur         1.1      {
293 marek          1.30         // TBD-7646
294 kumpf          1.25         PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL2,
295                                 "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                             PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4,
317                                 "CIM_ERROR_NOT_SUPPORTED for " + request->className.getString());
318                     
319 kumpf          1.21         CIMResponseMessage* response = request->buildResponse();
320                             response->cimException =
321                                 PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY);
322 schuur         1.1  
323 kumpf          1.21         _enqueueResponse(request, response);
324                             PEG_METHOD_EXIT();
325 schuur         1.1          return;
326                         }
327                     
328                         // We have instances for Providers and possibly repository.
329                         // Set up an aggregate object and save a copy of the original request.
330                     
331 kumpf          1.24     OperationAggregate* poA= new OperationAggregate(
332 schuur         1.1          new CIMExecQueryRequestMessage(*request),
333 kumpf          1.24             request->getType(),
334                                 request->messageId,
335                                 request->queueIds.top(),
336                                 className, CIMNamespaceName(),
337                                 qx.release(),
338                                 "WQL");
339 schuur         1.1  
340                         // Set the number of expected responses in the OperationAggregate
341                         Uint32 numClasses = providerInfos.size();
342                         poA->_aggregationSN = cimOperationAggregationSN++;
343                         poA->_nameSpace=request->nameSpace;
344                     
345                         if (_repository->isDefaultInstanceProvider())
346 brian.campbell 1.10     {
347 kumpf          1.24         // Loop through providerInfos, forwarding requests to repository
348                             for (Uint32 i = 0; i < numClasses; i++)
349                             {
350                                 ProviderInfo& providerInfo = providerInfos[i];
351                     
352                                 // this class is registered to a provider - skip
353                                 if (providerInfo.hasProvider)
354                                     continue;
355                     
356                                 // If this class does not have a provider
357                     
358 kumpf          1.25             PEG_TRACE((TRC_DISPATCHER, Tracer::LEVEL4,
359                                     "Routing ExecQuery request for class %s to the "
360                                         "repository.  Class # %u of %u, aggregation SN %u.",
361                                     (const char*)providerInfo.className.getString().getCString(),
362 mike           1.26                 (unsigned int)(i + 1),
363                                     (unsigned int)(numClasses),
364                                     (unsigned int)(poA->_aggregationSN)));
365 kumpf          1.24 
366 kumpf          1.29             // Create an EnumerateInstances response from an ExecQuery request
367 kumpf          1.24             AutoPtr<CIMEnumerateInstancesResponseMessage> response(
368                                     new CIMEnumerateInstancesResponseMessage(
369                                         request->messageId,
370                                         CIMException(),
371                                         request->queueIds.copyAndPop(),
372                                         Array<CIMInstance>()));
373                                 response->syncAttributes(request);
374                     
375                                 try
376                                 {
377                                     // Enumerate instances only for this class
378                                     response->cimNamedInstances =
379                                         _repository->enumerateInstancesForClass(
380                                             request->nameSpace,
381                                             providerInfo.className);
382                                 }
383                                 catch (CIMException& exception)
384                                 {
385                                     response->cimException = exception;
386                                 }
387                                 catch (Exception& exception)
388 kumpf          1.24             {
389                                     response->cimException = PEGASUS_CIM_EXCEPTION(
390                                         CIM_ERR_FAILED, exception.getMessage());
391                                 }
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 kumpf          1.24             _forwardRequestForAggregation(
410                                     String(PEGASUS_QUEUENAME_OPREQDISPATCHER),
411                                     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                                 (const char*)providerInfo.serviceName.getCString(),
438                                 (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                                         false,false,false,false,
460                                         CIMPropertyList(),
461                                         request->queueIds,
462                                         request->authType,
463 kumpf          1.24                     identityContainer.getUserName()));
464                     
465                                 context = &enumReq->operationContext;
466                                 if (providerIdContainer)
467                                     context->insert(*providerIdContainer);
468                                 context->insert(identityContainer);
469                                 _forwardRequestForAggregation(
470                                      providerInfo.serviceName,
471                                      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 kumpf          1.24             requestCopy->className = providerInfo.className;
485                     
486                                 _forwardRequestForAggregation(
487                                     providerInfo.serviceName,
488                                     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