How to change the header element - spring

I have the following code snippet:
<int-file:inbound-channel-adapter id="filteredFiles"
directory="#{controllerConfig['CYCLE'].params['SEMAPHORE_DIR']}"
channel="semaphoreChannel" filename-pattern="*.xml" prevent-duplicates="false">
<int:poller max-messages-per-poll="1" cron ="#{controllerConfig['CYCLE'].controllerTimer}"/>
</int-file:inbound-channel-adapter>
...
Later in the flow in have a header enricher:
<int:header-enricher id="Channel Name Setter">
<int:header name="channel.id" value="CYCLE"/>
<int:header name="flow.id" overwrite="true" value="#{T(hu.telekom.fdl.util.TimeBasedUUIDGenerator).generateId()}"/>
</int:header-enricher>
The problem is that although I used the overwrite="true" property the flow.id seems unchanged when the inbound-channel-adapter reads the second file.
Thanks,

Expressions with the form #{...} are evaluated once only, during context initialization. You need to use a runtime expression:
<int:header name="flow.id" overwrite="true" expresion="T(hu.telekom.fdl.util.TimeBasedUUIDGenerator).generateId()"/>
i.e. use expression= and remove the #{}.
You only need overwrite="true" if the header is already present on the inbound message to the enricher.

Related

Empty Default String for Property in logback.xml

Our project structure regarding the logback.xmls looks like this:
src\main\resources\logback.xml
src\main\resources\config\dev\logback.xml
src\main\resources\config\sjngm\dev\logback.xml
src\main\resources\config\int\logback.xml
src\main\resources\config\local\logback.xml
src\main\resources\config\prod\logback.xml
where the first one references to the environment specific one:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<contextName>sjngm</contextName>
<jmxConfigurator />
<include resource="config/${extra}${env:-local}/logback.xml" />
</configuration>
Note that extra is not defined most of the times, which is why used this for a while:
<include resource="config/${extra:-}${env:-local}/logback.xml" />
This stopped working at one point, can't remember which version of logback. So we changed it to
<include resource="config/${extra:-./}${env:-local}/logback.xml" />
which also worked for quite a while.
Now we switched to Spring Boot 1.5.4 (contains logback-classic 1.1.11 and logback-core 1.1.11) and it stopped working again. The latest error message is:
11:08:15,020 |-WARN in ch.qos.logback.core.joran.action.IncludeAction - Could not find resource corresponding to [config/./local/logback.xml]
If I go back to
<include resource="config/${extra:-}${env:-local}/logback.xml" />
the message is
11:19:28,778 |-WARN in ch.qos.logback.core.joran.action.IncludeAction - Could not find resource corresponding to [config/extra_IS_UNDEFINEDlocal/logback.xml]
Note that logback still uses "local" as a default string for env, so not all is broken.
What do I do now? Basically I want to tell logback that I want an empty string where extra would be.
This also doesn't work:
<property name="defaultExtra" value="" />
<include resource="config/${extra:-${defaultExtra}}${env:-local}/logback.xml" />
as an empty string seems to always result in an undefined property.
The only working thing I can come up with is this:
<if condition='isDefined("extra")'>
<then>
<include resource="config/${extra}${env:-local}/logback.xml" />
</then>
<else>
<include resource="config/${env:-local}/logback.xml" />
</else>
</if>
plus this into the pom.xml:
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
</dependency>
Isn't this nice?! So why did they have to break what was working nicely???
This worked for me:
<property name="extra" value="${logback.myApp.extra:- }" />
Logback seems to trim Whitespace out of the value. So the default value of Space did the trick.
Embedded Whitespace is preserved, which may lead to a FileNotFoundException if Tabs were embedded, but embedded Spaces were ok.
Setting a Property in a Java Initialiser had the desired effect:
System.setProperty("logback.myApp.extra", "\t \tEXTRA_EXTRA_EXTRA\t \t");
The Tabs & Spaces were removed from the Property, which was assigned the value EXTRA_EXTRA_EXTRA
(the Java Initialiser must be invoked before any Logging has taken place & may contain no Logging itself)
You could of course set the Property on the Java Command line.
P.S. if the Property is undefined & you omit the Space (${logback.myApp.extra:-}), it is assigned the value:
logback.myApp.extra_IS_UNDEFINED
...so it may be wise to add a suitable comment:
<property name="extra" value="${logback.myApp.extra:- }" /><!-- N.B. Empty Default value must contain # least 1 Space!! -->

How does Spring #Async choose a task executor/scheduler if multiple ones are defined?

I have the following defined in XML configuration:
<task:scheduler id="myScheduler" pool-size="10" />
<bean id="asyncExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
<bean id="asyncExecutor2" class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
When using the #Async annotation in Spring, how does it know which of these executors/schedulers to use? I would expect it to throw an error on startup since there are multiple here and I have not included a <task:annotation-driven executor="xxx"/> tag, but it appears to be working fine. Is there a way I can log somewhere which one is being used?
...
<task:annotation-driven executor="asyncExecutor" />
<task:executor id="asyncExecutor" pool-size="10" />
...
You might look at the thread name in the stacktrace when debugging, it should start with something like: [asyncExecutor-xx]

How to integrate legacy executables into Spring Integration application?

I have some legacy programs in C that work based on the input file and the result go to the output file. Both files are specified in the program arguments. So the call looks like the following:
prj.exe a.dat a.out
Based on Artem Bilan suggestion I created the project with the following Spring Configuration file. It works in terms of invoking executable! However, I still have the problem with the outbound channel. First, it contains nothing and I am getting the error "unsupported Message payload type". Second, what is more important, I need to process the output file a.out by a Java program. What is the best way to organize this workflow? Is it possible to substitute the useless in this case inbound-channel-adapter to something useful?
<int-file:inbound-channel-adapter id="producer-file-adapter"
channel="inboundChannel" directory="file:/Users/anarinsky/springint/chem"
prevent-duplicates="true">
<int:poller fixed-rate="5000" />
</int-file:inbound-channel-adapter>
<int:channel id="inboundChannel" />
<int:channel id="outboundChannel" />
<int:service-activator input-channel="inboundChannel" output-channel="outboundChannel"
expression="new ProcessBuilder('/Users/anarinsky/springint/chem/prj', '/Users/anarinsky/springint/chem/a.dat', '/Users/anarinsky/springint/chem/a.out').start()">
</int:service-activator>
<int-file:outbound-channel-adapter
channel="outboundChannel" id="consumer-file-adapter"
directory="file:/Users/anarinsky/springint/chem"/>
Something like this:
<int:service-activator expression="new ProcessBuilder('prj.exe', 'a.dat', 'a.out').start()"/>
?

Commenting Out in XML

Is the first set of comment out code below an issue for xml to process since it is put inside of the tag?
<!--Define name="default election policy">
<Policy name="DefaultToWaive"/>
</Define-->
<!--
<Define name="default election policy">
<Policy name="DefaultToWaive"/>
</Define>
-->
No, it's not an issue. It's just interpreted as a comment starting with "Define name=...". It also doesn't matter if you put it on the same line or on separate lines. You could as well write:
<!--<Define name="default election policy">
<Policy name="DefaultToWaive"/>
</Define>-->

Using setProperty variables as input to XSL

I am currently using setHeader variables in an Apache Camel route as input params to an XSL file. This does not work with setProperty variables, however. Is that not supported in Camel?
Thanks!
UPDATE--
Here's my route...
<camel:route>
<camel:from uri="file:/usr/local/jms_support/update"/>
<camel:convertBodyTo type="String" />
<camel:multicast>
<camel:pipeline>
<camel:bean ref="getPidsForUpdate"/>
<camel:setProperty propertyName="work_or_image"><camel:constant>image</camel:constant></camel:setProperty>
<camel:setProperty propertyName="pid"><camel:constant>1234</camel:constant></camel:setProperty>
<camel:setProperty propertyName="work_pid"><camel:constant>1234</camel:constant></camel:setProperty>
<camel:setProperty propertyName="bibid"><camel:constant>1234</camel:constant></camel:setProperty>
</camel:pipeline>
<camel:pipeline>
<camel:to uri="xslt:xsl/test.xsl"/>
<camel:to uri="file:/usr/local/jms_support/update_test"/>
</camel:pipeline>
</camel:multicast>
</camel:route>
What Camel version do you use?
The Xstl components sets the headers and properties as parameters. You can enable TRACE logging on org.apache.camel.builder.xml, and see which parameters is being added.
See the source code for XsltBuilder and the configureTransformer method in the bottom: https://svn.apache.org/repos/asf/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/xml/XsltBuilder.java
I ended up storing the content of the message in a variable and setting the message back to that content after it was changed, like so...
<!-- store original content in header variable -->
<camel:setHeader headerName="marc"><camel:simple>${body}</camel:simple></camel:setHeader>
<!-- run some logic, output gets saved as another header variable, message as this point is now that output -->
<camel:bean ref="getPidsForUpdate"/>
<camel:setHeader headerName="pids"><camel:simple>${body}</camel:simple></camel:setHeader>
....set a bunch of variables based on that output, and then
<!-- get original message to run some more logic-->
<camel:setBody><camel:simple>${headers.marc}</camel:simple></camel:setBody>

Resources