I implemented a step in spring batch that reads records from the database and generates output files.
The step is partitioned so that each slave step generates a different file.
Then I implemented a step which is executed after the slaves, and what it does is to read each of these
generated files and consolidate them into a single file (merge).
The problem I am having is that when run the consolidator step, the input files are empty (probably because
no flush was performed), then tried to configure forceSync = true and transactional = false in the slave writer, but without effect.
When they finish the job, the files generated by the slaves contains data, and the merge file is empty.
The problem, then, is that the input files are empty at the time of execution of consolidator step.
Can help me?, needs more information?
(sorry for my english)
thanks
<batch:job id="interfacesJob" xmlns="">
<batch:step id="step.1" parent="readerParent" next="step.2"/>
<batch:step id="step.2" parent="merge"/>
</batch:job>
<batch:step id="readerParent">
<batch:partition step="slave" partitioner="partitioner">
<batch:handler grid-size="50" task-executor="poolTaskExecutor" />
</batch:partition>
</batch:step>
<batch:step id="slave">
<batch:tasklet
transaction-manager="transactionManager">
<batch:chunk
reader="dummyReader"
processor="dummyProcessor"
writer="dummyWriter"
commit-interval="1"
skip-limit="50">
</batch:tasklet>
</batch:step>
<bean id="dummyWriter"
class="org.springframework.batch.item.file.FlatFileItemWriter"
scope="step" >
<property name="resource" value="file:operations_#{stepExecutionContext[fromId]}.txt" />
<property name="forceSync" value="true" />
<property name="transactional" value="false" />
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter" value="," /> <!-- default -->
<property name="fieldExtractor">
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="id,field1,field2" />
</bean>
</property>
</bean>
</property>
</bean>
<batch:step id="merge">
<tasklet>
<chunk reader="mergeReader" writer="mergeWriter" commit-interval="1" />
</tasklet>
</batch:step>
<bean id="mergeReader"
class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resources" value="file:operations_*.txt" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value="," />
<property name="names" value="id,field1,field2" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="dummyPrototypeBean" />
</bean>
</property>
</bean>
</property>
</bean>
<bean id="mergeWriter"
class="org.springframework.batch.item.file.FlatFileItemWriter">
<property name="resource" value="file:final.txt" />
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter" value="," />
<property name="fieldExtractor">
<bean class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
<property name="names" value="id,field1,field2" />
</bean>
</property>
</bean>
</property>
</bean>
I taste with a MultiResourceItemReader for the mergeReader, but still continue with the same problem:
<bean id="mergeReader"
class="org.springframework.batch.item.file.MultiResourceItemReader">
<property name="resources" value="file:operations_*.txt" />
<property name="delegate" ref="mergeReaderSpecific" />
</bean>
<bean id="mergeReaderSpecific"
class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value="," />
<property name="names" value="id,field1,field2" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="dummyPrototypeBean" />
</bean>
</property>
</bean>
</property>
</bean>
Probably you have to use a MultiResourceItemReader as mergeReader using a FlatFileItemReader as delegate.
FlatFileItemReader.resource property is intended to be used on a single resource opposite to
MultiResourceItemReader.resources (plurals).
Related
I am using Spring Batch 2 version. I am reading data from database using JdbcCursorItemReader.I have successfully fetched the data and also written it to a file.
Below is itemReader bean defined in Job.xml File::
<bean id="itemReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader"
scope="step">
<property name="dataSource" ref="dataSource" />
<property name="sql"
value="select u.ID, u.USER_LOGIN, u.PASSWORD, u.AGE from USERS u" />
</property>
<property name="rowMapper">
<bean class="com.example.UserRowMapper" />
</property>
</bean>
But the issue is,my query is quite big so I just want to keep that query out of xml file and get that query from other file or property file(.property,yaml or xml).
So that I can write xml code as below::
<bean id="itemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
<property name="dataSource" ref="dataSource" />
<property name="sql" value="$sql_query" />
</property><property name="rowMapper">
<bean class="com.example.UserRowMapper" />
</property>
</bean>
What is best way to achieve this?
<bean id="myProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>path1.properties</value>
<value>path2.properties</value>
.....
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>
...
<bean id="itemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
<property name="dataSource" ref="dataSource" />
<property name="sql" value="${sql_query}" />
</property><property name="rowMapper">
<bean class="com.example.UserRowMapper" />
</property>
</bean>
path1.properties:
sql_query=value
PropertySourcesPlaceholderConfigurer is preffered in 3.1 and higher, instead of PropertyPlaceholderConfigurer
You can add sql in jobexecutioncontext by using job listener before step.
Getting below error while executing a batch job. Not immediate but after half an hour.
2016-02-17 15:24:25,106 ERROR [AbstractStep ][poolTaskExecutor-2 ] Encountered an error executing step processSubscriptionFile-stepTwo in job subscriptionJob
org.springframework.jdbc.UncategorizedSQLException: Attempt to process next row failed; uncategorized SQLException for SQL [
SELECT DISTINCT PERSON_ID FROM CUST_SUB_INTER where job_id = 77317301 order by PERSON_ID
]; SQL state [99999]; error code [17010]; Closed Resultset: next; nested exception is java.sql.SQLException: Closed Resultset: next
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
at
My batch job files is as below. In first step I am reading the data from a file and adding to an intermediate table. This chunk uses partition and multiple threads. This step uses partitions and threads. In second step I am reading the data from this temporary table as distinct customer ids and passing it to writer. It is failing halfway through. There are 70000 records in intermediate table and 10000 distinct customer ids. Second step does not use partition and threads. Please help
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byName">
<bean id="SubscriptionJob-jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="uk.co.batch.datamigration.JobLaunchDetails"/>
<property name="jobDataAsMap">
<map>
<entry key="jobName" value="SubscriptionJob" />
<entry key="jobLocator" value-ref="jobRegistry" />
<entry key="jobLauncher" value-ref="jobLauncher" />
</map>
</property>
</bean>
<!-- Job -->
<batch:job id="SubscriptionJob" restartable="false">
<batch:step id="copySubscriptionFile" next="processSubscriptionFile">
<tasklet ref="copySubscriptionFileLocally" />
</batch:step>
<batch:step id="processSubscriptionFile" next="processSubscriptionFile-stepTwo">
<partition step="processSubscriptionFile-stepOne" partitioner="SubscriptionPartitioner">
<handler grid-size="20" task-executor="SubscriptionTaskExecutor"/>
</partition>
</batch:step>
<batch:step id="processSubscriptionFile-stepTwo">
<batch:tasklet>
<batch:chunk reader="SubscriptionItemStepTwoReader" writer="SubscriptionItemStepTwoWriter" commit-interval="200"/>
</batch:tasklet>
</batch:step>
<batch:listeners>
<batch:listener ref="SubscriptionJobListener"/>
<batch:listener ref="SubscriptionJobNotifier"/>
</batch:listeners>
</batch:job>
<batch:step id="processSubscriptionFile-stepOne">
<batch:tasklet>
<batch:chunk reader="SubscriptionItemStepOneReader" writer="SubscriptionItemStepOneWriter" commit-interval="200"/>
</batch:tasklet>
</batch:step>
<bean id ="SubscriptionJobNotifier" class="uk.co.and.batch.status.JobExecutionNotifier">
<property name="snsEventType" value="SUBSCRIPTION_JOB_NOTIFICATION"/>
<property name="onlyNotifyFailures" value="true"/>
</bean>
<bean id="SubscriptionPartitioner" class="uk.co.batch.datamigration.FlatFilePartitioner" scope="step">
<property name="resource" value="file:#{jobExecutionContext[tempSubscriptionFile]}" />
</bean>
<bean id="SubscriptionItemStepOneReader" scope="step" autowire-candidate="false" parent="SubscriptionItemStepOneReaderParent">
<property name="resource" value="file:#{jobExecutionContext[tempSubscriptionFile]}" />
<property name="startAt" value="#{stepExecutionContext['startAt']}"/>
<property name="itemsCount" value="#{stepExecutionContext['itemsCount']}"/>
</bean>
<bean id="SubscriptionItemStepOneReaderParent" abstract="true"
class="uk.co.batch.datamigration.MultiThreadedFlatFileItemReader">
<property name="linesToSkip" value="1"/>
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter" value="^"/>
<property name="names">
<list >
<value>city_name</value>
<value>country_name</value>
<value>publication_name</value>
<value>subscription_ref_code</value>
<value>subscription_state</value>
<value>unsubscribed</value>
<value>city_id</value>
<value>person_id</value>
<value>subscription_created_at</value>
<value>subscription_updated_at</value>
<value>end_value</value>
</list>
</property>
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="SubscriptionVO"/>
</bean>
</property>
</bean>
</property>
<property name="recordSeparatorPolicy">
<bean class="org.springframework.batch.item.file.separator.DefaultRecordSeparatorPolicy"/>
</property>
</bean>
<bean id="SubscriptionVO" class="uk.co.batch.datamigration.subscription.SubscriptionVO" scope="prototype"/>
<!-- TODO:Reduce number of columns to improve performance -->
<bean id="SubscriptionItemStepOneWriter"
class="org.springframework.batch.item.database.JdbcBatchItemWriter" scope="step">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
insert into CUST_SUB_INTER(ID,CITY_NAME,COUNTRY_NAME,PUBLICATION_NAME,SUBSCRIPTION_REF_CODE,SUBSCRIPTION_STATE,
UNSUBSCRIBED,CITY_ID,PERSON_ID,SUBSCRIPTION_CREATED_AT,SUBSCRIPTION_UPDATED_AT,END_VALUE,JOB_ID,
MIGRATION_FILE_NAME,RECORD_INSERT_DATE)
values (SEQ_CUST_SUB_ERROR.NEXTVAL, :city_name, :country_name, :publication_name,
:subscription_ref_code, :subscription_state, :unsubscribed,
:city_id, :person_id, :subscription_created_at, :subscription_updated_at, :end_value,
#{jobExecutionContext[jobId]}, '#{jobExecutionContext[tempSubscriptionFile]}', SYSTIMESTAMP)
]]>
</value>
</property>
<property name="itemSqlParameterSourceProvider">
<bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
</property>
</bean>
<!-- scope step is critical here-->
<bean id="SubscriptionItemStepTwoReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
<property name="dataSource" ref="dataSource"/>
<property name="sql">
<value>
<![CDATA[
SELECT DISTINCT PERSON_ID FROM CUST_SUB_INTER where job_id = #{jobExecutionContext.jobId} order by PERSON_ID
]]>
</value>
</property>
<property name="rowMapper">
<bean class="org.springframework.jdbc.core.SingleColumnRowMapper" p:requiredType="java.lang.Long"/>
</property>
</bean>
<bean id="SubscriptionItemStepTwoWriter" class="uk.co.batch.datamigration.subscription.SubscriptionItemStepTwoWriter" scope="step">
<property name="fileName" value="#{jobExecutionContext[tempSubscriptionFile]}" />
<property name="jobId" value="#{jobExecutionContext.jobId}" />
<property name="errorSaving" value="${Job.errorSaving}"/>
</bean>
<bean id="SubscriptionTaskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="10"/>
</bean>
<bean id="SubscriptionJobListener" class="uk.co.batch.datamigration.JobListener">
<property name="sessionFactory" ref="sftpSessionFactory"/>
<property name="remotePath" value="${Job.subscription.sftp.remoteDirectory}"/>
<property name="remoteExtension" value="${Job.sftp.remoteExtension}"/>
<property name="renameRemoteFile" value="true"/>
<property name="jobContextSingleFileParameterName" value="tempSubscriptionFile"/>
<property name="batchAdministratorUserId" value="${Job.batchAdministratorUserId}"/>
</bean>
<bean id="copySubscriptionFileLocally" class="uk.co.and.batch.core.LocalCopyTasklet" scope="prototype">
<property name="deleteRemoteFile" value="false"/>
<property name="fileNamePattern" value="${Job.subscription.filePattern}"/>
<property name="jobContextSingleFileParameterName" value="tempSubscriptionFile"/>
<property name="localPath" value="${Job.subscription.sftp.localDirectory}"/>
<property name="mustMatch" value="true"/>
<property name="remotePath" value="${Job.subscription.sftp.remoteDirectory}"/>
<property name="remoteSessionFactory" ref="sftpSessionFactory"/>
<property name="maxNumberDownload" value="1"/>
<property name="resolver">
<bean class="uk.co.and.batch.core.remote.FileNameResolvers.SFtpFileNameResolver" />
</property>
</bean>
<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
<property name="host" value="ftp.co.uk"/>
<property name="port" value="22"/>
<property name="user" value=""/>
<property name="password" value=""/>
<property name="proxy" value="#{ ${proxyRef} }"/>
</bean>
</beans>
We're running a webapp on OpenJDK IcedTea6 1.13.6 using Tomcat 6.0.35. For SSO we're using the Spring security SAML extension, which bases on OpenSAML 2.6.1.
When re-deploying our application (without restarting Tomcat), I get a
NoClassDefFoundError: org/bouncycastle/crypto/paddings/ISO10126d2Padding
which is very nicely described here. From an Eclipse MAT analysis, I gather that either BouncyCastleProvider or JCERSAPublicKey are preventing the WebappClassLoaderfrom being gc'ed.
How do I configure SAML so that all (bouncy castle) instances are properly destroyed? I have a hard time believing that SAML is designed such that a deployment mandates a Tomcat restart.
My current configuration:
...
<bean id="samlLogger" class="org.springframework.security.saml.log.SAMLDefaultLogger">
<property name="logErrors" value="true"/>
<property name="logMessages" value="true"/>
</bean>
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="mypassword"/>
<constructor-arg>
<map>
<entry key="tenzingfaces" value="keyphrase"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="tenzingfaces"/>
</bean>
<bean id="samlEntryPoint" class="org.springframework.security.saml.SAMLEntryPoint">
<property name="defaultProfileOptions">
<bean class="org.springframework.security.saml.websso.WebSSOProfileOptions">
<property name="binding" value="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"/>
<property name="includeScoping" value="false"/>
</bean>
</property>
</bean>
<bean id="metadataDisplayFilter" class="org.springframework.security.saml.metadata.MetadataDisplayFilter"/>
<bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider">
<property name="userDetails" ref="samlUserDetailService" />
<property name="forcePrincipalAsString" value="false" />
</bean>
<bean id="samlUserDetailService" class="ch.umbrella.springframework.security.SamlUserDetailsServiceImpl" />
<bean id="contextProvider" class="org.springframework.security.saml.context.SAMLContextProviderImpl"/>
<bean id="samlSuccessRedirectHandler" class="ch.umbrella.springframework.security.SsoAuthenticationSuccessHandler" >
<property name="defaultTargetUrl" value="/main.html" />
<property name="alwaysUseDefaultTargetUrl" value="false" />
<property name="credentialsExpiredUrl" value="/credentialsexpired.html" />
</bean>
<bean id="samlWebSSOProcessingFilter" class="org.springframework.security.saml.SAMLProcessingFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationSuccessHandler" ref="samlSuccessRedirectHandler"/>
</bean>
<bean id="processor" class="org.springframework.security.saml.processor.SAMLProcessorImpl">
<constructor-arg>
<list>
<ref bean="redirectBinding"/>
<ref bean="postBinding"/>
</list>
</constructor-arg>
</bean>
<bean id="webSSOprofileConsumer" class="org.springframework.security.saml.websso.WebSSOProfileConsumerImpl"/>
<bean id="hokWebSSOprofileConsumer" class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl"/>
<bean id="webSSOprofile" class="org.springframework.security.saml.websso.WebSSOProfileImpl"/>
<bean id="hokWebSSOProfile" class="org.springframework.security.saml.websso.WebSSOProfileConsumerHoKImpl"/>
<bean id="postBinding" class="org.springframework.security.saml.processor.HTTPPostBinding">
<constructor-arg ref="parserPool"/>
<constructor-arg ref="velocityEngine"/>
</bean>
<bean id="velocityEngine" class="org.springframework.security.saml.util.VelocityFactory" factory-method="getEngine"/>
<bean id="redirectBinding" class="org.springframework.security.saml.processor.HTTPRedirectDeflateBinding">
<constructor-arg ref="parserPool"/>
</bean>
<bean class="org.springframework.security.saml.SAMLBootstrap"/>
<bean id="parserPool" class="org.opensaml.xml.parse.StaticBasicParserPool" scope="singleton" init-method="initialize"/>
<bean id="parserPoolHolder" class="org.springframework.security.saml.parser.ParserPoolHolder" scope="singleton"/>
...
And, in a staging-specific file:
<bean id="metadata" class="org.springframework.security.saml.metadata.CachingMetadataManager">
<constructor-arg>
<list>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate" destroy-method="destroy">
<constructor-arg>
<bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider" destroy-method="destroy">
<constructor-arg ref="timer1" />
<constructor-arg>
<bean class="org.opensaml.util.resource.ClasspathResource">
<constructor-arg value="/security/idp.xml"/>
</bean>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
</bean>
</constructor-arg>
</bean>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadataDelegate" destroy-method="destroy">
<constructor-arg>
<bean class="org.opensaml.saml2.metadata.provider.ResourceBackedMetadataProvider" destroy-method="destroy">
<constructor-arg ref="timer2" />
<constructor-arg>
<bean class="org.opensaml.util.resource.ClasspathResource">
<constructor-arg value="/security/localhost_sp.xml"/>
</bean>
</constructor-arg>
<property name="parserPool" ref="parserPool"/>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="local" value="true"/>
<property name="securityProfile" value="metaiop"/>
<property name="sslSecurityProfile" value="pkix"/>
<property name="signMetadata" value="true"/>
<property name="signingKey" value="tenzingfaces"/>
<property name="encryptionKey" value="tenzingfaces"/>
<property name="requireArtifactResolveSigned" value="false" />
<property name="requireLogoutRequestSigned" value="false" />
<property name="requireLogoutResponseSigned" value="false" />
<property name="idpDiscoveryEnabled" value="false" />
</bean>
</constructor-arg>
</bean>
</list>
</constructor-arg>
<property name="hostedSPName" value="https://hurricane.umbrellanet.ch/uf-test/saml/metadata" />
</bean>
Thanks
Simon
If you are bundling the bouncycastle jars in your war, then don't do that. Instead put those jars in tomcat/lib . Hopefully, that would fix it.
Hi I am trying to implement concurrency control with spring security3.1 but it is not working.I am using FilterChainProxy so I don't know how to use concurrency control in it.The code I have tried are below what I am missing please help me out?
Bean file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd
">
<!-- Custom code by rajesh -->
<!-- =================================================================== -->
<!-- Create sessionRegistry Implementation Bean -->
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<bean name="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
<property name="sessionRegistry" ref="sessionRegistry"/>
<property name="expiredUrl" value="/modules/my/login.do"/>
</bean>
<bean id="sas" class="com.xxxx.xxx.security.filter.MyConcurrentSessionControlStrategy">
<constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<property name="securityImpl" ref="SecurityImpl"/>
</bean>
<!-- =================================================================== -->
<!-- Custom code ended by rajesh -->
<!-- Create ISecurity Implementation Bean -->
<bean id="SecurityImpl" class="com.xxxx.xxx.security.impl.SecurityImpl">
<property name="dao">
<bean class="com.xxxx.xxx.security.impl.SecurityDAO">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</property>
<property name="sessionRegistry" ref="sessionRegistry" />
<property name="persistentRememberMeTokenRepositoryImpl" >
<bean
class="com.xxxx.xxx.impl.core.security.persisted.tokens.PersistentRememberMeTokenRepositoryImpl">
<property name="dao">
<bean
class="com.xxxx.xxx.impl.core.security.persisted.tokens.PersistentRememberMeTokenDAO">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</property>
</bean>
</property>
</bean>
<bean id="ISecurityImpl"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="myTransactionManager" />
<property name="target" ref="SecurityImpl" />
<property name="proxyTargetClass" value="false" />
<property name="transactionAttributes">
<props>
<prop key="set*">PROPAGATION_REQUIRED</prop>
<prop key="checkPasswordExpiry">PROPAGATION_REQUIRED</prop>
<prop key="expireSessionBySessionId">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="myFilterSecurityInterceptor" class="org.springframework.security.web.FilterChainProxy">
<security:filter-chain-map request-matcher="ant" >
<security:filter-chain pattern="/**"
filters="securityContextPersistenceFilter,concurrencyFilter, logoutFilter, usernamePasswordAuthenticationFilter, rememberMeAuthenticationFilter, passwordExpiryFilter , anonymousAuthenticationFilter, accountExpiryFilter, exceptionTranslationFilter, filterSecurityInterceptor" />
</security:filter-chain-map>
</bean>
<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter" />
<bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<!-- the post-logout destination -->
<constructor-arg value="/modules/my/login.do" />
<constructor-arg>
<array>
<ref bean="myRememberMeService"/>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
</array>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout_my" />
</bean>
<bean id="usernamePasswordAuthenticationFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="sessionAuthenticationStrategy" ref="sas" />
<property name="authenticationManager" ref="myAuthenticationManager" />
<property name="rememberMeServices" ref="myRememberMeService" />
<property name="filterProcessesUrl" value="/my_authentication_service"></property>
<property name="usernameParameter" value="loginid" />
<property name="passwordParameter" value="password" />
<property name="authenticationFailureHandler" ref="AuthenticationFailureHandler" />
<property name="authenticationSuccessHandler" ref="AuthenticationSuccessHandler" />
</bean>
<bean id="accountExpiryFilter" class="com.xxxx.xxx.security.filter.MyAccountExpiryFilter">
<property name="securityImpl" ref="SecurityImpl"/>
<property name="authenticationFailureHandler" ref="AuthenticationFailureHandler" />
<property name="authenticationSuccessHandler" ref="AuthenticationSuccessHandler" />
</bean>
<bean id="passwordExpiryFilter"
class="com.xxxx.xxx.security.filter.MyPasswordExpiryFilter">
<property name="securityImpl" ref="SecurityImpl"/>
<property name="authenticationFailureHandler" ref="AuthenticationFailureHandler" />
<property name="authenticationSuccessHandler" ref="AuthenticationSuccessHandler" />
</bean>
<bean id="AuthenticationFailureHandlerImpl"
class="com.xxxx.xxx.security.impl.AuthenticationFailureHandlerImpl">
<property name="dao">
<bean class="com.xxxx.xxx.security.impl.SecurityDAO">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</property>
<property name="defaultFailureUrl" value="/modules/my/login.do?error=1" />
</bean>
<bean id="AuthenticationFailureHandler"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="myTransactionManager" />
<property name="target" ref="AuthenticationFailureHandlerImpl" />
<property name="proxyTargetClass" value="true" />
<property name="transactionAttributes">
<props>
<prop key="onAuthenticationFailure">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="AuthenticationSuccessHandlerImpl"
class="com.xxxx.xxx.security.impl.AuthenticationSuccessHandler">
<property name="dao">
<bean class="com.xxxx.xxx.security.impl.SecurityDAO">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</property>
<property name="targetUrlParameter" value="redirect-to"></property>
</bean>
<bean id="AuthenticationSuccessHandler"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="myTransactionManager" />
<property name="target" ref="AuthenticationSuccessHandlerImpl" />
<property name="proxyTargetClass" value="true" />
<property name="transactionAttributes">
<props>
<prop key="onAuthenticationSuccess">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="rememberMeAuthenticationFilter"
class="com.xxxx.xxx.security.filter.MyRememberMeAuthenticationFilter">
<property name="rememberMeServices" ref="myRememberMeService" />
<property name="authenticationManager" ref="myAuthenticationManager" />
<property name="securityImpl" ref="SecurityImpl"/>
</bean>
<bean id="anonymousAuthenticationFilter"
class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />
<property name="key" value="XXXXXXXX" />
</bean>
<bean id="exceptionTranslationFilter"
class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/modules/my/login.do" />
</bean>
</property>
<property name="accessDeniedHandler" ref="AccessDeniedHandler" />
</bean>
<bean id="AccessDeniedHandlerImpl" class="com.xxxx.xxx.security.impl.AccessDeniedHandlerImpl">
<property name="dao">
<bean class="com.xxxx.xxx.security.impl.SecurityDAO">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</property>
<property name="errorPage" value="/modules/errors/accessDenied.do" />
</bean>
<bean id="AccessDeniedHandler"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="myTransactionManager" />
<property name="target" ref="AccessDeniedHandlerImpl" />
<property name="proxyTargetClass" value="true" />
<property name="transactionAttributes">
<props>
<prop key="handle">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="myAuthenticationManager" />
<property name="accessDecisionManager" ref="myAffirmativeBasedAccessDecisionManager" />
<property name="securityMetadataSource">
<security:filter-security-metadata-source
use-expressions="true" lowercase-comparisons="true">
<!-- Core Actions -->
<security:intercept-url pattern="/modules/my/login.do"
access="permitAll" />
<security:intercept-url pattern="/modules/my/credentialExpired.do"
access="hasRole('ROLE_ANONYMOUS')" />
<security:intercept-url pattern="/modules/my/*"
access="hasRole('ROLE_ADMIN')" />
</security:filter-security-metadata-source>
</property>
</bean>
<bean class="org.springframework.security.access.vote.AffirmativeBased"
id="myAffirmativeBasedAccessDecisionManager">
<property name="decisionVoters">
<list>
<bean id="webExpressionVoter"
class="org.springframework.security.web.access.expression.WebExpressionVoter">
<property name="expressionHandler" ref="MyWebSecurityExpressionHandler" />
</bean>
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</property>
</bean>
<bean id="MyWebSecurityExpressionHandler"
class="com.xxxx.xxx.security.spring.web.MyWebSecurityExpressionHandler">
<property name="iSecurity" ref="SecurityImpl" />
<property name="roleHierarchy">
<bean
class="org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl">
<property name="hierarchy">
<value>
ROLE_MY > ROLE_ADMIN
ROLE_ADMIN > ROLE_USER
ROLE_USER > ROLE_PORTAL_USER
ROLE_PORTAL_USER > ROLE_GUEST
ROLE_GUEST > ROLE_ANONYMOUS
</value>
</property>
</bean>
</property>
</bean>
<bean id="myAuthenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<property name="authenticationEventPublisher" ref="myAuthEventPublisher" />
<property name="providers">
<list>
<bean
class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="myUserDetailsService" />
<property name="passwordEncoder">
<bean id="myPasswordEncoder"
class="com.xxxx.xxx.security.spring.MyPasswordEncoder">
<property name="passwordEncryptor" ref="myPasswordEncryptor"></property>
</bean>
</property>
</bean>
<bean
class="org.springframework.security.authentication.AnonymousAuthenticationProvider ">
<property name="key" value="xxxxxxxxxxxxxx" />
</bean>
<bean
class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
<property name="key" value="MY_SECURE_REMME_MY_APP" />
</bean>
</list>
</property>
</bean>
<bean id="myUserDetailsService" class="com.xxxx.xxx.impl.core.users.UserImpl">
<property name="dao" ref="userDao" />
<property name="passwordEncryptor" ref="myPasswordEncryptor" />
</bean>
<!-- like for example at new user sign-up. -->
<bean id="myRememberMeService"
class="com.xxxx.xxx.security.impl.DefaultMyRememberMeServices">
<property name="tokenRepository">
<bean
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="myTransactionManager" />
<property name="target">
<bean
class="com.xxxx.xxx.impl.core.security.persisted.tokens.PersistentRememberMeTokenRepositoryImpl">
<property name="dao">
<bean
class="com.xxxx.xxx.impl.core.security.persisted.tokens.PersistentRememberMeTokenDAO">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</property>
</bean>
</property>
<property name="proxyTargetClass" value="false" />
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</property>
<property name="userDetailsService" ref="myUserDetailsService" />
<property name="key" value="MY_SECURE_REMME_MY_APP" />
<property name="alwaysRemember" value="false" />
<property name="useSecureCookie" value="true" />
<property name="cookieName" value="MY_SECURE_REMME" />
<property name="parameter" value="MY_REMME" />
<property name="dao">
<bean class="com.xxxx.xxx.security.impl.SecurityDAO">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
</property>
</bean>
<bean id="myPasswordEncryptor" class="com.xxxx.xxx.security.spring.MyPasswordEncryptor" />
<bean id="myAuthEventPublisher"
class="org.springframework.security.authentication.DefaultAuthenticationEventPublisher" />
<bean id="authenticationListener"
class="org.springframework.security.authentication.event.LoggerListener" />
<bean id="authorizationListener"
class="org.springframework.security.access.event.LoggerListener" />
<bean id="DatabaseConfigImpl" class="com.xxxx.xxx.impl.core.database.config.DatabaseConfigImpl"></bean>
<bean id="IDatabaseConfig" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target" ref="DatabaseConfigImpl" />
<property name="proxyTargetClass" value="false"/>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
In this MyConcurrentSessionControlStrategy class extends ConcurrentSessionControlStrategy class with custom implementation.I am also using Custom filter.I have also added HttpSessionEventPublisher in web.xml
My application is working.I am not getting how to apply concurrency control.
Since you haven't shown the configuration for the usernamePasswordAuthenticationFilter, my first guess would be that you have forgotten to add the necessary hook there by injecting the ConcurrentSessionControlStrategy into that bean. Before adding your own custom versions of classes, you should show that you can get it working with the standard classes. There is an example configuration in the reference manual. Begin from there, make sure that works, and then try adding your MyConcurrentSessionControlStrategy. Without seeing the code for that class it could easily be something in there that is wrong.
Also, if you're trying to describe a problem, you should explain in detail what "isn't working", even if it's just that the feature doesn't seem to be enabled when you think it should be. The debug log is also a useful source of information.
I am configuring a job with two step, Both step need to read different file and dump the data to database. When I am launching the job it executed the first step and save the data successfully and second step is not reading the file. But in database I can see that both Step Status is successful. My Configuration is looks like:
job id="job1" job-repository="jobRepository" xmlns="http://www.springframework.org/schema/batch" restartable="true">
<step id="step1">
<tasklet transaction-manager="transactionManager" task-executor="taskExecutor">
<chunk reader="DomainItemReader" writer="DomainItemWriter" commit-interval="40" skip-limit="10">
<skippable-exception-classes>
<include class="java.lang.Exception"/>
<exclude class="java.io.FileNotFoundException"/>
</skippable-exception-classes>
<listeners>
<listener ref="MyListener"/>
</listeners>
</chunk>
</tasklet>
<next on="COMPLETED" to="step2"/>
</step>
<step id="step2" >
<tasklet transaction-manager="transactionManager" task-executor="taskExecutor" allow-start-if-complete="true">
<chunk reader="DomainItemReader2" writer="DomainItemWriter2" commit-interval="100" skip-limit="10">
<skippable-exception-classes>
<include class="java.lang.Exception"/>
<exclude class="java.io.FileNotFoundException"/>
</skippable-exception-classes>
<listeners>
<listener ref="MyListener2"/>
</listeners>
</chunk>
</tasklet>
</step>
</job>
And my reader is looks like :
<bean id="billDomainItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="file:./firstfile.txt" />
<property name="linesToSkip" value="1" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="delimiter">
<util:constant static-field="org.springframework.batch.item.file.transform.DelimitedLineTokenizer.DELIMITER_TAB"/>
</property>
</bean>
</property>
<property name="fieldSetMapper">
<bean class="com.abc.DomainMapper">
<property name="accessJobParam" ref="accessJobParam"/>
</bean>
</property>
</bean>
</property>
</bean>
And my second step's reader is looks like :
<bean id="DomainItemReader2" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="resource" value="file:./secondFile.txt" />
<property name="linesToSkip" value="1" />
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<!-- <property name="names" value="PRODUCT_ID,NAME,DESCRIPTION,PRICE" />-->
<property name="delimiter">
<util:constant static-field="org.springframework.batch.item.file.transform.DelimitedLineTokenizer.DELIMITER_TAB"/>
</property>
</bean>
</property>
<property name="fieldSetMapper">
<bean class="com.abc.DomainMapper2">
<property name="accessJobParam" ref="accessJobParam"/>
</bean>
</property>
</bean>
</property>
</bean>
Can any body please tell me where I am doing wrong and why it is not processing my second step file.
Thanks
I removed
allow-start-if-complete="true"`
from my second step and added
parent="step1"
in my second step and it works fine for me.
In your second reader configuration
<property name="fieldSetMapper">
<bean class="com.DomainMapper2">
<property name="accessJobParam" ref="accessJobParam"/>
</bean>
</property>
check the bean class mapping <bean class="com.DomainMapper2">
does this bean in same package or in different package <bean class="com.abc.DomainMapper2">