I need to process an XML file which has a namespace declaration on its root element and containing +133K sub elements, its size is around 500MB; to achieve this i'm using WSO2 ESB 5 and smooks mediator.
Basically what i'm looking for is to split the input file into little chunks with a predefined structure and send each of them to a queue for later processing.
I tried first to do an XSLT transformation first to remove the namespace from the input file but i got an OutOfMemory error like this:
TID: [-1234] [] [2017-03-02 03:04:43,900] ERROR {org.apache.axis2.transport.base.threads.NativeWorkerPool} - Uncaught exception {org.apache.axis2.transport.base.threads.NativeWorkerPool}
java.lang.OutOfMemoryError: GC overhead limit exceeded
at org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory.createOMText(OMLinkedListImplFactory.java:192)
at org.apache.axiom.om.impl.builder.StAXBuilder.createOMText(StAXBuilder.java:294)
at org.apache.axiom.om.impl.builder.StAXBuilder.createOMText(StAXBuilder.java:250)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:252)
at org.apache.axiom.om.impl.llom.OMSerializableImpl.build(OMSerializableImpl.java:78)
at org.apache.axiom.om.impl.llom.OMElementImpl.build(OMElementImpl.java:722)
at org.apache.axiom.om.impl.llom.OMElementImpl.detach(OMElementImpl.java:700)
at org.apache.axiom.om.impl.llom.OMNodeImpl.setParent(OMNodeImpl.java:105)
at org.apache.axiom.om.impl.llom.OMNodeImpl.insertSiblingAfter(OMNodeImpl.java:203)
at org.apache.synapse.mediators.transform.XSLTMediator.performXSLT(XSLTMediator.java:366)
at org.apache.synapse.mediators.transform.XSLTMediator.mediate(XSLTMediator.java:202)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:59)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:158)
at org.apache.synapse.core.axis2.ProxyServiceMessageReceiver.receive(ProxyServiceMessageReceiver.java:210)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.axis2.transport.base.AbstractTransportListener.handleIncomingMessage(AbstractTransportListener.java:328)
at org.apache.synapse.transport.vfs.VFSTransportListener.processFile(VFSTransportListener.java:824)
at org.apache.synapse.transport.vfs.VFSTransportListener.scanFileOrDirectory(VFSTransportListener.java:472)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:188)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:134)
at org.apache.axis2.transport.base.AbstractPollingTransportListener$1$1.run(AbstractPollingTransportListener.java:67)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
I did not understand why this is happening because my virtual machine is configured to work with -Xms4096m -Xmx6144m
Based on the previous error i decided to implement kind of streaming solution using smooks, then i defined a vfs proxy service to poll a folder and give the file to smook mediator but i keep getting an error that seems to be related to the namespace definition on the root element of the input file and i mention this because whenever i edit the input file and get rid of the namespace definition what i have defined and deployed on WSO2 ESB works perfectly. The point here is i'm receiving the large file from a backend black box system and i should deal with the namespace stuff.
The following are the definitions i have on my ESB:
Proxy Service
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="Tryzens_ProductProxy"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="vfs">
<target>
<inSequence>
<log level="custom">
<property name="Tryzens_ProductProxy__tracing" value="before smooks"/>
</log>
<property name="DISABLE_SMOOKS_RESULT_PAYLOAD" value="true"/>
<smooks config-key="ProductSplitJMS_Smook">
<input type="xml"/>
<output type="xml"/>
</smooks>
<log level="custom">
<property name="Tryzens_ProductProxy__tracing" value="after smooks"/>
</log>
</inSequence>
</target>
<parameter name="transport.vfs.Streaming">true</parameter>
<parameter name="transport.PollInterval">15</parameter>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.vfs.FileURI">vfs:file:///home/jairof/wso2/00_test/working/tryzens/smook_product/</parameter>
<parameter name="transport.vfs.MoveAfterProcess">vfs:file:///home/jairof/wso2/00_test/working/tryzens/output/</parameter>
<parameter name="transport.vfs.MoveAfterFailure">vfs:file:///home/jairof/wso2/00_test/working/tryzens/fails/</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.xml</parameter>
<parameter name="transport.vfs.ContentType">application/xml</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<description/>
</proxy>
Smooks configuration
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd" xmlns:xsl="http://www.milyn.org/xsd/smooks/xsl-1.1.xsd" xmlns:core="http://www.milyn.org/xsd/smooks/smooks-core-1.3.xsd" xmlns:jms="http://www.milyn.org/xsd/smooks/jms-routing-1.2.xsd">
<params>
<param name="stream.filter.type">SAX</param>
<param name="default.serialization.on">false</param>
</params>
<resource-config selector="product">
<resource>org.milyn.delivery.DomModelCreator</resource>
</resource-config>
<jms:router routeOnElement="product" beanId="productItem_xml" destination="dynamicQueues/TestFL">
<jms:connection factory="QueueConnectionFactory"/>
<jms:jndi contextFactory="org.apache.activemq.jndi.ActiveMQInitialContextFactory" providerUrl="tcp://localhost:61616"/>
<jms:highWaterMark mark="-1"/>
</jms:router>
<ftl:freemarker applyOnElement="product">
<ftl:template>/repository/resources/smooks/product.ftl</ftl:template>
<ftl:use>
<ftl:bindTo id="productItem_xml"/>
</ftl:use>
</ftl:freemarker>
</smooks-resource-list>
Smooks template
This template is only for testing purposes, the real one corresponds to the complete structure of the product element, but to reproduce the error situation it is enough:
<#ftl ns_prefixes={"ns1": "http://www.demandware.com/xml/impex/catalog/2006-10-31"}>
<product id='${.vars["product"]["#product-id"]}'>
<ean>${product.ean}</ean>
</product>
Sample input file
Note that the actual file has more than 133K products, in this sample I cut most part of the file and left only two products
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.demandware.com/xml/impex/catalog/2006-10-31" catalog-id="tml-catalog-en">
<header>
<image-settings>
<internal-location base-path="/images"/>
<view-types>
<view-type>original</view-type>
<view-type>portrait</view-type>
<view-type>badge_GBP</view-type>
<view-type>badge_EUR</view-type>
<view-type>badge_USD</view-type>
<view-type>badge_AUD</view-type>
<view-type>badge_CZH</view-type>
<view-type>ctlimage</view-type>
<view-type>badge_FRA</view-type>
<view-type>badge_GER</view-type>
<view-type>landscape</view-type>
</view-types>
<alt-pattern>${productname}, ${variationvalue}, ${viewtype}</alt-pattern>
<title-pattern>${productname}, ${variationvalue}</title-pattern>
</image-settings>
</header>
<category category-id="MensShoes">
<display-name xml:lang="de-DE">Schuhe</display-name>
<display-name xml:lang="x-default">Shoes</display-name>
<display-name xml:lang="fr-FR">Chaussures</display-name>
<online-flag>true</online-flag>
<parent>MENSWEAR</parent>
<position>12.0</position>
<image>images/slot/landing/men_menlanding_H1_GBP.jpg</image>
<template/>
<page-attributes/>
<custom-attributes>
<custom-attribute attribute-id="categoryRecommendationsEnable">false</custom-attribute>
<custom-attribute attribute-id="enableCompare">false</custom-attribute>
<custom-attribute attribute-id="enableGridItemButtonStrip">false</custom-attribute>
<custom-attribute attribute-id="enableGridItemMobileButtonStrip">false</custom-attribute>
<custom-attribute attribute-id="enableUserJourney">false</custom-attribute>
<custom-attribute attribute-id="enableWishlist">false</custom-attribute>
<custom-attribute attribute-id="fitsme_enabled">false</custom-attribute>
<custom-attribute attribute-id="rrGenere">false</custom-attribute>
<custom-attribute attribute-id="rsCategoryEnabled">false</custom-attribute>
<custom-attribute attribute-id="shopAllButton">false</custom-attribute>
<custom-attribute attribute-id="showInMenu">true</custom-attribute>
<custom-attribute attribute-id="showInMobileMenu">false</custom-attribute>
<custom-attribute attribute-id="show_alternate_image_on_plp">false</custom-attribute>
<custom-attribute attribute-id="slotBannerImage">images/slot/landing/men_menlanding_H1_GBP.jpg</custom-attribute>
</custom-attributes>
</category>
<category category-id="P50 SUIT">
<display-name xml:lang="de-DE">Hosen</display-name>
<display-name xml:lang="x-default">Trousers</display-name>
<display-name xml:lang="fr-FR">Pantalons</display-name>
<online-flag>true</online-flag>
<parent>WomensTailoring</parent>
<position>0.0</position>
<template/>
<page-attributes/>
</category>
<product product-id="0">
<ean/>
<upc/>
<unit/>
<min-order-quantity>1</min-order-quantity>
<step-quantity>1</step-quantity>
<store-force-price-flag>false</store-force-price-flag>
<store-non-inventory-flag>false</store-non-inventory-flag>
<store-non-revenue-flag>false</store-non-revenue-flag>
<store-non-discountable-flag>false</store-non-discountable-flag>
<online-flag>false</online-flag>
<available-flag>true</available-flag>
<searchable-flag>true</searchable-flag>
<images>
<image-group view-type="badge_EUR">
<image path="badge/blank.png"/>
</image-group>
<image-group view-type="badge_GBP">
<image path="badge/blank.png"/>
</image-group>
<image-group view-type="badge_GER">
<image path="badge/blank.png"/>
</image-group>
<image-group view-type="badge_USD">
<image path="badge/blank.png"/>
</image-group>
</images>
<page-attributes/>
<pinterest-enabled-flag>false</pinterest-enabled-flag>
<facebook-enabled-flag>false</facebook-enabled-flag>
<store-attributes>
<force-price-flag>false</force-price-flag>
<non-inventory-flag>false</non-inventory-flag>
<non-revenue-flag>false</non-revenue-flag>
<non-discountable-flag>false</non-discountable-flag>
</store-attributes>
</product>
<product product-id="12024">
<ean/>
<upc/>
<unit/>
<min-order-quantity>1</min-order-quantity>
<step-quantity>1</step-quantity>
<store-force-price-flag>false</store-force-price-flag>
<store-non-inventory-flag>false</store-non-inventory-flag>
<store-non-revenue-flag>false</store-non-revenue-flag>
<store-non-discountable-flag>false</store-non-discountable-flag>
<online-flag>false</online-flag>
<available-flag>true</available-flag>
<searchable-flag>true</searchable-flag>
<images>
<image-group view-type="original">
<image path="original/12024_original_original.jpg"/>
</image-group>
</images>
<brand>J FRANCOMB</brand>
<page-attributes/>
<custom-attributes>
<custom-attribute attribute-id="allocGroup">X</custom-attribute>
<custom-attribute attribute-id="colour">
<value>3PNK-PINK</value>
</custom-attribute>
<custom-attribute attribute-id="cuffType">
<value>SINGLE CUFF</value>
</custom-attribute>
<custom-attribute attribute-id="enable_pdp_asset_footer_layout">false</custom-attribute>
<custom-attribute attribute-id="fabric">
<value>LEWIN 100 PD</value>
</custom-attribute>
<custom-attribute attribute-id="fit">SEMI FIT</custom-attribute>
<custom-attribute attribute-id="gender">
<value>M</value>
</custom-attribute>
<custom-attribute attribute-id="look">PTRN447</custom-attribute>
<custom-attribute attribute-id="pattern">
<value>PATTERN</value>
</custom-attribute>
<custom-attribute attribute-id="productIDCIMS">12024</custom-attribute>
<custom-attribute attribute-id="retailTypeCIMS">M FORMAL</custom-attribute>
<custom-attribute attribute-id="seasonCIMS">307B</custom-attribute>
<custom-attribute attribute-id="styleName">MILSC PATTERN DOOM AND BLOOM</custom-attribute>
<custom-attribute attribute-id="styleNameCIMS">MILSC PATTERN DOOM AND BLOOM</custom-attribute>
<custom-attribute attribute-id="styleNumberCIMS">MS17</custom-attribute>
<custom-attribute attribute-id="typeDesc">MS SHIRTS</custom-attribute>
<custom-attribute attribute-id="weight">0.3</custom-attribute>
</custom-attributes>
<options>
<shared-option option-id="sleeveLengthAlteration"/>
<shared-option option-id="giftBox"/>
</options>
<variations>
<attributes>
<shared-variation-attribute attribute-id="collarSize" variation-attribute-id="collarSize"/>
<shared-variation-attribute attribute-id="sleeveLength" variation-attribute-id="sleeveLength"/>
</attributes>
</variations>
<classification-category>S17 MILAN</classification-category>
<pinterest-enabled-flag>false</pinterest-enabled-flag>
<facebook-enabled-flag>false</facebook-enabled-flag>
<store-attributes>
<force-price-flag>false</force-price-flag>
<non-inventory-flag>false</non-inventory-flag>
<non-revenue-flag>false</non-revenue-flag>
<non-discountable-flag>false</non-discountable-flag>
</store-attributes>
</product>
<category-assignment category-id="T43 HERITAGE" product-id="505158991125">
<primary-flag>true</primary-flag>
</category-assignment>
<category-assignment category-id="U30 BOXERS" product-id="505158774834"/>
<recommendation source-id="58462" source-type="product" target-id="505158886294" type="4"/>
</catalog>
Error in wso2carbon.log file
TID: [-1234] [] [2017-03-02 12:15:27,793] INFO {org.apache.synapse.mediators.builtin.LogMediator} - Tryzens_ProductProxy__tracing = before smooks {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2017-03-02 12:15:28,376] ERROR {freemarker.runtime} - {freemarker.runtime}
Error on line 3, column 12 in repository/resources/smooks/product.ftl
Expecting a string, date or number here, Expression product.ean is instead a freemarker.ext.dom.NodeListModel
The problematic instruction:
----------
==> ${product.ean} [on line 3, column 10 in repository/resources/smooks/product.ftl]
----------
Java backtrace for programmers:
----------
freemarker.core.NonStringException: Error on line 3, column 12 in repository/resources/smooks/product.ftl
Expecting a string, date or number here, Expression product.ean is instead a freemarker.ext.dom.NodeListModel
at freemarker.core.Expression.getStringValue(Expression.java:126)
at freemarker.core.Expression.getStringValue(Expression.java:93)
at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
at freemarker.core.Environment.visit(Environment.java:209)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:209)
at freemarker.core.Environment.process(Environment.java:189)
at freemarker.template.Template.process(Template.java:237)
at org.milyn.templating.freemarker.FreeMarkerTemplateProcessor.applyTemplate(FreeMarkerTemplateProcessor.java:358)
at org.milyn.templating.freemarker.FreeMarkerTemplateProcessor.applyTemplate(FreeMarkerTemplateProcessor.java:346)
at org.milyn.templating.freemarker.FreeMarkerTemplateProcessor.visitAfter(FreeMarkerTemplateProcessor.java:333)
at org.milyn.delivery.sax.SAXHandler.visitAfter(SAXHandler.java:389)
at org.milyn.delivery.sax.SAXHandler.endElement(SAXHandler.java:204)
at org.milyn.delivery.SmooksContentHandler.endElement(SmooksContentHandler.java:96)
at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.milyn.delivery.sax.SAXParser.parse(SAXParser.java:76)
at org.milyn.delivery.sax.SmooksSAXFilter.doFilter(SmooksSAXFilter.java:86)
at org.milyn.delivery.sax.SmooksSAXFilter.doFilter(SmooksSAXFilter.java:64)
at org.milyn.Smooks._filter(Smooks.java:526)
at org.milyn.Smooks.filterSource(Smooks.java:482)
at org.wso2.carbon.mediator.transform.SmooksMediator.mediate(SmooksMediator.java:146)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:59)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:158)
at org.apache.synapse.core.axis2.ProxyServiceMessageReceiver.receive(ProxyServiceMessageReceiver.java:210)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.axis2.transport.base.AbstractTransportListener.handleIncomingMessage(AbstractTransportListener.java:328)
at org.apache.synapse.transport.vfs.VFSTransportListener.processFile(VFSTransportListener.java:824)
at org.apache.synapse.transport.vfs.VFSTransportListener.scanFileOrDirectory(VFSTransportListener.java:472)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:188)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:134)
at org.apache.axis2.transport.base.AbstractPollingTransportListener$1$1.run(AbstractPollingTransportListener.java:67)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Please help, i would appreciate any comments to solve this issue
Thanks in advance
In the smooks template (.ftl file), if you want to use something like ${product.ean}, you must define "product" variable :
<#assign product = .vars["product"]>
In your xml input file, all nodes belongs to the same defaut namespace "http://www.demandware.com/xml/impex/catalog/2006-10-31"
You can define this default namespace in FTL with the reserved prefixe "D" : <#ftl ns_prefixes={"D":"http://www.demandware.com/xml/impex/catalog/2006-10-31"}>
Related
I want to sent a Postman request with a xml file like this to my api:
<data>
<user>
<name>Andrei</name>
<adress>Tudor Vladimirescu, nr2</adress>
<cnp>123456789</cnp>
<age>22</age>
</user>
<user>
<name>Ana</name>
<adress>Str. Pacurari, nr1</adress>
<cnp>123456789</cnp>
<age>26</age>
</user>
<user>
<name>Andreea</name>
<adress>Tudor Vladimirescu, nr1</adress>
<cnp>123456789</cnp>
<age>20</age>
</user>
</data>
And I want to add a <valid>Yes/No</valid> tag to each <user> based on the age. For example: if the age is above 23, the value of the valid tag should be Yes. I want to send the modified message to another API.
I know that I should use Enrich, Iterate and Filter mediators but I really need some help because I'm a beginner. Thank you!
I have used Iterate mediator as you need backend call and filter mediator used to set age is valid or not for each element and finally used enrich mediator to achieve your usecase.
<!-- iteration of incoming user data -->
<iterate expression="//data/user" id="iterateuser" sequential="true">
<target>
<sequence>
<property expression="//age/text()" name="age" scope="default" type="STRING"/>
<log level="custom">
<property name="Inside Iterator" value="is called*****"/>
<property expression="get-property('age')" name="age"/>
</log>
<!-- fiter to find valid age or not-->
<filter xpath="get-property('age')>='23'">
<then>
<property name="valid" scope="default" type="STRING" value="Yes"/>
</then>
<else>
<property name="valid" scope="default" type="STRING" value="No"/>
</else>
</filter>
<!-- enrich to add valid tag to existing payload-->
<enrich>
<source clone="true" type="inline">
<valid xmlns=""/>
</source>
<target action="child" xmlns:ns="http://www.wso2.org/types" xpath="//user"/>
</enrich>
<!-- enrich to add valid property value with validtag-->
<enrich>
<source clone="true" property="valid" type="property"/>
<target xpath="//valid"/>
</enrich>
<log level="full"/>
<!-- make an external endpoint call here -->
</sequence>
</target>
</iterate>
Input:
<data>
<user>
<name>Andrei</name>
<adress>Tudor Vladimirescu, nr2</adress>
<cnp>123456789</cnp>
<age>22</age>
</user>
<user>
<name>Ana</name>
<adress>Str. Pacurari, nr1</adress>
<cnp>123456789</cnp>
<age>26</age>
</user>
<user>
<name>Andreea</name>
<adress>Tudor Vladimirescu, nr1</adress>
<cnp>123456789</cnp>
<age>20</age>
</user>
</data>
Log for iteration:
[2022-03-15 12:27:23,032] INFO {org.apache.synapse.mediators.builtin.LogMediator} - Inside Iterator = is called*****, age = 22
[2022-03-15 12:27:23,032] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: /enrichapi, MessageID: urn:uuid:8101fdcc-0a29-4bea-a8f1-b8ad80f0c6ff, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><user>
<name>Andrei</name>
<adress>Tudor Vladimirescu, nr2</adress>
<cnp>123456789</cnp>
<age>22</age>
<valid>No</valid></user></soapenv:Body></soapenv:Envelope>
[2022-03-15 12:27:23,032] INFO {org.apache.synapse.mediators.builtin.LogMediator} - Inside Iterator = is called*****, age = 26
[2022-03-15 12:27:23,040] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: /enrichapi, MessageID: urn:uuid:b01f8b29-9fe5-43e6-a0ed-0a61d395fd1a, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><user>
<name>Ana</name>
<adress>Str. Pacurari, nr1</adress>
<cnp>123456789</cnp>
<age>26</age>
<valid>Yes</valid></user></soapenv:Body></soapenv:Envelope>
[2022-03-15 12:27:23,053] INFO {org.apache.synapse.mediators.builtin.LogMediator} - Inside Iterator = is called*****, age = 20
[2022-03-15 12:27:23,053] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: /enrichapi, MessageID: urn:uuid:1feeb723-8a72-475a-b014-cda2e7b7a90a, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><user>
<name>Andreea</name>
<adress>Tudor Vladimirescu, nr1</adress>
<cnp>123456789</cnp>
<age>20</age>
<valid>No</valid></user></soapenv:Body></soapenv:Envelope>
If you noticed above log <valid>No</valid> or <valid>Yes</valid> is added to payload.
Post this, you can make external endpoint call inside iterator.
Ref:
Enrich Mediator
Below is my request body xml and I am making rest call with this request. Having custom LoggingInterceptor to log the request and response. I want to mask the user and password in logs.
<login><credentials user="user" Password="pass"/></login>
private void traceRequest(final HttpRequest request, final byte[] body) throws IOException {
logger.trace(
String.format(
"REQUEST uri=%s, method=%s, requestBody=%s",
request.getURI(),
request.getMethod(),
new String(body, "UTF-8")));
}
Currently I am printing my logs like below:
LoggingRequestInterceptor - REQUEST uri=http://localhost:8080/, method=POST, requestBody=<login><credentials user="user" Password="pass"/></login>
Below is my logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<property name="logFile" value="logs/employee.log" />
<property name="logFile-WS" value="logs/employee-ws.log" />
<appender name="employee" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logFile}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logFile}.%d{yyyy-MM-dd}.gz</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d [%thread] %-5level %logger{64} - %msg%n</pattern>
</encoder>
</appender>
<appender name="mainAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logFile-WS}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logFile-WS}.%d{yyyy-MM-dd}.gz</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d [%thread] %-5level %logger{64} - %replace(%msg){'having masking logic for other property'}%n</pattern>
</encoder>
</appender>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.springframework.ws.client.MessageTracing" level="TRACE" additivity="false">
<appender-ref ref="mainAppender" />
</logger>
<logger name="org.springframework.ws.server.MessageTracing" level="TRACE" additivity="false">
<appender-ref ref="mainAppender" />
</logger>
<logger name="com.employee.LoggingRequestInterceptor" level="TRACE" additivity="false">
<appender-ref ref="mainAppender" />
</logger>
<root level="${root-log-level:-INFO}">
<appender-ref ref="stdout"/>
<appender-ref ref="mainAppender"/>
</root>
</configuration>
Please someone help me to solve this. Note: I am using spring boot 2 and slf4j logger
Referring to Mask sensitive data in logs with logback
Add logback-spring.xml in your project.
Customize regular expression in the <patternsProperty> value to match the content your want to mask.
Add the MaskingPatternLayout class (Use the updated one, the one in the beginning is not working) from the above answer
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="Console"
class="ch.qos.logback.core.ConsoleAppender">
<encoder
class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="com.example.springboot.MaskingPatternLayout">
<patternsProperty>(?:user|Password)="([a-zA-Z0-9]+)"
</patternsProperty>
<pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern>
</layout>
</encoder>
</appender>
<!-- LOG everything at INFO level -->
<root level="info">
<appender-ref ref="Console" />
</root>
</configuration>
HelloController class to test
#RestController
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
#RequestMapping("/")
public String index() {
logger.info("<login><credentials user=\"user\" Password=\"pass\"/></login>");
return "Greetings from Spring Boot!";
}
}
Expected output
2020-04-13 12:38:47,511 [http-nio-8080-exec-1] INFO c.e.springboot.HelloController - <login><credentials user="****" Password="****"/></login>
Update
Please check if "console" should be "stdout"
<root level="${root-log-level:-INFO}">
<appender-ref ref="console"/>
<appender-ref ref="mainAppender"/>
</root>
As no appender with name "console" is found.
Suppose the logger is in LoggingRequestInterceptor, you need to add the "stdout" appender also.
<logger name="com.employee.LoggingRequestInterceptor"
level="TRACE" additivity="false">
<appender-ref ref="stdout" />
<appender-ref ref="mainAppender" />
</logger>
I have added pattern with replace in logback.xml. It's masked user and password
<encoder>
<pattern>%d [%thread] %-5level %logger{64} - %replace( %replace( %replace(%msg){'user="[^"]+"', 'user=*****'} ){'Password="[^"]+"', 'Password=*****'} ){'my another pattern', 'replacement'}%n</pattern>
</encoder>
We are working with ESB 4.9.
We have a simple pass-through proxy service:
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="BankSeb1"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<outSequence>
<send/>
</outSequence>
<endpoint>
<address uri="https://server:port/bankas/seb"/>
</endpoint>
</target>
<description/>
</proxy>
This service works properly and I don't have any problems.
But when I try to design a scheduled task for this service, the exception is thrown:
TID: [-1234] [] [2015-12-08 15:25:32,943] ERROR {org.apache.synapse.core.axis2.Axis2Sender} -
Connection:Keep-Alive,Date:Tue, 08 Dec 2015 13:25:32 GMT,Transfer-Encoding:chunked,
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body/></soapenv:Envelope>
Unexpected error sending message back {org.apache.synapse.core.axis2.Axis2Sender}
org.apache.axis2.AxisFault: Transport out has not been set
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:432)
at org.apache.synapse.core.axis2.Axis2Sender.sendBack(Axis2Sender.java:212)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.send(Axis2SynapseEnvironment.java:444)
at org.apache.synapse.mediators.builtin.SendMediator.mediate(SendMediator.java:102)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:297)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:529)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:172)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:247)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745
Scheduled task configuration:
<task class="org.apache.synapse.startup.tasks.MessageInjector"
group="synapse.simple.quartz" name="BankSeb">
<trigger count="1" interval="10"/>
<property name="injectTo" value="proxy" xmlns:task="http://www.wso2.org/products/wso2commons/tasks"/>
<property name="proxyName" value="BankSeb1" xmlns:task="http://www.wso2.org/products/wso2commons/tasks"/>
<property name="message" xmlns:task="http://www.wso2.org/products/wso2commons/tasks">
<root>
<a>b</a>
</root>
</property>
</task>
The same task and service in ESB 4.8 works OK.
Could somebody help me to resolve this problem.
I tried such schema with several proxy services and always I get the same exception.
In wso2 esb 4.5.1, i don't have option of direct task scheduling for sequence or proxy service. so, i try to use property name SoapAction and to in task scheduling but iam getting the below error,
ERROR - TaskManagementHelper Invalid XML has been provided for property : message
ERROR - TaskManagementHelper Invalid XML has been provided for property : format
Here is a sample "Scheduled Task" that inject 2 times an XML message
<root>
<node1>value1</node1>
</root>
It works with ESB 4.5.1
<?xml version="1.0" encoding="UTF-8"?>
<task xmlns="http://ws.apache.org/ns/synapse"
name="TestTask"
class="org.apache.synapse.startup.tasks.MessageInjector"
group="synapse.simple.quartz">
<trigger count="2" interval="5"/>
<property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"
name="format"
value="application/xml"/>
<property xmlns:task="http://www.wso2.org/products/wso2commons/tasks"
name="to"
value="TestTaskProxy"/>
<property xmlns:task="http://www.wso2.org/products/wso2commons/tasks" name="message">
<root xmlns="">
<node1>value1</node1>
</root>
</property>
</task>
format and to properties are literal types
message property is an XML type
I have a WSO2ESB 4.7 proxy with vfs transport. I need to read some xml files like this one:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Header PUBLIC "/usr/xxx.dtd" "/usr/xxx.dtd">
<Header xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
...
Proxy:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="test" statistics="disable" trace="disable" transports="vfs">
<parameter name="transport.PollInterval">5</parameter>
<parameter name="transport.vfs.FileURI">C:\WSO2</parameter>
<parameter name="transport.vfs.FileNamePattern">.*[.][xX][mM][lL]$</parameter>
<parameter name="transport.vfs.ContentType">application/xml</parameter>
<target>
<inSequence>
<property name="OUT_ONLY" value="true"/>
<log level="full"/>
<send>
<endpoint>
...
</endpoint>
</send>
</inSequence>
</target>
</proxy>
Wso2 returns this error:
[2013-10-15 11:23:03,670] ERROR - VFSTransportListener Error processing File URI : file:///C:/WSO2/1_CHRG_2713540.XML
org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: DOCTYPE is not allowed
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:296)
at org.apache.axiom.om.impl.llom.OMDocumentImpl.getOMDocumentElement(OMDocumentImpl.java:109)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.getDocumentElement(StAXOMBuilder.java:570)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.getDocumentElement(StAXOMBuilder.java:566)
at org.apache.axis2.builder.ApplicationXMLBuilder.processDocument(ApplicationXMLBuilder.java:81)
at org.apache.synapse.transport.vfs.VFSTransportListener.processFile(VFSTransportListener.java:574)
at org.apache.synapse.transport.vfs.VFSTransportListener.scanFileOrDirectory(VFSTransportListener.java:324)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:158)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:107)
at org.apache.axis2.transport.base.AbstractPollingTransportListener$1$1.run(AbstractPollingTransportListener.java:67)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.xml.stream.XMLStreamException: DOCTYPE is not allowed
at org.apache.axiom.util.stax.dialect.DisallowDoctypeDeclStreamReaderWrapper.next(DisallowDoctypeDeclStreamReaderWrapper.java:36)
at org.apache.axiom.util.stax.wrapper.XMLStreamReaderWrapper.next(XMLStreamReaderWrapper.java:225)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:681)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214)
... 13 more
Is there a possibility to get wso2 ignoring the Doctype?
I dont want to read the file as text/plain, remove doctype, convert to xml, work with it, convert to text/plain, add doctype.
Add the following parameter as well to the proxy service. Then it will allow DOCTYPE declaration
<parameter name="ApplicationXMLBuilder.allowDTD">true</parameter>