How to make Drools KnowledgeAgent be dependant a custom component with Spring configuration? - spring

I have my KnowledgeAgent setup as
<drools:kagent kbase="kbase" id="knowledgeAgent" new-instance="false" >
<drools:resources>
<drools:resource source="classpath:change-set.xml" type="CHANGE_SET" />
</drools:resources>
</drools:kagent>
So it scans the change-set.xml from classpath for resources. And I have another component which will dynamially generate the change-set.xml based on rulefiles found on disk. The spring configuration for this is
<bean id="changesetHandler" class="ChangesetHandler" autowire="byName" lazy-init="true" />
The problem here is that the change-set.xml is generated by my custom component, but I cannot set the Drools KnowledgeAgent component to be dependant on it as it follows it's own schema which does not seem to have depends-on attribute.

Given that a knowledge agent listens for changes, it should reload the knowledge base as soon as your bean generates the change set. Why not load a default empty change set initially and then load the dynamic change set when it has been generated?
Personally I avoid the Drools-Spring components. I find it easier to create a service within my application, which holds my knowledge base. I can then define whatever dependencies I like within that service and ensure that any initialisation has been completed.

Related

Spring customised PropertyPlaceholderConfigurer

I have config xml based spring application for which I have moved proprties required at start up time in database. It was very difficult to manage hundreds in property file and that is why database is introduced. To read properties a spring restful service is developed to return a map of all properties required at start up time.
I want to know how to replace properties reading from a map to spring context file e.g. ${config.service.url} should be polulated from a map read via web service.
One option I considered is to upgrade to Annotation based and start using MapPropertySource and Environment interface as environment.getRequiredProperty("config.service.url"). However upgrading to Annotation based is a big impact on project and is no at this time.
Second option that I am looking forward is to have a customised PropertyPlaceholderConfigurer.
Any pointer/help on this will be great.
Cheers,
Amber
You could define a PropertyPlaceholderConfigurer, but instead of specifying a file location, you can pass the properties directly as returned by your restful service.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" .../>
</bean>

Get config setting in custom taglib using Spring "context-property-placeholder"

I'm creating a custom taglib, and would like to use some config options that are loaded via the underlying Spring framework using:
<context:property-placeholder location="classpath:config.properties" />
How would I get access to these variables in my taglib?
Thanks,
James.
The JSP taglibs have nothing in common with the Spring context's lifecycle, they're managed by the servlet container. This can complicate things a bit, for example: inject-dependency-into-a-taglib-class, how-to-write-tag-in-my-spring-project.
Since you're only mentioning the need for contents of the properties file, you could use plain old java.util.ResourceBundle (or, if you need more flexibility, Apache Commons' org.apache.commons.configuration.PropertiesConfiguration).
(One could also argue that requiring access to configuration in your tags indicates a design problem...)

Spring - usage of alias vs names

I am confused on the usage of alias. I do understand what alias is and how it is being used but i don't see how it can be any different than using names on a bean definition.
<bean id="xyx" name="abc,def" .. />
<alias name="xyx" alias="pqr"/>
Why the alias when i can use abc or def?
In my mind bean aliasing can be helpful in large system, where you can not manipulate bean names. You have option to create your own name (alias) specific for your part of the system...
from Spring documentation (3.0.x)
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/htmlsingle/
...it is sometimes desirable to give a single bean multiple names,
otherwise known as bean aliasing...
therefore creating multiple names or/and aliasing are the same thing.
A use case maybe when you want to customize some beans that are already defined somewhere in a modular application (each module is a spring project for example), the bean maybe defined by a third-party framework/API or even your team. In that case you want that only inside your spring project call the customized version without altering other modules (projects), to do that just add the alias in your spring configuration which is indeed a powerful feature:
<alias alias="globalBeanService" name="customizedBeanService" />
Hence, whenever spring find a call to the globalBeanService, it will inject customizedBeanService for you inside your specific module.
Without this feature, you should go through all classes and modify the bean manually!!
An aliased bean will always have higher priority over a non-aliased one, and in case of having different beans with the same alias then the last one declared will have the priority. In other words, the aliased bean will override the non-aliased beans.
This can be particularly useful when creating big projects or when you are building extensions to your project and don't want to touch the original bean definition.
Alias has a specific using scenario which multiple names don't have:
Imagine multiple config xml files in your project, most of which are authored by your colleagues, and you need to add your own config.xml file. Using you'll be able to refer to a bean defined in another config file with a different name that's maybe more meaningful to your config, without having to touch your colleagues' config files.
I recently found another use case where alias easily solved a problem.
When auto configuration is active, Spring Boot provides the bean serverProperties which can be used to access information about the server currently running the web app.
In integration tests (i.e. when #SpringBootTest annotation is present) the same bean is available under the name org.springframework.boot.autoconfigure.web.ServerProperties.
Of course it is possible to use a different profile for integration testing, but that would require manual change of configuration at multiple places. However, simply by adding
<alias name="serverProperties" alias="org.springframework.boot.autoconfigure.web.ServerProperties"/>
the same configuration files can be used for integration tests and in production.
This might be a bug in Spring Boot, however alias easily solve the problem without waiting for a new release. And most certainly I have no possibility to alter the Boot configuration myself.

Osgi Declarative service conditional binding

I have this scenario, I have three declarative services that provide the same interface (say a reader interface and I have readerimpl1-database- readerimpl2-flat file- readerimpl3-memory). I want to have a consumer that binds only to the database implementation. In the component definition we give it a name so I am pretty sure that the name is in the registry so if I were to add an activate method I can lookup from the component context using the name.
I want to try to it via the bind/unbind though using the service name as the parameter. I am pretty sure that the "target" parameter in the component reference element can be used to do this but I have not found how to use it.
Has anyone else done this?
This would be similar to using
#Reference(mapped-name="foo")
Target is simply an OSGi filter. You can use it to filter by any service property. So, if your services have property named backend with values file or database, you can bind with the following target:
<scr:reference ... target="(backend=database)"/>
And the service with database backend itself will register as:
<scr:component ...>
...
<property name="backend" type="String" value="database"/>
</scr:component>

Configuration file changes at runtime for a standalone app?

Say I have a Swing/Spring standalone application. I am wondering whether Spring does detect runtime changes to its configuration file such as this one (assuming the file is on the classpath):
Commenting second bean and adding first bean as below:
<beans>
<bean id="randonNumberGenerator" class="com.me.MyGenerator"/>
<!--
<bean id="randonNumberGenerator" class="com.someoneelse.ADifferentGenerator"/>
-->
</beans>
Will Spring change the implementation at runtime as expected?
I don't think Spring provides a way to reload the configuration on-the-fly. It could be possible by re-instantiating the entire ApplicationContext, but that would mean that all beans are recreated etc., and internal state of the software would probably fly out the window in the process.
I think you can use the "AbstractRefreshableApplicationContext" to refresh the context.
AbstractRefreshableApplicationContext refreshableContext = new ClassPathXmlApplicationContext ( "applicationContextRefreshable.xml" );
refreshableContext.refresh ( );
For details you can have a look here

Resources