MuleSoft — передать составную строку в качестве полезной нагрузки

У меня есть составная полезная нагрузка, которую я хочу передать в поток (прослушиватель HTTP):

--------=_Part_1_5138113571742769845
Content-Type: text/xml
Content-ID: <mm7-submit>

<soap:Envelope
  xmlns:soap = "http://schemas.xmlsoap.org/soap/envelope/"
  xmlns = "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-2">
  ...
</soap:Envelope>

--------=_Part_1_5138113571742769845
Content-Type: multipart/mixed; boundary = "------=_Part_2_3815517668157287202"
Content-ID: <attachment>

--------=_Part_2_3815517668157287202
Content-Type: text/plain; name=text1.txt
Content-ID: <text1.txt>
Content-Location: bundled/text1.txt

This is the text part I want to access

--------=_Part_2_3815517668157287202
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-ID: <image.png>
Content-Location: bundled/image.jpg

aGk=

--------=_Part_2_3815517668157287202--
--------=_Part_1_5138113571742769845--

Когда я отправляю эту полезную нагрузку с помощью SoapUI, я могу получить доступ к текстовой части как payload.parts.part1.content.parts.part0.content.

Как это сделать с помощью инструментов MuleSoft (например, выражений DataWeave)? Я хочу иметь возможность передавать эту полезную нагрузку из события MUnit Set, которое принимает выражения DataWeave и другие форматы.

Я нашел составную страницу в документации DataWeave, но она показывает, как преобразовать другие форматы в составные, в то время как у меня уже есть составная полезная нагрузка, мне просто нужно передать ее потоку таким образом, чтобы он мог анализировать.

Я также попытался просто вставить его в выражение DataWeave:

%dw 2.0
output multipart/form-data boundary = "------=_Part_1_5138113571742769845"
---
--------=_Part_1_5138113571742769845
Content-Type: text/xml
...

Но когда он попытался оценить payload.parts.part1.content.parts.part0.content, я получил ошибку:

Сообщение: "javax.mail.internet.ParseException - отсутствует начальная граница

Хотя границы я указал. Я что-то упускаю?

Обновлено: я использую munit-runner версии 2.3.9. Часть «Выполнение» тестового примера MUnit имеет только Set Event и Flow-ref (к HTTP-прослушивателю, где я просто пытаюсь войти payload.parts.part1.content.parts.part0.content).

Событие Set имеет галочку «Начать с пустого события», на вкладке «Полезная нагрузка» в разделе «Значение» оно имеет выражение DataWeave, в разделе «Тип носителя» оно имеет «multipart/form-data»,

на вкладке Атрибуты у него есть заголовки:

"headers": {
    "accept-encoding": "gzip,deflate",
    "content-type": "multipart/related; boundary=\"------=_Part_1_5138113571742769845\"; type=\"text/xml\"; start=\"<mm7-submit>\"",
    "host": "localhost:8081",
    "connection": "Keep-Alive",
    "user-agent": "Apache-HttpClient/4.5.5 (Java/16.0.1)"
  }

Обновлено еще раз: Полная трассировка ошибки:

ERROR 2022-10-31 11:39:08,780 [[MuleRuntime].uber.12:
[poc7].api-main.CPU_LITE @3bf5d6df]
org.mule.runtime.core.internal.exception.OnErrorPropagateHandler: 
******************************************************************************** Message               : "javax.mail.internet.ParseException - Missing
start boundary javax.mail.internet.ParseException: Missing start
boundary    at
javax.mail.internet.MimeMultipart.parse(MimeMultipart.java:656)     at
javax.mail.internet.MimeMultipart.getCount(MimeMultipart.java:312)  at
org.mule.weave.v2.module.multipart.MultiPartReader.doRead(MultiPartReader.scala:119)
    at org.mule.weave.v2.module.reader.Reader.read(Reader.scala:35)     at
org.mule.weave.v2.module.reader.Reader.read$(Reader.scala:33)   at
org.mule.weave.v2.module.multipart.MultiPartReader.read(MultiPartReader.scala:46)
    at
org.mule.weave.v2.el.MuleTypedValue.value(MuleTypedValue.scala:147)
    at
org.mule.weave.v2.model.values.wrappers.DelegateValue.valueType(DelegateValue.scala:17)
    at
org.mule.weave.v2.model.values.wrappers.DelegateValue.valueType$(DelegateValue.scala:16)
    at
org.mule.weave.v2.el.MuleTypedValue.valueType(MuleTypedValue.scala:177)
    at org.mule.weave.v2.model.types.ObjectType$.accepts(Type.scala:1068)
    at
org.mule.weave.v2.interpreted.node.executors.BinaryOverloadedStaticExecutor.findMatchingFunction(BinaryOverloadedStaticExecutor.scala:151)
    at
org.mule.weave.v2.interpreted.node.executors.BinaryOverloadedStaticExecutor.executeBinary(BinaryOverloadedStaticExecutor.scala:78)
    at
org.mule.weave.v2.interpreted.node.ChainedBinaryOpNode.doExecute(ChainedBinaryOpNode.scala:37)
    at
org.mule.weave.v2.interpreted.node.ValueNode.execute(ValueNode.scala:26)
    at
org.mule.weave.v2.interpreted.node.ValueNode.execute$(ValueNode.scala:21)
    at
org.mule.weave.v2.interpreted.node.ChainedBinaryOpNode.execute(ChainedBinaryOpNode.scala:7)
    at
org.mule.weave.v2.interpreted.node.NullSafeNode.doExecute(NullSafeNode.scala:14)
    at
org.mule.weave.v2.interpreted.node.ValueNode.execute(ValueNode.scala:26)
    at
org.mule.weave.v2.interpreted.node.ValueNode.execute$(ValueNode.scala:21)
    at
org.mule.weave.v2.interpreted.node.NullSafeNode.execute(NullSafeNode.scala:8)
    at
org.mule.weave.v2.interpreted.node.structure.DocumentNode.doExecute(DocumentNode.scala:26)
    at
org.mule.weave.v2.interpreted.node.ValueNode.execute(ValueNode.scala:26)
    at
org.mule.weave.v2.interpreted.node.ValueNode.execute$(ValueNode.scala:21)
    at
org.mule.weave.v2.interpreted.node.structure.DocumentNode.execute(DocumentNode.scala:11)
    at
org.mule.weave.v2.interpreted.InterpretedMappingExecutableWeave.$anonfun$writeWith$3(InterpreterMappingCompilerPhase.scala:264)
    at
org.mule.weave.v2.module.writer.WriterHelper$.writeValue(Writer.scala:161)
    at
org.mule.weave.v2.module.writer.WriterHelper$.writeAndGetResult(Writer.scala:139)
    at
org.mule.weave.v2.interpreted.InterpretedMappingExecutableWeave.writeWith(InterpreterMappingCompilerPhase.scala:264)
    at
org.mule.weave.v2.el.WeaveExpressionLanguageSession.evaluateLogExpression(WeaveExpressionLanguageSession.scala:330)
  [...]
    at
reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2205)
    at
reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onSubscribe(MonoFlatMapMany.java:134)
    at
reactor.core.publisher.MonoCurrentContext.subscribe(MonoCurrentContext.java:35)
    at
reactor.core.publisher.MonoFlatMapMany.subscribe(MonoFlatMapMany.java:52)
    at reactor.core.publisher.MonoNext.subscribe(MonoNext.java:40)  at
reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44)
    at reactor.core.publisher.MonoMap.subscribe(MonoMap.java:52)    at
reactor.core.publisher.MonoMap.subscribe(MonoMap.java:52)   at
reactor.core.publisher.MonoSubscriberContext.subscribe(MonoSubscriberContext.java:47)
    at
reactor.core.publisher.MonoSubscriberContext.subscribe(MonoSubscriberContext.java:47)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3873)    at
reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:420)
    at
reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:204)
    at
reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:204)
    at
reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.runAsync(FluxPublishOn.java:447)
    at
reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.run(FluxPublishOn.java:534)
    at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84)   at
reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37)  at
java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)  at
org.mule.service.scheduler.internal.AbstractRunnableFutureDecorator.doRun(AbstractRunnableFutureDecorator.java:151)
    at
org.mule.service.scheduler.internal.RunnableFutureDecorator.run(RunnableFutureDecorator.java:54)
    at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834), while reading
`payload` as MultiPart. Trace:   at main (Unknown)" evaluating
expression: "payload.parts.part1.content.parts.part0.content". Element
: api-main/processors/2 @ poc7:poc7.xml:20 (Copy_of_Text_Logger)
Element DSL           : <logger level = "INFO"
doc:name = "Copy_of_Text_Logger"
doc:id = "3672afde-5a7c-4745-bd78-540d726e9354" message = "Received text:
#[payload.parts.part1.content.parts.part0.content]"></logger> Error type            : MULE:EXPRESSION FlowStack             : at
api-main(api-main/processors/2 @ poc7:poc7.xml:20
(Copy_of_Text_Logger))

  (set debug level logging or '-Dmule.verbose.exceptions=true' for
everything)
********************************************************************************

И тестовый XML:

<munit:test name = "poc7-test-suite-api-mainTest" doc:id = "f625b0a6-55a7-431a-962f-cbc68587dca7" description = "Test" expectedErrorType = "ANY">
        <munit:execution >
            <munit:set-event doc:name = "Set Event" doc:id = "2fe9a6bc-b65d-4477-b705-010f247cec6f" >
                <munit:payload value='%dw 2.0
output multipart/form-data
ns soap http://schemas.xmlsoap.org/soap/envelope/
---
{
  parts: {
    part0: {
      headers: {
        "Content-Type": "text/xml",
        "Content-ID": "&lt;mm7-submit&gt;"
      },
      content: {
        soap#Envelope: "\n  ...\n"
      }
    },
    part1: {
      headers: {
        "Content-Type": "multipart/mixed; boundary=\"------=_Part_2_3815517668157287202\"",
        "Content-ID": "&lt;attachment&gt;"
      },
      content: {
        parts: {
          part0: {
            headers: {
              "Content-Type": "text/plain; name=text1.txt",
              "Content-ID": "&lt;text1.txt&gt;",
              "Content-Location": "bundled/text1.txt"
            },
            content: "This is the text part I want to access\n"
          },
          part1: {
            headers: {
              "Content-Type": "image/png",
              "Content-Transfer-Encoding": "base64",
              "Content-ID": "&lt;image.png&gt;",
              "Content-Location": "bundled/image.jpg"
            },
            content: "hi"
          }
        }
      }
    }
  }
}' mediaType = "multipart/form-data" />
                <munit:attributes value = "#[{&quot;headers&quot;: {
    &quot;accept-encoding&quot;: &quot;gzip,deflate&quot;,
    &quot;content-type&quot;: &quot;multipart/related; boundary=\&quot;------=_Part_1_5138113571742769845\&quot;; type=\&quot;text/xml\&quot;; start=\&quot;&lt;mm7-submit&gt;\&quot;&quot;,
    &quot;host&quot;: &quot;localhost:8081&quot;,
    &quot;connection&quot;: &quot;Keep-Alive&quot;,
    &quot;user-agent&quot;: &quot;Apache-HttpClient/4.5.5 (Java/16.0.1)&quot;
  }
}]" />
            </munit:set-event>
            <flow-ref doc:name = "Flow-ref to api-main" doc:id = "75a9f728-f461-4233-a5b2-1a01d7b21e80" name = "api-main"/>
        </munit:execution>
        <munit:validation >
            <munit-tools:assert-equals message = "Wrong HTTP Status code:" expected = "#[746]" actual = "#[message.inboundProperties['http.status']]" doc:name = "Assert Equals"/>
        </munit:validation>
    </munit:test>
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
133
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Чтобы создать составной вывод, просто напишите нужную структуру в DataWeave и используйте правильный формат вывода. Не пытайтесь вставить в скрипт то, чего нет в DataWeave. За исключением, может быть, JSON, который достаточно похож.

Я проанализировал ваш ввод и вывел его в JSON, а затем использовал его как скрипт. Я удалил некоторые ненужные кавычки из ключей, но оставил необходимые для имен с символом дефиса. Затем я добавил объявление пространства имен для SOAP. Вы можете использовать функции DataWeave для остальных.

Пример:

%dw 2.0
output multipart/form-data
ns soap http://schemas.xmlsoap.org/soap/envelope/
---
{
  parts: {
    part0: {
      headers: {
        "Content-Type": "text/xml",
        "Content-ID": "<mm7-submit>"
      },
      content: {
        soap#Envelope: "\n  ...\n"
      }
    },
    part1: {
      headers: {
        "Content-Type": "multipart/mixed; boundary=\"------=_Part_2_3815517668157287202\"",
        "Content-ID": "<attachment>"
      },
      content: {
        parts: {
          part0: {
            headers: {
              "Content-Type": "text/plain; name=text1.txt",
              "Content-ID": "<text1.txt>",
              "Content-Location": "bundled/text1.txt"
            },
            content: "This is the text part I want to access\n"
          },
          part1: {
            headers: {
              "Content-Type": "image/png",
              "Content-Transfer-Encoding": "base64",
              "Content-ID": "<image.png>",
              "Content-Location": "bundled/image.jpg"
            },
            content: "hi"
          }
        }
      }
    }
  }
}

Вывод:

------=_Part_5779_1231291611.1666866442792
Content-Type: text/xml
Content-ID: <mm7-submit>
Content-Disposition: form-data; name = "part0"

<soap:Envelope xmlns:soap = "http://schemas.xmlsoap.org/soap/envelope/">
  ...
</soap:Envelope>
------=_Part_5779_1231291611.1666866442792
Content-Type: multipart/mixed; boundary = "------=_Part_2_3815517668157287202"
Content-ID: <attachment>
Content-Disposition: form-data; name = "part1"

--------=_Part_2_3815517668157287202
Content-Type: text/plain; name=text1.txt
Content-ID: <text1.txt>
Content-Location: bundled/text1.txt

This is the text part I want to access

--------=_Part_2_3815517668157287202
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-ID: <image.png>
Content-Location: bundled/image.jpg

hi
--------=_Part_2_3815517668157287202--

------=_Part_5779_1231291611.1666866442792--

Я попробовал это, и я все еще получаю ту же ошибку («Отсутствует начальная граница»), когда я передаю это как полезную нагрузку из события MUnit Set. Однако я попытался установить переменную («tempvar») в это выражение, а затем оценить #[vars.tempvar.parts.part1.content.parts.part0.content], и это сработало. Так может быть, это проблема MUnit?

Bolchojeet 27.10.2022 17:04

Возможно. Вы должны поделиться подробностями того, как вы используете преобразование в MUnit. В противном случае вопрос не закончен.

aled 27.10.2022 17:05

Поскольку ответ, кажется, работает для заданного вопроса, вам следует задать новый вопрос по проблеме MUnit.

aled 30.10.2022 04:18

Но в вопросе прямо говорится: «Я хочу иметь возможность передавать эту полезную нагрузку из события MUnit Set», а сообщение об ошибке, которое я написал в вопросе (которое также получено из решения в вашем ответе), исходит из события MUnit Set...

Bolchojeet 30.10.2022 09:20

Затем добавьте все детали того, что вы делаете в Munit и версиях.

aled 30.10.2022 12:49

Добавлена ​​версия и подробности, пожалуйста, дайте мне знать, если потребуется дополнительная информация.

Bolchojeet 30.10.2022 16:18

Пожалуйста, добавьте XML для тестового примера MUnit и полную информацию об ошибке из журнала, а не только сообщение об ошибке. Если есть трассировка стека, то и то.

aled 30.10.2022 20:22

Добавлен тестовый XML. Полная трассировка ошибки была слишком длинной для сообщения, поэтому я оставил голову и хвост, надеюсь, все в порядке.

Bolchojeet 31.10.2022 10:51

Вы не должны использовать формат кавычек для журналов или кода.

aled 31.10.2022 12:48

Хорошо, я обновил его до формата кода. Итак, вы знаете, почему я получаю сообщение об ошибке?

Bolchojeet 31.10.2022 13:53
Ответ принят как подходящий

Обертывание полезной нагрузки с помощью #[] в MUnit Set Event решило проблему.

Таким образом, единственное необходимое изменение по сравнению с тем, что я написал в вопросе, было в Set Event -> Payload tab -> Value.

Меняться от:

%dw 2.0
output multipart/form-data
---
[DataWeave expression]

К:

#[
%dw 2.0
output multipart/form-data
---
[DataWeave expression]
]

Другие вопросы по теме