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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2