Trigger quartz job at certain time Java spring boot - java

I have issue when I launch the application quartz job in my JAVA Spring Boot project is triggered by itself despite it should trigger on the set certain timet for this case 12:00 o'clock every day. I tried to use with SimpleTriggerJobFactory class because I have issue with simple trigger class while configuring job.
My QuartzConfig class
package com.example.demo.config;
import com.example.demo.jobs.CurrencyImportJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
#Slf4j
#Configuration
public class QuartzConfig {
final ApplicationContext applicationContext;
public QuartzConfig(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Bean
SpringBeanJobFactory createSpringBeanJobFactory (){
return new SpringBeanJobFactory() {
#Override
protected Object createJobInstance
(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
applicationContext
.getAutowireCapableBeanFactory()
.autowireBean(job);
return job;
}
};
}
#Bean
public SchedulerFactoryBean createSchedulerFactory
(SpringBeanJobFactory springBeanJobFactory, Trigger trigger) {
SchedulerFactoryBean schedulerFactory
= new SchedulerFactoryBean();
schedulerFactory.setAutoStartup(true);
schedulerFactory.setWaitForJobsToCompleteOnShutdown(true);
schedulerFactory.setTriggers(trigger);
springBeanJobFactory.setApplicationContext(applicationContext);
schedulerFactory.setJobFactory(springBeanJobFactory);
return schedulerFactory;
}
#Bean
public SimpleTriggerFactoryBean
createSimpleTriggerFactoryBean(JobDetail jobDetail)
{
LocalDateTime now = LocalDateTime.now().withHour(12).withMinute(0);
Date date = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
SimpleTriggerFactoryBean simpleTriggerFactory = new SimpleTriggerFactoryBean();
simpleTriggerFactory.setStartTime(date);
simpleTriggerFactory.setJobDetail(jobDetail);
simpleTriggerFactory.setStartDelay(0);
simpleTriggerFactory.setRepeatInterval(1000);
simpleTriggerFactory.setRepeatCount(0);
return simpleTriggerFactory;
}
#Bean
public JobDetailFactoryBean createJobDetailFactoryBean(){
JobDetailFactoryBean jobDetailFactory
= new JobDetailFactoryBean();
jobDetailFactory.setJobClass(CurrencyImportJob.class);
return jobDetailFactory;
}
}

Related

This job run every 20s but noting saved in database, on the first time after first run the batch work but after that although the job is running

package com.wombatrack.configBatch;
import com.wombatrack.domain.entites.UserInstagram;
import com.wombatrack.service.UserInstagramService;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableBatchProcessing
public class BatchConfig {
#Bean
ItemReader<UserInstagram> restUserInstagramReader(UserInstagramService userInstagramService) {
return new RESTUserInstagramReader(userInstagramService);
}
#Bean
ItemProcessor<UserInstagram, UserInstagram> restUserInstagramProcessor() {
return new LoggingUserInstagramProcessor();
}
#Bean
ItemWriter<UserInstagram> restUserInstagramWriter() {
return new LoggingUserInstagramWriter();
}
#Bean
Step restUserInstagramStep(ItemReader<UserInstagram> restUserInstagramReader,
ItemProcessor<UserInstagram, UserInstagram> restUserInstagramProcessor,
ItemWriter<UserInstagram> restUserInstagramWriter,
StepBuilderFactory stepBuilderFactory) {
return stepBuilderFactory.get("restUserInstagramStep")
.<UserInstagram, UserInstagram>chunk(5)
.reader(restUserInstagramReader)
.processor(restUserInstagramProcessor)
.writer(restUserInstagramWriter)
.allowStartIfComplete(true)
.build();
}
#Bean
Job restUserInstagramJob(JobBuilderFactory jobBuilderFactory,
#Qualifier("restUserInstagramStep") Step restUserInstagramStep) {
return jobBuilderFactory.get("restUserInstagramJob")
.incrementer(new RunIdIncrementer())
.flow(restUserInstagramStep)
.end()
.build();
}
}
I have a probleme with this peace of code my job run first time, but after that return user null that mean busness ligique of job run one time whene the application start first time
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class BatchLauncher {
#Autowired
private JobLauncher jobLauncher;
#Autowired
private Job job;
public BatchStatus run() throws JobParametersInvalidException, JobExecutionAlreadyRunningException,
JobRestartException, JobInstanceAlreadyCompleteException {
JobParameters parameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis())
.toJobParameters();
JobExecution jobExecution = jobLauncher.run(job, parameters);
return jobExecution.getStatus();
}
}
** I put a schedular that will run every 20 seconds the job runs after every 20 seconds as expected, but the problem is that the business, i.e. the backup at the database level does not work no effect.
the job does its role only the first time after the application is started in the first time, but after that the scheduler makes the job run every 20 seconds but the information is not saved, I have a return every time the job with status COMPLETED but the job does nothing in terms of saving new data**
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
#Component
#Slf4j
public class Schedular {
#Autowired
private BatchLauncher batchLauncher;
#Scheduled(fixedDelay = 20000)
public void perform() throws Exception {
log.info("Batch programmé pour tourner toutes les 20 secondes");
batchLauncher.run();
}
}
**I don't have any idea how to do it to fix this problem, i debug application but
I did not find any solution Please if someone can help me **

spring-boot-jms Redeliverypolicy bean ignored?

So I'm setting up Spring jms with activemq. And I'm testing my setup a bit.
I'm trying to setup a redeliverypolicy so it isn't instantly retried, but I noticed in my logging + activemq broker that it's instantly retried and not using my redeliverypolicy bean. Could anyone point me out what I'm doing wrong? According to what I could find in the docs it seems to be correct. (and if anyone sees why my individualdeadletterstrategy is ignored but put on the general DLQ always welcome).
#Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_type");
return converter;
}
#Bean
public DeadLetterStrategy deadLetterStrategy() {
IndividualDeadLetterStrategy deadLetterStrategy = new IndividualDeadLetterStrategy();
deadLetterStrategy.setQueueSuffix(".dlq");
deadLetterStrategy.setUseQueueForQueueMessages(true);
return deadLetterStrategy;
}
#Bean
public RedeliveryPolicy redeliveryPolicy() {
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setInitialRedeliveryDelay(5000);
redeliveryPolicy.setBackOffMultiplier(2);
redeliveryPolicy.setUseExponentialBackOff(true);
redeliveryPolicy.setMaximumRedeliveries(5);
return redeliveryPolicy;
}
#Bean
public Queue myQueue() {
return new ActiveMQQueue("myQueue");
}
deadLetterStrategy concerns broker, so you have to define beans as below
take a look at
http://activemq.apache.org/message-redelivery-and-dlq-handling.html
import java.util.ArrayList;
import java.util.List;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.RedeliveryPolicy;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.region.policy.DeadLetterStrategy;
import org.apache.activemq.broker.region.policy.IndividualDeadLetterStrategy;
import org.apache.activemq.broker.region.policy.PolicyEntry;
import org.apache.activemq.broker.region.policy.PolicyMap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Component;
#SpringBootApplication
#Configuration
#ComponentScan(excludeFilters = #ComponentScan.Filter(type = FilterType.ANNOTATION, classes = { Configuration.class,
Component.class }))
public class ActiveMQConfigurationDeadLetterStrategy {
public static void main(String[] args) {
ConfigurableApplicationContext app = SpringApplication.run(ActiveMQConfigurationDeadLetterStrategy.class, args);
}
#Bean
public BrokerService broker() throws Exception {
final BrokerService broker = new BrokerService();
broker.addConnector("tcp://localhost:61616");
broker.addConnector("vm://localhost");
broker.setPersistent(false);
broker.setDestinationPolicy(policyMap());
return broker;
}
#Bean
public PolicyMap policyMap() {
PolicyMap destinationPolicy = new PolicyMap();
List<PolicyEntry> entries = new ArrayList<PolicyEntry>();
PolicyEntry queueEntry = new PolicyEntry();
queueEntry.setQueue(">");
queueEntry.setDeadLetterStrategy(deadLetterStrategy());
PolicyEntry topicEntry = new PolicyEntry();
topicEntry.setTopic(">");
topicEntry.setDeadLetterStrategy(deadLetterStrategy());
entries.add(queueEntry);
entries.add(topicEntry);
destinationPolicy.setPolicyEntries(entries);
return destinationPolicy;
}
#Bean
public DeadLetterStrategy deadLetterStrategy() {
IndividualDeadLetterStrategy deadLetterStrategy = new IndividualDeadLetterStrategy();
deadLetterStrategy.setQueueSuffix(".dlq");
deadLetterStrategy.setUseQueueForQueueMessages(true);
return deadLetterStrategy;
}
#Bean
public RedeliveryPolicy redeliveryPolicy() {
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setInitialRedeliveryDelay(5000);
redeliveryPolicy.setBackOffMultiplier(2);
redeliveryPolicy.setUseExponentialBackOff(true);
redeliveryPolicy.setMaximumRedeliveries(5);
return redeliveryPolicy;
}
#Bean
public ConnectionFactory jmsConnectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
connectionFactory.setRedeliveryPolicy(redeliveryPolicy());
return connectionFactory;
}
}
UPDATE
If you use an external AMQ the deadLetterStrategy can only be set in the destination policy map of the activemq.xml configuration file
For example :
<broker>
<destinationPolicy>
<policyMap>
<policyEntries>
<!-- Set the following policy on all queues using the '>' wildcard -->
<policyEntry queue=">">
<deadLetterStrategy>
<!--
Use the prefix 'DLQ.' for the destination name, and make
the DLQ a queue rather than a topic
-->
<individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true"/>
</deadLetterStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
</broker>
import java.util.ArrayList;
import java.util.List;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.RedeliveryPolicy;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.broker.region.policy.DeadLetterStrategy;
import org.apache.activemq.broker.region.policy.IndividualDeadLetterStrategy;
import org.apache.activemq.broker.region.policy.PolicyEntry;
import org.apache.activemq.broker.region.policy.PolicyMap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Component;
#SpringBootApplication
#Configuration
#ComponentScan(excludeFilters = #ComponentScan.Filter(type = FilterType.ANNOTATION, classes = { Configuration.class,
Component.class }))
public class ActiveMQConfigurationDeadLetterStrategy {
public static void main(String[] args) {
ConfigurableApplicationContext app = SpringApplication.run(ActiveMQConfigurationDeadLetterStrategy.class, args);
}
#Bean
public RedeliveryPolicy redeliveryPolicy() {
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setInitialRedeliveryDelay(5000);
redeliveryPolicy.setBackOffMultiplier(2);
redeliveryPolicy.setUseExponentialBackOff(true);
redeliveryPolicy.setMaximumRedeliveries(5);
return redeliveryPolicy;
}
#Bean
public ConnectionFactory jmsConnectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
connectionFactory.setRedeliveryPolicy(redeliveryPolicy());
return connectionFactory;
}
}

Spring Batch java config error using ClassifierCompositeItemWriter

I'm using spring batch with java configuration (new to this) and I'm running into a error when trying to use a ClassifierCompositeItemWriter so generate separate files based on a classifier.
The error im getting is org.springframework.batch.item.WriterNotOpenException: Writer must be open before it can be written to
My configuration looks like follows:
package com.infonova.btcompute.batch.geneva.job;
import com.infonova.btcompute.batch.billruntransfer.BillRunTranStatusFinishedJobAssignment;
import com.infonova.btcompute.batch.billruntransfer.BillRunTranStatusInprogressJobAssignment;
import com.infonova.btcompute.batch.billruntransfer.BillRunTransferStatus;
import com.infonova.btcompute.batch.geneva.camel.GenevaJobLauncher;
import com.infonova.btcompute.batch.geneva.dto.GenevaDetailsResultsDto;
import com.infonova.btcompute.batch.geneva.dto.GenveaDetailsTransactionDto;
import com.infonova.btcompute.batch.geneva.properties.GenevaDetailsExportJobProperties;
import com.infonova.btcompute.batch.geneva.rowmapper.GenevaDetailsTransactionsRowMapper;
import com.infonova.btcompute.batch.geneva.steps.*;
import com.infonova.btcompute.batch.repository.BillrunTransferStatusMapper;
import com.infonova.btcompute.batch.utils.FileNameGeneration;
import com.infonova.product.batch.camel.CamelEnabledJob;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.support.ClassifierCompositeItemWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.classify.BackToBackPatternClassifier;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public abstract class AbstractGenevaDetailsExportJob extends CamelEnabledJob {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGenevaDetailsExportJob.class);
#Autowired
protected JobBuilderFactory jobBuilders;
#Autowired
protected StepBuilderFactory stepBuilders;
#Autowired
protected DataSource datasource;
#Autowired
private BillrunTransferStatusMapper billrunTransferStatusMapper;
#Autowired
protected JdbcTemplate jdbcTemplate;
public abstract GenevaDetailsExportJobProperties jobProperties();
#Bean
public RouteBuilder routeBuilder(final GenevaDetailsExportJobProperties jobProperties, final Job job) {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from(jobProperties.getConsumer())
.transacted("PROPAGATION_REQUIRED")
.routeId(jobProperties.getInputRouteName())
.process(genevaJobLauncher(job));
//.to("ftp://app#127.0.0.1?password=secret");
}
};
}
#Bean
public Processor genevaJobLauncher(Job job) {
return new GenevaJobLauncher(job);
}
#Bean
#StepScope
public GenevaDetailsReader reader() {
GenevaDetailsReader reader = new GenevaDetailsReader(jobProperties().getMandatorKey(),
jobProperties().getInvoiceType(), jobProperties().getSqlResourcePath());
reader.setSql("");
reader.setDataSource(datasource);
reader.setRowMapper(new GenevaDetailsTransactionsRowMapper());
reader.setFetchSize(jobProperties().getFetchSize());
return reader;
}
#Bean
#StepScope
public GenevaDetailsItemProcessor processor() {
return new GenevaDetailsItemProcessor();
}
#Bean
#StepScope
public ClassifierCompositeItemWriter writer() {
List<String> serviceCodes = new ArrayList<>();//billrunTransferStatusMapper.getServiceCodes(jobProperties().getMandatorKey());
Long billingTaskId = billrunTransferStatusMapper.getCurrentTaskId(jobProperties().getMandatorKey());
String countryKey = billrunTransferStatusMapper.getCountryKey(billingTaskId);
serviceCodes.add("BTCC");
serviceCodes.add("CCMS");
BackToBackPatternClassifier classifier = new BackToBackPatternClassifier();
classifier.setRouterDelegate(new GenveaDetailsRouterClassifier());
HashMap<String, Object> map = new HashMap<>();
for (String serviceCode : serviceCodes) {
map.put(serviceCode, genevaDetailsWriter(serviceCode, countryKey));
}
classifier.setMatcherMap(map);
ClassifierCompositeItemWriter<GenveaDetailsTransactionDto> writer = new ClassifierCompositeItemWriter<>();
writer.setClassifier(classifier);
return writer;
}
#Bean
#StepScope
public GenevaDetailsFlatFileItemWriter genevaDetailsWriter(String serviceCode, String countryKey) {
GenevaDetailsFlatFileItemWriter writer = new GenevaDetailsFlatFileItemWriter(jobProperties().getDelimiter());
FileNameGeneration fileNameGeneration = new FileNameGeneration();
try {
FileSystemResource fileSystemResource = new FileSystemResource(new File(jobProperties().getExportDir(), fileNameGeneration.generateFileName(jdbcTemplate,
serviceCode, countryKey)));
writer.setResource(fileSystemResource);
} catch (SQLException e) {
LOGGER.error("Error creating FileSystemResource : " + e.getMessage());
}
return writer;
}
#Bean
public Job job() {
return jobBuilders.get(jobProperties().getJobName())
.start(setBillRunTransferStatusDetailInprogressStep())
.next(processGenevaDetailsStep())
.next(setBillRunTransferStatusProcessedStep())
.build();
}
#Bean
public Step setBillRunTransferStatusDetailInprogressStep() {
return stepBuilders.get("setBillRunTransferStatusDetailInprogressStep")
.tasklet(setBillRunTransferStatusDetailInprogress())
.build();
}
#Bean
public Tasklet setBillRunTransferStatusDetailInprogress() {
return new BillRunTranStatusInprogressJobAssignment(BillRunTransferStatus.SUMMARY.toString(), BillRunTransferStatus.DETAILS_INPROGRESS.toString(),
jobProperties().getMandatorKey(), jobProperties().getInvoiceTypeNum(), jobProperties().getReportTypeNum());
}
#Bean
public Step setBillRunTransferStatusProcessedStep() {
return stepBuilders.get("setBillRunTransferStatusProcessedStep")
.tasklet(setBillRunTransferStatusProcessed())
.build();
}
#Bean
public Tasklet setBillRunTransferStatusProcessed() {
return new BillRunTranStatusFinishedJobAssignment(BillRunTransferStatus.PROCESSED.toString());
}
#Bean
public Step processGenevaDetailsStep() {
return stepBuilders.get("processGenevaDetailsStep")
.<GenveaDetailsTransactionDto, GenevaDetailsResultsDto>chunk(jobProperties().getChunkSize())
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
}
and my writer looks like:
package com.infonova.btcompute.batch.geneva.steps;
import com.infonova.btcompute.batch.geneva.dto.GenevaDetailsResultsDto;
import com.infonova.btcompute.batch.repository.BillrunTransferStatusMapper;
import com.infonova.btcompute.batch.utils.FileNameGeneration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.annotation.BeforeStep;
import org.springframework.batch.item.*;
import org.springframework.batch.item.file.FlatFileHeaderCallback;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor;
import org.springframework.batch.item.file.transform.DelimitedLineAggregator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
#Component
public class GenevaDetailsFlatFileItemWriter extends FlatFileItemWriter<GenevaDetailsResultsDto> {
private static final Logger LOGGER = LoggerFactory.getLogger(GenevaDetailsFlatFileItemWriter.class);
#Autowired
protected JdbcTemplate jdbcTemplate;
#Autowired
private BillrunTransferStatusMapper billrunTransferStatusMapper;
private String delimiter;
public GenevaDetailsFlatFileItemWriter(String delimiter) {
this.delimiter = delimiter;
this.setLineAggregator(getLineAggregator());
this.setHeaderCallback(getHeaderCallback());
}
private DelimitedLineAggregator<GenevaDetailsResultsDto> getLineAggregator() {
DelimitedLineAggregator<GenevaDetailsResultsDto> delLineAgg = new DelimitedLineAggregator<>();
delLineAgg.setDelimiter(delimiter);
BeanWrapperFieldExtractor<GenevaDetailsResultsDto> fieldExtractor = new BeanWrapperFieldExtractor<>();
fieldExtractor.setNames(getNames());
delLineAgg.setFieldExtractor(fieldExtractor);
return delLineAgg;
}
private String[] getHeaderNames() {
return new String[] {"Record ID", "Service Identifier", "Billing Account Reference", "Cost Description", "Event Cost",
"Event Date and Time", "Currency Code", "Charge Category", "Order Identifier", "Net Usage", "UOM",
"Quantity", "Service Start Date", "Service End Date"};
}
private String[] getNames() {
return new String[] {"RECORD_ID", "SERVICE_CODE", "BILLING_ACCOUNT_REFERENCE", "COST_DESCRIPTION", "EVENT_COST",
"EVENT_DATE_AND_TIME", "CURRENCY_CODE", "CHARGE_CATEGORY", "ORDER_IDENTIFIER", "NET_USAGE", "UOM",
"QUANTITY", "SERVICE_START_DATE", "SERVICE_END_DATE"};
}
private FlatFileHeaderCallback getHeaderCallback()
{
return new FlatFileHeaderCallback() {
#Override
public void writeHeader(Writer writer) throws IOException {
writer.write(String.join(delimiter, getHeaderNames()));
}
};
}
// #BeforeStep
// public void beforeStep(StepExecution stepExecution) {
// billingTaskId = (Long) stepExecution.getJobExecution().getExecutionContext().get("billingTaskId");
// FileNameGeneration fileNameGeneration = new FileNameGeneration();
//
// try {
// FileSystemResource fileSystemResource = new FileSystemResource(new File(exportDir, fileNameGeneration.generateFileName(jdbcTemplate,
// serviceCode, billrunTransferStatusMapper.getCountryKey(billingTaskId))));
// setResource(fileSystemResource);
// } catch (SQLException e) {
// LOGGER.error("Error creating FileSystemResource : " + e.getMessage());
// }
// }
}
I have searched the web and cannot find a solution to this issue.
What #Hansjoerg Wingeier wrote about ClassifierCompositeItemWriter is correct, but the right way to resolve the problem is to register delegated writer(s) as stream(s) using AbstractTaskletStepBuilder.stream() to let SB manage execution context lifecycle.
ClassifierCompositeItemWriter does not implement the ItemStream interface, hence the open method of your FlatFileItemWriter is never called.
The easiest thing to do is to call the open method when you create your classifier map:
for (String serviceCode : serviceCodes) {
FlatFileItemWriter writer =genevaDetailsWriter(serviceCode, countryKey);
writer.open (new ExecutionContext ());
map.put(serviceCode, writer);
}

Spring, Gradle compiling error with org.springframework.boot.autoconfigure

I want to write my own IM using Spring Framework.
I read this one:
Getting Started - Messaging with RabbitMQ
When I compile this code below I get this error message:
http://pastebin.com/7gNJBAE2
I will be grateful for any help or advise.
I'm using:
Windows 8.1,
Java 8,
NetBeans 8.0.2.,
Gradle 2.5
Receiver.java
package hello;
import java.util.concurrent.CountDownLatch;
public class Receiver {
private CountDownLatch latch = new CountDownLatch(1);
public void receiveMessage(String message) {
System.out.println("Received <" + message + ">");
latch.countDown();
}
public CountDownLatch getLatch() {
return latch;
}
}
Application.java
package hello;
import java.util.concurrent.TimeUnit;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class Application implements CommandLineRunner {
final static String queueName = "spring-boot";
#Autowired
AnnotationConfigApplicationContext context;
#Autowired
RabbitTemplate rabbitTemplate;
#Bean
Queue queue() {
return new Queue(queueName, false);
}
#Bean
TopicExchange exchange() {
return new TopicExchange("spring-boot-exchange");
}
#Bean
Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(queueName);
}
#Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queueName);
container.setMessageListener(listenerAdapter);
return container;
}
#Bean
Receiver receiver() {
return new Receiver();
}
#Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(Application.class, args);
}
#Override
public void run(String... args) throws Exception {
System.out.println("Waiting five seconds...");
Thread.sleep(5000);
System.out.println("Sending message...");
rabbitTemplate.convertAndSend(queueName, "Hello from RabbitMQ!");
receiver().getLatch().await(10000, TimeUnit.MILLISECONDS);
context.close();
}
}
java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration#transactionManager due to internal class not found. This can happen if you are #ComponentScanning a springframework package (e.g. if you put a #ComponentScan in the default package by mistake)
It seems that your source file is in src/main/java instead of being in src/main/java/demo
Didn't you add the package hello; manually? I copy pasted that code in a fresh project created from start.spring.io and it worked without touching anything.

JobParameter & ItemReader

i'm trying to access to the JobParameters in an itemReader, I followed the "Late Binding of Job and Step Attributes" in spring user guide, but can't make it work.
Here is my configuration:
Spring-batch 2.1.8
Spring-core 3.0.5
<bean id="ipcFileReader" scope="step" class="org.springframework.batch.item.file.FlatFileItemReader">
<property name="resource" value="#{jobParameters['filename']}"/>
<property name="lineMapper" ref="lineMapper"/>
<property name="comments" value="#"/>
</bean>
My test class:
#TestExecutionListeners({DependencyInjectionTestExecutionListener.class,StepScopeTestExecutionListener.class})
#ContextConfiguration
public class IpcFileReaderTest {
#Autowired
private ItemReader<Client> ipcFileReader;
public StepExecution getStepExecution(){
StepExecution execution = MetaDataInstanceFactory.createStepExecution();
execution.getExecutionContext().putString("filename",System.getProperty("user.dir") + "/src/test/resources/OMC_File/OMC_Test_1.csv");
return execution;
#Test
public void testReader() throws UnexpectedInputException, ParseException, NonTransientResourceException, Exception{
Assert.assertNotNull(ipcFileReader.read());
}
}
But i always got this error:
Error creating bean with name 'lazyBindingProxy.lazyBindingProxy.ipcFileReader#execution#1234' defined in class path resource [applicationContext-Ipc.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot bind to placeholder: jobParameters['filename']
any ideas ?
Thx
Actually, this is due to a very minor typo.
#{jobParameters['filename']}
should be:
#{jobParameters[filename]}
The single quotes are not needed.
I'm using this UnitTest to pass JobParameters :
package com.test;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {
"/data-source-context.xml",
"/env-test-context.xml",
"/hibernate-context.xml",
"/job-context.xml",
"/job-runner-test-context.xml"
})
public class CopyOfStep1Tests {
#Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
private SimpleJdbcTemplate simpleJdbcTemplate;
#Autowired
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
#Before
public void onSetUp() throws Exception {
// delete previous batch
simpleJdbcTemplate.update("delete from LEGACY_FILE");
}
#After
public void tearDown() throws Exception {
simpleJdbcTemplate.update("delete from LEGACY_FILE");
}
#Test
public void testStep1() throws Exception {
Map<String, JobParameter> parameters = new HashMap<String, JobParameter>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
Date date = sdf.parse("2011/10/20");
JobParameter jobParameter = new JobParameter(date);
parameters.put("input.date", jobParameter);
parameters.put("timestamp", new JobParameter(new Date().getTime()));
JobParameters jobParameters = new JobParameters(parameters);
JobExecution jobExecution = jobLauncherTestUtils.launchStep("step1", jobParameters);
BatchStatus status = jobExecution.getStatus();
Assert.assertEquals("COMPLETED", status.name());
}
}

Categories

Resources