// Need a static method to act as a callback for the control provider. // This doesn't belong here, but I don't have a better place to put it. static Message* controlProviderReceiveMessageCallback( Message* message, void* instance) { CIMRequestMessage* request = dynamic_cast<CIMRequestMessage*>(message); PEGASUS_ASSERT(request != 0); Thread::setLanguages( ((AcceptLanguageListContainer) request->operationContext.get( AcceptLanguageListContainer::NAME)).getLanguages()); ProviderMessageHandler* pmh = reinterpret_cast<ProviderMessageHandler*>(instance); MessageType reqType = request->getType(); if (reqType == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) { pmh->terminate(); return 0; } else if (reqType == CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) { pmh->subscriptionInitComplete(); return 0; } else if (reqType == CIM_INDICATION_SERVICE_DISABLED_REQUEST_MESSAGE) { pmh->indicationServiceDisabled(); return 0; } return pmh->processMessage(request); }
Message* DefaultProviderManager::processMessage(Message* message) { PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "DefaultProviderManager::processMessage()"); CIMRequestMessage* request = dynamic_cast<CIMRequestMessage*>(message); PEGASUS_ASSERT(request != 0); CIMResponseMessage* response = 0; try { // pass the request message to a handler method based on message type switch(request->getType()) { case CIM_GET_INSTANCE_REQUEST_MESSAGE: case CIM_ENUMERATE_INSTANCES_REQUEST_MESSAGE: case CIM_ENUMERATE_INSTANCE_NAMES_REQUEST_MESSAGE: case CIM_CREATE_INSTANCE_REQUEST_MESSAGE: case CIM_MODIFY_INSTANCE_REQUEST_MESSAGE: case CIM_DELETE_INSTANCE_REQUEST_MESSAGE: case CIM_EXEC_QUERY_REQUEST_MESSAGE: case CIM_ASSOCIATORS_REQUEST_MESSAGE: case CIM_ASSOCIATOR_NAMES_REQUEST_MESSAGE: case CIM_REFERENCES_REQUEST_MESSAGE: case CIM_REFERENCE_NAMES_REQUEST_MESSAGE: case CIM_GET_PROPERTY_REQUEST_MESSAGE: case CIM_SET_PROPERTY_REQUEST_MESSAGE: case CIM_INVOKE_METHOD_REQUEST_MESSAGE: case CIM_CREATE_SUBSCRIPTION_REQUEST_MESSAGE: case CIM_MODIFY_SUBSCRIPTION_REQUEST_MESSAGE: case CIM_DELETE_SUBSCRIPTION_REQUEST_MESSAGE: case CIM_EXPORT_INDICATION_REQUEST_MESSAGE: { ProviderIdContainer providerId = request->operationContext.get(ProviderIdContainer::NAME); // resolve provider name ProviderName name = _resolveProviderName(providerId); // get cached or load new provider module ProviderOperationCounter poc( _getProvider( name.getPhysicalName(), name.getModuleName(), name.getLogicalName())); response = poc.GetProvider().processMessage(request); break; } case CIM_DISABLE_MODULE_REQUEST_MESSAGE: response = _handleDisableModuleRequest(request); break; case CIM_ENABLE_MODULE_REQUEST_MESSAGE: response = _handleEnableModuleRequest(request); break; case CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE: // tell the provider manager to shutdown all the providers _shutdownAllProviders(); response = request->buildResponse(); break; case CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE: response = _handleSubscriptionInitCompleteRequest(request); break; case CIM_INDICATION_SERVICE_DISABLED_REQUEST_MESSAGE: response = _handleIndicationServiceDisabledRequest(request); break; default: PEGASUS_UNREACHABLE(PEGASUS_ASSERT(0);) break; } } catch (CIMException& e) { PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL1,"CIMException: %s", (const char*)e.getMessage().getCString())); response = request->buildResponse(); response->cimException = PEGASUS_CIM_EXCEPTION_LANG( e.getContentLanguages(), e.getCode(), e.getMessage()); } catch (Exception& e) { PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL1,"Exception: %s", (const char*)e.getMessage().getCString())); response = request->buildResponse(); response->cimException = PEGASUS_CIM_EXCEPTION_LANG( e.getContentLanguages(), CIM_ERR_FAILED, e.getMessage()); } catch (...) { PEG_TRACE_CSTRING(TRC_PROVIDERMANAGER, Tracer::LEVEL1, "Exception: Unknown"); response = request->buildResponse(); response->cimException = PEGASUS_CIM_EXCEPTION( CIM_ERR_FAILED, "Unknown error."); } PEG_METHOD_EXIT(); return response; }
Boolean ProviderAgent::_readAndProcessRequest() { PEG_METHOD_ENTER(TRC_PROVIDERAGENT, "ProviderAgent::_readAndProcessRequest"); CIMRequestMessage* request; // // Read the request from CIM Server // CIMMessage* cimMessage; AnonymousPipe::Status readStatus = _pipeFromServer->readMessage(cimMessage); request = dynamic_cast<CIMRequestMessage*>(cimMessage); // Read operation was interrupted if (readStatus == AnonymousPipe::STATUS_INTERRUPT) { PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL1, "Read operation was interrupted."); PEG_METHOD_EXIT(); return false; } if (readStatus == AnonymousPipe::STATUS_CLOSED) { // The CIM Server connection is closed PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL2, "CIMServer connection closed. Exiting."); _terminating = true; PEG_METHOD_EXIT(); return false; } if (readStatus == AnonymousPipe::STATUS_ERROR) { PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL1, "Error reading from pipe. Exiting."); Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING, MessageLoaderParms( "ProviderManager.ProviderAgent.ProviderAgent." "CIMSERVER_COMMUNICATION_FAILED", "cimprovagt \"$0\" communication with CIM Server failed. " "Exiting.", _agentId)); _terminating = true; PEG_METHOD_EXIT(); return false; } // The message was not a request message. if (request == 0) { // The message was not empty. if (0 != cimMessage ) { // The message was not a "wake up" message. if (cimMessage->getType() == PROVAGT_GET_SCMOCLASS_RESPONSE_MESSAGE) { PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL3, "Processing a SCMOClassResponseMessage."); AutoPtr<ProvAgtGetScmoClassResponseMessage> response( dynamic_cast<ProvAgtGetScmoClassResponseMessage*> (cimMessage)); PEGASUS_DEBUG_ASSERT(response.get()); _processGetSCMOClassResponse(response.get()); // The provider agent is still busy. PEG_METHOD_EXIT(); return true; } } // A "wake up" message means we should unload idle providers PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL4, "Got a wake up message."); if (!_providerManagerRouter.hasActiveProviders()) { // No active providers, so do not start an idle unload thread return false; } try { _unloadIdleProviders(); } catch (...) { // Ignore exceptions from idle provider unloading PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL2, "Ignoring exception from _unloadIdleProviders()"); } PEG_METHOD_EXIT(); return false; } PEG_TRACE((TRC_PROVIDERAGENT, Tracer::LEVEL3, "Received request from server with messageId %s", (const char*)request->messageId.getCString())); const AcceptLanguageListContainer acceptLang = request->operationContext.get(AcceptLanguageListContainer::NAME); Thread::setLanguages(acceptLang.getLanguages()); // Get the ProviderIdContainer to complete the provider module instance // optimization. If the provider module instance is blank (optimized // out), fill it in from our cache. If it is not blank, update our // cache. (See the _providerModuleCache member description.) if (request->operationContext.contains(ProviderIdContainer::NAME)) { ProviderIdContainer pidc = request->operationContext.get( ProviderIdContainer::NAME); if (pidc.getModule().isUninitialized()) { // Provider module is optimized out. Fill it in from the cache. request->operationContext.set(ProviderIdContainer( _providerModuleCache, pidc.getProvider(), pidc.isRemoteNameSpace(), pidc.getRemoteInfo())); } else { // Update the cache with the new provider module instance. _providerModuleCache = pidc.getModule(); } } // // It never should be possible to receive a request other than "initialise" // before the provider agent is in state isInitialised // // Bail out. // if (!_isInitialised && (request->getType() != CIM_INITIALIZE_PROVIDER_AGENT_REQUEST_MESSAGE)) { Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING, MessageLoaderParms( "ProviderManager.ProviderAgent.ProviderAgent." "PROVIDERAGENT_NOT_INITIALIZED", "cimprovagt \"$0\" was not yet initialized " "prior to receiving a request message. Exiting.", _agentId)); _terminating = true; PEG_METHOD_EXIT(); return false; } // // Check for messages to be handled by the Agent itself. // if (request->getType() == CIM_INITIALIZE_PROVIDER_AGENT_REQUEST_MESSAGE) { // Process the request in this thread AutoPtr<CIMInitializeProviderAgentRequestMessage> ipaRequest( dynamic_cast<CIMInitializeProviderAgentRequestMessage*>(request)); PEGASUS_ASSERT(ipaRequest.get() != 0); ConfigManager::setPegasusHome(ipaRequest->pegasusHome); ConfigManager* configManager = ConfigManager::getInstance(); // Initialize the configuration properties for (Uint32 i = 0; i < ipaRequest->configProperties.size(); i++) { configManager->initCurrentValue( ipaRequest->configProperties[i].first, ipaRequest->configProperties[i].second); } // Set the default resource bundle directory for the MessageLoader MessageLoader::setPegasusMsgHome(ConfigManager::getHomedPath( configManager->getCurrentValue("messageDir"))); // Set the log file directory #if !defined(PEGASUS_USE_SYSLOGS) Logger::setHomeDirectory(ConfigManager::getHomedPath( configManager->getCurrentValue("logdir"))); #endif System::bindVerbose = ipaRequest->bindVerbose; // // Set _subscriptionInitComplete from value in // InitializeProviderAgent request // _providerManagerRouter.setSubscriptionInitComplete (ipaRequest->subscriptionInitComplete); PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL2, "Processed the agent initialization message."); // Notify the cimserver that the provider agent is initialized. Uint32 messageLength = 0; _pipeToServer->writeBuffer((const char*)&messageLength, sizeof(Uint32)); #if defined(PEGASUS_OS_ZOS) && defined(PEGASUS_ZOS_SECURITY) // prepare and setup the thread-level security environment on z/OS // if security initialization fails startupCheckBPXServer(false); startupCheckMSC(); if (!isZOSSecuritySetup()) { Logger::put_l(Logger::ERROR_LOG, ZOS_SECURITY_NAME, Logger::FATAL, MessageLoaderParms( "ProviderManager.ProviderAgent.ProviderAgent." "UNINITIALIZED_SECURITY_SETUP.PEGASUS_OS_ZOS", "Security environment could not be initialised. " "Assume security fraud. Stopping Provider Agent.")); exit(1); } #endif // provider agent is initialised and ready to go _isInitialised = true; } else if (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE) { // Process the request in this thread AutoPtr<CIMNotifyConfigChangeRequestMessage> notifyRequest( dynamic_cast<CIMNotifyConfigChangeRequestMessage*>(request)); PEGASUS_ASSERT(notifyRequest.get() != 0); // // Update the ConfigManager with the new property value // ConfigManager* configManager = ConfigManager::getInstance(); CIMException responseException; try { if (notifyRequest->currentValueModified) { String userName = ((IdentityContainer) request->operationContext.get( IdentityContainer::NAME)).getUserName(); configManager->updateCurrentValue( notifyRequest->propertyName, notifyRequest->newPropertyValue, userName, 0, false); } else { configManager->updatePlannedValue( notifyRequest->propertyName, notifyRequest->newPropertyValue, true); } } catch (Exception& e) { responseException = PEGASUS_CIM_EXCEPTION( CIM_ERR_FAILED, e.getMessage()); } AutoPtr<CIMResponseMessage> response(notifyRequest->buildResponse()); response->cimException = responseException; // Return response to CIM Server _writeResponse(response.get()); } else if ((request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE) || (request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE)) { // Process the request in this thread AutoPtr<Message> response(_processRequest(request)); _writeResponse(response.get()); CIMResponseMessage * respMsg = dynamic_cast<CIMResponseMessage*>(response.get()); // If StopAllProviders, terminate the agent process. // If DisableModule not successful, leave agent process running. if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) || ((request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE) && (!dynamic_cast<CIMDisableModuleRequestMessage*>(request)-> disableProviderOnly) && (respMsg->cimException.getCode() == CIM_ERR_SUCCESS))) { // Operation is successful. End the agent process. _providersStopped = true; _terminating = true; } delete request; } else if (request->getType () == CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE || request->getType () == CIM_INDICATION_SERVICE_DISABLED_REQUEST_MESSAGE) { // // Process the request in this thread // AutoPtr <Message> response (_processRequest (request)); _writeResponse (response.get ()); // // Note: the response does not contain interesting data // delete request; } else { // Start a new thread to process the request ProviderAgentRequest* agentRequest = new ProviderAgentRequest(this, request); ThreadStatus rtn = PEGASUS_THREAD_OK; while ((rtn = _threadPool.allocate_and_awaken(agentRequest, ProviderAgent::_processRequestAndWriteResponse)) != PEGASUS_THREAD_OK) { if (rtn == PEGASUS_THREAD_INSUFFICIENT_RESOURCES) { Threads::yield(); } else { PEG_TRACE_CSTRING(TRC_PROVIDERAGENT, Tracer::LEVEL1, "Could not allocate thread to process agent request."); AutoPtr<CIMResponseMessage> response(request->buildResponse()); response->cimException = PEGASUS_CIM_EXCEPTION_L( CIM_ERR_FAILED, MessageLoaderParms( "ProviderManager.ProviderAgent.ProviderAgent." "THREAD_ALLOCATION_FAILED", "Failed to allocate a thread in cimprovagt \"$0\".", _agentId)); // Return response to CIM Server _writeResponse(response.get()); delete agentRequest; delete request; break; } } } PEG_METHOD_EXIT(); return true; }
Message* BasicProviderManagerRouter::processMessage(Message * message) { PEG_METHOD_ENTER(TRC_PROVIDERMANAGER, "BasicProviderManagerRouter::processMessage"); CIMRequestMessage* request = dynamic_cast<CIMRequestMessage *>(message); PEGASUS_ASSERT(request != 0); Message* response = 0; Boolean remoteNameSpaceRequest=false; // // Retrieve the ProviderManager routing information // CIMInstance providerModule; if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) || (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE)) { // Provider information is in OperationContext ProviderIdContainer pidc = (ProviderIdContainer) request->operationContext.get(ProviderIdContainer::NAME); providerModule = pidc.getModule(); remoteNameSpaceRequest=pidc.isRemoteNameSpace(); } else if (dynamic_cast<CIMIndicationRequestMessage*>(request) != 0) { // Provider information is in CIMIndicationRequestMessage CIMIndicationRequestMessage* indReq = dynamic_cast<CIMIndicationRequestMessage*>(request); ProviderIdContainer pidc = indReq->operationContext.get(ProviderIdContainer::NAME); providerModule = pidc.getModule(); } else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE) { // Provider information is in CIMEnableModuleRequestMessage CIMEnableModuleRequestMessage* emReq = dynamic_cast<CIMEnableModuleRequestMessage*>(request); providerModule = emReq->providerModule; } else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE) { // Provider information is in CIMDisableModuleRequestMessage CIMDisableModuleRequestMessage* dmReq = dynamic_cast<CIMDisableModuleRequestMessage*>(request); providerModule = dmReq->providerModule; } else if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) || (request->getType() == CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) || (request->getType() == CIM_INDICATION_SERVICE_DISABLED_REQUEST_MESSAGE) || (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE)) { // This operation is not provider-specific } else { // Error: Unrecognized message type. PEGASUS_ASSERT(0); CIMResponseMessage* resp = request->buildResponse(); resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "Unknown message type."); response = resp; } // // Forward the request to the appropriate ProviderManager(s) // if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) || (request->getType() == CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) || (request->getType() == CIM_INDICATION_SERVICE_DISABLED_REQUEST_MESSAGE)) { if (request->getType() == CIM_INDICATION_SERVICE_DISABLED_REQUEST_MESSAGE) { _subscriptionInitComplete = false; } else { _subscriptionInitComplete = true; } // Send CIMStopAllProvidersRequestMessage or // CIMIndicationServiceDisabledRequestMessage or // CIMSubscriptionInitCompleteRequestMessage to all ProviderManagers ReadLock tableLock(_providerManagerTableLock); for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++) { ProviderManagerContainer* pmc=_providerManagerTable[i]; Message* resp = pmc->getProviderManager()->processMessage(request); delete resp; } response = request->buildResponse(); } else if (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE) { // Do not need to forward this request to in-process provider // managers response = request->buildResponse(); } else { // Retrieve the provider interface type String interfaceType; CIMValue itValue = providerModule.getProperty( providerModule.findProperty("InterfaceType")).getValue(); itValue.get(interfaceType); // Get ProviderModule name. String providerModuleName; CIMValue nameValue = providerModule.getProperty( providerModule.findProperty(PEGASUS_PROPERTYNAME_NAME)).getValue(); nameValue.get(providerModuleName); // Get providerManager path String provMgrPath; if (request->operationContext.contains(ProviderIdContainer::NAME)) { ProviderIdContainer pidc = (ProviderIdContainer) request->operationContext.get(ProviderIdContainer::NAME); provMgrPath = pidc.getProvMgrPath(); } ProviderManager* pm = 0; Boolean gotError = false; try { // Look up the appropriate ProviderManager by InterfaceType pm = _getProviderManager(interfaceType, providerModuleName, provMgrPath); } catch (const CIMException& e) { // This is not an error incase of CIMEnableModuleRequestMessage or // CIMDisableModuleRequestMessage. This means there is no provider // to enable or disable. if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE) { CIMEnableModuleResponseMessage* emResponse = dynamic_cast<CIMEnableModuleResponseMessage*>( request->buildResponse()); emResponse->operationalStatus.append( CIM_MSE_OPSTATUS_VALUE_OK); response = emResponse; } else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE) { CIMDisableModuleResponseMessage* dmResponse = dynamic_cast<CIMDisableModuleResponseMessage*>( request->buildResponse()); dmResponse->operationalStatus.append( CIM_MSE_OPSTATUS_VALUE_STOPPED); response = dmResponse; } else { CIMResponseMessage *cimResponse = request->buildResponse(); cimResponse->cimException = e; response = cimResponse; } gotError = true; } if (!gotError && remoteNameSpaceRequest && !pm->supportsRemoteNameSpaces()) { CIMResponseMessage* resp = request->buildResponse(); resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "Remote Namespace operations not supported for interface type " + interfaceType); response = resp; gotError = true; } if (!gotError) { response = pm->processMessage(request); } } PEG_METHOD_EXIT(); return response; }