Mule 3.2. How to Evaluate Empty Session Variable in Flow? - session

How can I check if my session variable is null or empty in this CHOICE
Its not working for me.
<processor-chain doc:name="Processor Chain">
<choice>
<when evaluator="groovy" expression="#[header:session:countryCode] != ">
<logger message="Valid Country Id" level="INFO" doc:name="Logger"/>
</when>
<otherwise>
<logger message="Invalid Country Id" level="INFO" doc:name="Logger"/>
</otherwise>
</choice>
</processor-chain>
I also tried != '' and != null

If you're using Mule 3.3.x, better use MEL than Groovy:
<when expression="#[org.mule.util.StringUtils.isNotEmpty(sessionVars.countryCode)]">

You are using an invalid groovy expression. It should be:
...
<when expression="message.getProperty('countryCode',org.mule.api.transport.PropertyScope.SESSION)!=null
|| message.getProperty('countryCode',org.mule.api.transport.PropertyScope.SESSION)!=''"
evaluator="groovy">
...
You can also access properties with Header evaluator but I'm not sure if you can evaluate to find out if it is null or empty

Related

message-filter onUnaccepted not breaking execution when used in "mule:choice" in custom policy mule 3

I am working on a custom policy in mule 3. When I am using message-filter inside mule:choice, on onUnaccpted, execution of next statement DOES NOT stop.
if I do not use mule:choice, execution of next statement stop on onUnaccepted in message-filter.
I need to use message-filter in mule:choice, can you please let me know how to stop next statement execution on message-filer onUnaccepted.
I have provided example below:
Case 1:
<before>
<mule:logger level="INFO" message="Logger 0"/>
<mule:message-filter onUnaccepted="policyViolation">
<mule:expression-filter expression="true==false" />
</mule:message-filter>
<mule:logger level="INFO" message="Logger 1"/>
</before>
<mule:processor-chain name="policyViolation">
<mule:logger message="The custom policy filtered the message #[message.getId()] based on a MEL query" level="DEBUG" />
<mule:set-property propertyName="http.status" value="403"/>
<mule:set-property propertyName="Content-Type" value="application/json"/>
<mule:set-payload value='{ "error" : "Custom Policy: {{ denied-message }}"}'/>
</mule:processor-chain>
Output: 403 - {"error": "Custom Policy: Access denied"}
and DOES NOT log message Logger 1.
execution breaks when onUnaccepted
Case 2:
<before>
<mule:logger level="INFO" message="Logger 0"/>
<mule:choice>
<mule:when expression="true==false" >
<mule:logger level="INFO" message="Logger 1"/>
</mule:when>
<mule:otherwise>
<mule:message-filter onUnaccepted="policyViolation">
<mule:expression-filter expression="true==false" />
</mule:message-filter>
</mule:otherwise>
</mule:choice>
<mule:logger level="INFO" message="Logger 2"/>
</before>
<mule:processor-chain name="policyViolation">
<mule:logger message="The custom policy filtered the message #[message.getId()] based on a MEL query" level="DEBUG" />
<mule:set-property propertyName="http.status" value="403"/>
<mule:set-property propertyName="Content-Type" value="application/json"/>
<mule:set-payload value='{ "error" : "Custom Policy: {{ denied-message }}"}'/>
</mule:processor-chain>
Output: 403 - {"error": "Custom Policy: Access denied"}
and LOGS message Logger 2. after message filter onUnaccepted, execution does not break and continues
DO NOT want to print Logger 2.
onUnaccepted doesn't seem to play well with MUnit. I have seen in the past that using filters with onUnaccepted produce unexpected results with MUnit. I recommend to avoid using it at all. I prefer to use Validators, which throw exceptions.

How can I get a pathname from a groupId? [duplicate]

Is there a simple way of taking the value of a property and then copy it to another property with certain characters replaced?
Say propA=This is a value. I want to replace all the spaces in it into underscores, resulting in propB=This_is_a_value.
Here is the solution without scripting and no external jars like ant-conrib:
The trick is to use ANT's resources:
There is one resource type called "propertyresource" which is like a source file, but provides an stream from the string value of this resource. So you can load it and use it in any task like "copy" that accepts files
There is also the task "loadresource" that can load any resource to a property (e.g., a file), but this one could also load our propertyresource. This task allows for filtering the input by applying some token transformations. Finally the following will do what you want:
<loadresource property="propB">
<propertyresource name="propA"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from=" " to="_"/>
</tokenfilter>
</filterchain>
</loadresource>
This one will replace all " " in propA by "_" and place the result in propB. "filetokenizer" treats the whole input stream (our property) as one token and appies the string replacement on it.
You can do other fancy transformations using other tokenfilters: http://ant.apache.org/manual/Types/filterchain.html
Use the propertyregex task from Ant Contrib.
I think you want:
<propertyregex property="propB"
input="${propA}"
regexp=" "
replace="_"
global="true" />
Unfortunately the examples given aren't terribly clear, but it's worth trying that. You should also check what happens if there aren't any underscores - you may need to use the defaultValue option as well.
If ant-contrib isn't an option, here's a portable solution for Java 1.6 and later:
<property name="before" value="This is a value"/>
<script language="javascript">
var before = project.getProperty("before");
project.setProperty("after", before.replaceAll(" ", "_"));
</script>
<echo>after=${after}</echo>
In case you want a solution that does use Ant built-ins only, consider this:
<target name="replace-spaces">
<property name="propA" value="This is a value" />
<echo message="${propA}" file="some.tmp.file" />
<loadfile property="propB" srcFile="some.tmp.file">
<filterchain>
<tokenfilter>
<replaceregex pattern=" " replace="_" flags="g"/>
</tokenfilter>
</filterchain>
</loadfile>
<echo message="$${propB} = "${propB}"" />
</target>
Output is ${propB} = "This_is_a_value"
Use some external app like sed:
<exec executable="sed" inputstring="${wersja}" outputproperty="wersjaDot">
<arg value="s/_/./g"/>
</exec>
<echo>${wersjaDot}</echo>
If you run Windows get it googling for "gnuwin32 sed".
The command s/_/./g replaces every _ with .
This script goes well under windows. Under linux arg may need quoting.
Two possibilities :
via script task and builtin javascript engine (if using jdk >= 1.6)
<project>
<property name="propA" value="This is a value"/>
<script language="javascript">
project.setProperty('propB', project.getProperty('propA').
replace(" ", "_"));
</script>
<echo>$${propB} => ${propB}</echo>
</project>
or using Ant addon Flaka
<project xmlns:fl="antlib:it.haefelinger.flaka">
<property name="propA" value="This is a value"/>
<fl:let> propB := replace('${propA}', '_', ' ')</fl:let>
<echo>$${propB} => ${propB}</echo>
</project>
to overwrite exisiting property propA simply replace propB with propA
Here's a more generalized version of Uwe Schindler's answer:
You can use a macrodef to create a custom task.
<macrodef name="replaceproperty" taskname="#{taskname}">
<attribute name="src" />
<attribute name="dest" default="" />
<attribute name="replace" default="" />
<attribute name="with" default="" />
<sequential>
<loadresource property="#{dest}">
<propertyresource name="#{src}" />
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from="#{replace}" to="#{with}"/>
</tokenfilter>
</filterchain>
</loadresource>
</sequential>
</macrodef>
you can use this as follows:
<replaceproperty src="property1" dest="property2" replace=" " with="_"/>
this will be pretty useful if you are doing this multiple times
Adding an answer more complete example over a previous answer
<property name="propB_" value="${propA}"/>
<loadresource property="propB">
<propertyresource name="propB_" />
<filterchain>
<tokenfilter>
<replaceregex pattern="\." replace="/" flags="g"/>
</tokenfilter>
</filterchain>
</loadresource>
Just an FYI for answer Replacing characters in Ant property - if you are trying to use this inside of a maven execution, you can't reference maven variables directly. You will need something like this:
...
<target>
<property name="propATemp" value="${propA}"/>
<loadresource property="propB">
<propertyresource name="propATemp" />
...
Properties can't be changed but antContrib vars (http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html ) can.
Here is a macro to do a find/replace on a var:
<macrodef name="replaceVarText">
<attribute name="varName" />
<attribute name="from" />
<attribute name="to" />
<sequential>
<local name="replacedText"/>
<local name="textToReplace"/>
<local name="fromProp"/>
<local name="toProp"/>
<property name="textToReplace" value = "${#{varName}}"/>
<property name="fromProp" value = "#{from}"/>
<property name="toProp" value = "#{to}"/>
<script language="javascript">
project.setProperty("replacedText",project.getProperty("textToReplace").split(project.getProperty("fromProp")).join(project.getProperty("toProp")));
</script>
<ac:var name="#{varName}" value = "${replacedText}"/>
</sequential>
</macrodef>
Then call the macro like:
<ac:var name="updatedText" value="${oldText}"/>
<current:replaceVarText varName="updatedText" from="." to="_" />
<echo message="Updated Text will be ${updatedText}"/>
Code above uses javascript split then join, which is faster than regex. "local" properties are passed to JavaScript so no property leakage.
Or... You can also to try Your Own Task
JAVA CODE:
class CustomString extends Task{
private String type, string, before, after, returnValue;
public void execute() {
if (getType().equals("replace")) {
replace(getString(), getBefore(), getAfter());
}
}
private void replace(String str, String a, String b){
String results = str.replace(a, b);
Project project = getProject();
project.setProperty(getReturnValue(), results);
}
..all getter and setter..
ANT SCRIPT
...
<project name="ant-test" default="build">
<target name="build" depends="compile, run"/>
<target name="clean">
<delete dir="build" />
</target>
<target name="compile" depends="clean">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes" includeantruntime="true"/>
</target>
<target name="declare" depends="compile">
<taskdef name="string" classname="CustomString" classpath="build/classes" />
</target>
<!-- Replacing characters in Ant property -->
<target name="run" depends="declare">
<property name="propA" value="This is a value"/>
<echo message="propA=${propA}" />
<string type="replace" string="${propA}" before=" " after="_" returnvalue="propB"/>
<echo message="propB=${propB}" />
</target>
CONSOLE:
run:
[echo] propA=This is a value
[echo] propB=This_is_a_value

XPath to obtain a node not working in mule esb

I have following xml response out of a transformer:-
<?xml version="1.0" encoding="UTF-8"?>
<detailList>
<details>
<Id>ID123</Id>
<personInfo>
<address>
<address>All the address</address>
<city>CITY</city>
<state>STATE</state>
<postalCode>123123</postalCode>
<country>UNITED STATES</country>
</address>
</personInfo>
<nameF>NAME1</nameF>
<nameL>NAME2</nameL>
</details>
</detailList>
I want to obtain the details node (including all of its child nodes).
I have used following xpath expressions to get this but all of them are printing blank spaces :-
<logger level="INFO" message="#[xpath://detailList]" />
<logger level="INFO" message="#[xpath:/detailList]" />
<logger level="INFO" message="#[xpath:/detailList/*]" />
<logger level="INFO" message="#[xpath://detailList/details]" />
<logger level="INFO" message="#[xpath:/detailList/details]" />
The response that gets printed is (blank space after LoggerMessageProcessor) :-
INFO TimeStamp org.mule.api.processor.LoggerMessageProcessor:
Everything looks fine but I am puzzled why it is not able to locate the node(s)/element(s) through these xpath evaluators.
Assume you are using 3.5+ (else use Xpath3()). You can use splitter, soon after that dont keep logger it would provide you empty result like below org.dom4j.tree.DefaultElement#22a76cce [Element: <details attributes: []/>]. So use any transformer which is required `dom to xml', followed by logger will provide the details value. If you dont use splitter, use expression component or whatever you are currently using.
<splitter expression="#[xpath('/detailList/details')]" doc:name="Splitter"/>
<mulexml:dom-to-xml-transformer doc:name="DOM to XML"/>
<logger message="****Logger:#[payload]" level="INFO" doc:name="Logger"/>
The XPATH you are trying is old and depriciated
You can extract all the values easily using the new Mule XPATH3 :- https://developer.mulesoft.com/docs/display/current/XPath
for example :-
<splitter expression="#[xpath3('//detailList/details', message.payload, 'NODESET')]" doc:name="Splitter"/>
<logger level="INFO" message=" #[xpath3('Id', payload, 'STRING')]" doc:name="Logger"/>
<logger level="INFO" message=" #[xpath3('personInfo/address/address', payload, 'STRING')]" doc:name="Logger"/>
and so on ..

Logs in two different files log4Net

I wanted to write logs in two different files using log4net, one in the global log file while the other for particular user file, for this I set the param in appender like this
<param name="File" value="D:\Projects\Web\Web\Services\Log\%property{LogFileName}" />
And defined a function like this
public void AddInfo(string message)
{
log4net.GlobalContext.Properties["LogFileName"] = this.UserId + ".txt";
log4net.Config.XmlConfigurator.Configure();
Logger.Info(message);
log4net.GlobalContext.Properties["LogFileName"] = "ServiceLog.txt";
log4net.Config.XmlConfigurator.Configure();
Logger.Info(message);
}
This all is working find, every log is written in two different files successfully.
My concern is, is the approach correct if we think about performance?
For each and every log it will configure log4net two times, will it affect performance negatively?
Create two file appenders - one for user log (with pattern for file name), and another for global log:
<appender name="UserFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="%property{userId}.txt" />
...
</appender>
<appender name="GlobalFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.txt" />
...
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="UserFileAppender" />
<appender-ref ref="GlobalFileAppender" />
</root>
Then configure log4net only once per user:
GlobalContext.Properties["userId"] = "Bob";
XmlConfigurator.Configure();
And use loggers in your application.

nlog using the connectionStringName for database logging

here is my nlog.config file. I have turned on the throwsException.
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" throwExceptions="true">
<targets>
<target type="Database" name="databaseLog"
dbProvider="sqlserver" connectionstring="server=.\SQLExpress;database=Movie;integrated security=true">
<commandText>
INSERT INTO [Log] ([Description] , [Level] ) VALUES (#Description, #Level )
</commandText>
<parameter name="#Description" layout="${message}"/>
<parameter name="#Level" layout="${level}"/>
</target>
</targets>
<rules>
<logger name="*" minLevel="Trace" appendTo="databaseLog"/>
</rules>
</nlog>
This will work and will insert records into the database. However I would like to use connectionstringName and not retype the connectionstring.
When I change the connectionstring to connectionstringname like this....
connectionstring="server=.\SQLExpress;database=Movie;integrated security=true"
to
connectionStringName="ApplicationConnectionString"
I get an error
Expecting non-empty string for 'providerInvariantName' parameter
Add System.Data.SqlClient to attribute ProviderName in your connection string in web.config/app.config:
<add name="ApplicationConnectionString"
providerName="System.Data.SqlClient"
connectionString="server=.\SQLExpress;database=Movie;integrated security=true;"/>

Resources