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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2