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

  1 karl  1.11 //%2005////////////////////////////////////////////////////////////////////////
  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 schuur 1.1  //
 12             // Permission is hereby granted, free of charge, to any person obtaining a copy
 13             // of this software and associated documentation files (the "Software"), to
 14             // deal in the Software without restriction, including without limitation the
 15             // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 16             // sell copies of the Software, and to permit persons to whom the Software is
 17             // furnished to do so, subject to the following conditions:
 18 karl   1.8  // 
 19 schuur 1.1  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 20             // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 21             // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 22             // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 23             // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 24             // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 25             // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 26             // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27             //
 28             //==============================================================================
 29             //
 30             // Author: Adrain Schuur (schuur@de.ibm.com)
 31             //
 32             // Modified By:
 33 a.arora 1.2  //     Amit K Arora, IBM (amita@in.ibm.com) for PEP#101
 34 se.gupta 1.3  //	   Seema Gupta (gseema@in.ibm.com) for PEP135
 35 schuur   1.1  //
 36               //%/////////////////////////////////////////////////////////////////////////////
 37               
 38               #include "WQLOperationRequestDispatcher.h"
 39 a.arora  1.2  #include <Pegasus/Common/AutoPtr.h>
 40 schuur   1.1  
 41               PEGASUS_NAMESPACE_BEGIN
 42               
 43               PEGASUS_USING_STD;
 44               
 45               
 46               void WQLOperationRequestDispatcher::applyQueryToEnumeration(
 47                          CIMResponseMessage* msg,
 48                          QueryExpressionRep* query)
 49               {
 50                  CIMEnumerateInstancesResponseMessage *enr=(CIMEnumerateInstancesResponseMessage*)msg;
 51                  WQLSelectStatement *qs=((WQLQueryExpressionRep*)query)->_stmt;
 52               
 53                  for (int i=enr->cimNamedInstances.size()-1; i>=0; i--) {
 54                     WQLInstancePropertySource ips(enr->cimNamedInstances[i]);
 55                     try {
 56                        if (qs->evaluateWhereClause(&ips)) {
 57               	    qs->applyProjection(enr->cimNamedInstances[i]);
 58                        }
 59                        else enr->cimNamedInstances.remove(i);
 60                     }
 61 schuur   1.1        catch (...) {
 62                        enr->cimNamedInstances.remove(i);
 63                     }
 64                  }
 65               }
 66               
 67               
 68               void WQLOperationRequestDispatcher::handleQueryResponseAggregation(
 69                                          OperationAggregate* poA)
 70               {
 71 brian.campbell 1.10 	PEG_METHOD_ENTER(TRC_DISPATCHER,
 72                     									 "CIMOperationRequestDispatcher::handleExecQueryResponse");
 73 schuur         1.1  
 74 brian.campbell 1.10 	Uint32 numberResponses = poA->numberResponses();
 75                     	Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
 76                     							"CIMOperationRequestDispatcher::ExecQuery Response - "
 77                     							"Name Space: $0  Class name: $1 Response Count: $2",
 78                     							poA->_nameSpace.getString(),
 79                     							poA->_className.getString(),
 80                     							numberResponses);
 81                     
 82                     	if (numberResponses == 0)
 83                     		return;
 84                     
 85                     	CIMResponseMessage *response = poA->getResponse(0);
 86                     	CIMExecQueryResponseMessage *toResponse = 0;
 87                     	Uint32 startIndex = 0;
 88                     	Uint32 endIndex = numberResponses - 1;
 89                     
 90                     	if (response->getType() == CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE)
 91                     	{
 92                     		CIMRequestMessage &request = *poA->getRequest();
 93                     		AutoPtr<CIMExecQueryResponseMessage> query
 94                     			(new CIMExecQueryResponseMessage(request.messageId,
 95 brian.campbell 1.10 																			 CIMException(),
 96                     																			 request.queueIds.copyAndPop(),
 97                     																			 Array<CIMObject>()));
 98                     		toResponse = query.release();
 99                     	}
100                     	else
101                     	{
102                     		toResponse = (CIMExecQueryResponseMessage *)response;
103                     		startIndex = 1;
104                     	}
105 schuur         1.1  
106 brian.campbell 1.10 	// Work backward and delete each response off the end of the array
107                     	for(Uint32 i = endIndex; i >= startIndex; i--)
108                     	{
109                     		response = poA->getResponse(i);
110                     
111                     		if (response->getType() == CIM_ENUMERATE_INSTANCES_RESPONSE_MESSAGE)
112                     		{
113                     			// convert enumerate instances responses to exec query responses
114                     			applyQueryToEnumeration(response, poA->_query);
115                     			CIMEnumerateInstancesResponseMessage *fromResponse =
116                     				(CIMEnumerateInstancesResponseMessage *)response;
117                     			CIMClass cimClass;
118                     
119                     			Boolean clsRead=false;
120                     			for (Uint32 j = 0,m = fromResponse->cimNamedInstances.size(); j<m; j++)
121                     			{
122 schuur         1.1  	      CIMObject co=CIMObject(fromResponse->cimNamedInstances[j]);
123                     	      CIMObjectPath op=co.getPath();
124 brian.campbell 1.10 				const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
125                     	      if (kbs.size()==0)
126                     				{     // no path set why ?
127                     					if (clsRead==false)
128                     					{
129                     						cimClass = 
130                     							_repository->getClass(poA->_nameSpace, op.getClassName(),
131                     																		false,true,false, CIMPropertyList());
132                     						clsRead=true;
133                     					}
134                     					op = fromResponse->cimNamedInstances[j].buildPath(cimClass);     
135 schuur         1.1  	      }
136                     	      op.setNameSpace(poA->_nameSpace);
137                     	      op.setHost(System::getHostName());
138                     	      co.setPath(op);
139 brian.campbell 1.10 				toResponse->cimObjects.append(co);
140                     			}
141                     		}
142                     		else
143                     		{
144                     			CIMExecQueryResponseMessage *fromResponse =
145                     				(CIMExecQueryResponseMessage *)response;
146                     			CIMClass cimClass;
147                     			Boolean clsRead=false;
148                     			for (Uint32 j = 0, m = fromResponse->cimObjects.size(); j<m; j++)
149                     			{
150 schuur         1.1  	      CIMObject co=fromResponse->cimObjects[j];
151                     	      CIMObjectPath op=co.getPath();
152 brian.campbell 1.10 				const Array<CIMKeyBinding>& kbs=op.getKeyBindings();
153                     	      if (kbs.size()==0)
154                     				{     // no path set why ?
155                     					if (clsRead==false)
156                     					{
157                     						cimClass = 
158                     							_repository->getClass(poA->_nameSpace,op.getClassName(),
159                     																		false,true,false, CIMPropertyList());
160                     						clsRead=true;
161                     					}
162                     					op=CIMInstance(fromResponse->cimObjects[j]).buildPath(cimClass);     
163 schuur         1.1  	      }
164                     	      op.setNameSpace(poA->_nameSpace);
165                     	      op.setHost(System::getHostName());
166                     	      co.setPath(op);
167 brian.campbell 1.10 				toResponse->cimObjects.append(co);
168                     			}
169                     		}
170                     
171                     		poA->deleteResponse(i);
172                     		if (i == 0)
173                     			break;
174                     	} // for all responses in response list
175                     
176                     	// if we started with an enumerateInstances repsonse, then add it to overall
177                     	if (startIndex == 0)
178                     		poA->appendResponse(toResponse);
179                     
180                     	PEG_METHOD_EXIT();
181 schuur         1.1  }
182                     
183                     
184                     
185                     void WQLOperationRequestDispatcher::handleQueryRequest(
186                        CIMExecQueryRequestMessage* request)
187                     {
188                        Boolean exception=false;
189 a.arora        1.2     AutoPtr<WQLSelectStatement> selectStatement(new WQLSelectStatement());
190                        AutoPtr<WQLQueryExpressionRep> qx;
191 schuur         1.1     CIMException cimException;
192                        CIMName className;
193                     
194                        //if (getenv("CMPI_DEBUG")) asm("int $3");
195                        PEG_METHOD_ENTER(TRC_DISPATCHER,
196                           "CIMOperationRequestDispatcher::handleExecQueryRequest");
197                     
198                         if (request->queryLanguage!="WQL") {
199                           cimException =
200                              PEGASUS_CIM_EXCEPTION(CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED, request->queryLanguage);
201                           exception=true;
202                        }
203                        else {
204                           try {
205 a.arora        1.2           WQLParser::parse(request->query, *selectStatement.get());
206 schuur         1.1  	 className=selectStatement->getClassName();
207 a.arora        1.2  	 qx.reset(new WQLQueryExpressionRep("WQL",selectStatement.get()));
208 a.dunfey       1.7  	 selectStatement.release();
209 schuur         1.1        }
210 brian.campbell 1.9        catch (ParseError&) {
211 schuur         1.1           cimException =
212                                 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
213                              exception=true;
214                           }
215 brian.campbell 1.9        catch (MissingNullTerminator&) {
216 schuur         1.1           cimException =
217                                 PEGASUS_CIM_EXCEPTION(CIM_ERR_INVALID_QUERY, request->query);
218                              exception=true;
219                           }
220                     
221                           if (exception==false) {
222                             _checkExistenceOfClass(request->nameSpace,
223                                                className,
224                                                cimException);
225                             if (cimException.getCode() != CIM_ERR_SUCCESS)
226                     	   exception=true;
227                           }
228                        }
229                     
230                        if (exception) {
231                        Array<CIMObject> cimObjects;
232                     
233 a.arora        1.2     AutoPtr<CIMExecQueryResponseMessage> response(
234 schuur         1.1        new CIMExecQueryResponseMessage(
235                     	 request->messageId,
236                     	 cimException,
237                     	 request->queueIds.copyAndPop(),
238 a.arora        1.2  	 cimObjects));
239 schuur         1.1  
240                             STAT_COPYDISPATCHER_REP
241 a.arora        1.2          _enqueueResponse(request, response.release());
242 schuur         1.1          PEG_METHOD_EXIT();
243                             return;
244                         }
245                     
246                         //
247                         // Get names of descendent classes:
248                         //
249                         Array<ProviderInfo> providerInfos;
250                     
251                         // This gets set by _lookupAllInstanceProviders()
252                         Uint32 providerCount;
253                     
254                         try {
255                             providerInfos = _lookupAllInstanceProviders(request->nameSpace,
256                                                                         className,
257                     				  //                request->className,
258                                                                         providerCount,
259                     						    true);
260                         }
261                         catch(CIMException& exception) {
262                             // Return exception response if exception from getSubClasses
263 schuur         1.1          cimException = exception;
264 a.arora        1.2          AutoPtr<CIMExecQueryResponseMessage> response(
265 schuur         1.1          new CIMExecQueryResponseMessage(request->messageId,
266                                 cimException,
267                                 request->queueIds.copyAndPop(),
268 a.arora        1.2              Array<CIMObject>()));
269 schuur         1.1  
270 w.white        1.5  		STAT_COPYDISPATCHER_REP
271                     
272 a.arora        1.2          _enqueueResponse(request, response.release());
273 schuur         1.1          PEG_METHOD_EXIT();
274                             return;
275                         }
276                     
277                         // Test for "enumerate too Broad" and if so, execute exception.
278                         // This limits the number of provider invocations, not the number
279                         // of instances returned.
280                         if(providerCount > _maximumEnumerateBreadth)
281                         {
282                             Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
283                                         "Request-too-broad exception.  Namespace: $0  "
284                                             "Class Name: $1 Limit: $2  ProviderCount: $3",
285                                         request->nameSpace.getString(),
286                                         request->className.getString(),
287                                         _maximumEnumerateBreadth, providerCount);
288                     
289                             PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4,
290                                 Formatter::format("ERROR Enumerate too broad for class $0. "
291                                                       "Limit = $1, Request = $2",
292                                                   request->className.getString(),
293                                                   _maximumEnumerateBreadth,
294 schuur         1.1                                providerCount));
295                     
296                             // l10n
297                     
298 a.arora        1.2          AutoPtr<CIMExecQueryResponseMessage> response(
299 schuur         1.1              new CIMExecQueryResponseMessage(request->messageId,
300                                     PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
301                                         MessageLoaderParms("Server.CIMOperationRequestDispatcher."
302                                             "QUERY_REQ_TOO_BROAD", "Query request too Broad")),
303                                     request->queueIds.copyAndPop(),
304 a.arora        1.2                  Array<CIMObject>()));
305 schuur         1.1  
306                        STAT_COPYDISPATCHER
307                     
308 a.arora        1.2     _enqueueResponse(request, response.release());
309 schuur         1.1          PEG_METHOD_EXIT();
310                             return;
311                         }
312                     
313                         // If no provider is registered and the repository isn't the default,
314                         // return CIM_ERR_NOT_SUPPORTED
315                         if ((providerCount == 0) && !(_repository->isDefaultInstanceProvider()))
316                         {
317                             PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4,
318                                 "CIM_ERROR_NOT_SUPPORTED for " + request->className.getString());
319                     
320 a.arora        1.2          AutoPtr<CIMExecQueryResponseMessage> response(
321 schuur         1.1              new CIMExecQueryResponseMessage(request->messageId,
322                                     PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_SUPPORTED, String::EMPTY),
323                                     request->queueIds.copyAndPop(),
324 a.arora        1.2                  Array<CIMObject>()));
325 schuur         1.1  
326                        STAT_COPYDISPATCHER
327                     
328 a.arora        1.2     _enqueueResponse(request, response.release());
329 schuur         1.1     PEG_METHOD_EXIT();
330                             return;
331                         }
332                     
333                         // We have instances for Providers and possibly repository.
334                         // Set up an aggregate object and save a copy of the original request.
335                     
336                         OperationAggregate *poA= new OperationAggregate(
337                             new CIMExecQueryRequestMessage(*request),
338                             request->getType(),
339                             request->messageId,
340                             request->queueIds.top(),
341 brian.campbell 1.9          className, CIMNamespaceName(),
342 a.arora        1.2  	qx.release(),
343 schuur         1.1  	"WQL");
344                     
345                         // Set the number of expected responses in the OperationAggregate
346                         Uint32 numClasses = providerInfos.size();
347                         poA->_aggregationSN = cimOperationAggregationSN++;
348                         poA->_nameSpace=request->nameSpace;
349                     
350                         if (_repository->isDefaultInstanceProvider())
351 brian.campbell 1.10     {
352                     			// Loop through providerInfos, forwarding requests to repository
353                     			for (Uint32 i = 0; i < numClasses; i++)
354                     			{
355                     				ProviderInfo &providerInfo = providerInfos[i];
356                     			
357                     				// this class is registered to a provider - skip
358                     				if (providerInfo.hasProvider)
359                     					continue;
360                     
361                     				// If this class does not have a provider
362                     				
363                     				PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4,  Formatter::format
364                     												 ("ExcecQuery Req. class $0 to repository, "
365                     													"No $1 of $2, SN $3",
366                     													providerInfo.className.getString(),
367                     													i, numClasses, poA->_aggregationSN));
368                     				
369                     				CIMException cimException;
370                     				Array<CIMInstance> cimInstances;
371                     				STAT_PROVIDERSTART
372 brian.campbell 1.10 
373                     				try
374                     				{
375                     					// Enumerate instances only for this class
376                     					cimInstances =
377                     						_repository->enumerateInstancesForClass(
378                     																										request->nameSpace,
379                     																										providerInfo.className,
380                     																										false);
381                     				}
382                     				catch(CIMException& exception)
383                     				{
384                     					cimException = exception;
385                     				}
386                     				catch(Exception& exception)
387                     				{
388                     					cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
389                     																							 exception.getMessage());
390                     				}
391                     				catch(...)
392                     				{
393 brian.campbell 1.10 					cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
394                     																							 String::EMPTY);
395                     				}
396                     				
397                     				STAT_PROVIDEREND
398                     
399                     				AutoPtr<CIMEnumerateInstancesResponseMessage> response
400                     					(new CIMEnumerateInstancesResponseMessage
401                     					 (request->messageId,	cimException, request->queueIds.copyAndPop(),
402                     						cimInstances));
403                     
404                     				STAT_COPYDISPATCHER_REP
405                     
406                     				poA->appendResponse(response.release());
407                     			} // for all classes and derived classes
408                     
409                     			Uint32 numberResponses = poA->numberResponses();
410                     			Uint32 totalIssued = providerCount + (numberResponses > 0 ? 1 : 0);
411                     			poA->setTotalIssued(totalIssued);
412                     			
413                     			if (numberResponses > 0)
414 brian.campbell 1.10 			{
415                     				handleEnumerateInstancesResponseAggregation(poA);
416                     				CIMResponseMessage *response = poA->removeResponse(0);
417                     				_forwardRequestForAggregation(String(PEGASUS_QUEUENAME_OPREQDISPATCHER),
418                     																			String(), 
419                     																			new CIMExecQueryRequestMessage(*request),
420                     																			poA, response);
421                     			}
422                         } // if isDefaultInstanceProvider
423                     		else
424                     		{
425                     			// Set the number of expected responses in the OperationAggregate
426                     			poA->setTotalIssued(providerCount);
427                     		}
428 schuur         1.1  
429                         // Loop through providerInfos, forwarding requests to providers
430                         for (Uint32 i = 0; i < numClasses; i++)
431                         {
432                             // If this class has a provider
433 brian.campbell 1.10 			ProviderInfo &providerInfo = providerInfos[i];
434 schuur         1.1  
435 brian.campbell 1.10 			// this class is NOT registered to a provider - skip
436                     			if (! providerInfo.hasProvider)
437                     				continue;
438                     
439                     			STAT_PROVIDERSTART
440                     
441                     			PEG_TRACE_STRING(TRC_DISPATCHER, Tracer::LEVEL4, Formatter::format
442                     											 ("Query Req. class $0 to svc \"$1\" for "
443                     												"control provider \"$2\", No $3 of $4, SN $5",
444                     												providerInfo.className.getString(),
445                     												providerInfo.serviceName,
446                     												providerInfo.controlProviderName,
447                     												i, numClasses, poA->_aggregationSN));
448                     				
449                     			ProviderIdContainer *providerIdContainer = 
450                     				providerInfo.providerIdContainer.get();
451                     
452                     			if (providerInfo.hasNoQuery && providerIdContainer)
453                     			{
454                     				OperationContext *context = &request->operationContext;
455                     				const OperationContext::Container *container = 0;
456 brian.campbell 1.10 				container = &context->get(IdentityContainer::NAME);
457                     				const IdentityContainer &identityContainer = 
458                     					dynamic_cast<const IdentityContainer &>(*container);
459                     
460                     				CIMEnumerateInstancesRequestMessage *enumReq = new 
461                     					CIMEnumerateInstancesRequestMessage(request->messageId, 
462                     																							request->nameSpace,
463                     																							providerInfo.className,
464                     																							false,false,false,false,
465                     																							CIMPropertyList(),
466                     																							request->queueIds,
467                     																							request->authType,
468                     																							identityContainer.getUserName());
469                     				
470                     				context = &enumReq->operationContext;
471                     				context->insert(*providerIdContainer);
472                     				context->insert(identityContainer);
473                     				_forwardRequestForAggregation(providerInfo.serviceName,
474                     																			providerInfo.controlProviderName,
475                     																			enumReq, poA);
476                     	    }
477 brian.campbell 1.10 	    else
478                     			{
479                     				AutoPtr<CIMExecQueryRequestMessage> requestCopy
480                     					(new CIMExecQueryRequestMessage(*request));
481                     
482                     				requestCopy->className = providerInfo.className;
483                     
484                     				_forwardRequestForAggregation(providerInfo.serviceName,
485                     																			providerInfo.controlProviderName,
486                     																			requestCopy.release(), poA);
487 schuur         1.1  	    }
488 brian.campbell 1.10 			
489                     			STAT_PROVIDEREND
490 schuur         1.1  
491 brian.campbell 1.10     } // for all classes and derived classes
492 schuur         1.1  
493                        PEG_METHOD_EXIT();
494 brian.campbell 1.10 	 return;
495 schuur         1.1  }
496                     
497                     
498                     PEGASUS_NAMESPACE_END
499                     

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2