Introducing Batch User Guide Samples

This commit is contained in:
Glenn Renfro
2019-04-19 14:50:48 -04:00
parent ad22ce2c08
commit 6d46829ed6
32 changed files with 2594 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package io.spring.billrun;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class BillrunApplication {
public static void main(String[] args) {
SpringApplication.run(BillrunApplication.class, args);
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.billrun.configuration;
public class Bill {
private Long id;
private String firstName;
private String lastName;
private Long dataUsage;
private Long minutes;
private Double billAmount;
public Bill(Long id, String firstName, String lastName, Long dataUsage, Long minutes, Double billAmount) {
this.firstName = firstName;
this.lastName = lastName;
this.dataUsage = dataUsage;
this.minutes = minutes;
this.billAmount = billAmount;
this.id = id;
}
public Bill() {
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Long getDataUsage() {
return dataUsage;
}
public void setDataUsage(Long dataUsage) {
this.dataUsage = dataUsage;
}
public Long getMinutes() {
return minutes;
}
public void setMinutes(Long minutes) {
this.minutes = minutes;
}
public Double getBillAmount() {
return billAmount;
}
public void setBillAmount(Double billAmount) {
this.billAmount = billAmount;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.billrun.configuration;
import org.springframework.batch.item.ItemProcessor;
public class BillProcessor implements ItemProcessor<Usage, Bill> {
@Override
public Bill process(Usage usage) {
Double billAmount = usage.getDataUsage() * .001 + usage.getMinutes() * .01;
return new Bill(usage.getId(), usage.getFirstName(), usage.getLastName(),
usage.getDataUsage(), usage.getMinutes(), billAmount);
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.billrun.configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.batch.item.database.JdbcBatchItemWriter;
import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
import org.springframework.batch.item.json.JacksonJsonObjectReader;
import org.springframework.batch.item.json.JsonItemReader;
import org.springframework.batch.item.json.builder.JsonItemReaderBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
@Configuration
@EnableTask
@EnableBatchProcessing
public class BillingConfiguration {
private static final Log logger = LogFactory.getLog(BillingConfiguration.class);
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Value("${usage.file.name:classpath:usageinfo.json}")
private Resource usageResource;
@Bean
public Job job1(ItemReader<Usage> reader, ItemProcessor<Usage,Bill> itemProcessor, ItemWriter<Bill> writer) {
Step step = stepBuilderFactory.get("BillProcessing")
.<Usage, Bill>chunk(1)
.reader(reader)
.processor(itemProcessor)
.writer(writer)
.build();
return jobBuilderFactory.get("BillJob")
.incrementer(new RunIdIncrementer())
.start(step)
.build();
}
@Bean
public JsonItemReader<Usage> jsonItemReader() {
ObjectMapper objectMapper = new ObjectMapper();
JacksonJsonObjectReader<Usage> jsonObjectReader =
new JacksonJsonObjectReader<>(Usage.class);
jsonObjectReader.setMapper(objectMapper);
return new JsonItemReaderBuilder<Usage>()
.jsonObjectReader(jsonObjectReader)
.resource(usageResource)
.name("UsageJsonItemReader")
.build();
}
@Bean
public ItemWriter<Bill> jdbcBillWriter(DataSource dataSource) {
JdbcBatchItemWriter<Bill> writer = new JdbcBatchItemWriterBuilder<Bill>()
.beanMapped()
.dataSource(dataSource)
.sql("INSERT INTO BILL_STATEMENTS (id, first_name, last_name, minutes, data_usage,bill_amount) VALUES (:id, :firstName, :lastName, :minutes, :dataUsage, :billAmount)")
.build();
return writer;
}
@Bean
ItemProcessor<Usage, Bill> billProcessor() {
return new BillProcessor();
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.billrun.configuration;
public class Usage {
private Long id;
private String firstName;
private String lastName;
private Long minutes;
private Long dataUsage;
public Usage() {
}
public Usage(Long id, String firstName, String lastName, Long minutes, Long dataUsage) {
this.firstName = firstName;
this.lastName = lastName;
this.minutes = minutes;
this.dataUsage = dataUsage;
this.id = id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Long getDataUsage() {
return dataUsage;
}
public void setDataUsage(Long dataUsage) {
this.dataUsage = dataUsage;
}
public Long getMinutes() {
return minutes;
}
public void setMinutes(Long minutes) {
this.minutes = minutes;
}
@Override
public String toString() {
return "Usage{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", minutes=" + minutes +
", dataUsage=" + dataUsage +
'}';
}
}

View File

@@ -0,0 +1,4 @@
logging.level.org.springframework.cloud.task=debug
spring.datasource.initialization-mode=always
spring.batch.initialize-schema=always
spring.application.name=Bill Run

View File

@@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS BILL_STATEMENTS
(
id int,
first_name varchar(50),
last_name varchar(50),
minutes int,
data_usage int,
bill_amount double
);

View File

@@ -0,0 +1,5 @@
[{"id":"1","firstName":"jane","lastName":"doe","minutes":"500","dataUsage":"1000"},
{"id":"2","firstName":"john","lastName":"doe","minutes":"550","dataUsage":"1500"},
{"id":"3","firstName":"melissa","lastName":"smith","minutes":"600","dataUsage":"1550"},
{"id":"4","firstName":"michael","lastName":"smith","minutes":"650","dataUsage":"1500"},
{"id":"5","firstName":"mary","lastName":"jones","minutes":"700","dataUsage":"1500"}]

View File

@@ -0,0 +1,81 @@
package io.spring.billrun;
import java.util.List;
import io.spring.billrun.configuration.Usage;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
@SpringBatchTest
public class BillrunApplicationTests {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
@Before
public void setup() {
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
}
@Test
public void testJobResults() throws Exception{
testResult();
}
private void testResult() {
List<BillStatement> billStatements = this.jdbcTemplate.query("select ID, " +
"first_name, last_name, minutes, data_usage, bill_amount FROM bill_statements",
(rs, rowNum) -> new BillStatement(rs.getLong("id"),
rs.getString("FIRST_NAME"), rs.getString("LAST_NAME"),
rs.getLong("MINUTES"), rs.getLong("DATA_USAGE"),
rs.getDouble("bill_amount")));
assertThat(billStatements.size()).isEqualTo(5);
BillStatement billStatement = billStatements.get(0);
assertThat(billStatement.getBillAmount()).isEqualTo(6);
assertThat(billStatement.getFirstName()).isEqualTo("jane");
assertThat(billStatement.getLastName()).isEqualTo("doe");
assertThat(billStatement.getId()).isEqualTo(1);
assertThat(billStatement.getMinutes()).isEqualTo(500);
assertThat(billStatement.getDataUsage()).isEqualTo(1000);
}
public static class BillStatement extends Usage {
public BillStatement(Long id, String firstName, String lastName, Long minutes, Long dataUsage, double billAmount) {
super(id, firstName, lastName, minutes, dataUsage);
this.billAmount = billAmount;
}
private double billAmount;
public double getBillAmount() {
return billAmount;
}
public void setBillAmount(double billAmount) {
this.billAmount = billAmount;
}
}
}