How to set property in jms selector in Groovy - groovy

I want get message in queue (in) and I want correlate messages.
I must to put value from property in jms selector in Groovy but this not works.
The message is not picked up from the queue.
<script:transformer name="some">
<script:script engine="groovy">
<property key="id" value="123" />
<script:text>
String url = "jms://queue.in?selector=someId%3Did";
return muleContext.client.request(url, 0);
</script:text>
</script:script>
</script:transformer>
Some intresting is that works this:
jms://queue.in?selector=MULE_CORRELATION_ID%3Did
but I don't want above.
I want use another property name.
Not works this:
jms://queue.in?selector=someId%3Did
and this:
jms://queue.in?selector=someId%3D+id
and this:
jms://queue.in?selector=someId%3D+"id"
and this:
jms://queue.in?selector=someId%3Did
but works this (some interesting):
jms://queue.in?selector=someId%3D'123456'
but i don't want above.
What am i doing wrong ?

Hurra! I did it :)
It works this:
jms://queue.in?selector=someId%3Did+'$id'

Related

ReplyRequiredException on attempt to get data from <int-jdbc:outbound-gateway>?

I would like to define an
<int-jdbc:outbound-gateway/> with query and without update to retrieve data from database. Then I would like to use the int-jdbc:outbound-gateway as an implementation of Service.findSomeData() interface method. The data retrieved from interface implementation is used in my custom transformer's CheckService class. See the configuration below:
<int:service-activator method=“performCheck”>
<bean class=“com.example.service.CheckService”
c:service-ref=“service”
</int:service-activator>
<int:gateway id=“service” service-interface=“com.example.service.Service”>
<int:method name=“findSomeData” request-channel=“jdbcChan” reply-channel=“jdbcChanReply”/>
</int:gateway>
<int-jdbc:outbound-gateway request-channel=“jdbcChan”
data-source=“pooledDs” row-mapper=“dataRowMapper” reply-channel=“jdbcChanReply”>
<int-jdbc:query>
select some, data from some_table
</int-jdbc:query>
The problem is that I get ReplyRequiredException exception when I move my payload to jdbcChan:
org.springframework.integration.handler.ReplyRequiredException: No reply produced by handler 'org.springframework.integration.jdbc.JdbcOutboundGateway#0', and its 'requiresReply' property is set to true.
I decided to pay more attention on example located in spring in spring-integration-samples repository on GitHub, but looks like it also does not work as expected. I get exactly the same exception in example project trying to find User by name foo. You can easily reproduce the exception with basic jdbc example located on GitHub and the following test method:
#Test
public void findPerson() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"/META-INF/spring/integration/spring-integration-context.xml");
PersonService service = context.getBean(PersonService.class);
final List<Person> foo = service.findPersonByName("foo");
assertThat(foo, is(not(empty())));
}
Am I doing it wrong or there is a bug in latest Spring Integration JDBC? (for me looks like even example is broken)
I fixed the sample.
We changed the default for requires-reply to true a long time ago but the sample was never updated.
assertThat(foo, is(not(empty())));
However, the List<Person> is null when no results are received.
EDIT
But I would expect empty list instead of a null if ResultSet was empty.
That's not how it works.
If the resultSet is empty, null is returned (hence the original error you were seeing).
If the resultSet has 1 entry, just that entry is returned.
Otherwise a list of entities is returned.
Object payload = list;
if (list.isEmpty()) {
return null;
}
if (list.size() == 1) {
payload = list.get(0);
}
return payload;
It's been like that forever but I believe the single Object Vs. List is wrong (if maxRows > 1).
maxRows is 1 by default so it made sense then; however, if maxRows is > 1 and only 1 row is returned I think it should still be a list of 1. The application shouldn't have to check the type of the result. It either expects a list or a single object (or null). INT-4559.

access response in SOAP UI in Groovy Script

I am new to Groovy Scripting. I am trying to access the value of a Response node
below is the script
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context);
def responseHolder = groovyUtils.getXmlHolder( testRunner.testCase.testSteps["request"].testRequest.response.responseContent );
responseHolder.namespaces["ns0"]="http://xmlns.int.com/orders/xsd/v1"
String mySection = responseHolder.getNodeValue["//ns0:MT_OrderCreateDTCFulfillmentResponse/ns0:StatusCode"] ;
log.info mySection
mySection is printed as []
Response XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header xmlns:v1="http://xmlns.int.com/orders/xsd/v1"/>
<soapenv:Body xmlns:v1="http://xmlns.int.com/orders/xsd/v1">
<ns0:MT_OrderCreateDTCFulfillmentResponse xmlns:ns0="http://xmlns.int.com/orders/xsd/v1">
<StatusCode>000</StatusCode>
<ReferenceDocNbr>NA</ReferenceDocNbr>
<SchemaValidationStatus>Validated</SchemaValidationStatus>
<StatusTimestamp>2015-08-03T18:58:01.602</StatusTimestamp>
<FaultDetails>Request for customer order number NA received successfully and format validated.</FaultDetails>
</ns0:MT_OrderCreateDTCFulfillmentResponse>
</soapenv:Body>
</soapenv:Envelope>
SOAP UI Project Structure - I am running Test_Script. Suggest me what i am missing
You've to use:
responseHolder.getNodeValue("//ns0:MT_OrderCreateDTCFulfillmentResponse/StatusCode");
instead of responseHolder.getNodeValue["//ns0:MT_OrderCreateDTCFulfillmentResponse/ns0:StatusCode"];
Note that I change responseHolder.getNodeValue invocation to use () instead of [], and also change your xpath since in your response <StatusCode> it's not defined in xmlns:ns0="http://xmlns.int.com/orders/xsd/v1".
Another option is to use the * wildcard as a namespace to map anyone. So in this case you can use:
responseHolder.getNodeValue("//*:MT_OrderCreateDTCFulfillmentResponse/*:StatusCode");
Additionally, note that probably you XML is wrong, since I suppose that all sub elements of <MT_OrderCreateDTCFulfillmentResponse> must belongs to "http://xmlns.int.com/orders/xsd/v1" namespace... so you've to declare it as:
<ns0:MT_OrderCreateDTCFulfillmentResponse xmlns:ns0="http://xmlns.int.com/orders/xsd/v1">
<ns0:StatusCode>000</ns0:StatusCode>
<ns0:ReferenceDocNbr>NA</ns0:ReferenceDocNbr>
<ns0:SchemaValidationStatus>Validated</ns0:SchemaValidationStatus>
<ns0:StatusTimestamp>2015-08-03T18:58:01.602</ns0:StatusTimestamp>
<ns0:FaultDetails>Request for customer order number NA received successfully and format validated.</ns0:FaultDetails>
</ns0:MT_OrderCreateDTCFulfillmentResponse>
Or using as default for this tag:
<MT_OrderCreateDTCFulfillmentResponse xmlns="http://xmlns.int.com/orders/xsd/v1">
<StatusCode>000</StatusCode>
<ReferenceDocNbr>NA</ReferenceDocNbr>
<SchemaValidationStatus>Validated</SchemaValidationStatus>
<StatusTimestamp>2015-08-03T18:58:01.602</StatusTimestamp>
<FaultDetails>Request for customer order number NA received successfully and format validated.</FaultDetails>
</MT_OrderCreateDTCFulfillmentResponse>
Note that if you change you XML with my indication your first XPath it's correct since now StatusCode belongs to your namespace.
Hope it helps,

Change dynamical directory on file:inbound-channel-adapter

I'm new with Spring and I'm using Citrus Framework.
I'll try to change, dynamically, the inbound-channel-adapter destination variable. This variable is located in properties file and change all the time.
Currently I'm using an AtomicReference and I change its value in java code
In context.xml :
<bean id="targetDir" class="java.util.concurrent.atomic.AtomicReference">
<constructor-arg value="${output.path.temp}"/>
</bean>
<file:inbound-channel-adapter id="fileInboundAdapter" auto-create-directory="false"
channel="fileChannel" directory="file:#targetDir.get()" auto-startup="false"
filename-pattern="*.xml">
<si:poller cron="0 * * * * ?"/>
</file:inbound-channel-adapter>
And in java file :
SourcePollingChannelAdapter fileInboundAdapter = (SourcePollingChannelAdapter)context.getApplicationContext().getBean("fileInboundAdapter");
if (fileInboundAdapter.isRunning()) {
fileInboundAdapter.stop();
#SuppressWarnings("unchecked")
AtomicReference<String> targetDir = (AtomicReference<String>)
context.getApplicationContext().getBean("targetDir", AtomicReference.class);
targetDir.set(strOutPath[0]+"/"+strOutPath[1]+"/"+strOutPath[2]+"/"+strOutPath[3]+"/");
fileInboundAdapter.start();
}
This solution don't works ... someone have any solutions ?
Thanks a lot.
That's true. Because your AtomicReference doesn't have affect to the target directory.
You do this directory="file:#targetDir.get()". It isn't correct at all, because this String will try to be converted to the File object. If you want to use here a SpEL it should be like this:
directory="#{targetDir.get()}"
without any file: prefix.
Anyway it doesn't help because that SpEL is evaluated only once at applicationContext strtup.
Since you are going to change the directory at runtime you should use FileReadingMessageSource.setDirectory from your service. Something like this:
SourcePollingChannelAdapter fileInboundAdapter = (SourcePollingChannelAdapter)context.getApplicationContext().getBean("fileInboundAdapter");
if (fileInboundAdapter.isRunning())
fileInboundAdapter.stop();
FileReadingMessageSource source = (FileReadingMessageSource) context.getApplicationContext().getBean("fileInboundAdapter.source");
source.setDirectory(new File(strOutPath[0]+"/"+strOutPath[1]+"/"+strOutPath[2]+"/"+strOutPath[3]+"/"));
fileInboundAdapter.start();
}
And get rid of that AtomicReference.
From the start you can use property-placeholder for the directory attribute directly.

Xquery - to get the count of an element

I am new to Xquery. My requirement is very simple, but I couldn’t - due to my lack of knowledge.
I am trying to query a sharepoint site. The sharepoint site’s sample data in xml format is:
<z:row ows_owshiddenversion="4"
ows_Regional_x0020_Regulatory_x0020_="Kyle Godfrey"
ows_Status="No Activity"/>
<z:row ows_owshiddenversion="4"
ows_Regional_x0020_Regulatory_x0020_="Grace Flux"
ows_Status="Strong Interest"/>
<z:row ows_owshiddenversion="4"
ows_Regional_x0020_Regulatory_x0020_="Foo Bar"
ows_Status="Active State"/>
<z:row ows_owshiddenversion="4"
ows_Regional_x0020_Regulatory_x0020_="Batz Quix"
ows_Status="Active State"/>
The requirement is to get the ows_Status and its count. For example:
Strong Interest 1
No Activity 1
Active State 2
As a beginner, I tried a simple query - that is, hardcoded the status name in the where clause of the let statement, but it seems that the where clause didn’t have any effect on the query.
let $Statusvariable := $queryresponse//#ows_Status
where ($queryresponse//#ows_Status="Active State")
return
<Status>{fn:data($Statusvariable)}</Status>
I expected the above code to return only “Active State” status. But it returned all the statuses.
Can you point out my mistake in the above query and provide me the right query to get both statuses and its counts.
OK, let's take this one step at a time. First, what's going wrong. Paraphrased in English, your query means "Let the variable $Statusvariable have as its value the set of ows_Status attributes in the query response, but only in the case that there is at least one ows_Status attribute with the value "Active State". Then return the typed value of $Statusvariable." You may have meant to write something more like
for $x in $queryresponse//#ows_Status
where $x = "Active State"
return <Status>{$x}</Status>
If you want to know how many occurrences there are of each value of the ows_Status attribute, in descending frequency order, I'd write something like this (not tested):
for $value in distinct-values($queryresponse//#ows_Status)
let $n := count($queryresponse//#ows_Status[. = $value])
order by $n descending
return <Status count="{$n}">{$value}</Status>
The probleme here is, that the $queryresponse in each case has such an element, so the condition is always true. You should instead compare it to each individual row record, not the whole response data.
You should also use for if you want to iterate over a set of results.
for $row in $queryresponse//*:row
let $Statusvariable := $row/#ows_Status
where $row/#ows_Status="Active State"
return
<Status>{fn:data($Statusvariable)}</Status>
The query you're using could be shortened to
$queryresponse//#ows_Status[.="Active State"]/element { 'Status' } { data(.) }
For the problem you're really trying to solve (grouping and counting), use C. M. Sperberg-McQueen's answer which is totally fine. XQuery 3.0 would support group by which would be more declarative, but sharepoint doesn't know that.

How to get a child node value based on another child in the same group

I'm developing in C#, and am processing xml from an external soap call.
I have loaded the xml response into an XElement.
Given the following xml stub
<record>
<node>
<a>My title</a>
<name>title_en</name>
</node>
<node>
<a>...</a>
<name>contact_name</name>
</node>
.....
</record>
Using xpath in C#: I'm trying to do the follow when using the method XPathSelectElement.
where
\record\node\name == 'title_en' select \record\node\a
If there is a better method to use or another suggestion on how to preform the query, I'm open to ideas.
Thanks in advance.
You need a predicate to constrain which node elements you need:
/record/node[name = 'title_en']/a
You read this expression as "find the record element, find all its child elements named node that have a name child with value "title_en", and for each of those find all a children"
Use this:
var title = doc.Descendants("node")
.Where(x => (string)x.Element("name") == "title_en")
.Select(x => (string)x.Element("a"))
.FirstOrDefault();

Resources