Spring multiple beans with same id in a factory pattern? - spring

I have a two beans with the same id as thats the Neo4j Class it maps to internally so i can't have the id changed for both. Now for a clustered environment I need this bean:
<bean id="graphDatabaseService" factory-bean="graphDbBuilderFinal"
factory-method="newGraphDatabase" destroy-method="shutdown" />
And for a non-clustered one I need this :
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.support.GraphDatabaseServiceFactoryBean"
destroy-method="shutdown" scope="singleton">
<constructor-arg value="${neo4j.database.path}" />
</bean>
Right now I comment either one of them based on environment as not all environments will have cluster setup. Is there a way where as based on environment value(a property may be) it picks one bean among these.
This is how it is used in java class.
#Autowired
private GraphDatabaseService graphDB;
Thanks,

You can use spring profile feature (since spring 3.1.X) see link
e.g
<beans profile="cluster">
<bean id="graphDatabaseService" factory-bean="graphDbBuilderFinal"
factory-method="newGraphDatabase" destroy-method="shutdown" />
</beans>
<beans profile="no_cluster">
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.support.GraphDatabaseServiceFactoryBean"
destroy-method="shutdown" scope="singleton">
<constructor-arg value="${neo4j.database.path}" />
</bean>
</beans>
and active the profile in your application in this way
-Dspring.profiles.active="cluster"
Will be loaded only the beans without profile and all those with the profile activated.
I hope this solution can help to solve your problem.

You dont need to define with different Id´s just in different xml configuration files. Like
cluster.xml --->
<bean id="graphDatabaseService" factory-bean="graphDbBuilderFinal"
factory-method="newGraphDatabase" destroy-method="shutdown" />
no_cluster.xml
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.support.GraphDatabaseServiceFactoryBean"
destroy-method="shutdown" scope="singleton">
And then use Spring profile to load one file or another depending of the profile
<beans profile="cluster">
<import resource="spring/cluster.xml" />
</beans>
<beans profile="no_cluster">
<import resource="spring/no_cluster.xml" />
</beans>

Related

How to create a new cache region in SAP Commerce (hybris)

I need to create a new region for a specific set of models. I've followed the documentation about RegionCache but it doesn't work.
Here is the configuration :
<alias name="defaultTestCacheRegion" alias="testCacheRegion"/>
<bean name="defaultTestCacheRegion" class="de.hybris.platform.regioncache.region.impl.EHCacheRegion">
<constructor-arg name="name" value="testCacheRegion" />
<constructor-arg name="maxEntries" value="${regioncache.testcacheregion.maxentries}" />
<constructor-arg name="evictionPolicy" value="${regioncache.testcacheregion.evictionpolicy}" />
<constructor-arg name="statsEnabled" value="${regioncache.stats.enabled}" />
<constructor-arg name="exclusiveComputation" value="${regioncache.exclusivecomputation}" />
<property name="handledTypes">
<array>
<value>25049</value>
<value>25050</value>
<value>25051</value>
</array>
</property>
</bean>
<bean id="testCacheRegionRegistrar" class="de.hybris.platform.regioncache.region.CacheRegionRegistrar" c:region-ref="testCacheRegion" />
I actually miss how the Spring context works in hybris. Since it has to be accessible from all application contexts it has to be set on global level.
All application contexts have as the parent the global application context.
The cache region bean has to be defined in a "global" spring file. In hybris it's done by setting this property. (my_cache.xml has to be in resources in project_name)
<project_name>.global-context=my_cache.xml

Spring Security LDAP - Problems Authenticating a User - Container Issue?

Let me preface this by saying I'm not well versed in Spring. I was thrown into a project at work and am trying to spin up as quickly as possible
With that in mind, I'm trying to implement spring security using Jasig's CAS and LDAP.
When I had loaded this set up from a local LDAP, things worked fine. However, since I've relocated it to the corporate LDAP, the webapp is no longer working.
At the moment, I can confirm this script successfully logs into LDAP and verifies the paths to the containers, however I get a server error before the page loads.
Code:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd" >
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<!-- The URL of the ldap server, along with the base path that all other ldap path will be relative to -->
<constructor-arg value="ldaps://141.161.99.74:636/dc=testing,dc=com"/>
<property name="userDn" value="uid=OdinAdmin,ou=Specials,dc=testing,dc=com" />
<property name="password" value="testpw" />
</bean>
<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg>
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="contextSource"/>
<property name="userSearch" ref="ldapUserSearch"/>
</bean>
</constructor-arg>
<constructor-arg ref="authoritiesPopulator" /> <!-- Populates authorities in the UserDetails object -->
<property name="userDetailsContextMapper" ref="userDetailsMapper" /> <!-- Adds OWF groups to the UserDetails object -->
</bean>
<bean id="authoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<constructor-arg ref="contextSource"/>
<constructor-arg value="ou=OdinRoles,ou=Odin,ou=Apps"/> <!-- search base for determining what roles a user has -->
<property name="groupRoleAttribute" value="cn"/>
<!-- the following properties are shown with their default values -->
<property name="rolePrefix" value="ROLE_"/>
<property name="convertToUpperCase" value="true"/>
<property name="searchSubtree" value="true"/>
</bean>
<bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg value="ou=people" /> <!-- search base for finding User records -->
<constructor-arg value="(uid={0})" /> <!-- filter applied to entities under the search base in order to find a given user.
this default searches for an entity with a matching uid -->
<constructor-arg ref="contextSource" />
</bean>
<!-- Custom class that goes back to the ldap database to search for OWF group records and also adds
extra attributes from the user's ldap record to the UserDetails object.
The class implementation of this will likely need to be changed out for differnt setups -->
<bean id="userDetailsMapper" class="ozone.securitysample.authentication.ldap.OWFUserDetailsContextMapper">
<constructor-arg ref="contextSource" />
<constructor-arg value="ou=OdinGroups,ou=Odin,ou=Apps" /> <!-- search base for finding OWF group membership -->
<constructor-arg value="(uniqueMember={0})" /> <!-- filter that matches only groups that have the given username listed
as a "member" attribute -->
<property name="searchSubtree" value="true"/>
</bean>
<bean id="ldapUserService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
<constructor-arg ref="ldapUserSearch" />
<constructor-arg ref="authoritiesPopulator" />
<property name="userDetailsMapper" ref="userDetailsMapper" />
</bean>
</beans>
My question is, am I allowed to have the subcontainers in the constructor-arg values for group and role searches? In my previous version, everything was in the same container. That way I could just have all that included in my base-dn and just reference the specific OU within that. Ie. instead of
I'm not sure if that is causing the issue, but any insight would be greatly appreciated. Thanks!
Can you provide what exactly is the error you're getting and which part actually fails? There is quite a bit of configuration in there and it'd very much help us if we narrow it down to one error or so.
P.S: I wanted this to be a comment but I'm sorry, i'm not yet allowed to comment due to the restrictions of SO.
This issue actually was based on the application I was implementing. It required specific role names (ROLE_ADMIN, ROLE_USER) to function. I had to map the existing roles to these 2 through a custom Java class.
Thanks for the help!

Implementing a process with JPA for Activiti 5.9

how can we write Spring bean with JPA logic in activiti 5.9 using oracle as back end
I'm not sure this answers your question but I'll give it a try.
You don't need to do something special to achieve your goal.
Declare you processEngine as a Spring bean, you can find information about that at Activiti user guide:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
<property name="mailServerHost" value="mail.my-corp.com" />
<property name="mailServerPort" value="5025" />
</bean>
</beans>
After that you implement your Spring bean including JPA logic. There is nothing Activiti specific here, you just implement it like there is no Activiti. You can find details at this site. Finally you can use this bean in your Service Tasks by that method:
<serviceTask id="javaService"
name="My Java Service Task"
activiti:expression="#{printer.printMessage(myVar1, myVar2)}" />
Here, printer can be your Spring bean or just a named variable in your process context. Variables myVar1 and myVar2 are variables residing in your process context.
You can also design your JPA-logic-including-bean as an Activiti aware one by that:
<serviceTask id="serviceTask" activiti:delegateExpression="${delegateExpressionBean}" />
In this case, delegateExpressionBean is your JPA-logic-including-bean, but class of that bean must implement Activiti's JavaDelegate interface.
It is your choice.

Activemq cluster of embedded brokers and failover consumers

Environment
There is an existing software with propietary way of clustering, which should be moved to use JMS
The customer do not want to pay for setting up and mainaining a
messaging system, so it can be used ONLY if I can embedd the whole
messaging into the existing virtual machines
Broker instances and consumers should be in the same JVM. Consumers
should be able to connect to remote broker in failover situations, since all consumers no matter in which JVM will they run, should have ONE input queue.
it would be nice if the consumers would use direct method calls to
communicate with local broker
Demo Project
I have created a really simple demo (eclipse) project with ActiveMQ + Maven + Spring (the whole project is at http://www.woofiles.com/dl-279452-fOcsWkcm-activemq.zip). If you try it, change the dataDirectory of activemq, since it is a wired absolute path till now.
I try to start up a broker from spring, and also a set of consumers. See Spring config below:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK" />
</bean>
<bean id="embeddedBroker" class="org.apache.activemq.broker.BrokerService"
destroy-method="stop" init-method="start" >
<property name="brokerName" value="conversion" />
<property name="dataDirectory"
value="c:\eclipseWithMaven\activemq\working\conversion" />
<property name="schedulerSupport" value="false" />
<property name="transportConnectorURIs">
<list>
<value>tcp://127.0.0.1:600${idOfClusterNode}</value>
</list>
</property>
<property name="managementContext">
<bean class="org.apache.activemq.broker.jmx.ManagementContext">
<property name="connectorPort" value="201${idOfClusterNode}" />
</bean>
</property>
</bean>
<!-- depends-on see why at http://activemq.apache.org/vm-transport-reference.html -->
<!--depends-on="embeddedBroker" -->
<bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory" depends-on="embeddedBroker">
<property name="brokerURL">
<value>failover:(vm:/conversion,tcp://127.0.0.1:6001,tcp://127.0.0.1:6002)</value>
</property>
</bean>
<bean id="cachedConnectionFactory"
class="org.springframework.jms.connection.CachingConnectionFactory"
p:targetConnectionFactory-ref="jmsFactory" p:sessionCacheSize="10" />
<bean id="container"
class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="concurrentConsumers" value="10" />
<property name="connectionFactory" ref="cachedConnectionFactory" />
<property name="messageListener" ref="conversion" />
<property name="destination" ref="conversionInputQueue" />
</bean>
<bean id="conversionInputQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="conversionInputQueue" />
</bean>
<bean id="conversion" class="activemq.Conversion"
p:clusterId="${idOfClusterNode}" />
</beans>
I simply try to start up one or two instances of the activemq.ConversionDemo class with different parameters used by spring & log4j config. The environment entries of the run config looks like this:
Instance 1 : -DidOfClusterNode=1 -DidOfOtherClusterNode=2 -DlogFile=conversion1.log
Instance 2: -DidOfClusterNode=2 -DidOfOtherClusterNode=1
-DlogFile=conversion2.log
If I start up one instance, it is fine. If two is running the following problems occoured:
The second broker will not start up at all. It says it does not have the lock. Its fine, but I supposed, it just starts up a thread asynchronously, and will give back the control to spring. But it seems, that it wont let spring to continue.
SimpleMessageListenerContainer also seems like holding the control
over spring till all consumers are started.
What I want
I want to meet the requirements above
I think I have to start up both brokers and consumers asynchronously,
which I cannot really do in spring with this config
It would be nice to have real load balancing between brokers. It seems, that ActiveMQ is prepared only for failover.
If my needs cannot be satisfied by ActiveMQ, please recommend
other free solution.
If you need further info, just let me know.
EDIT
I think ActiveMQ supports my needs, I just need to understand "network of brokers". So I guess I have to have two filestore, and a network from my two brokers.
if you point 2 brokers at the same file store, then the first one will get the lock and the 2nd will block until the lock is released...this is a shared file system master/slave setup
if you want an active/active setup, then you'll need to use separate file stores and wire them together as a network of brokers

Spring PropertiesFactoryBean that automatically exposes a PropertyPlaceholderConfigurer's property

Ideally I'd like to do this from code:
#Value("#{aPropertiesFactoryBean.aProperty}")
private String aProperty;
Based on a spring configuration where I set up a PropertyPlaceholderConfigurer and a PropertiesFactoryBean, and just pass the configurer bean as a ref to the bean, and everything that the configurer generates is exposed as a property of the factory bean.
There is a hack to just redefine every property from the Configurer like:
<bean id="aPropertiesFactoryBean"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="properties">
<props>
<prop key="aProperty">${aProperty}</prop>
</props>
</property>
</bean>
And then every time you add a property to the Configurer, you have to re-expose it with the FactoryBean. And the punchline is, I want all the management features of the configurer, and also be able to reference the same batch of properties from both the spring xml files, and #Value annotations.
So the two questions:
Is there something like this out of the box?
It looks like it would be simple to override PropertiesFactoryBean and give it a property for the PlaceholderConfigurer, but the code to actually access the properties would have to involve unwelding the hood through reflection and digging into Spring's internal PropertiesLoaderSupport class. Is there a less hacky way to do this?
Note, I'm not looking for something that can just quickly get me on my way, the above hack with PropertiesFactoryBean suffices for now. I'm looking to either find or make a reusable component that I can use to easily manage injectable properties for projects down the road.
I was just thinking about this backwards. This config does exactly what I want, being able to have properties defined in the xml config, overridable from a properties file, and available as both placeholder properties and injectable values.
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--
One-stop shopping for properties here.
Available as injected values and elsewhere in the spring config.
-->
<bean id="injectableProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="properties">
<props>
<prop key="prop1">value1</prop>
<prop key="prop2">value2</prop>
</props>
</property>
<!-- Allow foo.conf to override default properties -->
<property name="location" value="file:/etc/foo/foo.conf" />
</bean>
<!-- Expose the properties so other parts of the spring config can use them -->
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="properties" ref="injectableProperties"/>
</bean>
</beans>
Maybe I'm misunderstanding the situation, but you can inject properties without having to define a PropertiesFactoryBean by using the syntax:
#Value("${my.property}") String myProperty;

Resources