示例#1
0
Boolean WsmResponseEncoder::_encodeEnumerationData(
    SoapResponse& soapResponse,
    Buffer& headers,
    WsmOperationType operation,
    Uint64 contextId,
    Boolean isComplete,
    WsenEnumerationData& data,
    const String& resourceUri)
{
    Buffer bodyHeader, bodyTrailer;

    PEGASUS_ASSERT(operation == WS_ENUMERATION_ENUMERATE ||
        operation == WS_ENUMERATION_PULL);

    WsmWriter::appendStartTag(
        bodyHeader, WsmNamespaces::WS_ENUMERATION, 
        operation == WS_ENUMERATION_ENUMERATE ? 
            STRLIT("EnumerateResponse") : STRLIT("PullResponse"));

#if defined(PEGASUS_BUILD_SCX)

    // WINRM rejects empty EnumerationContext elements.

    WsmWriter::appendStartTag(
        bodyHeader, WsmNamespaces::WS_ENUMERATION, 
        STRLIT("EnumerationContext"));
    WsmWriter::append(bodyHeader, contextId);
    WsmWriter::appendEndTag(
        bodyHeader, WsmNamespaces::WS_ENUMERATION, 
        STRLIT("EnumerationContext"));

#else /* defined(PEGASUS_BUILD_SCX) */

    if (!isComplete)
    {
        WsmWriter::appendStartTag(
            bodyHeader, WsmNamespaces::WS_ENUMERATION, 
            STRLIT("EnumerationContext"));
        WsmWriter::append(bodyHeader, contextId);
        WsmWriter::appendEndTag(
            bodyHeader, WsmNamespaces::WS_ENUMERATION, 
            STRLIT("EnumerationContext"));
    }
    else
    {
        WsmWriter::appendEmptyTag(
            bodyHeader, WsmNamespaces::WS_ENUMERATION, 
            STRLIT("EnumerationContext"));
    }

#endif /* !defined(PEGASUS_BUILD_SCX) */

    if (data.getSize() > 0)
    {
        WsmWriter::appendStartTag(
            bodyHeader, 
            operation == WS_ENUMERATION_ENUMERATE ? 
                WsmNamespaces::WS_MAN : WsmNamespaces::WS_ENUMERATION, 
            STRLIT("Items"));
        WsmWriter::appendEndTag(
            bodyTrailer, 
            operation == WS_ENUMERATION_ENUMERATE ? 
                WsmNamespaces::WS_MAN : WsmNamespaces::WS_ENUMERATION, 
            STRLIT("Items"));
    }

    Uint32 eosPos = bodyTrailer.size();
    Uint32 eosSize = 0;
    if (isComplete)
    {
        WsmWriter::appendEmptyTag(
            bodyTrailer, 
            operation == WS_ENUMERATION_ENUMERATE ? 
                WsmNamespaces::WS_MAN : WsmNamespaces::WS_ENUMERATION, 
            STRLIT("EndOfSequence"));
        eosSize = bodyTrailer.size() - eosPos;
    }

    WsmWriter::appendEndTag(
        bodyTrailer, WsmNamespaces::WS_ENUMERATION, 
        operation == WS_ENUMERATION_ENUMERATE ? 
            STRLIT("EnumerateResponse") : STRLIT("PullResponse"));

    // Fault the request if it can't be encoded within the limits
    if (!soapResponse.appendHeader(headers) ||
        !soapResponse.appendBodyHeader(bodyHeader) ||
        !soapResponse.appendBodyTrailer(bodyTrailer))
    {
        return false;
    }

    // Now add the list of items
    Uint32 i = 0;

    if (data.enumerationMode == WSEN_EM_OBJECT)
    {
        for (i = 0; i < data.instances.size(); i++)
        {
            Buffer body;

            if (data.polymorphismMode == WSMB_PM_EXCLUDE_SUBCLASS_PROPERTIES)
            {
                // The response does not contain the subclass properties, but
                // the class name is still that of the subclass. 
                // Replace it here.
                data.instances[i].setClassName(
                    WsmToCimRequestMapper::convertResourceUriToClassName(
                        data.classUri).getString());
            }

            WsmWriter::appendInstanceElement(body, resourceUri, 
                data.instances[i], PEGASUS_INSTANCE_NS, false);
            if (!soapResponse.appendBodyContent(body))
            {
                break;
            }
        }
    }
    else if (data.enumerationMode == WSEN_EM_EPR)
    {
        for (i = 0; i < data.eprs.size(); i++)
        {
            Buffer body;

            WsmWriter::appendStartTag(
                body, 
                WsmNamespaces::WS_ADDRESSING, 
                STRLIT("EndpointReference"));
            WsmWriter::appendEPRElement(body, data.eprs[i]);
            WsmWriter::appendEndTag(
                body, 
                WsmNamespaces::WS_ADDRESSING, 
                STRLIT("EndpointReference"));
            if (!soapResponse.appendBodyContent(body))
            {
                break;
            }
        }
    }
    else if (data.enumerationMode == WSEN_EM_OBJECT_AND_EPR)
    {
        for (i = 0; i < data.instances.size(); i++)
        {
            Buffer body;

            WsmWriter::appendStartTag(
                body, 
                WsmNamespaces::WS_MAN, 
                STRLIT("Item"));

            if (data.polymorphismMode == WSMB_PM_EXCLUDE_SUBCLASS_PROPERTIES)
            {
                // The response does not contain the subclass properties, but
                // the class name is still that of the subclass. 
                // Replace it here.
                data.instances[i].setClassName(
                    WsmToCimRequestMapper::convertResourceUriToClassName(
                        data.classUri).getString());
            }

            WsmWriter::appendInstanceElement(body, resourceUri, 
                data.instances[i], PEGASUS_INSTANCE_NS, false);
 
            WsmWriter::appendStartTag(
                body, 
                WsmNamespaces::WS_ADDRESSING, 
                STRLIT("EndpointReference"));
            WsmWriter::appendEPRElement(body, data.eprs[i]);
            WsmWriter::appendEndTag(
                body, 
                WsmNamespaces::WS_ADDRESSING, 
                STRLIT("EndpointReference"));

            WsmWriter::appendEndTag(
                body, 
                WsmNamespaces::WS_MAN, 
                STRLIT("Item"));

            if (!soapResponse.appendBodyContent(body))
            {
                break;
            }
        }
    }
    else
    {
        PEGASUS_ASSERT(0);
    }

    // If the list is not empty, but none of the items have been successfully
    // added to the soapResponse, fault the request because it cannot be
    // encoded within the specified limits.
    if (data.getSize() > 0 && i == 0)
    {
        return false;
    }

    // Remove the items we processed. The rest will be added back 
    // to the context
    if (i != 0)
    {
        data.remove(0, i);
    }

    // The request is complete but could not be encoded with MaxEnvelopeSize.
    // Clear EndOfSequence tag.
    if (isComplete && data.getSize() > 0)
    {
        soapResponse.getBodyTrailer().remove(eosPos, eosSize);
    }

    return true;
}
Boolean WsmResponseEncoder::_encodeEnumerationData(
    SoapResponse& soapResponse,
    Buffer& headers,
    WsmOperationType operation,
    Uint64 contextId,
    Boolean isComplete,
    WsenEnumerationData& data,
    Uint32& numDataItemsEncoded,
    const String& resourceUri)
{
    Buffer bodyHeader, bodyTrailer;

    PEGASUS_ASSERT(operation == WS_ENUMERATION_ENUMERATE ||
        operation == WS_ENUMERATION_PULL);

    numDataItemsEncoded = 0;

    WsmWriter::appendStartTag(
        bodyHeader, WsmNamespaces::WS_ENUMERATION,
        operation == WS_ENUMERATION_ENUMERATE ?
            STRLIT("EnumerateResponse") : STRLIT("PullResponse"));

    // Include an EnumerationContext in the response.  If this response
    // completes the enumeration, this element will be modified/removed below.
    Uint32 ecPos = bodyHeader.size();
    WsmWriter::appendStartTag(
        bodyHeader, WsmNamespaces::WS_ENUMERATION,
        STRLIT("EnumerationContext"));
    WsmWriter::append(bodyHeader, contextId);
    WsmWriter::appendEndTag(
        bodyHeader, WsmNamespaces::WS_ENUMERATION,
        STRLIT("EnumerationContext"));
    Uint32 ecSize = bodyHeader.size() - ecPos;

    if (data.getSize() > 0)
    {
        WsmWriter::appendStartTag(
            bodyHeader,
            operation == WS_ENUMERATION_ENUMERATE ?
                WsmNamespaces::WS_MAN : WsmNamespaces::WS_ENUMERATION,
            STRLIT("Items"));
        WsmWriter::appendEndTag(
            bodyTrailer,
            operation == WS_ENUMERATION_ENUMERATE ?
                WsmNamespaces::WS_MAN : WsmNamespaces::WS_ENUMERATION,
            STRLIT("Items"));
    }

    Uint32 eosPos = bodyTrailer.size();
    Uint32 eosSize = 0;
    if (isComplete)
    {
        // Write an EndOfSequence element with the expectation that all the
        // elements fit within MaxEnvelopeSize.  This element will be removed
        // below if the assumption proves untrue.  This element is written
        // up front before all the response data was included, because adding
        // the EndOfSequence element later might push the response size past
        // the MaxEnvelopeSize.
        WsmWriter::appendEmptyTag(
            bodyTrailer,
            operation == WS_ENUMERATION_ENUMERATE ?
                WsmNamespaces::WS_MAN : WsmNamespaces::WS_ENUMERATION,
            STRLIT("EndOfSequence"));
        eosSize = bodyTrailer.size() - eosPos;
    }

    WsmWriter::appendEndTag(
        bodyTrailer, WsmNamespaces::WS_ENUMERATION,
        operation == WS_ENUMERATION_ENUMERATE ?
            STRLIT("EnumerateResponse") : STRLIT("PullResponse"));

    // Fault the request if it can't be encoded within the limits
    if (!soapResponse.appendHeader(headers) ||
        !soapResponse.appendBodyHeader(bodyHeader) ||
        !soapResponse.appendBodyTrailer(bodyTrailer))
    {
        return false;
    }

    // Now add the list of items
    Uint32 i = 0;

    if (data.enumerationMode == WSEN_EM_OBJECT)
    {
        for (i = 0; i < data.instances.size(); i++)
        {
            Buffer body;

            if (data.polymorphismMode == WSMB_PM_EXCLUDE_SUBCLASS_PROPERTIES)
            {
                // The response does not contain the subclass properties, but
                // the class name is still that of the subclass.
                // Replace it here.
                data.instances[i].setClassName(
                    WsmToCimRequestMapper::convertResourceUriToClassName(
                        data.classUri).getString());
            }

            WsmWriter::appendInstanceElement(body, resourceUri,
                data.instances[i], PEGASUS_INSTANCE_NS, false);

            if (!soapResponse.appendBodyContent(body))
            {
                break;
            }
        }
    }
    else if (data.enumerationMode == WSEN_EM_EPR)
    {
        for (i = 0; i < data.eprs.size(); i++)
        {
            Buffer body;

            WsmWriter::appendStartTag(
                body,
                WsmNamespaces::WS_ADDRESSING,
                STRLIT("EndpointReference"));
            WsmWriter::appendEPRElement(body, data.eprs[i]);
            WsmWriter::appendEndTag(
                body,
                WsmNamespaces::WS_ADDRESSING,
                STRLIT("EndpointReference"));
            if (!soapResponse.appendBodyContent(body))
            {
                break;
            }
        }
    }
    else if (data.enumerationMode == WSEN_EM_OBJECT_AND_EPR)
    {
        for (i = 0; i < data.instances.size(); i++)
        {
            Buffer body;

            WsmWriter::appendStartTag(
                body,
                WsmNamespaces::WS_MAN,
                STRLIT("Item"));

            if (data.polymorphismMode == WSMB_PM_EXCLUDE_SUBCLASS_PROPERTIES)
            {
                // The response does not contain the subclass properties, but
                // the class name is still that of the subclass.
                // Replace it here.
                data.instances[i].setClassName(
                    WsmToCimRequestMapper::convertResourceUriToClassName(
                        data.classUri).getString());
            }

            WsmWriter::appendInstanceElement(body, resourceUri,
                data.instances[i], PEGASUS_INSTANCE_NS, false);

            WsmWriter::appendStartTag(
                body,
                WsmNamespaces::WS_ADDRESSING,
                STRLIT("EndpointReference"));
            WsmWriter::appendEPRElement(body, data.eprs[i]);
            WsmWriter::appendEndTag(
                body,
                WsmNamespaces::WS_ADDRESSING,
                STRLIT("EndpointReference"));

            WsmWriter::appendEndTag(
                body,
                WsmNamespaces::WS_MAN,
                STRLIT("Item"));

            if (!soapResponse.appendBodyContent(body))
            {
                break;
            }
        }
    }
    else
    {
        PEGASUS_ASSERT(0);
    }

    numDataItemsEncoded = i;

    // If the list is not empty, but none of the items have been successfully
    // added to the soapResponse, fault the request because it cannot be
    // encoded within the specified limits.
    if (data.getSize() > 0 && numDataItemsEncoded == 0)
    {
        return false;
    }

    if (isComplete)
    {
        if (data.getSize() > numDataItemsEncoded)
        {
            // The request is complete but could not be encoded within
            // MaxEnvelopeSize.  Clear EndOfSequence tag.
            soapResponse.getBodyTrailer().remove(eosPos, eosSize);
        }
        else
        {
            // All the enumeration results were written.  Update the
            // EnumerationContext element.
            if (operation == WS_ENUMERATION_ENUMERATE)
            {
                // DSP0226 R8.2.3-5:  A conformant service that supports
                // optimized enumeration and has not returned all items of the
                // enumeration sequence in the wsen:EnumerateResponse message
                // shall return a wsen:EnumerationContext element that is
                // initialized such that a subsequent wsen:Pull message will
                // return the set of items after those returned in the
                // wsen:EnumerateResponse. If all items of the enumeration
                // sequence have been returned in the wsen:EnumerateResponse
                // message, the service should return an empty
                // wsen:EnumerationContext element and shall return the
                // wsman:EndOfSequence element in the response.
                Buffer emptyEc(50);
                WsmWriter::appendEmptyTag(
                    emptyEc, WsmNamespaces::WS_ENUMERATION,
                    STRLIT("EnumerationContext"));
                soapResponse.getBodyHeader().remove(ecPos, ecSize);
                soapResponse.getBodyHeader().insert(
                    ecPos, emptyEc.getData(), emptyEc.size());
            }
            else
            {
                // DSP0226 R8.4-8:  If the wsen:EndOfSequence marker occurs in
                // the wsen:PullResponse message, the wsen:EnumerationContext
                // element shall be omitted, as the enumeration has completed.
                // The client cannot subsequently issue a wsen:Release message.
                soapResponse.getBodyHeader().remove(ecPos, ecSize);
            }
        }
    }

    return true;
}