WSO2 - Script Mediator XML property retrieval using getPayloadXML(); - esb

Hi I'm trying to use Script Mediator to do a SOAP -> JSON transformation
<ns:getTestMethodResponse xmlns:ns="http://main.wsmediator">
<ns:return>getTestMethod is called</ns:return>
</ns:getTestMethodResponse>
This is part of the response I'm receiving from the test service I've created. Question is I am unable to get the element data as mentioned in the WO2 ESB docs.
Which is
mc.getPayloadXML()..::return.toString();
I've even tried
mc.getPayloadXML()..::ns:return.toString();
What am I doing wrong here?
Appreciate the help.

E4X is namespace aware, so to access the element that is in a non-Default namespace you either need to declare the namespace/prefix or use a wildcard *.
Edit: Some debugging in the ESB itself showed me that we cannot use the word "return". This is a reserved word, and is not allowed, not even as part of the query string to retrieve the "return" element from your xml.
Lets assume for a moment that the element was called "value" instead, then the code would compile and work as follows:
var ns = new Namespace('http://main.wsmediator');
var xmlValue = mc.getPayloadXML()..ns::value.toString();
Another option is to use the wildcard:
var return = mc.getPayloadXML()..*::value.toString();
However changing the xml payload to adhere to JavaScript standards is not a very pretty, and possibly not a viable solution. Instead we can to try to acces the element in another way.
<inSequence>
<script language="js">
var ns = new Namespace('http://main.wsmediator');
var value = mc.getPayloadXML().*.toString();
mc.setProperty("Asterisk", value);
</script>
<log>
<property name="Asterisk" expression="get-
property('Asterisk')"/>
</log>
<respond/>
</inSequence>
The getTestMethodResponse element is the root element when you do mc.getPayloadXML(), the asterisk gives you the children of this element. This works, yet is not very pretty because it is based on some assumptions about the message structure.
Another option might be to completely forego using the script mediator and use a PayloadFactory instead. For example:
<payloadFactory media-type="json">
<format>
{"return":"$1"}
</format>
<args>
<arg xmlns:ns="http://main.wsmediator"
evaluator="xml"
expression="//ns:return"/>
</args>
</payloadFactory>
For more on E4X, check here
For more on PayloadFactoryMediator check here

Related

Wildfly json-formatter class name metadata

Is it possible to configure a non-static value for the metadata field in the wildly json-formatter?
I didn't find anything about it in the wildfly documentation- it only has a simple static field example (meta-data=[#version=1])
For example, I would like to have a field "simpleClassName" - The class of the code calling the log method.
I also tried to use a similar syntax to pattern-formatter(example below) but it doesn't work
<formatter name="JSON">
<json-formatter>
<meta-data>
<property name="simpleClassName" value="%c{1}"/>
</meta-data>
</json-formatter>
</formatter>
No the meta-data is only static information. However what you're looking for seems to be the details of the caller. Note that this is an expensive operation should you should use it with caution. What you'd want to do is change the print-details to true. In CLI it would be something like:
/subsystem=logging/json-formatter=JSON:write-attribute(name=print-details, value=true)

Is there a checkstyle rule for forcing every field in a class to have an annotation?

We want to make compliance easy and for FedRAMP want something like this on all fields in our database objects
#FedRamp(confidentiality=LOW, integrity=MODERATE, availability=HIGH)
We want checkstyle to break the builds if people add data and forget to add these on 'any' field in the *Dbo.java class. Then, we can generate the FedRAMP compliance on each data item (and therefore the entire system). We run checkstyle on every class but only want this rule run on classes ending in *Dbo.java. Is this possible where we import some already existing checkstyle rule or plugin and add the class name filter to it?
thanks,
Dean
To report violations for such cases for any classes, you can use MatchXpathCheck (you need checkstyle 8.39+)
Config will look like:
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name = "Checker">
<module name="TreeWalker">
<module name="MatchXpath">
<property name="id" value="fedramp_check"/>
<property name="query" value="//CLASS_DEF/OBJBLOCK/VARIABLE_DEF/MODIFIERS/ANNOTATION/IDENT[not(#text='FedRamp')]"/>
<message key="matchxpath.match"
value="Field should have 'FedRamp' annotation."/>
</module>
</module>
</module>
This will report violations like this:
$ cat Test.java
class Test {
#FedRamp(confidentiality=LOW, integrity=MODERATE, availability=HIGH)
private int withAnnotation = 11; // no violation
#Fed(confidentiality=LOW, integrity=MODERATE, availability=HIGH)
private int without = 11; // violation
#NotNull
int without = 11; // violation
}
$ java -jar checkstyle-8.42-all.jar -c config.xml Test.java
Starting audit...
[ERROR] C:\workdir\Test.java:6:4: Field should have FedRamp annotation. [fedramp_check]
[ERROR] C:\workdir\Test.java:9:4: Field should have FedRamp annotation. [fedramp_check]
Audit done.
Checkstyle ends with 2 errors.
Second part of your question - narrow execution only to specific classes - can be solved in several ways.
Use a bit different xpath to filter class names (not files, since there can be many classes in single file)
<property name="query"
value="//CLASS_DEF[./IDENT[ends-with(#text,
'Dbo')]]/OBJBLOCK/VARIABLE_DEF/MODIFIERS/ANNOTATION/IDENT[not(#text='FedRamp')]"/>
Use BeforeExecutionExclusionFileFilter - it is filter for whole config and will work ok only if you have a separate config only for checking annotation thing.
Suppress violations for this check (by id, for example) for other class files, see doc

Execute a function in the context of another cfc in ColdFusion while honoring import statements

Background
I'm trying to create a function componentFromJson that can reconstitute a component graph from JSON. I took a simple approach where I'm using getMetaData in order to lookup the component properties to instantiate the right types.
The function would be used like: comp = componentFromJson(json, 'RootComponentType')
Problem
The problem is that the type of the properties are not necessarily fully qualified because namespaces may have been imported, as we can see below.
<cfimport path="some.namespace.Test">
<cfcomponent>
<cfproperty name="test" type="Test">
</cfcomponent>
When I'm trying to do createObject('Test') from the componentFromJson function context it's obviously failing because the calling context doesn't have the imports.
I have tried many different ways to resolve the problem, including temporarily defining the component factory function on the parent component dynamically and using invoke to call the factory function in the context of the parent CFC, but it doesn't work.
E.g.
<cfscript>
parentCmp = createObject('SomeCmp');
parentCmp.createComponent = function (type) {
return createObject(type);
};
childCmp = invoke(parentCmp, 'createComponent', { type = 'Test' });
</cfscript>
Horrible solution
The only way I can think of solving this issue right now is to parse the ColdFusion code of the CFC and extract the import statements, but I'm expecting this to be way too slow for the purpose. Not only that but this wouldn't cover all edge cases.
Ideas?
I'd like to know if someone has a better idea for solving this issue? Is there an entirely different approach I could take? There is probably a way to do this using the ColdFusion runtime classes, but I haven't figured it out yet.
Well, it turns out that it wasn't so hard when you knew the underlying mechanics of the ColdFusion runtime (which I had trouble to find initially).
I finally discovered that a ColdFusion component, which is represented as a coldfusion.runtime.TemplateProxy was encapsulating a coldfusion.runtime.CFPage instance which in turns has a createObject method.
Therefore, here's the solution I came up with using Java reflection:
<cfset host = new SomeComponent()>
<cfset pageField = createObject('java', 'coldfusion.runtime.TemplateProxy').getClass().getDeclaredField('page')>
<cfset pageField.setAccessible(true)>
<cfset page = pageField.get(host)>
<cfset test = page.createObject('Test')>

Issue while saving Non-English character

We are working with one application where we need to save data in language Gujarati.
Technologies used in Applcation is listed below.
Spring MVC Version 4.1.6.RELEASE
Hibernate Version 4.3.5.Final
MySQL 6.0.11
My JSP is configured with
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
And
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Hibernate configuration is
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.characterEncoding">UTF-8</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
MySQL URL is
jdbc:mysql://host:port/dbName?useUnicode=true&connectionCollation=utf8_general_ci&characterSetResults=utf8
Pojo having String field to store that data.
MySQL have VARCHAR datatype to store data with charset=utf8 and Collation=utf8_general_ci
When i tried to save any non-english(Gujrati) character it show some garbage character like àª?à«?àª? for "ગુજ".
Is there any other configuration which i missed here.
I was facing the same problem while inserting "tamil" characters into the database.After surfing a lot I got a better and working solution and it solves my problem.Here I am sharing my solution with you.I hope it will help you to clear your doubts regarding that Non English character.
INSERT INTO
STUDENT(name,address)
VALUES
(N'பெயர்', N'முகவரி');
I am using a sample since you have not provided me any structure of your table and field name.
I am assuming you want ગુજ (GA JA with Vowel sign U)?
I think you somehow specified "latin5". (Yes I see you have UTF-8 everywhere, but "latin5" is the only way I can make things work.)
CONVERT(CONVERT(UNHEX('C3A0C2AAC297C3A0C2ABC281C3A0C2AAC29C')
USING utf8) USING latin5) = 'ગુજ'
Plus you ended up with "double encoding"; I suspect this is what happened:
The client had characters encoded as utf8 (good); and
SET NAMES latin5 was used, but it lied by claiming that the client had latin5 encoding; and
The column in the table declared CHARACTER SET utf8 (good).
If possible, it would be better to start over -- empty the tables, be sure to have SET NAMES utf8 or establish utf8 when connecting from your client to the database. Then repopulate the tables.
If you would rather try to recover the existing data, this might work:
UPDATE ... SET col = CONVERT(BINARY(CONVERT(
CONVERT(UNHEX(col) USING utf8)
USING latin5)) USING utf8);
But you would need to do that for each messed up column in each table.
A partial test of that code is to do
SELECT CONVERT(BINARY(CONVERT(
CONVERT(UNHEX(col) USING utf8)
USING latin5)) USING utf8)
FROM table;
I say "partial test" because looking right may not prove that is right.
After the UPDATE, SELECT HEX(col) get E0AA97E0AB81E0AA9C for ગુજ. Note that most Gujarati hex should be of the form E0AAyy or E0AByy. You might also find 20 for a blank space.
I apologize for not being more certain. I have been tackling Character Set issues for a decade, but this is a new variant.
There might be a couple of things that you could have missed out. I had the same problem with mysql on linux, what I had to do is to edit my.cnf like this:
[client]
default-character-set = utf8
[mysqld]
character-set-server = utf8
For e.g. on Centos this file is location at /etc/my.cnf on Windows (my pc) C:\ProgramData\MySQL\MySQL Server 5.5\my.ini. Please note that ProgramData might be hidden.
Also the other thing if you are using Tomcat is that you have to sepcify UTF-8 for URI encoding. Just edit server.xml and modify your main Connector element:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
Also make sure you added character encoding filter in your application:
#WebFilter(filterName = "CharacterEncodingFilter", urlPatterns = {"/*"})
public class CharacterEncodingFilter implements Filter {
#Override
public void init(FilterConfig filterConfig)
throws ServletException {
}
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
request.setCharacterEncoding("UTF-8");
servletResponse.setContentType("text/html; charset=UTF-8");
filterChain.doFilter(request, servletResponse);
}
#Override
public void destroy() {
}
}
Hope this helps.
Another tip, don't lean only on setting the characterEncoding as a hibernate property <prop key="hibernate.connection.characterEncoding">UTF-8</prop>, make sure you add it explicitely as connection variable on the DB url, so
jdbc:mysql://host:port/dbName?useUnicode=true&characterEncoding=UTF-8&connectionCollation=utf8_general_ci&characterSetResults=utf8
Also, as there is some many layers where an encoding would be lost, you can try to isolate the layer and update to a question. E.g. if its upon storing to DB, or at some point before
Your applicationContext file should be like this:
To make Spring MVC application supports the internationalization, register two beans :
SessionLocaleResolver
Register a “SessionLocaleResolver” bean, named it exactly the same characters “localeResolver“. It resolves the locales by getting the predefined attribute from user’s session.
Note
If you do not register any “localeResolver”, the default AcceptHeaderLocaleResolver will be used, which resolves the locale by checking the accept-language header in the HTTP request.
LocaleChangeInterceptor
Register a “LocaleChangeInterceptor” interceptor and reference it to any handler mapping that need to supports the multiple languages. The “paramName” is the parameter value that’s used to set the locale.
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
<bean id="localeChangeInterceptor"
class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="language" />
</bean>
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" >
<property name="interceptors">
<list>
<ref bean="localeChangeInterceptor" />
</list>
</property>
</bean>
<!-- Register the bean -->
<bean class="com.common.controller.WelcomeController" />
<!-- Register the welcome.properties -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="welcome" />
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
The native2ascii is a handy tool build-in in the JDK, which is used to convert a file with ‘non-Latin 1′ or ‘non-Unicode’ characters to ‘Unicode-encoded’ characters.
Native2ascii example
Create a file (source.txt)
Create a file named “source.txt”, put some Chinese characters inside, and save it as “UTF-8″ format.
native2ascii
Use native2ascii command to convert it into Unicode format.
C:>native2ascii -encoding utf8 c:\source.txt c:\output.txt
The native2ascii will read all the characters from “c:\source.txt” and encode it with “utf8″ format, and output all encoded characters to “c:\output.txt”
Read Output
Open the “c:\output.txt”, you will see the all encoded characters, e.g \ufeff\u6768\u6728\u91d1
welcome.properties
welcome.springmvc = \u5feb\u4e50\u5b66\u4e60
Call the above string and store the value in database.
And if you want to display that inside JSP page:
Remember add the line
“<%# page contentType=”text/html;charset=UTF-8″ %>”
on top of the jsp page, else the page may not able to display the UTF-8
(Chinese) characters properly.

Number of lines read with Spring Batch ItemReader

I am using SpringBatch to write a csv-file to the database. This works just fine.
I am using a FlatFileItemReader and a custom ItemWriter. I am using no processor.
The import takes quite some time and on the UI you don't see any progress. I implemented a progress bar and got some global properties where i can store some information (like lines to read or current import index).
My question is: How can i get the number of lines from the csv?
Here's my xml:
<batch:job id="importPersonsJob" job-repository="jobRepository">
<batch:step id="importPersonStep">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="personItemReader"
writer="personItemWriter"
commit-interval="5"
skip-limit="10">
<batch:skippable-exception-classes>
<batch:include class="java.lang.Throwable"/>
</batch:skippable-exception-classes>
</batch:chunk>
<batch:listeners>
<batch:listener ref="skipListener"/>
<batch:listener ref="chunkListener"/>
</batch:listeners>
</batch:tasklet>
</batch:step>
<batch:listeners>
<batch:listener ref="authenticationJobListener"/>
<batch:listener ref="afterJobListener"/>
</batch:listeners>
</batch:job>
I already tried to use the ItemReadListener Interface, but this isn't possible as well.
if you need to know how many lines where read, it's available in spring batch itself,
take a look at the StepExecution
The method getReadCount() should give you the number you are looking for.
You need to add a step execution listener to your step in your xml configuration. To do that (copy/pasted from spring documentation):
<step id="step1">
<tasklet>
<chunk reader="reader" writer="writer" commit-interval="10"/>
<listeners>
<listener ref="chunkListener"/>
</listeners>
</tasklet>
</step>
where "chunkListner" is a bean of yours annotated with a method annotated with #AfterStep to tell spring batch to call it after your step.
you should take a look at the spring reference for step configuration
Hope that helps,