this is my xml file configuration.
<batch:job id="pdgRecallJob">
<batch:step id="stepTmpRecall">
<batch:tasklet>
<batch:chunk reader="readFileRecall" processor="" writer="tmpRecallWriter" commit-interval="10000">
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="tmpRecall" class="it.mef.pdg.batch.model.TmpRecall" scope="prototype" />
<bean id="readFileRecall" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="strict" value="false" />
<property name="resource" value="classpath:/properties/RECALLPDG_*.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="appNomeFile, appCodFisc, appRata, appImporto, appIscrizione, appNumTitolo,
appProgQuota, appAnnoEmissione, appCodEnte, appEsitoMef, appStatoFile, appDpt, appPostazione, appNLotto,
appDLotto, appNomeFileOrigine" />
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="tmpRecall" />
</bean>
</property>
</bean>
</property>
</bean>
<bean id="tmpRecallWriter" class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
INSERT INTO APP_TMP_RECALL(APP_NOME_FILE,APP_COD_FISC,APP_RATA,APP_IMPORTO,APP_ISCRIZIONE,APP_NUM_TITOLO,APP_PROGR_QUOTA,APP_ANNO_EMISSIONE,APP_COD_ENTE,APP_ESITO_MEF,APP_STATO_FILE,APP_DPT,APP_POSTAZIONE,APP_NLOTTO,APP_DLOTTO,APP_NOME_FILE_ORIGINE)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
]]>
</value>
</property>
<property name="itemPreparedStatementSetter">
<bean class="it.mef.pdg.batch.items.TmpRecallPreparedStatementSetter" />
</property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.user}" />
<property name="password" value="${db.pass}" />
</bean>
Then my itemPreparedStatementSetter Class:
final class TmpRecallPreparedStatementSetter implements ItemPreparedStatementSetter<TmpRecall>{
public void setValues(TmpRecall tmp, PreparedStatement ps) throws SQLException {
ps.setString(1, tmp.getAppNomeFile());
ps.setString(2, tmp.getAppCodFisc());
ps.setInt(3, tmp.getAppRata());
ps.setDouble(4, tmp.getAppImporto());
ps.setString(5, tmp.getAppIscrizione());
ps.setInt(6, tmp.getAppNumTitolo());
ps.setString(7, tmp.getAppProgQuota());
ps.setInt(8, tmp.getAppAnnoEmissione());
ps.setString(9, tmp.getAppCodEnte());
ps.setString(10, tmp.getAppEsitoMef());
ps.setString(11, tmp.getAppStatoFile());
ps.setString(12, tmp.getAppDpt());
ps.setInt(13, tmp.getAppPostazione());
ps.setInt(14, tmp.getAppNLotto());
ps.setDate(15, tmp.getAppDLotto());
ps.setInt(16, tmp.getAppNLotto());
}
}
My batch seems to work then I have final status COMPLETED, but it doesn't write no record inside my table.
I'm using jdk 1.5, ojdbc5-11.2.0.3.jar.
Either is there something I'm missing in my xml conf or any bean is not ok?
I was thinking that might be even a mismatch in Date field in table.
You don't currently have an item processor, which (I think) is needed to pass records from the reader to the writer. Since you are not doing any processing (that is, your reader produces the same type that your writer consumes), I think you could use a PassThroughItemProcessor here.
I am trying to validate the database health manually using #Aspect.
And if something happened in DatabaseA (in my case is DatabaseA have no more write permission) the application will switch to DatabaseB.
How can I manually re-initialize the connection pool so that I can ensure all connection is going to DatabaseB?
#Aspect
#Component
#Order(value=1)
public class PostServiceAspect extends BaseService {
#Before("execution(* com.some.class.execute(..))")
public void databaseHealthCheck() {
try {
databaseDao.excuteHealthCheckSQL(); // execute "UPDATE table SET field = 1;"
} catch (Exception ex) {
databaseDao.switchTargetDatabase(); // switch to databaseB
// How to re-initialize the connection pool
}
}
//DataSource config
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://testinghost:3306/devgpayment" />
<property name="username" value="root" />
<property name="password" value="password" />
<property name="defaultAutoCommit" value="false" />
<property name="maxTotal" value="40" />
<property name="maxIdle" value="40" />
<property name="maxWaitMillis" value="10000" />
<property name="validationQuery" value="SELECT 1" />
<property name="testWhileIdle" value="true" />
<property name="timeBetweenEvictionRunsMillis" value="5000" />
</bean>
Just need to check, If there is the the way to hide Database connectivity details like username or password from hibernate configuration file:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe"></property>
<property name="username" value="system"></property>
<property name="password" value="tiger"></property>
</bean>
You have 2 options
1) Use JNDI
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
<jee:jndi-lookup id="dbDataSource" jndi-name="jdbc/DatabaseName" expected-type="javax.sql.DataSource" />
2) Use a property placeholder
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:database.properties</value>
<!-- this example use the system parameter configlocation, add -Dconfiglocation -->
<value>file:${configlocation}/database.properties</value>
</property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe"></property>
<property name="username" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
The password can be in the file database.properties which is only in the classpath for the running application and not visible to all.
I have been looking at these for days and still haven't have mush success.
I have install and run activeMQ on a server. Created a queue called "testUpdate". I also have another queue on another server, let call this "forward" and this is on the IBM MQ (WMQ).
So we have testUpdate on ActiveMQ and forward on WMQ. I want the message on forward queue to be placed into testUpdate queue. Trying to use Camel for this process.
So the setup in ActiveMQ has an XML(activemq.xml) that I can place spring beans and configure to do the routing. In this xml, I added http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd to the xmlns and then added
import resource="camel.xml"
In this new xml, I have the following:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<description>Example Camel Route</description>
<from uri="mqseries:forward"/>
<to uri="activemq:testUpdate"/>
</route>
</camelContext>
<bean id="mqseries" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType" value="1"/>
<property name="hostName" value="172.00.12.21/>
<property name="port" value="xyza"/>
<property name="queueManager" value="manager"/>
<property name="channel" value="srvcChannel"/>
</bean>
<!--
Lets configure some Camel endpoints
http://camel.apache.org/components.html
-->
<!-- configure the camel activemq component to use the current broker -->
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent" >
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="vm://amq-broker?create=false"/>
<property name="userName" value="${activemq.username}"/>
<property name="password" value="${activemq.password}"/>
</bean>
</property>
</bean>
</beans>
I added the jar file com.ibm.mq.allclient.jar into the lib folder of ActiveMQ. When running the program, I am getting this exception:
java.lang.ClassNotFoundException: javax.jms.JMSRuntimeException
It sounds like I am missing the websphere jar file? Is this correct?
I use both IBM MQ and ActiveMQ on a regular basis. This example below will show you some sample configuration options. Please make sure you configure these to your own use cases.
//ActiveMQ connection factory
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent" destroy-method="doStop">
<property name="configuration">
<bean class="org.apache.camel.component.jms.JmsConfiguration">
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="1" />
<property name="acceptMessagesWhileStopping" value="true" />
<property name="acknowledgementModeName" value="CLIENT_ACKNOWLEDGE" />
<property name="cacheLevelName" value="CACHE_CONSUMER" />
<property name="connectionFactory">
<bean class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">
<property name="maxConnections" value="1" />
<property name="MaximumActiveSessionPerConnection" value="500" />
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${activemq1.brokerUrl}" />
<property name="userName" value="${activemq1.username}" />
<property name="password" value="${activemq1.password}" />
<property name="redeliveryPolicy">
<bean class="org.apache.activemq.RedeliveryPolicy">
<property name="maximumRedeliveries" value="-1" />
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
</property>
</bean>
//IBM MQ connection factory
<bean id="ibmmq" class="org.apache.camel.component.jms.JmsComponent" destroy-method="doStop">
<property name="concurrentConsumers" value="1" />
<property name="maxConcurrentConsumers" value="1" />
<property name="connectionFactory">
<bean class="org.springframework.jms.connection.SingleConnectionFactory" destroy-method="destroy">
<constructor-arg>
<bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType" value="1" />
<property name="channel" value="${channel}" />
<property name="hostName" value="${hostname}" />
<property name="port" value="${port}" />
<property name="queueManager" value="${queueManager}" />
</bean>
</constructor-arg>
</bean>
</property>
</bean>
You can use jms component to consume the message from IBM MQ and use activemq component to post it to ActiveMQ
have a look at the following links
http://camel.apache.org/jms.html
http://camel.apache.org/activemq.html
Thanks,
Gibu
You can use users camel extra component https://github.com/camel-extra/camel-extra/blob/master/components/camel-wmq/README.md to get messages from wmq without using the JMS wrapping and then send messages to ActiveMQ with custom camel component https://camel.apache.org/components/latest/activemq-component.html. See also a similar topic Apache Camel with IBM MQ.
I have a problem in retrieving attributes from java cas (JA-SIG). It always return null.
Below is my code. What I guess was attributeRepository bean is never called, because I have changed table name to wrong one, and it ran, but it didn't give the runtime error for SQL Exception.
This is my deployerConfigContext.xml file (only the relevant part)
<bean id="authenticationManager" class="org.jasig.cas.authentication.AuthenticationManagerImpl">
<property name="credentialsToPrincipalResolvers">
<list>
<bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver">
<property name="attributeRepository">
<ref bean="attributeRepository"/>
</property>
</bean>
</list>
</property>
</bean>
<bean id="attributeRepository" class="org.jasig.services.persondir.support.jdbc.SingleRowJdbcPersonAttributeDao">
<constructor-arg index="0" ref="dataSource"/>
<constructor-arg index="1" value="SELECT id,is_admin,screen_name FROM user WHERE {0}"/>
<property name="queryAttributeMapping">
<map>
<entry key="login" value="eroshan#rcapl.com" />
</map>
</property>
<property name="resultAttributeMapping">
<map>
<entry key="id" value="150" />
<entry key="is_admin" value="0" />
<entry key="screen_name" value="xxxx.." />
</map>
</property>
</bean>
Below is my client code to retrieve attributes. org.jasig.cas.client.authentication.Saml11AuthenticationFilter is used for getting data.
<h1>CAS Attribute Test</h1>
<p>User Id: <%= request.getRemoteUser() %></p>
<%
if (request.getUserPrincipal() != null) {
AttributePrincipal principal = (AttributePrincipal) request.getUserPrincipal();
Map attributes = principal.getAttributes();
out.println("attribute :"+attributes.size());
if (attributes != null) {
Iterator attributeNames = attributes.keySet().iterator();
out.println("Received attributes: <b>" + (attributeNames.hasNext() ? "YES!" : "No") + "</b>");
out.println("<hr><table border='3pt' width='100%'>");
out.println("<th colspan='2'>Attributes</th>");
out.println("<tr><td><b>Key</b></td><td><b>Value</b></td></tr>");
for (; attributeNames.hasNext();) {
out.println("<tr><td>");
String attributeName = (String) attributeNames.next();
out.println(attributeName);
out.println("</td><td>");
Object attributeValue = attributes.get(attributeName);
out.println(attributeValue);
out.println("</td></tr>");
}
out.println("</table>");
} else {
out.println("<pre>The attribute map is empty. Review your CAS filter configurations.</pre>");
}
} else {
out.println("<pre>The user principal is empty from the request object. Review the wrapper filter configuration.</pre>");
}
%>
When I print the attribute size it shows 0. What is wrong with my code? I'm having big trouble sorting this issue. Lot of resources are available for getting attributes from Ldap, but I need from my db.
Your config looks good, nonetheless you need to define for your CAS service which attributes you want to return and I don't see this part in your extracted config : this is done in the serviceRegistryDao bean for a RegisteredServiceImpl bean, property "allowedAttributes".
An example :
<bean id="serviceRegistryDao" class="org.jasig.cas.services.InMemoryServiceRegistryDaoImpl">
<property name="registeredServices">
<list>
<bean class="org.jasig.cas.services.RegisteredServiceImpl">
<property name="id" value="0" />
<property name="name" value="HTTP" />
<property name="description" value="Only Allows HTTP Urls" />
<property name="serviceId" value="http://**" />
<property name="evaluationOrder" value="10000001" />
<property name="allowedAttributes">
<list>
<value>name</value>
<value>first_name</value>
<value>middle_name</value>`
...