Issues Migrating Mule 3.6 expression component into DataWeave 2.0 - mule

My company is moving toward migrating our current Mule 3.6 APIs into Mule 4.2 and I'm trying to migrate our first API at present. There are numerous differences between the runtimes not least the wide use of Dataweave 2.0 in Mule 4. I'm new to a lot of the components of Mule 4 having used Mule 3 extensively, and I'm currently stuck with moving the following expression component into Dataweave. I'm struggling to get the correct syntax without Studio complaining that there are errors.
The current expression is
<expression-component doc:name="Expression"><![CDATA[
flowVars.pSector="ELECTRICITY";
if(flowVars.serialNo.length()==14){
if (flowVars.serialNo.substring(0,2)=="G4" || flowVars.serialNo.substring(0,2)=="E6" ||
flowVars.serialNo.substring(0,2)=="JE" || flowVars.serialNo.substring(0,2)=="JA" ||
flowVars.serialNo.substring(0,2)=="JS") {
flowVars.pSector="GAS";
}
}]]></expression-component>
this is essentially determining the fuel type of a meter based on component parts of its serial number and it's length. Any help on converting this expression into a Dataweave would be appreciated

Note that in Mule 4 there can not be side effects, meaning that you can assign the result of one script to the payload or to one variable. Also DataWeave is functional rather than an imperative language.
In Mule 4 variables are referenced as vars.name instead of flowVars.name.
A naive translation could be like this:
<ee:transform doc:name="Transform Message">
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/java
fun checkSerial(serial)=if (sizeOf(serial) == 14 )
if (serial[0 to 1] == "G4" or serial[0 to 1]=="E6" or serial[0 to 1]=="JE"
or serial[0 to 1]=="JA" or serial[0 to 1]=="JS")
"GAS"
else
"ELECTRICITY"
else "ELECTRICITY"
---
checkSerial(vars.serialNo)]]></ee:set-payload>
</ee:message>
</ee:transform>

Related

'File' access is not allowed due to restriction set by the accessExternalSchema property

I'm trying to validate xml payload with XSD, where this XSD is referring other and the other is referring someother. Something like nested reference.
When I include all the .xsd's in Validate Schema path, I still get:
Root Exception stack trace: org.xml.sax.SAXParseException;
schema_reference: Failed to read schema document 'MPProduct.xsd',
because 'file' access is not allowed due to restriction set by the
accessExternalSchema property.
om.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
at
com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
at
com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
at
com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:306)
at
com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(XSDHandler.java:4160)
at
com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaFatalError(XSDHandler.java:4135)
at
com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSchemaDocument(XSDHandler.java:2172)
at
com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.resolveSchema(XSDHandler.java:2100)
at
com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1104)
at
com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:623)
at
com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:613)
at
com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:572)
at
com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:538)
at
com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:255)
at
org.mule.module.xml.internal.operation.SchemaValidatorOperation$2.create(SchemaValidatorOperation.java:142)
at
org.mule.module.xml.internal.operation.SchemaValidatorOperation$2.create(SchemaValidatorOperation.java:132)
at
org.apache.commons.pool2.BasePooledObjectFactory.makeObject(BasePooledObjectFactory.java:58)
at
org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:888)
at
org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:432)
Any suggestions to resolve this please?
I tried adding -Djavax.xml.accessExternalSchema=all in VM arguments while running on local still it remains same
<flow name="mytestingFlow" doc:id="4efe5074-da20-4164-843a-06ca9a2a9979" >
<http:listener doc:name="Listener" doc:id="74f4f199-00cb-460d-b72f-df3497f26e6a" config-ref="HTTP_Listener_config" path="/service/path/one"/>
<set-payload value="#["<MPItemFeed xmlns=\"http://walmart.com/\"><MPItemFeedHeader><version>3.2</version></MPItemFeedHeader><MPItem><processMode>CREATE</processMode><sku>10145802</sku><productIdentifiers><productIdentifier><productIdType>UPC</productIdType><productId>123456789123</productId></productIdentifier></productIdentifiers><MPProduct><SkuUpdate>NO</SkuUpdate><msrp>183.99</msrp><productName>CARQUEST Platinum Professional Ceramic Brake Pads - Front (4-Pad Set)</productName><ProductIdUpdate>YES</ProductIdUpdate><category><Vehicle><VehiclePartsAndAccessories><shortDescription>Ceramic Brake Pads - Front (4-Pad Set)</shortDescription><keyFeatures><keyFeaturesValue>Premium brake pad underlayer reduces vibration for silent braking Industry leading number of application specific formulations for maximum performance Revolutionary burnishing compound strip allows for proper break-in of pads and rotors.</keyFeaturesValue></keyFeatures><brand>CARQUEST Platinum Professional</brand><manufacturer>CARQUEST Platinum Professional</manufacturer><manufacturerPartNumber>PXD1210H</manufacturerPartNumber><mainImageUrl>http://pdfifsvcprd.corp.advancestores.com/assets/epc50x50/std.lang.all/1012147531.jpg</mainImageUrl><isProp65WarningRequired>Yes</isProp65WarningRequired><prop65WarningText>cancer and reproductive</prop65WarningText><hasWarranty>YES</hasWarranty><warrantyText>LIMITED LIFETIME REPLACEMENT</warrantyText></VehiclePartsAndAccessories></Vehicle></category></MPProduct><MPOffer><price>182.99</price><ShippingWeight><measure>4</measure><unit>lb</unit></ShippingWeight><ProductTaxCode>2038710</ProductTaxCode></MPOffer></MPItem><MPItem><processMode>CREATE</processMode><sku>11395545</sku><productIdentifiers><productIdentifier><productIdType>UPC</productIdType><productId>123456789123</productId></productIdentifier></productIdentifiers><MPProduct><SkuUpdate>NO</SkuUpdate><msrp>183.99</msrp><productName>CARQUEST Platinum Brake Rotor - Front</productName><ProductIdUpdate>YES</ProductIdUpdate><category><Vehicle><VehiclePartsAndAccessories><shortDescription>Brake Rotor - Front</shortDescription><keyFeatures><keyFeaturesValue>Engineered to withstand 120 hours of salt spray testing Manufactured to exacting quality and dimensional specifications for Superior Stopping Power Exceeds ISO manufacturing guidelines (International Organization for Standardization)</keyFeaturesValue></keyFeatures><brand>CARQUEST Platinum</brand><manufacturer>CARQUEST Platinum</manufacturer><manufacturerPartNumber>YH145232P</manufacturerPartNumber><mainImageUrl>http://pdfifsvcprd.corp.advancestores.com/assets/epc50x50/std.lang.all/1017931756.jpg</mainImageUrl><isProp65WarningRequired>No</isProp65WarningRequired><prop65WarningText/><hasWarranty>YES</hasWarranty><warrantyText>2 YR REPLACEMENT IF DEFECTIVE</warrantyText></VehiclePartsAndAccessories></Vehicle></category></MPProduct><MPOffer><price>182.99</price><ShippingWeight><measure>4</measure><unit>lb</unit></ShippingWeight><ProductTaxCode>2038710</ProductTaxCode></MPOffer></MPItem><MPItem><processMode>CREATE</processMode><sku>10556036</sku><productIdentifiers><productIdentifier><productIdType>UPC</productIdType><productId>123456789123</productId></productIdentifier></productIdentifiers><MPProduct><SkuUpdate>NO</SkuUpdate><msrp>183.99</msrp><productName>CARQUEST Premium Lube Element with Lid</productName><ProductIdUpdate>YES</ProductIdUpdate><category><Vehicle><VehiclePartsAndAccessories><shortDescription>Lube Element with Lid</shortDescription><keyFeatures><keyFeaturesValue>Environmental cartridge lube filter High efficiency and durable cellulose/synthetic blended media for longer drain intervals Silicone anti-drain back valve has 3X the durability verses nitrile for engine start-up protection</keyFeaturesValue></keyFeatures><brand>CARQUEST Premium</brand><manufacturer>CARQUEST Premium</manufacturer><manufacturerPartNumber>84312</manufacturerPartNumber><mainImageUrl>http://pdfifsvcprd.corp.advancestores.com/assets/epc50x50/std.lang.all/1015772990.jpg</mainImageUrl><isProp65WarningRequired>Yes</isProp65WarningRequired><prop65WarningText>cancer and reproductive</prop65WarningText><hasWarranty>YES</hasWarranty><warrantyText>REPLACE OR REFUND AT MGR DISCRETION</warrantyText></VehiclePartsAndAccessories></Vehicle></category></MPProduct><MPOffer><price>182.99</price><ShippingWeight><measure>4</measure><unit>lb</unit></ShippingWeight><ProductTaxCode>2038710</ProductTaxCode></MPOffer></MPItem><MPItem><processMode>CREATE</processMode><sku>20471798</sku><productIdentifiers><productIdentifier><productIdType>UPC</productIdType><productId>123456789123</productId></productIdentifier></productIdentifiers><MPProduct><SkuUpdate>NO</SkuUpdate><msrp>183.99</msrp><productName>Denso Air-Fuel Ratio Sensor 4 Wire, Direct Fit, Heated, Wire Length: 10.63</productName><ProductIdUpdate>YES</ProductIdUpdate><category><Vehicle><VehiclePartsAndAccessories><shortDescription>Air-Fuel Ratio Sensor 4 Wire, Direct Fit, Heated, Wire Length: 10.63</shortDescription><keyFeatures><keyFeaturesValue>Specifically designed to meet the increasing demands of today's engines 100% checked for high temperature signal output, air tightness, continuity, and heat resistance for optimal efficiency and performance Double protection cover helps maintain proper unit temperature for quicker response times, which is critical to your vehicle's fuel efficiency</keyFeaturesValue></keyFeatures><brand>Denso</brand><manufacturer>Denso</manufacturer><manufacturerPartNumber>234-9001</manufacturerPartNumber><mainImageUrl>http://pdfifsvcprd.corp.advancestores.com/assets/epc50x50/std.lang.all/524891.jpg</mainImageUrl><isProp65WarningRequired>No</isProp65WarningRequired><prop65WarningText/><hasWarranty>YES</hasWarranty><warrantyText>1 YR REPLACEMENT IF DEFECTIVE</warrantyText></VehiclePartsAndAccessories></Vehicle></category></MPProduct><MPOffer><price>182.99</price><ShippingWeight><measure>4</measure><unit>lb</unit></ShippingWeight><ProductTaxCode>2038710</ProductTaxCode></MPOffer></MPItem></MPItemFeed>
"]" doc:name="Set Payload" doc:id="b16a5f07-fa58-4c36-837a-3533eecdcccd" mimeType="application/xml"/>
<ee:transform doc:name="Transform Message" doc:id="a6d22ddb-1e3a-4519-a22f-41987f9b5049" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/xml
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
<xml-module:validate-schema doc:name="Validate schema" doc:id="c5dbaef9-d4f3-4aeb-b15a-516aa0eb2479" schemas="Animal.xsd,ArtAndCraftCategory.xsd,Baby.xsd,CarriersAndAccessoriesCategory.xsd,ClothingCategory.xsd,Electronics.xsd,FoodAndBeverageCategory.xsd,FootwearCategory.xsd,FurnitureCategory.xsd,GardenAndPatioCategory.xsd,HealthAndBeauty.xsd,Home.xsd,JewelryCategory.xsd,Media.xsd,MPCommons.xsd,MPItem.xsd,MPItemFeed.xsd,MPItemFeedHeader.xsd,MPOffer.xsd,MPProduct.xsd,MusicalInstrument.xsd,OccasionAndSeasonal.xsd,OfficeCategory.xsd,OtherCategory.xsd,Photography.xsd,SportAndRecreation.xsd,ToolsAndHardware.xsd,ToysCategory.xsd,Vehicle.xsd,WatchesCategory.xsd" config-ref="XML_Config"/>
<logger level="INFO" doc:name="Logger" doc:id="a74dbf49-d111-4eb3-84c3-598845ecaf48" />
</flow>
What is the location in which the XSD files are present? The path needs to be specified for the XSD as mentioned here
Reading file is the problem. Similar issue is faced while reading mUnit input file also. In these cases, files can be read as : getResourceAsString or getResourceAsStream
This should be helpful.

Mule Error - Collectiion Splitter - Exception Thrown on HTTP Return

getting an interesting exception. Using a splitter processor to split a collection using a Collection Splitter. It splits the collection fine but when the flow returns back to the main flow and the flow ends, it throws this exception. Wondering if you'd seen it before :
ERROR 2018-12-07 16:06:26,052 [[ahld_kpi_enabler].HTTP_Listener_Configuration.worker.01] org.mule.exception.DefaultMessagingExceptionStrategy: Caught exception in Exception Strategy: java.lang.UnsupportedOperationException: getPayloadAsBytes(), There has been an attempt to directly access the payload of a message collection, which is unsupported.
Please retrieve the value from messageList or use getPayload(DataType.BYTE_ARRAY_DATA_TYPE)
java.lang.RuntimeException: java.lang.UnsupportedOperationException: getPayloadAsBytes(), There has been an attempt to directly access the payload of a message collection, which is unsupported.
Please retrieve the value from messageList or use getPayload(DataType.BYTE_ARRAY_DATA_TYPE)
The flow is triggered via HTTP and it makes outbound HTTP calls.
There's no aggregation happening of the collection split, its merely used to split the collection and for each object in the collection subsbequent calls / actions are taken
At the end of your flow when using a collection-splitter, your payload is going to be a Mule message collection and as your using HTTP, it's going to try and serialise that as the HTTP response, which it can't.
So you can either aggregate your payload and then set your payload to something to return or even #[null].
Or you can put your collection-splitter and the logic after that in a separate flow - wrapped in an enricher:
<enricher target="#[flowVars.someVar]">
<flow-ref name="myCollectionSplitterLogicFlow" />
</enricher>
Or you can just use foreach, which I would personally advise, as splitters are removed in Mule 4.
If you have nested collections, you can have any number of nested foreach :
<foreach collection="#[payload]">
<foreach collection="#[payload.nestedCollection]">
</foreach>
</foreach>

Mule flatten arrays with one of the arrays as null

I am learning mule4 and while trying out scatter-gather, i have run into an issue.
There are 3 flows in the scatter gather task, 2 of these flows return valid payload with data but the 3rd flow returns a empty payload.
thus when i am trying to flatten these 3 results , i am running into null pointer issue. i am not able to make out way to handle this. can anybody help please.
My dataweave expression is as below
%dw 2.0
output application/java
---
flatten(payload..payload)
logs
ERROR 2018-10-27 07:10:00,249 [[MuleRuntime].cpuLight.06: [apdev-flights-ws].getAllFlightsFlow.CPU_LITE #5abc6c4c] [event: ] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
********************************************************************************
Message : "Unexpected end-of-input at payload#[1:1] (line:column), expected false or true or null or {...} or [...] or number but was , while reading `payload`as Json.
1|
^" evaluating expression: "%dw 2.0
output application/java
---
flatten(payload..payload) ".
Error type : MULE:EXPRESSION
Element : getAllFlightsFlow/processors/2 # apdev-flights-ws:implementation.xml:102 (Flatten)
Element XML : <ee:transform doc:name="Flatten" doc:id="46245fd1-5ebd-4b16-b83e-31ea4dbb53e8">
<ee:message>
<ee:set-payload>%dw 2.0
output application/java
---
flatten(payload..payload)</ee:set-payload>
</ee:message>
</ee:transform>
(set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
INFO 2018-10-27 07:10:00,323 [[MuleRuntime].cpuLight.06: [apdev-flights-ws].getAllFlightsFlow.CPU_LITE #5abc6c4c] [event: ] org.mule.runtime.core.internal.context.notification.Policy: NotificationListener com.mulesoft.mule.debugger.server.DebuggerPipelineMessageNotificationListener#20d9c50f was unable to fire notification PipelineMessageNotification{action=pipeline process complete, resourceId=getAllFlightsFlow, serverId=de-PC..apdev-flights-ws, timestamp=1540604400323} due to an exception: java.lang.NullPointerException.
I believe it's the payload..payload call that's messing you up. If you want to flatten the payload, it should just be:
%dw 2.0
output application/java
---
flatten(payload)

How to get more information about dataweave exception in muleosft

I am getting below dataweave exception while executing a mule flow :
"
INFO 2016-11-06 09:02:42,097 [[abc].HTTP_Listener_Configuration.worker.01] com.mulesoft.weave.mule.utils.MuleWeaveFactory$: MimeType was not resolved '*/*' delegating to Java.
ERROR 2016-11-06 09:02:42,290 [[abc].HTTP_Listener_Configuration.worker.01] org.mule.exception.CatchMessagingExceptionStrategy:
Message : Exception while executing:
"Response": {
^
Unexpected character '\u000a' at index 25 (line 2, position 24), expected '"'
Payload : test
Payload Type : java.lang.String
Element : /Process11/processors/9/1/9 # abc:def.xml:331 (TM_F1)
Element XML : <dw:transform-message doc:name="TM_F1">
<dw:set-payload>%dw 1.0%output application/json---{Data: [{// in_id : flowVars.instanceId,pd: '{AmIds:[{AmId:' ++ flowVars.AmId ++ '}]}'}]}</dw:set-payload>
</dw:transform-message>
Root Exception stack trace:
com.mulesoft.weave.reader.json.JsonReaderException: Unexpected character '\u000a' at index 25 (line 2, position 24), expected '"'
at com.mulesoft.weave.reader.json.JsonTokenizer.fail(JsonTokenizer.scala:193)
at com.mulesoft.weave.reader.json.JsonTokenizer.require(JsonTokenizer.scala:190)
at com.mulesoft.weave.reader.json.JsonTokenizer.readString(JsonTokenizer.scala:80)
"
Is there any possibility to enable more debug options to get more information about this particular exception so that it will be easy to find out the root cause.
The problem here is, even though i am not using the payload in transform message i am getting error because of the payload returned by the previous http call in muleflow.
Mule version is : studio 6.1 and runtime 3.8.
Please help me to solve this issue.
Thanks
sdg
This is not dataweave question. Exception what you have is from JsonReaderException:
com.mulesoft.weave.reader.json.JsonReaderException: Unexpected character '\u000a' at index 25 (line 2, position 24), expected '"'
It means that JSON what you provide has new line (\u000a) ate line 2 position 24. I imagine it is something like this:
"Response": {
"Message" : "67890123
456 the end"
}
Use special characters to represent new line in JSON.
"Response": {
"Message" : "67890123\n456 the end"
}
Enable info logs in log4j and enable debug logs at cloudhub if its an on cloud deployment.
Please Try validating the json as well
Debug is the best option to figure out these kind of errors. Also you may use the logger feature of dataweave to log specific values on console and see whats wrong with the value.

Run Mule Quartz with condition

I want to start mule quartz with condition..
For ex: In mule peroperties file I put one flag=on.If that flag is on then and only then Scheduler will be start.If that flag is off then schedule will be not called.
How can I do this in mule?
Please help
Mule is wired up with Spring so the tricks/features you can use to make some beans conditional should work for Mule too.
I would try the following:
Extract the flow definition where the Quartz endpoint is started into quartz-config-on.xml
Create an empty Mule XML config named quartz-config-off.xml
In your main Mule XML config, use: <import resource="quartz-config-${quartz.flag}.xml"/> where quartz.flag is a property that is either on or off
I used a work around to achieve this kind of behavior. I defined a Quartz connector where the cron expression to trigger it is loaded from a property file.
If you put the expression to something that won't trigger until 2099 it's almost equivalent to a disabled cron.
<quartz:inbound-endpoint cronExpression="${cron1.expression}"
jobName="scheduler1" doc:name="Scheduler 1">
<quartz:event-generator-job>
<quartz:payload>${cron1.request};${cron1.trade.date.offset}/quartz:payload>
</quartz:event-generator-job>
</quartz:inbound-endpoint>
And the property file:
#Scheduler 1 settings
cron1.expression = 3 14 15 9 2 ? 2099
cron1.request = none
cron1.trade.date.offset = 0