Why do I get Referenced bean nullChannel not found? - java

I usually get a warning about nullChannel not being defined in STS Problems view:
Referenced bean 'nullChannel' not found
But then if I add a declaration in context file, like <int:channel id="nullChannel" /> or <int:publish-subscribe-channel id="nullChannel">, I get an:
java.lang.IllegalStateException: The bean name 'nullChannel' is reserved.
I guess that's a warning I can safely ignore, but I usually try to zero out warnings, so is there something I'm missing?
UPDATE
These are the portions involved with the warning, removing them made it disappear:
<int:header-value-router input-channel="listOfMaps" header-name="transaction_type" resolution-required="false" default-output-channel="nullChannel">
<int:mapping value="52" channel="requests52ListOfMaps"/>
</int:header-value-router>
<int:service-activator input-channel="httpRequestsSendsChannel" output-channel="nullChannel" ref="conversionController" method="enable52Delivery" />
<int:service-activator input-channel="httpRequestsDeletesChannel" output-channel="nullChannel" ref="inspector" method="inspect" />

I am not sure why it was ok for me last week (probably pilot error) but I get it now with
<int:service-activator input-channel="errorChannel" output-channel="nullChannel" expression="foo" />
and, if I flip the in/out channels, the warning changes to errorChannel - the reason we don't get a warning for the input channel is because STS presumably knows that we will create input channels on the fly if needed.
I guess STS just doesn't know about these implicit beans.
I'll ask the STS guys if we can come up with a way to give them a list of implicit beans to suppress these warnings.
If that's not possible, we could consider relaxing the rule preventing the adding of a custom nullChannel bean.

Related

Issue with DataHub in spring-integration

I am getting the below error when I try to post IDOC.
Dispatcher has no subscribers for channel
'DataHubWebApplicationContext.DEBMAS-DEBI'.; nested exception is
org.springframework.integration.MessageDispatchingException:
Dispatcher has no subscribers.
Xml mapping looks like this:
<int-xml:xpath-router id="splitKTOKD" input-channel="DEBMAS" evaluate-as-string="true" resolution-required="false"default-output-channel="DEBMAS-NOTSUPPORTED-KTOKD">
<int-xml:xpath-expression id="splitKTOKDExpression" expression="//KTOKD" />
<int-xml:mapping value="DEBI" channel="DEBMAS-DEBI" />
<int-xml:mapping value="0170" channel="DEBMAS-0170" />
<int-xml:mapping value="Z001" channel="DEBMAS-Z001" />
</int-xml:xpath-router>
<int:service-activator id="sapcustomerDEBMASCustomerServiceActivator" input-channel="DEBMAS-DEBI" output-channel="rawFragmentDataInputChannel" ref="sapcustomerDEBMASCustomerMappingService" method="map" />
<int:service-activator id="sapcustomerDEBMASCustomerServiceActivator" input-channel="DEBMAS-Z001" output-channel="rawFragmentDataInputChannel" ref="sapcustomerDEBMASCustomerMappingService" method="map" />
Though I have configured proper input-channel and output-channel I am getting the message delivery Exception only for channel DEBMAS-DEBI. DEBMAS-Z001, DEBMAS-0170 works fine.
Looks like this is something related to spring framework issue.
How can I resolve this spring issue?
You have two beans declared with the same sapcustomerDEBMASCustomerServiceActivator Id. By default the second wins. There is no the first bean in the application context. That's why you are observing that issue.
Use different ids or even without it to fix the problem.

How to scan multiple directory locations for files with only one input-channel-adapter in Spring?

I have a assignment where I am reading two different folders for the files using spring-integration inbound-channel-adapter.
My bean is defined as below:
<file:inbound-channel-adapter id="channel1"
directory="file:${java.io.tmpdir}/input1">
<integration:poller id="poller" fixed-delay="60000">
</integration:poller>
</file:inbound-channel-adapter>
<file:inbound-channel-adapter id="channel2"
directory="file:${java.io.tmpdir}/input2">
<integration:poller id="poller2" fixed-delay="60000">
</integration:poller>
</file:inbound-channel-adapter>
<integration:service-activator
input-channel="channel1" ref="handler" />
<integration:service-activator
input-channel="channel2" ref="handler" />
<bean id="handler" class="c.d.Handler" />
I want to read the files from both the location and to whichever location it comes I want to process it with same handler class. I cannot write two main classes to read different inbound-channel-adapters. I have tried adding scanner to the same but it didn't workout. I had tried above but it is giving error expected single matching bean but found 2:. Any help upon this would be much appreciated.
Simply declare one service activator with input-channel="in", then your two adapters...
<file:inbound-channel-adapter id="one" channel="channel" ...
<file:inbound-channel-adapter id="two" channel="channel" ...
i.e. route the output from both adapters to the same bean.

How to open/close Spring Integration channel based on environmental variable?

I have a channel that is used as input-channel in a chain. I need to use it only when the environmental variable sd is not true. Is it possible to write this condition into the spring-integration file without creating an additional Java filter? So, I would like this chain not to work when -Dsd=true in the startup script and work in any other case.
<int:channel id="sdCreationChannel">
<int:queue/>
</int:channel>
<int:chain input-channel="sdCreationChannel" output-channel="debugLogger">
<int:poller fixed-delay="500" />
<int:filter ref="sdIntegrationExistingRequestSentFilter" method="filter"/>
<int:transformer ref="sdCreationTransformer" method="transformOrder"/>
<int:service-activator ref="sdCreationServiceImpl" method="processMessage">
<int:request-handler-advice-chain>
<ref bean="retryAdvice"/>
</int:request-handler-advice-chain>
</int:service-activator>
</int:chain>
The <chain> is a normal endpoint which can be started/stopped according it lifecycle contract.
So, you can start/stop it by its id at runtime at any time or with any condition.
Another trick that it is just enough to add auto-startup="false" to its definition based on that variable.
M-m-m. I think that should work even with normal property-placeholder:
<int:chain auto-startup="${myChain.autoStartup}">
From other side you can take a look to the profile feature and configure it like this:
<beans profile="myChain.profile">
<int:chain>
....
</int:chain>
</beans>
UPDATE
According to your concern:
So, I would like this chain not to work when -Dsd=true in the startup script and work in any other case
As I said above: you can just only mark it in auto-startup="false" from the beginning, for example using the same Environment:
<int:chain auto-startup="#{environment.getProperty('sd', true)}">

dynamically determining polling frequency in mule

I have been struggling to find a work around to be able to dynamically read the polling frequency in mule flow. Currently I am reading that from a file using spring's Propertyplaceholder at the start up and value remains the same even if the fie is changed(as we all know)..
Since poll tag needs to be the first component in the flow, There is nothing much i could do to read the "live" file update.
Is there any way I could set the polling frequency dynamically read from a file(without requiring restart)?
For Reference:
<spring:beans>
<context:property-placeholder location="file:///C:/Users/test/config.properties" />
</spring:beans>
<flow name="querying-database-pollingFlow1" doc:name="querying-database-pollingFlow1">
<poll doc:name="Poll3e3">
<fixed-frequency-scheduler frequency="${pollinginterval}"/>
<db:select config-ref="MySQL_Configuration1" doc:name="Perform a query in MySQL">
<db:dynamic-query><![CDATA[select empId,empName from employer where status='active';]]></db:dynamic-query>
</db:select>
</poll>
....</flow>
There is absolutely no issue with <fixed-frequency-scheduler frequency="${pollinginterval}"/> as you can dynamically read polling frequency from a properties file ...
The only thing I am concern here is :- <context:property-placeholder location="file:///C:/Users/test/config.properties" />
Since you are reading from a properties file outside your classpath, better try with the following :-
<context:property-placeholder
location="file:C:/Users/test/config.properties" />
One more thing .. if you are using Spring beans for properties file use the following way :-
<spring:beans>
<spring:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="locations">
<spring:list>
<spring:value>file:C:/Users/test/config.properties</spring:value>
</spring:list>
</spring:property>
</spring:bean>
</spring:beans>
The clean way using FixedFrequencyScheduler is not there. You could potentially go to the registry, fetch your flow by name, then get the MessageSource and cast it to FixedFrequencyScheduler set the new interval and stop-start, however if you take a look to the code you'll see there is no setter for it and reflexion it's just too dirty.
My first choice would probably be to leverage a quartz endpoint and then leverage the quartz abilities to expose the configuration throught jmx/rmi.
I would definitely advise against using hot deploy to solve this problem especially if you need to change the frequency often. There is a risk that this will lead to problems with permgen running out of memory.
Instead you could use a flow with a quartz endpoint that fires at a relatively low frequency. Then add a filter that only lets through the message at the required frequency.
The filter can either watch a properties file for changes or expose attributes over JMX to allow you to change the frequency. Something like this.
<spring:beans>
<spring:bean id="frequencyFilter" class="FrequencyFilter" />
</spring:beans>
<flow name="trigger-polling-every-second" doc:name="trigger-polling-every-second">
<quartz:inbound-endpoint repeatInterval="1000" doc:name="Quartz" responseTimeout="10000" jobName="poll-trigger">
<quartz:event-generator-job>
<quartz:payload>Scheduled Trigger</quartz:payload>
</quartz:event-generator-job>
</quartz:inbound-endpoint>
<filter ref="frequencyFilter" />
<vm:outbound-endpoint path="query-database" />
</flow>
<flow name="query-database">
<vm:inbound-endpoint path="query-database" />
<db:select config-ref="databaseConfig" doc:name="Perform a query in database">
<db:dynamic-query><![CDATA[select empId,empName from employer where status='active']]></db:dynamic-query>
</db:select>
<logger level="ERROR" message="#[payload]"/>
</flow>

How to turn off VelocityViewResolver errors in Spring?

I'm using Velocity and Spring. Within Spring, I'm using the VelocityViewResolver paired with the ContentNegotiatingViewResolver. For the most part, this works great. The only problem is that the ContentNegotiatingViewResolver queries the VelocityViewResolver with many different content sets (as it should).
When the Velocity engine doesn't find the particular template, an error is produced similar to the following:
2011-02-04 13:37:15,074 ERROR [http-8080-2] VelocityEngine: ResourceManager : unable to find resource 'foo.json.vm' in any resource loader.
This is not ideal. Ideally, if a template isn't found, a warning or something similar would be produced. If a template doesn't exist for a particular content type, I don't really care... as that means that content type isn't supported through that view resolver.
Any idea on how I could suppress this error though the VelocityViewResolver, VelocityView, or ContentNegotiatingViewResolver?
So, I found that the best way to do this was to add a logger statement to my log config file specifically for the Velocity engine (Velocity and my project both use Commons logging). My logger statement looks like this:
<logger name="org.apache.velocity.app">
<level value="OFF" />
</logger>
The problem will be fixed in Spring 3.2, see SPR-8640. After this improvement you will be able to configure Velocity view resolver to check unresolved views only once.
This happens because your ContentNegotiatingViewResolver uses VelocityViewResolver. You can stop it from doing that by giving it an empty (but non-null) list of view resolvers.
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
...
<property name="viewResolvers">
<list />
</property>
</bean>

Categories

Resources