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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2