Procesamiento de mensajes multiparte/mixed en script groovy

Estoy recibiendo una carga útil similar a abajo en CPI

Mi objetivo es sustituir el valor "PurReqnExternalSystemType" por el valor del campo "PurchasingDocumentCategory" y eliminar el campo "PurchasingDocumentCategory" y su valor de la carga útil

Estos campos aparecen en múltiples ocasiones en la carga útil

PATCH A_PurchaseRequisiciónItem(PurchaseRequisición='0011234',PurchaseRequisiciónItem='2') HTTP/1.1

y

PATCH A_PurchaseRequisiciónItem(PurchaseRequisición='0011234',PurchaseRequisiciónItem='2') HTTP/1.1

Cómo lo logro en SAP CPI. ¿Alguna pista sobre el guión grrovy?

--batch
content-type: multipart/mixed; boundary=changeset
--changeset
content-type: application/http
content-transfer-encoding: binary
PATCH A_PurchaseRequisitionHeader(PurchaseRequisition='001234') HTTP/1.1
accept: application/json
content-type: application/json
{"PurchaseRequisition":"","PurchaseRequisitionType":"NB","PurReqnDescription":"CPI payloads","SourceDetermination":false}
--changeset
content-type: application/http
content-transfer-encoding: binary
PATCH A_PurchaseRequisitionItem(PurchaseRequisition='0011234',PurchaseRequisitionItem='1') HTTP/1.1
accept: application/json
content-type: application/json
{"PurchaseRequisition":"","PurReqnExternalReference":"6149","PurReqnItemExternalReference":"1","PurReqnExternalSystemType":"A","ExternalApprovalStatus":"A","AccountAssignmentCategory":"K","MaterialGroup":"A00906","PurchasingDocumentCategory":"B","RequestedQuantity":"1.0000000000"}
--changeset
content-type: application/http
content-transfer-encoding: binary
PATCH A_PurchaseRequisitionItem(PurchaseRequisition='0011234',PurchaseRequisitionItem='2') HTTP/1.1
accept: application/json
content-type: application/json
{"PurchaseRequisition":"","PurReqnExternalReference":"6149","PurReqnItemExternalReference":"2","PurReqnExternalSystemType":"A","ExternalApprovalStatus":"A","AccountAssignmentCategory":"K","MaterialGroup":"A00906","PurchasingDocumentCategory":"C","RequestedQuantity":"1.0000000000"}
--changeset
content-type: application/http
content-transfer-encoding: binary
PATCH A_PurchaseReqnItemText(PurchaseRequisition='0011234',PurchaseRequisitionItem='1',DocumentText='B01',TechnicalObjectType='EBAN',Language='EN') HTTP/1.1
accept: application/json
content-type: application/json
{"NoteDescription":"Test "}
--changeset
content-type: application/http
content-transfer-encoding: binary
PATCH A_PurchaseReqnItemText(PurchaseRequisition='001234',PurchaseRequisitionItem='2',DocumentText='B01',TechnicalObjectType='EBAN',Language='EN') HTTP/1.1
accept: application/json
content-type: application/json
{"NoteDescription":"Test "}
--changeset--
--batch--

Pregunta hecha hace 3 años, 4 meses, 26 días - Por gitguru


3 Respuestas:

  • He utilizado el enfoque java.io.reader para leer cada línea del mensaje. en un bucle utilizado reemplazarTodo el método para modificar el contenido. en el bucle cada línea se añade a una variable de stringbuilder. Este constructor de cuerdas es finalmente devuelto.

    Respondida el Dec 19, 2020 a las 10:54 - por scriptsorcerer

    Votos positivos: 0 | Votos negativos: 0

  • Para lograr sustituir el valor de "PurReqnExternalSystemType" por el valor de "PurchasingDocumentCategory" y eliminar este último campo de la carga útil en un script Groovy en SAP CPI, puedes seguir estos pasos:

    • Para procesar el mensaje multipart/mixed, debes analizar cada parte por separado.
    • Identifica las partes de tipo application/http que contienen la información que deseas modificar.
    • Utiliza expresiones regulares o funciones de procesamiento de JSON para acceder y modificar los valores necesarios.
    • Une todas las partes modificadas nuevamente en una nueva carga útil multipart/mixed.

    Aquí te dejo un ejemplo de cómo podrías abordar esto en un script Groovy en CPI:

    groovy
    import groovy.json.JsonSlurper
    
    def payload = message.getBody(String.class)
    
    // Dividir el payload en las partes multipart/mixed
    def parts = payload.split("--changeset")
    
    // Iterar sobre cada parte
    def modifiedParts = parts.collect { part ->
        if (part.contains("content-type: application/http")) {
            // Si es una parte de tipo application/http, procesarla
            def slurper = new JsonSlurper()
            def json = slurper.parseText(part)
    
            // Reemplazar el valor de "PurReqnExternalSystemType" por el valor de "PurchasingDocumentCategory"
            if (json.PurchaseRequisitionCategory || json.PurchasingDocumentCategory) {
                json.PurReqnExternalSystemType = json.PurchasingDocumentCategory
                json.remove("PurchasingDocumentCategory")
            }
    
            // Convertir el JSON modificado de vuelta a String
            def modifiedJson = JsonOutput.toJson(json)
    
            // Crear la parte modificada
            return part.split('{')[0] + modifiedJson
        } else {
            // Mantener las partes que no son de tipo application/http
            return part
        }
    }
    
    // Unir las partes modificadas en una nueva carga útil
    def modifiedPayload = modifiedParts.join("--changeset") 
    
    // Actualizar el cuerpo del mensaje con la carga útil modificada
    message.setBody(modifiedPayload)
    

    Este script analiza cada parte del mensaje, busca aquellas que son de tipo application/http, modifica el JSON según tus requerimientos y luego une todas las partes nuevamente.

    Por favor, ajusta este script según la estructura exacta de tus mensajes y los campos que necesitas modificar. Adicionalmente, ten en cuenta que la manipulación de JSON puede variar dependiendo de la estructura exacta de tus datos. ¡Espero que esto te ayude a resolver tu duda!

    Respondida el Dec 20, 2020 a las 10:54 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • groovy
    import com.sap.gateway.ip.core.customdev.util.Message
    
    def Message processData(Message message) {
        def body = message.getBody(String)
        def boundary = body.indexOf('\n\n--changeset\ncontent-type: application/http\ncontent-transfer-encoding: binary')
        def contentParts = []
        while(boundary != -1){
            contentParts.add(body.substring(0, boundary).strip())
            body = body.substring(boundary + '\n\n--changeset\ncontent-type: application/http\ncontent-transfer-encoding: binary'.length())
            boundary = body.indexOf('\n\n--changeset\ncontent-type: application/http\ncontent-transfer-encoding: binary')
        }
        def modifiedContent = ''
        contentParts.each { part ->
            def method = part.substring(0, part.indexOf(' '))
            def path = part.substring(part.indexOf(' ')+1, part.indexOf('HTTP/1.1')-1)
            def index = path.lastIndexOf('/')
            def entityName = path.substring(index+1)
            def newPart = method + ' ' + path[:index] + '/' + entityName + '('
            if(entityName == 'PurchaseRequisitionHeader'){
                newPart += 'PurchaseRequisition'
            }else{
                newPart += 'PurchaseRequisition=\'' + path.substring(path.indexOf('(')+1, path.indexOf(',')) + '\',PurchaseRequisitionItem'
            }
            newPart += ')\' HTTP/1.1\n'
            def updatedBody = part.substring(part.indexOf('\n\n')+2)
            if(entityName == 'PurchaseRequisitionItem'){
                String newBody = updatedBody[:updatedBody.indexOf('"PurchasingDocumentCategory"')-1] + '"PurReqnExternalSystemType":"' + updatedBody[updatedBody.indexOf('"PurchasingDocumentCategory"')+30..updatedBody.indexOf(',', updatedBody.indexOf('"PurchasingDocumentCategory"')+30)] + '", ' + updatedBody[updatedBody.indexOf(',')+1:]
                updatedBody = newBody.substring(0,newBody.length()-1)
            }
            def newPartWithBody = newPart + updatedBody
            modifiedContent += newPartWithBody + '\n\n'
        }
        message.setBody(modifiedContent)
        return message
    }
    

    Respondida el Dec 20, 2020 a las 10:57 - por Gemini

    Votos positivos: 0 | Votos negativos: 0