//
// Send notify config change message to provider manager service
// This code was borrowed from the ConfigSettingProvider and should
// be kept in sync.
// The purpose is to ensure that OOP agents also get the update.
// TBD, or is it for other reasons as well?
//
void ZOSConsoleManager::_sendNotifyConfigChangeMessage(
    const String& propertyName,
    const String& newPropertyValue,
    Boolean currentValueModified)
{
    PEG_METHOD_ENTER(TRC_SERVER,
                     "ZOSConsoleManager::_sendNotifyConfigChangeMessage");

    ModuleController* controller = ModuleController::getModuleController();

    MessageQueue * queue = MessageQueue::lookup(
                               PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP);

    MessageQueueService * service = dynamic_cast<MessageQueueService *>(queue);

    if (service != NULL)
    {
        // create CIMNotifyConfigChangeRequestMessage
        CIMNotifyConfigChangeRequestMessage * notify_req =
            new CIMNotifyConfigChangeRequestMessage (
            XmlWriter::getNextMessageId (),
            propertyName,
            newPropertyValue,
            currentValueModified,
            QueueIdStack(service->getQueueId()));

        notify_req->operationContext.insert(
            IdentityContainer(System::getEffectiveUserName()));

        // create request envelope
        AsyncLegacyOperationStart asyncRequest(
            NULL,
            service->getQueueId(),
            notify_req);

        AutoPtr<AsyncReply> asyncReply(
            controller->ClientSendWait(service->getQueueId(), &asyncRequest));

        AutoPtr<CIMNotifyConfigChangeResponseMessage> response(
            reinterpret_cast<CIMNotifyConfigChangeResponseMessage *>(
                (static_cast<AsyncLegacyOperationResult *>
                 (asyncReply.get()))->get_result()));

        if (response->cimException.getCode() != CIM_ERR_SUCCESS)
        {
            CIMException e = response->cimException;
            const CString exMsg = e.getMessage().getCString();
            PEG_TRACE((TRC_SERVER, Tracer::LEVEL1,
                       "Notify config changed failed with rc=%d, message = %s",
                       e.getCode(),
                       (const char*)exMsg));

            PEG_METHOD_EXIT();
        }
    }
    PEG_METHOD_EXIT();
}
const IdentityContainer&
Pib::getIdentities() const
{
  if (m_needRefreshIdentities) {
    m_identities = IdentityContainer(m_impl->getIdentities(), m_impl);
    m_needRefreshIdentities = false;
  }

  return m_identities;
}
//
// send notify config change message to provider manager service
//
void ConfigSettingProvider::_sendNotifyConfigChangeMessage(
    const String& propertyName,
    const String& newPropertyValue,
    const String& userName,
    const char *queueName,
    Boolean currentValueModified)
{
    PEG_METHOD_ENTER(TRC_CONFIG,
        "ConfigSettingProvider::_sendNotifyConfigChangeMessage");

    ModuleController* controller = ModuleController::getModuleController();

    MessageQueue * queue = MessageQueue::lookup(queueName);

    MessageQueueService * service = dynamic_cast<MessageQueueService *>(queue);

    if (service != NULL)
    {
        // create CIMNotifyConfigChangeRequestMessage
        CIMNotifyConfigChangeRequestMessage * notify_req =
            new CIMNotifyConfigChangeRequestMessage (
            XmlWriter::getNextMessageId (),
            propertyName,
            newPropertyValue,
            currentValueModified,
            QueueIdStack(service->getQueueId()));

        notify_req->operationContext.insert(
            IdentityContainer(userName));

        // create request envelope
        AsyncLegacyOperationStart asyncRequest(
            NULL,
            service->getQueueId(),
            notify_req);

        AutoPtr<AsyncReply> asyncReply(
            controller->ClientSendWait(service->getQueueId(), &asyncRequest));

        AutoPtr<CIMNotifyConfigChangeResponseMessage> response(
            reinterpret_cast<CIMNotifyConfigChangeResponseMessage *>(
            (static_cast<AsyncLegacyOperationResult *>
            (asyncReply.get()))->get_result()));

        if (response->cimException.getCode() != CIM_ERR_SUCCESS)
        {
            CIMException e = response->cimException;
            throw (e);
        }
    }
}
void DefaultPropertyOwner::_requestIndicationServiceStateChange(
    const String& userName,
    Boolean enable,
    Uint32 timeoutSeconds)
{
    MessageQueue *queue = MessageQueue::lookup(
        PEGASUS_QUEUENAME_INDICATIONSERVICE);
    // Return if indication service can not be found
    if (!queue)
    {
        return;
    }

    Uint32 queueId = queue->getQueueId();

    const String METHOD_NAME = "RequestStateChange";
    const String PARAMNAME_REQUESTEDSTATE = "RequestedState";
    const String PARAMNAME_TIMEOUTPERIOD = "TimeoutPeriod";
    const Uint16 STATE_ENABLED = 2;
    const Uint16 STATE_DISABLED = 3;

    String referenceStr("//", 2);
    referenceStr.append(System::getHostName());
    referenceStr.append("/");
    referenceStr.append(PEGASUS_NAMESPACENAME_INTEROP.getString());
    referenceStr.append(":");
    referenceStr.append(
        PEGASUS_CLASSNAME_CIM_INDICATIONSERVICE.getString());
    CIMObjectPath reference(referenceStr);

    Array<CIMParamValue> inParams;
    Array<CIMParamValue> outParams;

    inParams.append(CIMParamValue(PARAMNAME_REQUESTEDSTATE,
        CIMValue(enable ? STATE_ENABLED : STATE_DISABLED)));

    inParams.append(CIMParamValue(PARAMNAME_TIMEOUTPERIOD,
        CIMValue(CIMDateTime(timeoutSeconds * 1000000, true))));

    MessageQueueService *controller = ModuleController::getModuleController();

    try
    {
        CIMInvokeMethodRequestMessage* request =
            new CIMInvokeMethodRequestMessage(
                XmlWriter::getNextMessageId(),
                PEGASUS_NAMESPACENAME_INTEROP,
                referenceStr,
                CIMNameCast(METHOD_NAME),
                inParams,
                QueueIdStack(queueId));

        request->operationContext.insert(
            IdentityContainer(userName));

        AsyncLegacyOperationStart *asyncRequest =
            new AsyncLegacyOperationStart(
                0,
                queueId,
                request);

        AsyncReply * asyncReply = controller->SendWait(asyncRequest);

        CIMInvokeMethodResponseMessage * response =
            reinterpret_cast<CIMInvokeMethodResponseMessage *>(
                (static_cast<AsyncLegacyOperationResult *>(
                    asyncReply))->get_result());

        CIMException e = response->cimException;

        delete response;
        delete asyncRequest;
        delete asyncReply;

        if (e.getCode() != CIM_ERR_SUCCESS)
        {
            throw e;
        }
    }
    catch(const Exception &e)
    {
        PEG_TRACE((TRC_CONFIG,Tracer::LEVEL1,
            "Exception caught while invoking CIM_IndicationService."
                "RequestStateChange()  method: %s",
        (const char*)e.getMessage().getCString()));
        throw;
    }
    catch(...)
    {
        PEG_TRACE_CSTRING(TRC_CONFIG,Tracer::LEVEL1,
            "Unknown exception caught while invoking CIM_IndicationService."
                "RequestStateChange()  method");
        throw;
    }
}
void CIMExportRequestDecoder::handleMethodRequest(
    Uint32 queueId,
    HttpMethod httpMethod,
    char* content,
    const String& requestUri,
    const char* cimProtocolVersionInHeader,
    const char* cimExportMethodInHeader,
    const String& userName,
    const String& ipAddress,
    const AcceptLanguageList& httpAcceptLanguages,
    const ContentLanguageList& httpContentLanguages,
    Boolean closeConnect)
{
    // Set the Accept-Language into the thread for this service.
    // This will allow all code in this thread to get
    // the languages for the messages returned to the client.
    Thread::setLanguages(httpAcceptLanguages);

    //
    // If CIM Listener is shutting down, return error response
    //
    if (_serverTerminating)
    {
        sendHttpError(
            queueId,
            HTTP_STATUS_SERVICEUNAVAILABLE,
            String::EMPTY,
            "CIM Listener is shutting down.",
            closeConnect);
        return;
    }

    // Create a parser:

    XmlParser parser(content);
    XmlEntry entry;
    String messageId;
    const char* cimExportMethodName = "";
    AutoPtr<CIMExportIndicationRequestMessage> request;

    try
    {
        //
        // Process <?xml ... >
        //

        // These values are currently unused
        const char* xmlVersion = 0;
        const char* xmlEncoding = 0;

        XmlReader::getXmlDeclaration(parser, xmlVersion, xmlEncoding);

        // Expect <CIM ...>

        const char* cimVersion = 0;
        const char* dtdVersion = 0;

        XmlReader::getCimStartTag(parser, cimVersion, dtdVersion);

        if (!XmlReader::isSupportedCIMVersion(cimVersion))
        {
            sendHttpError(
                queueId,
                HTTP_STATUS_NOTIMPLEMENTED,
                "unsupported-cim-version",
                String::EMPTY,
                closeConnect);
            return;
        }

        if (!XmlReader::isSupportedDTDVersion(dtdVersion))
        {
            sendHttpError(
                queueId,
                HTTP_STATUS_NOTIMPLEMENTED,
                "unsupported-dtd-version",
                String::EMPTY,
                closeConnect);
            return;
        }

        // Expect <MESSAGE ...>

        String protocolVersion;
        if (!XmlReader::getMessageStartTag(
                    parser, messageId, protocolVersion))
        {
            MessageLoaderParms mlParms(
                "ExportServer.CIMExportRequestDecoder.EXPECTED_MESSAGE_ELEMENT",
                "expected MESSAGE element");

            throw XmlValidationError(parser.getLine(), mlParms);
        }

        // Validate that the protocol version in the header matches the XML

        if (!String::equalNoCase(protocolVersion, cimProtocolVersionInHeader))
        {
            sendHttpError(
                queueId,
                HTTP_STATUS_BADREQUEST,
                "header-mismatch",
                String::EMPTY,
                closeConnect);
            return;
        }

        if (!XmlReader::isSupportedProtocolVersion(protocolVersion))
        {
            // See Specification for CIM Operations over HTTP section 4.3
            sendHttpError(
                queueId,
                HTTP_STATUS_NOTIMPLEMENTED,
                "unsupported-protocol-version",
                String::EMPTY,
                closeConnect);
            return;
        }

        if (XmlReader::testStartTag(parser, entry, "MULTIEXPREQ"))
        {
            // We wouldn't have gotten here if CIMExportBatch header was
            // specified, so this must be indicative of a header mismatch
            sendHttpError(
                queueId,
                HTTP_STATUS_BADREQUEST,
                "header-mismatch",
                String::EMPTY,
                closeConnect);
            return;
            // Future: When MULTIEXPREQ is supported, must ensure
            // CIMExportMethod header is absent, and CIMExportBatch header
            // is present.
        }

        // Expect <SIMPLEEXPREQ ...>

        XmlReader::expectStartTag(parser, entry, "SIMPLEEXPREQ");

        // Expect <EXPMETHODCALL ...>

        if (!XmlReader::getEMethodCallStartTag(parser, cimExportMethodName))
        {
            MessageLoaderParms mlParms(
                "ExportServer.CIMExportRequestDecoder."
                "EXPECTED_EXPMETHODCALL_ELEMENT",
                "expected EXPMETHODCALL element");

            throw XmlValidationError(parser.getLine(), mlParms);
        }

        // The Specification for CIM Operations over HTTP reads:
        //     3.3.9. CIMExportMethod
        //
        //     This header MUST be present in any CIM Export Request
        //     message that contains a Simple Export Request.
        //
        //     It MUST NOT be present in any CIM Export Response message,
        //     nor in any CIM Export Request message that is not a
        //     Simple Export Request. It MUST NOT be present in any CIM
        //     Operation Request or Response message.
        //
        //     The name of the CIM export method within a Simple Export
        //     Request is defined to be the value of the NAME attribute
        //     of the <EXPMETHODCALL> element.
        //
        //     If a CIM Listener receives a CIM Export Request for which
        //     either:
        //
        //     - The CIMExportMethod header is present but has an invalid
        //       value, or;
        //     - The CIMExportMethod header is not present but the Export
        //       Request Message is a Simple Export Request, or;
        //     - The CIMExportMethod header is present but the Export
        //       Request Message is not a Simple Export Request, or;
        //     - The CIMExportMethod header is present, the Export Request
        //       Message is a Simple Export Request, but the CIMIdentifier
        //       value (when unencoded) does not match the unique method
        //       name within the Simple Export Request,
        //
        //     then it MUST fail the request and return a status of
        //     "400 Bad Request" (and MUST include a CIMError header in the
        //     response with a value of header-mismatch), subject to the
        //     considerations specified in Errors.
        if (System::strcasecmp(
                    cimExportMethodName, cimExportMethodInHeader) != 0)
        {
            // ATTN-RK-P3-20020404: How to decode cimExportMethodInHeader?
            sendHttpError(
                queueId,
                HTTP_STATUS_BADREQUEST,
                "header-mismatch",
                String::EMPTY,
                closeConnect);
            return;
        }

        // This try block only catches CIMExceptions, because they must be
        // responded to with a proper EMETHODRESPONSE.  Other exceptions are
        // caught in the outer try block.
        try
        {
            // Delegate to appropriate method to handle:

            if (System::strcasecmp(
                        cimExportMethodName, "ExportIndication") == 0)
            {
                request.reset(decodeExportIndicationRequest(
                                  queueId, parser, messageId, requestUri));
            }
            else
            {
                throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_NOT_SUPPORTED,
                                              MessageLoaderParms(
                                                  "ExportServer.CIMExportRequestDecoder."
                                                  "UNRECOGNIZED_EXPORT_METHOD",
                                                  "Unrecognized export method: $0",
                                                  cimExportMethodName));
            }
        }
        catch (CIMException& e)
        {
            sendEMethodError(
                queueId,
                httpMethod,
                messageId,
                cimExportMethodName,
                e,
                closeConnect);

            return;
        }

        // Expect </EXPMETHODCALL>

        XmlReader::expectEndTag(parser, "EXPMETHODCALL");

        // Expect </SIMPLEEXPREQ>

        XmlReader::expectEndTag(parser, "SIMPLEEXPREQ");

        // Expect </MESSAGE>

        XmlReader::expectEndTag(parser, "MESSAGE");

        // Expect </CIM>

        XmlReader::expectEndTag(parser, "CIM");
    }
    catch (XmlValidationError& e)
    {
        PEG_TRACE((TRC_XML,Tracer::LEVEL1,
                   "CIMExportRequestDecoder::handleMethodRequest - "
                   "XmlValidationError exception has occurred. Message: %s",
                   (const char*) e.getMessage().getCString()));

        sendHttpError(
            queueId,
            HTTP_STATUS_BADREQUEST,
            "request-not-valid",
            e.getMessage(),
            closeConnect);
        return;
    }
    catch (XmlSemanticError& e)
    {
        PEG_TRACE((TRC_XML,Tracer::LEVEL1,
                   "CIMExportRequestDecoder::handleMethodRequest - "
                   "XmlSemanticError exception has occurred. Message: %s",
                   (const char*) e.getMessage().getCString()));
        // ATTN-RK-P2-20020404: Is this the correct response for these errors?
        sendHttpError(
            queueId,
            HTTP_STATUS_BADREQUEST,
            "request-not-valid",
            e.getMessage(),
            closeConnect);
        return;
    }
    catch (XmlException& e)
    {
        PEG_TRACE((TRC_XML,Tracer::LEVEL1,
                   "CIMExportRequestDecoder::handleMethodRequest - "
                   "XmlException has occurred. Message: %s",
                   (const char*) e.getMessage().getCString()));

        sendHttpError(
            queueId,
            HTTP_STATUS_BADREQUEST,
            "request-not-well-formed",
            e.getMessage(),
            closeConnect);
        return;
    }
    catch (Exception& e)
    {
        // Don't know why I got this exception.  Seems like a bad thing.
        // Any exceptions we're expecting should be caught separately and
        // dealt with appropriately.  This is a last resort.
        sendHttpError(
            queueId,
            HTTP_STATUS_INTERNALSERVERERROR,
            String::EMPTY,
            e.getMessage(),
            closeConnect);
        return;
    }
    catch (...)
    {
        // Don't know why I got whatever this is.  Seems like a bad thing.
        // Any exceptions we're expecting should be caught separately and
        // dealt with appropriately.  This is a last resort.
        sendHttpError(
            queueId,
            HTTP_STATUS_INTERNALSERVERERROR,
            String::EMPTY,
            String::EMPTY,
            closeConnect);
        return;
    }

// l10n TODO - might want to move A-L and C-L to Message
// to make this more maintainable
    // Add the language headers to the request.
    // Note: Since the text of an export error response will be ignored
    // by the export client, ignore Accept-Language in the export request.
    // This will cause any export error response message to be sent in the
    // default language.
    request->operationContext.insert(IdentityContainer(userName));
    request->operationContext.set(
        ContentLanguageListContainer(httpContentLanguages));
    request->operationContext.set(
        AcceptLanguageListContainer(AcceptLanguageList()));

    request->ipAddress = ipAddress;

    request->setCloseConnect(closeConnect);

    _outputQueue->enqueue(request.release());
}
CIMHandleIndicationResponseMessage*
IndicationHandlerService::_handleIndication(
    CIMHandleIndicationRequestMessage* request)
{
    PEG_METHOD_ENTER(TRC_IND_HANDLER,
        "IndicationHandlerService::_handleIndication()");

    Boolean handleIndicationSuccess = true;
    CIMException cimException =
        PEGASUS_CIM_EXCEPTION(CIM_ERR_SUCCESS, String::EMPTY);

    CIMName className = request->handlerInstance.getClassName();
    CIMNamespaceName nameSpace = request->nameSpace;

    CIMInstance indication = request->indicationInstance;
    CIMInstance handler = request->handlerInstance;

    PEG_TRACE ((TRC_INDICATION_GENERATION, Tracer::LEVEL4,
        "Handler service received %s Indication %s for %s:%s.%s Handler",
        (const char*)(indication.getClassName().getString().getCString()),
        (const char*)(request->messageId.getCString()),
        (const char*)(request->nameSpace.getString().getCString()),
        (const char*)(handler.getClassName().getString().getCString()),
        (const char*)(handler.getProperty(handler.findProperty(
        PEGASUS_PROPERTYNAME_NAME)).getValue().toString().getCString())));
    Uint32 pos = PEG_NOT_FOUND;

    if (className.equal (PEGASUS_CLASSNAME_INDHANDLER_CIMXML) ||
        className.equal (PEGASUS_CLASSNAME_LSTNRDST_CIMXML))
    {
        pos = handler.findProperty(PEGASUS_PROPERTYNAME_LSTNRDST_DESTINATION);

        if (pos == PEG_NOT_FOUND)
        {
            cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                MessageLoaderParms(
                    "HandlerService.IndicationHandlerService."
                        "CIMXML_HANDLER_WITHOUT_DESTINATION",
                    "CIMXml Handler missing Destination property"));
            handleIndicationSuccess = false;
        }
        else
        {
            CIMProperty prop = handler.getProperty(pos);
            String destination = prop.getValue().toString();

            if (destination.size() == 0)
            {
                cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                    MessageLoaderParms(
                        "HandlerService.IndicationHandlerService."
                            "INVALID_DESTINATION",
                        "invalid destination"));
                handleIndicationSuccess = false;
            }
//compared index 10 is not :
            else if (destination.subString(0, 10) == String("localhost/"))
            {
                Uint32 exportServer =
                    find_service_qid(PEGASUS_QUEUENAME_EXPORTREQDISPATCHER);

                // Listener is build with Cimom, so send message to ExportServer
               AutoPtr<CIMExportIndicationRequestMessage> exportmessage( 
                    new CIMExportIndicationRequestMessage(
                        XmlWriter::getNextMessageId(),
                        //taking localhost/CIMListener portion out from reg
                        destination.subString(21),
                        indication,
                        QueueIdStack(exportServer, getQueueId()),
                        String::EMPTY,
                        String::EMPTY));

                exportmessage->operationContext.insert(
                    IdentityContainer(String::EMPTY));
                exportmessage->operationContext.set(
                    request->operationContext.get(
                    ContentLanguageListContainer::NAME)); 
                AutoPtr<AsyncOpNode> op( this->get_op());

                AutoPtr<AsyncLegacyOperationStart> asyncRequest(
                    new AsyncLegacyOperationStart(
                    op.get(),
                    exportServer,
                    exportmessage.get()));

                exportmessage.release();

                PEG_TRACE((TRC_IND_HANDLER, Tracer::LEVEL4,
                    "Indication handler forwarding message to %s",
                        ((MessageQueue::lookup(exportServer)) ?
                            ((MessageQueue::lookup(exportServer))->
                                getQueueName()):
                            "BAD queue name")));
                PEG_TRACE ((TRC_INDICATION_GENERATION, Tracer::LEVEL4,
                    "Sending %s Indication %s to destination %s",
                    (const char*) (indication.getClassName().getString().
                    getCString()),
                    (const char*)(request->messageId.getCString()),
                    (const char*) destination.getCString()));

                //SendAsync(op,
                //      exportServer[0],
                //      IndicationHandlerService::_handleIndicationCallBack,
                //      this,
                //      (void *)request->queueIds.top());
                AutoPtr<AsyncReply> asyncReply(SendWait(asyncRequest.get()));
                asyncRequest.release();

                // Return the ExportIndication results in HandleIndication 
                //response
                AutoPtr<CIMExportIndicationResponseMessage> exportResponse(
                    reinterpret_cast<CIMExportIndicationResponseMessage *>(
                        (static_cast<AsyncLegacyOperationResult *>(
                            asyncReply.get()))->get_result()));
                cimException = exportResponse->cimException;

                this->return_op(op.release());
            }
            else
            {
                handleIndicationSuccess = _loadHandler(request, cimException);
            }
        }
    }
    else if (className.equal (PEGASUS_CLASSNAME_INDHANDLER_SNMP))
    {
        pos = handler.findProperty(PEGASUS_PROPERTYNAME_LSTNRDST_TARGETHOST);

        if (pos == PEG_NOT_FOUND)
        {
            cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                MessageLoaderParms(
                    "HandlerService.IndicationHandlerService."
                        "SNMP_HANDLER_WITHOUT_TARGETHOST",
                    "Snmp Handler missing Targethost property"));
            handleIndicationSuccess = false;
        }
        else
        {
            CIMProperty prop = handler.getProperty(pos);
            String destination = prop.getValue().toString();

            if (destination.size() == 0)
            {
                cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
                    MessageLoaderParms(
                        "HandlerService.IndicationHandlerService."
                            "INVALID_TARGETHOST",
                        "invalid targethost"));
                handleIndicationSuccess = false;
            }
            else
            {
                handleIndicationSuccess = _loadHandler(request, cimException);
            }
        }
    }
    else if ((className.equal (PEGASUS_CLASSNAME_LSTNRDST_SYSTEM_LOG)) ||
             (className.equal (PEGASUS_CLASSNAME_LSTNRDST_EMAIL)))
    {
        handleIndicationSuccess = _loadHandler(request, cimException);
    }

    // no success to handle indication
    // somewhere an exception message was build
    // time to write the error message to the log
    if (!handleIndicationSuccess)
    {
        Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING,
            MessageLoaderParms(
                "HandlerService.IndicationHandlerService."
                    "INDICATION_DELIVERY_FAILED",
                "Failed to deliver an indication: $0",
                cimException.getMessage()));
    }

    CIMHandleIndicationResponseMessage* response =
        dynamic_cast<CIMHandleIndicationResponseMessage*>(
            request->buildResponse());
    response->cimException = cimException;

    delete request;
    PEG_METHOD_EXIT();
    return response;
}