From 3c7297533920cd90c0df1317db2c27035decd695 Mon Sep 17 00:00:00 2001 From: Bogdan Apetrei Date: Mon, 10 Mar 2014 17:50:38 +0200 Subject: [PATCH 1/5] create add some code --- README.md | 2 + pom.xml | 21 +++++-- src/main/java/app/Application.java | 31 ++++++++++ src/main/java/app/Main.java | 14 +++++ src/main/java/app/domain/Product.java | 48 ++++++++++++++++ .../app/repository/JdbcProductRepository.java | 56 +++++++++++++++++++ .../app/repository/ProductRepository.java | 19 +++++++ .../app/service/ProductManagerService.java | 19 +++++++ .../service/SimpleProductManagerService.java | 42 ++++++++++++++ .../resources/META-INF/applicationContext.xml | 17 ++++++ .../META-INF/infrastructureContext.xml | 23 ++++++++ src/main/resources/jdbc.properties | 4 ++ src/main/resources/logback.xml | 16 ++++++ src/test/java/app/domain/ProductTests.java | 39 +++++++++++++ 14 files changed, 345 insertions(+), 6 deletions(-) create mode 100644 src/main/java/app/Application.java create mode 100644 src/main/java/app/Main.java create mode 100644 src/main/java/app/domain/Product.java create mode 100644 src/main/java/app/repository/JdbcProductRepository.java create mode 100644 src/main/java/app/repository/ProductRepository.java create mode 100644 src/main/java/app/service/ProductManagerService.java create mode 100644 src/main/java/app/service/SimpleProductManagerService.java create mode 100644 src/main/resources/META-INF/applicationContext.xml create mode 100644 src/main/resources/META-INF/infrastructureContext.xml create mode 100644 src/main/resources/jdbc.properties create mode 100644 src/main/resources/logback.xml create mode 100644 src/test/java/app/domain/ProductTests.java diff --git a/README.md b/README.md index a1d2939..8af197b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ SpringCore ========== + +http://docs.spring.io/docs/Spring-MVC-step-by-step/index.html \ No newline at end of file diff --git a/pom.xml b/pom.xml index 902ab97..fd03c7d 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,8 @@ 4.0.2.RELEASE - + 1.4-DBCP330 + 2.3.2 1.7.6 1.1.1 4.11-20120805-1225 @@ -59,16 +60,24 @@ ${org.springframework.version} - org.springframework - spring-context-support + spring-jdbc ${org.springframework.version} + + commons-dbcp + commons-dbcp + ${commons-dbcp.version} + + + + org.hsqldb + hsqldb + ${org.hsqldb.version} + + diff --git a/src/main/java/app/Application.java b/src/main/java/app/Application.java new file mode 100644 index 0000000..ca0b60b --- /dev/null +++ b/src/main/java/app/Application.java @@ -0,0 +1,31 @@ +package app; + +import app.domain.Product; +import app.service.ProductManagerService; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.util.List; + +/** + * User: Bogdan Apetrei + * Date: 3/10/14 + * Time: 4:37 PM + */ +public class Application { + + public void run() { + ApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/applicationContext.xml"); + + ProductManagerService productManager = (ProductManagerService) context.getBean("productManager"); + + Product product = new Product(); + product.setPrice(new Double(100)); + product.setDescription("First product"); + + productManager.saveProduct(product); + + List products = productManager.getProducts(); + + } +} diff --git a/src/main/java/app/Main.java b/src/main/java/app/Main.java new file mode 100644 index 0000000..eff6bb9 --- /dev/null +++ b/src/main/java/app/Main.java @@ -0,0 +1,14 @@ +package app; + +/** + * User: Bogdan Apetrei + * Date: 3/10/14 + * Time: 4:37 PM + */ +public class Main { + + public static void main(String[] args) { + Application application = new Application(); + application.run(); + } +} diff --git a/src/main/java/app/domain/Product.java b/src/main/java/app/domain/Product.java new file mode 100644 index 0000000..e123c38 --- /dev/null +++ b/src/main/java/app/domain/Product.java @@ -0,0 +1,48 @@ +package app.domain; + +/** + * User: Bogdan Apetrei + * Date: 3/10/14 + * Time: 3:17 PM + */ + + +public class Product { + + private int id; + private String description; + private Double price; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + @Override + public String toString() { + return "Product{" + + "id=" + id + + ", description='" + description + '\'' + + ", price=" + price + + '}'; + } +} diff --git a/src/main/java/app/repository/JdbcProductRepository.java b/src/main/java/app/repository/JdbcProductRepository.java new file mode 100644 index 0000000..43f683c --- /dev/null +++ b/src/main/java/app/repository/JdbcProductRepository.java @@ -0,0 +1,56 @@ +package app.repository; + + +import app.domain.Product; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.simple.ParameterizedRowMapper; +import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * User: Bogdan Apetrei + * Date: 3/10/14 + * Time: 3:41 PM + */ + +public class JdbcProductRepository extends SimpleJdbcDaoSupport implements ProductRepository { + + /** Logger for this class and subclasses */ + private final Logger logger = LoggerFactory.getLogger(JdbcProductRepository.class); + + @Override + public List getProductList() { + logger.debug("JdbcProductRepository -> getProductList"); + List products = getSimpleJdbcTemplate().query( + "select id, description, price from products", + new ProductMapper()); + return products; + } + + @Override + public void saveProduct(Product prod) { + logger.debug("JdbcProductRepository -> saveProduct: {}", prod.getDescription()); + int count = getSimpleJdbcTemplate().update( + "update products set description = :description, price = :price where id = :id", + new MapSqlParameterSource().addValue("description", prod.getDescription()) + .addValue("price", prod.getPrice()) + .addValue("id", prod.getId())); + logger.debug("JdbcProductRepository -> Rows affected: {}", count); + } + + private static class ProductMapper implements ParameterizedRowMapper { + + public Product mapRow(ResultSet rs, int rowNum) throws SQLException { + Product prod = new Product(); + prod.setId(rs.getInt("id")); + prod.setDescription(rs.getString("description")); + prod.setPrice(new Double(rs.getDouble("price"))); + return prod; + } + } +} diff --git a/src/main/java/app/repository/ProductRepository.java b/src/main/java/app/repository/ProductRepository.java new file mode 100644 index 0000000..aefb0d2 --- /dev/null +++ b/src/main/java/app/repository/ProductRepository.java @@ -0,0 +1,19 @@ +package app.repository; + +import app.domain.Product; + +import java.util.List; + +/** + * User: Bogdan Apetrei + * Date: 3/10/14 + * Time: 3:40 PM + */ + +public interface ProductRepository { + + List getProductList(); + + void saveProduct(Product prod); + +} diff --git a/src/main/java/app/service/ProductManagerService.java b/src/main/java/app/service/ProductManagerService.java new file mode 100644 index 0000000..2191c4f --- /dev/null +++ b/src/main/java/app/service/ProductManagerService.java @@ -0,0 +1,19 @@ +package app.service; + +import app.domain.Product; + +import java.util.List; + +/** + * User: Bogdan Apetrei + * Date: 3/10/14 + * Time: 3:14 PM + */ +public interface ProductManagerService { + + void increasePrice(int percentage); + + List getProducts(); + + void saveProduct(Product prod); +} diff --git a/src/main/java/app/service/SimpleProductManagerService.java b/src/main/java/app/service/SimpleProductManagerService.java new file mode 100644 index 0000000..d2481cf --- /dev/null +++ b/src/main/java/app/service/SimpleProductManagerService.java @@ -0,0 +1,42 @@ +package app.service; + +import app.domain.Product; +import app.repository.ProductRepository; + +import java.util.List; + +/** + * User: Bogdan Apetrei + * Date: 3/10/14 + * Time: 3:14 PM + */ +public class SimpleProductManagerService implements ProductManagerService { + + private ProductRepository productRepository; + + @Override + public List getProducts() { + return productRepository.getProductList(); + } + + @Override + public void increasePrice(int percentage) { + List products = productRepository.getProductList(); + if (products != null) { + for (Product product : products) { + double newPrice = product.getPrice().doubleValue() * (100 + percentage)/100; + product.setPrice(newPrice); + productRepository.saveProduct(product); + } + } + } + + @Override + public void saveProduct(Product product) { + productRepository.saveProduct(product); + } + + public void setProductRepository(ProductRepository productRepository) { + this.productRepository = productRepository; + } +} diff --git a/src/main/resources/META-INF/applicationContext.xml b/src/main/resources/META-INF/applicationContext.xml new file mode 100644 index 0000000..f24ac11 --- /dev/null +++ b/src/main/resources/META-INF/applicationContext.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/META-INF/infrastructureContext.xml b/src/main/resources/META-INF/infrastructureContext.xml new file mode 100644 index 0000000..8789954 --- /dev/null +++ b/src/main/resources/META-INF/infrastructureContext.xml @@ -0,0 +1,23 @@ + + + + + + + classpath:jdbc.properties + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/jdbc.properties b/src/main/resources/jdbc.properties new file mode 100644 index 0000000..2c7227d --- /dev/null +++ b/src/main/resources/jdbc.properties @@ -0,0 +1,4 @@ +db.driver=org.hsqldb.jdbcDriver +db.url=jdbc:hsqldb:hsql://localhost/test +db.username=sa +db.password= \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..50b03e0 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,16 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/app/domain/ProductTests.java b/src/test/java/app/domain/ProductTests.java new file mode 100644 index 0000000..e610985 --- /dev/null +++ b/src/test/java/app/domain/ProductTests.java @@ -0,0 +1,39 @@ +package app.domain; + +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +/** + * User: Bogdan Apetrei + * Date: 3/10/14 + * Time: 3:21 PM + */ + +public class ProductTests { + + private Product product; + + @Before + public void setUp() throws Exception { + product = new Product(); + } + + @Test + public void testSetAndGetDescription() { + String testDescription = "aDescription"; + assertThat(product.getDescription(), is(nullValue())); + product.setDescription(testDescription); + assertThat(product.getDescription(), is(testDescription)); + } + + public void testSetAndGetPrice() { + double testPrice = 100.00; + assertThat(product.getPrice(), is(0.0)); + product.setPrice(testPrice); + assertThat(product.getPrice(), is(testPrice)); + } +} \ No newline at end of file From 2f4ac2fc9c94e8377673371a0ec2406cb093d1a3 Mon Sep 17 00:00:00 2001 From: Bogdan Apetrei Date: Sun, 30 Mar 2014 20:45:40 +0300 Subject: [PATCH 2/5] partial commit --- README.md | 2 - pom.xml | 60 ++++++-- src/main/java/app/Application.java | 31 ---- src/main/java/app/Main.java | 30 +++- src/main/java/app/domain/Account.java | 41 +++++ src/main/java/app/domain/Entity.java | 21 +++ src/main/java/app/domain/Product.java | 48 ------ src/main/java/app/domain/Transaction.java | 45 ++++++ .../app/repository/AccountRepository.java | 15 ++ .../app/repository/JdbcAccountRepository.java | 43 ++++++ .../app/repository/JdbcProductRepository.java | 56 ------- .../repository/JdbcTransactionRepository.java | 25 ++++ .../app/repository/ProductRepository.java | 19 --- .../app/repository/TransactionRepository.java | 9 ++ .../app/service/AccountManagerService.java | 51 +++++++ src/main/java/app/service/AccountService.java | 12 ++ .../app/service/MoneyTransferService.java | 37 +++++ .../app/service/ProductManagerService.java | 19 --- .../service/SimpleProductManagerService.java | 42 ------ .../service/TransactionManagerService.java | 25 ++++ .../java/app/service/TransactionService.java | 9 ++ .../java/app/service/TransferService.java | 9 ++ src/main/java/app/util/AccountMapper.java | 20 +++ .../java/app/util/TransactionValidator.java | 30 ++++ .../resources/META-INF/applicationContext.xml | 17 --- .../META-INF/infrastructureContext.xml | 23 --- .../{jdbc.properties => database.properties} | 2 +- .../resources/spring/application-config.xml | 27 ++++ src/main/resources/spring/database-config.xml | 24 +++ src/main/resources/testdb/data.sql | 2 + src/main/resources/testdb/schema.sql | 19 +++ src/main/resources/testdbdata/data.log | 34 +++++ src/main/resources/testdbdata/data.properties | 4 + src/main/resources/testdbdata/data.script | 53 +++++++ src/test/java/app/domain/ProductTests.java | 39 ----- .../JdbcAccountRepositoryTestIT.java | 140 ++++++++++++++++++ .../service/AccountManagerServiceTest.java | 121 +++++++++++++++ .../JdbcAccountRepositoryTestIT-context.xml | 9 ++ .../resources/spring/database-test-config.xml | 14 ++ 39 files changed, 910 insertions(+), 317 deletions(-) delete mode 100644 src/main/java/app/Application.java create mode 100644 src/main/java/app/domain/Account.java create mode 100644 src/main/java/app/domain/Entity.java delete mode 100644 src/main/java/app/domain/Product.java create mode 100644 src/main/java/app/domain/Transaction.java create mode 100644 src/main/java/app/repository/AccountRepository.java create mode 100644 src/main/java/app/repository/JdbcAccountRepository.java delete mode 100644 src/main/java/app/repository/JdbcProductRepository.java create mode 100644 src/main/java/app/repository/JdbcTransactionRepository.java delete mode 100644 src/main/java/app/repository/ProductRepository.java create mode 100644 src/main/java/app/repository/TransactionRepository.java create mode 100644 src/main/java/app/service/AccountManagerService.java create mode 100644 src/main/java/app/service/AccountService.java create mode 100644 src/main/java/app/service/MoneyTransferService.java delete mode 100644 src/main/java/app/service/ProductManagerService.java delete mode 100644 src/main/java/app/service/SimpleProductManagerService.java create mode 100644 src/main/java/app/service/TransactionManagerService.java create mode 100644 src/main/java/app/service/TransactionService.java create mode 100644 src/main/java/app/service/TransferService.java create mode 100644 src/main/java/app/util/AccountMapper.java create mode 100644 src/main/java/app/util/TransactionValidator.java delete mode 100644 src/main/resources/META-INF/applicationContext.xml delete mode 100644 src/main/resources/META-INF/infrastructureContext.xml rename src/main/resources/{jdbc.properties => database.properties} (50%) create mode 100644 src/main/resources/spring/application-config.xml create mode 100644 src/main/resources/spring/database-config.xml create mode 100644 src/main/resources/testdb/data.sql create mode 100644 src/main/resources/testdb/schema.sql create mode 100644 src/main/resources/testdbdata/data.log create mode 100644 src/main/resources/testdbdata/data.properties create mode 100644 src/main/resources/testdbdata/data.script delete mode 100644 src/test/java/app/domain/ProductTests.java create mode 100644 src/test/java/app/repository/JdbcAccountRepositoryTestIT.java create mode 100644 src/test/java/app/service/AccountManagerServiceTest.java create mode 100644 src/test/resources/app/repository/JdbcAccountRepositoryTestIT-context.xml create mode 100644 src/test/resources/spring/database-test-config.xml diff --git a/README.md b/README.md index 8af197b..a1d2939 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,2 @@ SpringCore ========== - -http://docs.spring.io/docs/Spring-MVC-step-by-step/index.html \ No newline at end of file diff --git a/pom.xml b/pom.xml index fd03c7d..4eaf1a3 100644 --- a/pom.xml +++ b/pom.xml @@ -1,29 +1,30 @@ - - 4.0.0 app SpringCore 1.0-SNAPSHOT + jar + + SpringCore - - 4.0.2.RELEASE - 1.4-DBCP330 + 4.0.3.RELEASE + 1.4 2.3.2 1.7.6 1.1.1 - 4.11-20120805-1225 + 4.11 + 1.9.5 + Core utilities used by other modules. + Define this if you use Spring Utility APIs (org.springframework.core.*/org.springframework.util.*) + --> org.springframework spring-core @@ -66,6 +67,14 @@ ${org.springframework.version} + + org.springframework + spring-test + ${org.springframework.version} + test + + + commons-dbcp commons-dbcp @@ -109,6 +118,12 @@ test + + org.mockito + mockito-core + ${mockito.version} + test + @@ -120,7 +135,12 @@ 1.7 1.7 - + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 org.codehaus.mojo @@ -128,10 +148,24 @@ 2.1 false + false + + org.apache.maven.plugins + maven-pmd-plugin + 3.0.1 + + + compile + + check + cpd-check + + + + - - \ No newline at end of file + diff --git a/src/main/java/app/Application.java b/src/main/java/app/Application.java deleted file mode 100644 index ca0b60b..0000000 --- a/src/main/java/app/Application.java +++ /dev/null @@ -1,31 +0,0 @@ -package app; - -import app.domain.Product; -import app.service.ProductManagerService; -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; - -import java.util.List; - -/** - * User: Bogdan Apetrei - * Date: 3/10/14 - * Time: 4:37 PM - */ -public class Application { - - public void run() { - ApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/applicationContext.xml"); - - ProductManagerService productManager = (ProductManagerService) context.getBean("productManager"); - - Product product = new Product(); - product.setPrice(new Double(100)); - product.setDescription("First product"); - - productManager.saveProduct(product); - - List products = productManager.getProducts(); - - } -} diff --git a/src/main/java/app/Main.java b/src/main/java/app/Main.java index eff6bb9..b6ada8b 100644 --- a/src/main/java/app/Main.java +++ b/src/main/java/app/Main.java @@ -1,14 +1,30 @@ package app; -/** - * User: Bogdan Apetrei - * Date: 3/10/14 - * Time: 4:37 PM - */ +import app.domain.Account; +import app.domain.Transaction; +import app.service.AccountManagerService; +import app.service.MoneyTransferService; +import app.service.TransferService; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.math.BigDecimal; + public class Main { public static void main(String[] args) { - Application application = new Application(); - application.run(); + + ApplicationContext context = new ClassPathXmlApplicationContext("/spring/application-config.xml","/spring/database-config.xml"); + + Transaction transaction = new Transaction("12345678901234", "12345678909876", BigDecimal.TEN); + TransferService transferService = context.getBean("transferService", MoneyTransferService.class); + transferService.transferAmount(transaction); + + AccountManagerService accountService = context.getBean("accountService", AccountManagerService.class); + Account payerAccount = accountService.findByNumber("12345678901234"); + Account beneficiaryAccount = accountService.findByNumber("12345678909876"); + + System.out.println(payerAccount); + System.out.println(beneficiaryAccount); } } diff --git a/src/main/java/app/domain/Account.java b/src/main/java/app/domain/Account.java new file mode 100644 index 0000000..d2809b8 --- /dev/null +++ b/src/main/java/app/domain/Account.java @@ -0,0 +1,41 @@ +package app.domain; + +import java.math.BigDecimal; + +public class Account extends Entity { + + private String number; + private String name; + private BigDecimal moneyAmount; + + public Account(String number, String name, BigDecimal moneyAmount) { + this.number = number; + this.name = name; + this.moneyAmount = moneyAmount; + } + + public String getNumber() { + return number; + } + + public String getName() { + return name; + } + + public BigDecimal getMoneyAmount() { + return moneyAmount; + } + + public void setMoneyAmount(BigDecimal moneyAmount) { + this.moneyAmount = moneyAmount; + } + + @Override + public String toString() { + return "Account{" + + "number='" + number + '\'' + + ", name='" + name + '\'' + + ", moneyAmount=" + moneyAmount + + '}'; + } +} diff --git a/src/main/java/app/domain/Entity.java b/src/main/java/app/domain/Entity.java new file mode 100644 index 0000000..969e057 --- /dev/null +++ b/src/main/java/app/domain/Entity.java @@ -0,0 +1,21 @@ +package app.domain; + +public class Entity { + + private long entityId; + + public long getEntityId() { + return entityId; + } + + public void setEntityId(long entityId) { + this.entityId = entityId; + } + + @Override + public String toString() { + return "Entity{" + + "entityId=" + entityId + + '}'; + } +} diff --git a/src/main/java/app/domain/Product.java b/src/main/java/app/domain/Product.java deleted file mode 100644 index e123c38..0000000 --- a/src/main/java/app/domain/Product.java +++ /dev/null @@ -1,48 +0,0 @@ -package app.domain; - -/** - * User: Bogdan Apetrei - * Date: 3/10/14 - * Time: 3:17 PM - */ - - -public class Product { - - private int id; - private String description; - private Double price; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Double getPrice() { - return price; - } - - public void setPrice(Double price) { - this.price = price; - } - - @Override - public String toString() { - return "Product{" + - "id=" + id + - ", description='" + description + '\'' + - ", price=" + price + - '}'; - } -} diff --git a/src/main/java/app/domain/Transaction.java b/src/main/java/app/domain/Transaction.java new file mode 100644 index 0000000..6271c7e --- /dev/null +++ b/src/main/java/app/domain/Transaction.java @@ -0,0 +1,45 @@ +package app.domain; + +import java.math.BigDecimal; +import java.util.Date; + +public class Transaction extends Entity { + + private String payerAccountNumber; + private String beneficiaryAccountNumber; + private BigDecimal moneyAmount; + private Date date; + + public Transaction(String payerAccountNumber, String beneficiaryAccount, BigDecimal moneyAmount) { + this.payerAccountNumber = payerAccountNumber; + this.beneficiaryAccountNumber = beneficiaryAccount; + this.moneyAmount = moneyAmount; + this.date = new Date(); + } + + public String getPayerAccountNumber() { + return payerAccountNumber; + } + + public String getBeneficiaryAccountNumber() { + return beneficiaryAccountNumber; + } + + public BigDecimal getMoneyAmount() { + return moneyAmount; + } + + public Date getDate() { + return date; + } + + @Override + public String toString() { + return "Transaction{" + + ", payerAccountNumber='" + payerAccountNumber + '\'' + + ", beneficiaryAccountNumber='" + beneficiaryAccountNumber + '\'' + + ", moneyAmount=" + moneyAmount + + ", date=" + date + + '}'; + } +} diff --git a/src/main/java/app/repository/AccountRepository.java b/src/main/java/app/repository/AccountRepository.java new file mode 100644 index 0000000..e1698c9 --- /dev/null +++ b/src/main/java/app/repository/AccountRepository.java @@ -0,0 +1,15 @@ +package app.repository; + + +import app.domain.Account; + +import java.util.List; + +public interface AccountRepository { + + List findByNumber(String number); + + int insert(Account account); + + int updateMoneyAmount(Account account); +} diff --git a/src/main/java/app/repository/JdbcAccountRepository.java b/src/main/java/app/repository/JdbcAccountRepository.java new file mode 100644 index 0000000..538a168 --- /dev/null +++ b/src/main/java/app/repository/JdbcAccountRepository.java @@ -0,0 +1,43 @@ +package app.repository; + +import app.domain.Account; +import app.util.AccountMapper; +import org.springframework.jdbc.core.JdbcTemplate; + +import javax.sql.DataSource; +import java.util.List; + +public class JdbcAccountRepository implements AccountRepository { + + private JdbcTemplate jdbcTemplate; + + public JdbcAccountRepository(DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public List findByNumber(String number) { + return jdbcTemplate.query( + "SELECT * FROM t_account WHERE number = ?", + new AccountMapper(), + number); + } + + @Override + public int insert(Account account) { + return jdbcTemplate.update( + "INSERT INTO t_account (number, name, money_amount) VALUES(?, ?, ?)", + account.getNumber(), + account.getName(), + account.getMoneyAmount()); + } + + @Override + public int updateMoneyAmount(Account account) { + return jdbcTemplate.update( + "UPDATE t_account SET money_amount = ? WHERE id = ?", + account.getMoneyAmount(), + account.getEntityId() + ); + } +} diff --git a/src/main/java/app/repository/JdbcProductRepository.java b/src/main/java/app/repository/JdbcProductRepository.java deleted file mode 100644 index 43f683c..0000000 --- a/src/main/java/app/repository/JdbcProductRepository.java +++ /dev/null @@ -1,56 +0,0 @@ -package app.repository; - - -import app.domain.Product; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.simple.ParameterizedRowMapper; -import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - -/** - * User: Bogdan Apetrei - * Date: 3/10/14 - * Time: 3:41 PM - */ - -public class JdbcProductRepository extends SimpleJdbcDaoSupport implements ProductRepository { - - /** Logger for this class and subclasses */ - private final Logger logger = LoggerFactory.getLogger(JdbcProductRepository.class); - - @Override - public List getProductList() { - logger.debug("JdbcProductRepository -> getProductList"); - List products = getSimpleJdbcTemplate().query( - "select id, description, price from products", - new ProductMapper()); - return products; - } - - @Override - public void saveProduct(Product prod) { - logger.debug("JdbcProductRepository -> saveProduct: {}", prod.getDescription()); - int count = getSimpleJdbcTemplate().update( - "update products set description = :description, price = :price where id = :id", - new MapSqlParameterSource().addValue("description", prod.getDescription()) - .addValue("price", prod.getPrice()) - .addValue("id", prod.getId())); - logger.debug("JdbcProductRepository -> Rows affected: {}", count); - } - - private static class ProductMapper implements ParameterizedRowMapper { - - public Product mapRow(ResultSet rs, int rowNum) throws SQLException { - Product prod = new Product(); - prod.setId(rs.getInt("id")); - prod.setDescription(rs.getString("description")); - prod.setPrice(new Double(rs.getDouble("price"))); - return prod; - } - } -} diff --git a/src/main/java/app/repository/JdbcTransactionRepository.java b/src/main/java/app/repository/JdbcTransactionRepository.java new file mode 100644 index 0000000..71d6876 --- /dev/null +++ b/src/main/java/app/repository/JdbcTransactionRepository.java @@ -0,0 +1,25 @@ +package app.repository; + +import app.domain.Transaction; +import org.springframework.jdbc.core.JdbcTemplate; + +import javax.sql.DataSource; + +public class JdbcTransactionRepository implements TransactionRepository { + + private JdbcTemplate jdbcTemplate; + + public JdbcTransactionRepository(DataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public int insert(Transaction transaction) { + return jdbcTemplate.update( + "INSERT INTO t_transaction (payer_account, beneficiary_account, money_amount, date) VALUES(?, ?, ?, ?)", + transaction.getPayerAccountNumber(), + transaction.getBeneficiaryAccountNumber(), + transaction.getMoneyAmount(), + transaction.getDate()); + } +} \ No newline at end of file diff --git a/src/main/java/app/repository/ProductRepository.java b/src/main/java/app/repository/ProductRepository.java deleted file mode 100644 index aefb0d2..0000000 --- a/src/main/java/app/repository/ProductRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package app.repository; - -import app.domain.Product; - -import java.util.List; - -/** - * User: Bogdan Apetrei - * Date: 3/10/14 - * Time: 3:40 PM - */ - -public interface ProductRepository { - - List getProductList(); - - void saveProduct(Product prod); - -} diff --git a/src/main/java/app/repository/TransactionRepository.java b/src/main/java/app/repository/TransactionRepository.java new file mode 100644 index 0000000..9301e14 --- /dev/null +++ b/src/main/java/app/repository/TransactionRepository.java @@ -0,0 +1,9 @@ +package app.repository; + +import app.domain.Transaction; + +public interface TransactionRepository { + + int insert(Transaction transaction); + +} diff --git a/src/main/java/app/service/AccountManagerService.java b/src/main/java/app/service/AccountManagerService.java new file mode 100644 index 0000000..1af754c --- /dev/null +++ b/src/main/java/app/service/AccountManagerService.java @@ -0,0 +1,51 @@ +package app.service; + +import app.domain.Account; +import app.repository.AccountRepository; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; + +import java.util.List; + +public class AccountManagerService implements AccountService { + + private AccountRepository accountRepository; + + public AccountManagerService(AccountRepository accountRepository) { + this.accountRepository = accountRepository; + } + + @Override + public Account findByNumber(String number) { + List accounts = accountRepository.findByNumber(number); + if (accounts == null || accounts.size() ==0) { + throw new EmptyResultDataAccessException("No account found for number " + number + ".", 1); + } + if (accounts.size() > 1) { + throw new IncorrectResultSizeDataAccessException("More than one account found for number" + number + ".", 1); + } + return accounts.get(0); + } + + @Override + public void save(Account account) { + int count = accountRepository.insert(account); + if (count == 0) { + throw new IncorrectResultSizeDataAccessException("Account not saved.", 1); + } + if (count > 1) { + throw new IncorrectResultSizeDataAccessException("More than once account was saved.", 1); + } + } + + @Override + public void updateMoneyAmount(Account account) { + int count = accountRepository.updateMoneyAmount(account); + if (count == 0) { + throw new IncorrectResultSizeDataAccessException("No accounts were updated", 1); + } + if (count > 1) { + throw new IncorrectResultSizeDataAccessException("More than once account was updated", 1); + } + } +} diff --git a/src/main/java/app/service/AccountService.java b/src/main/java/app/service/AccountService.java new file mode 100644 index 0000000..49c9dd3 --- /dev/null +++ b/src/main/java/app/service/AccountService.java @@ -0,0 +1,12 @@ +package app.service; + +import app.domain.Account; + +public interface AccountService { + + Account findByNumber(String number); + + void save(Account account); + + void updateMoneyAmount(Account account); +} diff --git a/src/main/java/app/service/MoneyTransferService.java b/src/main/java/app/service/MoneyTransferService.java new file mode 100644 index 0000000..17ec6f6 --- /dev/null +++ b/src/main/java/app/service/MoneyTransferService.java @@ -0,0 +1,37 @@ +package app.service; + +import app.domain.Account; +import app.domain.Transaction; +import app.util.TransactionValidator; + +import java.math.BigDecimal; + +public class MoneyTransferService implements TransferService { + + private AccountService accountService; + private TransactionService transactionService; + + public MoneyTransferService(AccountService accountService, TransactionService transactionService) { + this.accountService = accountService; + this.transactionService = transactionService; + } + + @Override + public void transferAmount(Transaction transaction) { + + TransactionValidator.validate(transaction); + + Account payerAccount = accountService.findByNumber(transaction.getPayerAccountNumber()); + Account beneficiaryAccount = accountService.findByNumber(transaction.getBeneficiaryAccountNumber()); + + BigDecimal amount = transaction.getMoneyAmount(); + payerAccount.setMoneyAmount(payerAccount.getMoneyAmount().subtract(amount)); + beneficiaryAccount.setMoneyAmount(beneficiaryAccount.getMoneyAmount().add(amount)); + + accountService.updateMoneyAmount(payerAccount); + accountService.updateMoneyAmount(beneficiaryAccount); + + transactionService.save(transaction); + } + +} diff --git a/src/main/java/app/service/ProductManagerService.java b/src/main/java/app/service/ProductManagerService.java deleted file mode 100644 index 2191c4f..0000000 --- a/src/main/java/app/service/ProductManagerService.java +++ /dev/null @@ -1,19 +0,0 @@ -package app.service; - -import app.domain.Product; - -import java.util.List; - -/** - * User: Bogdan Apetrei - * Date: 3/10/14 - * Time: 3:14 PM - */ -public interface ProductManagerService { - - void increasePrice(int percentage); - - List getProducts(); - - void saveProduct(Product prod); -} diff --git a/src/main/java/app/service/SimpleProductManagerService.java b/src/main/java/app/service/SimpleProductManagerService.java deleted file mode 100644 index d2481cf..0000000 --- a/src/main/java/app/service/SimpleProductManagerService.java +++ /dev/null @@ -1,42 +0,0 @@ -package app.service; - -import app.domain.Product; -import app.repository.ProductRepository; - -import java.util.List; - -/** - * User: Bogdan Apetrei - * Date: 3/10/14 - * Time: 3:14 PM - */ -public class SimpleProductManagerService implements ProductManagerService { - - private ProductRepository productRepository; - - @Override - public List getProducts() { - return productRepository.getProductList(); - } - - @Override - public void increasePrice(int percentage) { - List products = productRepository.getProductList(); - if (products != null) { - for (Product product : products) { - double newPrice = product.getPrice().doubleValue() * (100 + percentage)/100; - product.setPrice(newPrice); - productRepository.saveProduct(product); - } - } - } - - @Override - public void saveProduct(Product product) { - productRepository.saveProduct(product); - } - - public void setProductRepository(ProductRepository productRepository) { - this.productRepository = productRepository; - } -} diff --git a/src/main/java/app/service/TransactionManagerService.java b/src/main/java/app/service/TransactionManagerService.java new file mode 100644 index 0000000..76b36f1 --- /dev/null +++ b/src/main/java/app/service/TransactionManagerService.java @@ -0,0 +1,25 @@ +package app.service; + +import app.domain.Transaction; +import app.repository.TransactionRepository; +import org.springframework.dao.IncorrectResultSizeDataAccessException; + +public class TransactionManagerService implements TransactionService { + + private TransactionRepository transactionRepository; + + public TransactionManagerService(TransactionRepository transactionRepository) { + this.transactionRepository = transactionRepository; + } + + @Override + public void save(Transaction transaction) { + int count = transactionRepository.insert(transaction); + if (count == 0) { + throw new IncorrectResultSizeDataAccessException("Transaction not saved.", 1); + } + if (count > 1) { + throw new IncorrectResultSizeDataAccessException("More than once transaction was saved.", 1); + } + } +} diff --git a/src/main/java/app/service/TransactionService.java b/src/main/java/app/service/TransactionService.java new file mode 100644 index 0000000..3773b81 --- /dev/null +++ b/src/main/java/app/service/TransactionService.java @@ -0,0 +1,9 @@ +package app.service; + +import app.domain.Transaction; + +public interface TransactionService { + + void save(Transaction transaction); + +} diff --git a/src/main/java/app/service/TransferService.java b/src/main/java/app/service/TransferService.java new file mode 100644 index 0000000..9256b57 --- /dev/null +++ b/src/main/java/app/service/TransferService.java @@ -0,0 +1,9 @@ +package app.service; + +import app.domain.Transaction; + +public interface TransferService { + + void transferAmount(Transaction transaction); + +} diff --git a/src/main/java/app/util/AccountMapper.java b/src/main/java/app/util/AccountMapper.java new file mode 100644 index 0000000..c7adef8 --- /dev/null +++ b/src/main/java/app/util/AccountMapper.java @@ -0,0 +1,20 @@ +package app.util; + +import app.domain.Account; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class AccountMapper implements RowMapper { + + @Override + public Account mapRow(ResultSet resultSet, int i) throws SQLException { + Account account = new Account( + resultSet.getString("number"), + resultSet.getString("name"), + resultSet.getBigDecimal("money_amount", 2)); + account.setEntityId(resultSet.getLong("id")); + return account; + } +} diff --git a/src/main/java/app/util/TransactionValidator.java b/src/main/java/app/util/TransactionValidator.java new file mode 100644 index 0000000..8ff3c2f --- /dev/null +++ b/src/main/java/app/util/TransactionValidator.java @@ -0,0 +1,30 @@ +package app.util; + +import app.domain.Transaction; + +import java.math.BigDecimal; + +public class TransactionValidator { + + private static final String ACCOUNT_NUMBER_FORMAT_REGEXP = "\\d{14}"; + + public static void validate(Transaction transaction) { + + BigDecimal amount = transaction.getMoneyAmount(); + if (amount == null || amount.compareTo(BigDecimal.ZERO) < 0) { + throw new IllegalArgumentException("Invalid transaction, amount value is null or less than zero."); + } + String payerAccount = transaction.getPayerAccountNumber(); + if (payerAccount == null || !isValidAccountNumberFormat(payerAccount)) { + throw new IllegalArgumentException("Invalid transaction, payer account has an invalid format."); + } + String beneficiaryAccount = transaction.getBeneficiaryAccountNumber(); + if (beneficiaryAccount == null || !isValidAccountNumberFormat(beneficiaryAccount)) { + throw new IllegalArgumentException("Invalid transaction, beneficiary account has an invalid format."); + } + } + + private static boolean isValidAccountNumberFormat(String accountNumber) { + return accountNumber.matches(ACCOUNT_NUMBER_FORMAT_REGEXP); + } +} diff --git a/src/main/resources/META-INF/applicationContext.xml b/src/main/resources/META-INF/applicationContext.xml deleted file mode 100644 index f24ac11..0000000 --- a/src/main/resources/META-INF/applicationContext.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/META-INF/infrastructureContext.xml b/src/main/resources/META-INF/infrastructureContext.xml deleted file mode 100644 index 8789954..0000000 --- a/src/main/resources/META-INF/infrastructureContext.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - classpath:jdbc.properties - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/jdbc.properties b/src/main/resources/database.properties similarity index 50% rename from src/main/resources/jdbc.properties rename to src/main/resources/database.properties index 2c7227d..3867621 100644 --- a/src/main/resources/jdbc.properties +++ b/src/main/resources/database.properties @@ -1,4 +1,4 @@ db.driver=org.hsqldb.jdbcDriver -db.url=jdbc:hsqldb:hsql://localhost/test +db.url=jdbc:hsqldb:file:src/main/resources/testdbdata/data db.username=sa db.password= \ No newline at end of file diff --git a/src/main/resources/spring/application-config.xml b/src/main/resources/spring/application-config.xml new file mode 100644 index 0000000..916da7e --- /dev/null +++ b/src/main/resources/spring/application-config.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring/database-config.xml b/src/main/resources/spring/database-config.xml new file mode 100644 index 0000000..fd24228 --- /dev/null +++ b/src/main/resources/spring/database-config.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/testdb/data.sql b/src/main/resources/testdb/data.sql new file mode 100644 index 0000000..f83b7d3 --- /dev/null +++ b/src/main/resources/testdb/data.sql @@ -0,0 +1,2 @@ +insert into T_ACCOUNT (NUMBER, NAME, MONEY_AMOUNT) values ('12345678901234', 'Bogdan', '100.00'); +insert into T_ACCOUNT (NUMBER, NAME, MONEY_AMOUNT) values ('12345678909876', 'Dragos', '100.00'); diff --git a/src/main/resources/testdb/schema.sql b/src/main/resources/testdb/schema.sql new file mode 100644 index 0000000..3606469 --- /dev/null +++ b/src/main/resources/testdb/schema.sql @@ -0,0 +1,19 @@ +drop table T_ACCOUNT if exists; +drop table T_TRANSACTION if exists; + +create table T_ACCOUNT( + ID integer identity primary key, + NUMBER varchar(14) not null, + NAME varchar(50) not null, + MONEY_AMOUNT double not null, + unique(NUMBER) +); + +create table T_TRANSACTION( + ID integer identity primary key, + PAYER_ACCOUNT varchar(14) not null, + BENEFICIARY_ACCOUNT varchar(14) not null, + MONEY_AMOUNT double not null, + DATE date not null, + unique(PAYER_ACCOUNT, BENEFICIARY_ACCOUNT, MONEY_AMOUNT, DATE) +); \ No newline at end of file diff --git a/src/main/resources/testdbdata/data.log b/src/main/resources/testdbdata/data.log new file mode 100644 index 0000000..f0f01b4 --- /dev/null +++ b/src/main/resources/testdbdata/data.log @@ -0,0 +1,34 @@ +/*C8*/SET SCHEMA PUBLIC +drop table T_ACCOUNT if exists +drop table T_TRANSACTION if exists +create table T_ACCOUNT( ID integer identity primary key, NUMBER varchar(14) not null, NAME varchar(50) not null, MONEY_AMOUNT double not null, unique(NUMBER) ) +create table T_TRANSACTION( ID integer identity primary key, PAYER_ACCOUNT varchar(14) not null, BENEFICIARY_ACCOUNT varchar(14) not null, MONEY_AMOUNT double not null, DATE date not null, unique(PAYER_ACCOUNT, BENEFICIARY_ACCOUNT, MONEY_AMOUNT, DATE) ) +INSERT INTO T_ACCOUNT VALUES(0,'12345678901234','Bogdan',100.0E0) +COMMIT +INSERT INTO T_ACCOUNT VALUES(1,'12345678909876','Dragos',100.0E0) +COMMIT +DISCONNECT +/*C9*/SET SCHEMA PUBLIC +DISCONNECT +/*C10*/SET SCHEMA PUBLIC +DISCONNECT +/*C11*/SET SCHEMA PUBLIC +DELETE FROM T_ACCOUNT WHERE ID=0 +INSERT INTO T_ACCOUNT VALUES(0,'12345678901234','Bogdan',90.0E0) +COMMIT +DISCONNECT +/*C12*/SET SCHEMA PUBLIC +DELETE FROM T_ACCOUNT WHERE ID=1 +INSERT INTO T_ACCOUNT VALUES(1,'12345678909876','Dragos',110.0E0) +COMMIT +DISCONNECT +/*C13*/SET SCHEMA PUBLIC +INSERT INTO T_TRANSACTION VALUES(0,'12345678901234','12345678909876',10.0E0,'2014-03-30') +COMMIT +DISCONNECT +/*C14*/SET SCHEMA PUBLIC +DISCONNECT +/*C15*/SET SCHEMA PUBLIC +DISCONNECT +/*C16*/SET SCHEMA PUBLIC +DISCONNECT diff --git a/src/main/resources/testdbdata/data.properties b/src/main/resources/testdbdata/data.properties new file mode 100644 index 0000000..e869e9d --- /dev/null +++ b/src/main/resources/testdbdata/data.properties @@ -0,0 +1,4 @@ +#HSQL Database Engine 2.3.2 +#Sun Mar 30 14:10:53 EEST 2014 +version=2.3.2 +modified=yes diff --git a/src/main/resources/testdbdata/data.script b/src/main/resources/testdbdata/data.script new file mode 100644 index 0000000..9ee52eb --- /dev/null +++ b/src/main/resources/testdbdata/data.script @@ -0,0 +1,53 @@ +SET DATABASE UNIQUE NAME HSQLDB451294B2C7 +SET DATABASE GC 0 +SET DATABASE DEFAULT RESULT MEMORY ROWS 0 +SET DATABASE EVENT LOG LEVEL 0 +SET DATABASE TRANSACTION CONTROL LOCKS +SET DATABASE DEFAULT ISOLATION LEVEL READ COMMITTED +SET DATABASE TRANSACTION ROLLBACK ON CONFLICT TRUE +SET DATABASE TEXT TABLE DEFAULTS '' +SET DATABASE SQL NAMES FALSE +SET DATABASE SQL REFERENCES FALSE +SET DATABASE SQL SIZE TRUE +SET DATABASE SQL TYPES FALSE +SET DATABASE SQL TDC DELETE TRUE +SET DATABASE SQL TDC UPDATE TRUE +SET DATABASE SQL TRANSLATE TTI TYPES TRUE +SET DATABASE SQL CONCAT NULLS TRUE +SET DATABASE SQL UNIQUE NULLS TRUE +SET DATABASE SQL CONVERT TRUNCATE TRUE +SET DATABASE SQL AVG SCALE 0 +SET DATABASE SQL DOUBLE NAN TRUE +SET FILES WRITE DELAY 500 MILLIS +SET FILES BACKUP INCREMENT TRUE +SET FILES CACHE SIZE 10000 +SET FILES CACHE ROWS 50000 +SET FILES SCALE 32 +SET FILES LOB SCALE 32 +SET FILES DEFRAG 0 +SET FILES NIO TRUE +SET FILES NIO SIZE 256 +SET FILES LOG TRUE +SET FILES LOG SIZE 50 +CREATE USER SA PASSWORD DIGEST 'd41d8cd98f00b204e9800998ecf8427e' +ALTER USER SA SET LOCAL TRUE +CREATE SCHEMA PUBLIC AUTHORIZATION DBA +SET SCHEMA PUBLIC +CREATE MEMORY TABLE PUBLIC.T_ACCOUNT(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,NUMBER VARCHAR(14) NOT NULL,NAME VARCHAR(50) NOT NULL,MONEY_AMOUNT DOUBLE NOT NULL,UNIQUE(NUMBER)) +ALTER TABLE PUBLIC.T_ACCOUNT ALTER COLUMN ID RESTART WITH 2 +CREATE MEMORY TABLE PUBLIC.T_TRANSACTION(ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,PAYER_ACCOUNT VARCHAR(14) NOT NULL,BENEFICIARY_ACCOUNT VARCHAR(14) NOT NULL,MONEY_AMOUNT DOUBLE NOT NULL,DATE DATE NOT NULL,UNIQUE(PAYER_ACCOUNT,BENEFICIARY_ACCOUNT,MONEY_AMOUNT,DATE)) +ALTER TABLE PUBLIC.T_TRANSACTION ALTER COLUMN ID RESTART WITH 1 +ALTER SEQUENCE SYSTEM_LOBS.LOB_ID RESTART WITH 1 +SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.SQL_IDENTIFIER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.YES_OR_NO TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.TIME_STAMP TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CARDINAL_NUMBER TO PUBLIC +GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CHARACTER_DATA TO PUBLIC +GRANT DBA TO SA +SET SCHEMA SYSTEM_LOBS +INSERT INTO BLOCKS VALUES(0,2147483647,0) +SET SCHEMA PUBLIC +INSERT INTO T_ACCOUNT VALUES(0,'12345678901234','Bogdan',90.0E0) +INSERT INTO T_ACCOUNT VALUES(1,'12345678909876','Dragos',110.0E0) +INSERT INTO T_TRANSACTION VALUES(0,'12345678901234','12345678909876',10.0E0,'2014-03-30') diff --git a/src/test/java/app/domain/ProductTests.java b/src/test/java/app/domain/ProductTests.java deleted file mode 100644 index e610985..0000000 --- a/src/test/java/app/domain/ProductTests.java +++ /dev/null @@ -1,39 +0,0 @@ -package app.domain; - -import org.junit.Before; -import org.junit.Test; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -/** - * User: Bogdan Apetrei - * Date: 3/10/14 - * Time: 3:21 PM - */ - -public class ProductTests { - - private Product product; - - @Before - public void setUp() throws Exception { - product = new Product(); - } - - @Test - public void testSetAndGetDescription() { - String testDescription = "aDescription"; - assertThat(product.getDescription(), is(nullValue())); - product.setDescription(testDescription); - assertThat(product.getDescription(), is(testDescription)); - } - - public void testSetAndGetPrice() { - double testPrice = 100.00; - assertThat(product.getPrice(), is(0.0)); - product.setPrice(testPrice); - assertThat(product.getPrice(), is(testPrice)); - } -} \ No newline at end of file diff --git a/src/test/java/app/repository/JdbcAccountRepositoryTestIT.java b/src/test/java/app/repository/JdbcAccountRepositoryTestIT.java new file mode 100644 index 0000000..ff2b48e --- /dev/null +++ b/src/test/java/app/repository/JdbcAccountRepositoryTestIT.java @@ -0,0 +1,140 @@ +package app.repository; + +import app.domain.Account; +import app.util.AccountMapper; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import javax.sql.DataSource; +import java.math.BigDecimal; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class JdbcAccountRepositoryTestIT { + + private static String ACCOUNT_NUMBER = "12345678901234"; + private static String ACCOUNT_NAME = "NAME"; + private static BigDecimal ACCOUNT_MONEY_AMOUNT = new BigDecimal("100.00"); + + @Autowired + private AccountRepository accountRepository; + + @Autowired + private DataSource dataSource; + + private JdbcTemplate jdbcTemplate; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Test + @DirtiesContext + public void testFindByNumberReturnOnceResult() throws Exception { + + jdbcTemplate.update( + "INSERT INTO t_account (number, name, money_amount) VALUES(?, ?, ?)", + ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_MONEY_AMOUNT); + + List accounts = accountRepository.findByNumber(ACCOUNT_NUMBER); + + assertThat(accounts, is(notNullValue())); + assertThat(accounts.size(), is(1)); + + Account account = accounts.get(0); + assertThat(account.getEntityId(), is(0L)); + assertThat(account.getName(), is(ACCOUNT_NAME)); + assertThat(account.getNumber(), is(ACCOUNT_NUMBER)); + assertThat(account.getMoneyAmount(), is(ACCOUNT_MONEY_AMOUNT)); + } + + @Test + public void testFindByNumberReturnEmptyList() throws Exception { + + List accounts = accountRepository.findByNumber(ACCOUNT_NUMBER); + + assertThat(accounts, is(notNullValue())); + assertThat(accounts.size(), is(0)); + } + + @Test + @DirtiesContext + public void testInsertSuccess() throws Exception { + + accountRepository.insert(new Account(ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_MONEY_AMOUNT)); + + List accounts = jdbcTemplate.query( + "SELECT * FROM t_account WHERE number = ?", + new AccountMapper(), + ACCOUNT_NUMBER); + + assertThat(accounts, is(notNullValue())); + assertThat(accounts.size(), is(1)); + + Account account = accounts.get(0); + assertThat(account.getEntityId(), is(0L)); + assertThat(account.getName(), is(ACCOUNT_NAME)); + assertThat(account.getNumber(), is(ACCOUNT_NUMBER)); + assertThat(account.getMoneyAmount(), is(ACCOUNT_MONEY_AMOUNT)); + } + + @Test + public void testInsertFailed() throws Exception { + exception.expect(DataIntegrityViolationException.class); + + accountRepository.insert(new Account(null, ACCOUNT_NAME, ACCOUNT_MONEY_AMOUNT)); + + } + + @Test + @DirtiesContext + public void testUpdateMoneyAmountSuccess() throws Exception { + + jdbcTemplate.update( + "INSERT INTO t_account (number, name, money_amount) VALUES(?, ?, ?)", + ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_MONEY_AMOUNT); + + List accounts = jdbcTemplate.query("SELECT * FROM t_account WHERE number = ?", + new AccountMapper(), + ACCOUNT_NUMBER); + + BigDecimal NEW_MONEY_AMOUNT = ACCOUNT_MONEY_AMOUNT.add(BigDecimal.TEN); + Account account = accounts.get(0); + account.setMoneyAmount(NEW_MONEY_AMOUNT); + + accountRepository.updateMoneyAmount(account); + + BigDecimal moneyAmount = jdbcTemplate.queryForObject( + "SELECT money_amount FROM t_account WHERE id = ?", BigDecimal.class, account.getEntityId()); + moneyAmount = moneyAmount.setScale(2); + + assertThat(moneyAmount, is(NEW_MONEY_AMOUNT)); + } + + @Test + public void testUpdateMoneyAmountFail() throws Exception { + + Account account = new Account(ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_MONEY_AMOUNT); + account.setEntityId(0L); + + accountRepository.updateMoneyAmount(account); + } +} \ No newline at end of file diff --git a/src/test/java/app/service/AccountManagerServiceTest.java b/src/test/java/app/service/AccountManagerServiceTest.java new file mode 100644 index 0000000..3449c53 --- /dev/null +++ b/src/test/java/app/service/AccountManagerServiceTest.java @@ -0,0 +1,121 @@ +package app.service; + +import app.domain.Account; +import app.repository.AccountRepository; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Collections; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class AccountManagerServiceTest { + + private static String ACCOUNT_NUMBER = "12345678901234"; + private static String ACCOUNT_NAME = "NAME"; + private static BigDecimal ACCOUNT_MONEY_AMOUNT = new BigDecimal("100.00"); + private static Account ACCOUNT = new Account(ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_MONEY_AMOUNT); + + @InjectMocks + AccountManagerService accountService; + + @Mock + private AccountRepository accountRepository; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void testFindByNumberSuccess() throws Exception { + + when(accountRepository.findByNumber(ACCOUNT_NUMBER)).thenReturn(Arrays.asList(ACCOUNT)); + + Account actualAccount = accountService.findByNumber(ACCOUNT_NUMBER); + + assertThat(actualAccount, is(ACCOUNT)); + verify(accountRepository, times(1)).findByNumber(ACCOUNT_NUMBER); + } + + @Test + public void testFindByNumberFail() throws Exception { + exception.expect(EmptyResultDataAccessException.class); + exception.expectMessage("No account found for number " + ACCOUNT_NUMBER); + + when(accountRepository.findByNumber(ACCOUNT_NUMBER)).thenReturn(Collections.emptyList()); + + accountService.findByNumber(ACCOUNT_NUMBER); + } + + @Test + public void testSaveSuccess() throws Exception { + + when(accountRepository.insert(ACCOUNT)).thenReturn(1); + + accountService.save(ACCOUNT); + + verify(accountRepository, times(1)).insert(ACCOUNT); + } + + @Test + public void testSaveFailNoUpdate() throws Exception { + exception.expect(IncorrectResultSizeDataAccessException.class); + exception.expectMessage("Account not saved."); + + when(accountRepository.insert(ACCOUNT)).thenReturn(0); + + accountService.save(ACCOUNT); + + } + + @Test + public void testSaveFailMoreThanOneFieldUpdate() throws Exception { + exception.expect(IncorrectResultSizeDataAccessException.class); + exception.expectMessage("More than once account was saved."); + + when(accountRepository.insert(ACCOUNT)).thenReturn(2); + + accountService.save(ACCOUNT); + } + + @Test + public void testUpdateMoneyAmountSuccess() throws Exception { + + when(accountRepository.updateMoneyAmount(ACCOUNT)).thenReturn(1); + + accountService.updateMoneyAmount(ACCOUNT); + + verify(accountRepository, times(1)).updateMoneyAmount(ACCOUNT); + } + + @Test + public void testUpdateMoneyAmountFailNoUpdate() throws Exception { + exception.expect(IncorrectResultSizeDataAccessException.class); + exception.expectMessage("No accounts were updated"); + + when(accountRepository.updateMoneyAmount(ACCOUNT)).thenReturn(0); + + accountService.updateMoneyAmount(ACCOUNT); + } + + @Test + public void testUpdateMoneyAmountMoreThanOneFieldUpdate() throws Exception { + exception.expect(IncorrectResultSizeDataAccessException.class); + exception.expectMessage("More than once account was updated"); + + when(accountRepository.updateMoneyAmount(ACCOUNT)).thenReturn(2); + + accountService.updateMoneyAmount(ACCOUNT); + } +} \ No newline at end of file diff --git a/src/test/resources/app/repository/JdbcAccountRepositoryTestIT-context.xml b/src/test/resources/app/repository/JdbcAccountRepositoryTestIT-context.xml new file mode 100644 index 0000000..425a54d --- /dev/null +++ b/src/test/resources/app/repository/JdbcAccountRepositoryTestIT-context.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/src/test/resources/spring/database-test-config.xml b/src/test/resources/spring/database-test-config.xml new file mode 100644 index 0000000..dd79093 --- /dev/null +++ b/src/test/resources/spring/database-test-config.xml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file From aaeed6b7b189b5d3924a62a66a078bf3fb09cdce Mon Sep 17 00:00:00 2001 From: Bogdan Apetrei Date: Mon, 31 Mar 2014 21:29:02 +0300 Subject: [PATCH 3/5] partial commit spring xml branch --- README.md | 6 ++ ...stIT.java => JdbcAccountRepositoryIT.java} | 2 +- .../JdbcTransactionRepositoryIT.java | 91 +++++++++++++++++++ .../service/AccountManagerServiceTest.java | 2 +- .../app/service/MoneyTransferServiceTest.java | 53 +++++++++++ .../TransactionManagerServiceTest.java | 67 ++++++++++++++ ...ml => JdbcAccountRepositoryIT-context.xml} | 0 .../JdbcTransactionRepositoryIT-context.xml | 9 ++ 8 files changed, 228 insertions(+), 2 deletions(-) rename src/test/java/app/repository/{JdbcAccountRepositoryTestIT.java => JdbcAccountRepositoryIT.java} (99%) create mode 100644 src/test/java/app/repository/JdbcTransactionRepositoryIT.java create mode 100644 src/test/java/app/service/MoneyTransferServiceTest.java create mode 100644 src/test/java/app/service/TransactionManagerServiceTest.java rename src/test/resources/app/repository/{JdbcAccountRepositoryTestIT-context.xml => JdbcAccountRepositoryIT-context.xml} (100%) create mode 100644 src/test/resources/app/repository/JdbcTransactionRepositoryIT-context.xml diff --git a/README.md b/README.md index a1d2939..4f67641 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,8 @@ SpringCore ========== +example with xml metadata configuration + +//homework - review code, ask questions +//homework - change constructor injection with setter injection +//homework - do validation for AccountMapper class +//homework - do validation for Transaction Validator \ No newline at end of file diff --git a/src/test/java/app/repository/JdbcAccountRepositoryTestIT.java b/src/test/java/app/repository/JdbcAccountRepositoryIT.java similarity index 99% rename from src/test/java/app/repository/JdbcAccountRepositoryTestIT.java rename to src/test/java/app/repository/JdbcAccountRepositoryIT.java index ff2b48e..3dd2425 100644 --- a/src/test/java/app/repository/JdbcAccountRepositoryTestIT.java +++ b/src/test/java/app/repository/JdbcAccountRepositoryIT.java @@ -24,7 +24,7 @@ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration -public class JdbcAccountRepositoryTestIT { +public class JdbcAccountRepositoryIT { private static String ACCOUNT_NUMBER = "12345678901234"; private static String ACCOUNT_NAME = "NAME"; diff --git a/src/test/java/app/repository/JdbcTransactionRepositoryIT.java b/src/test/java/app/repository/JdbcTransactionRepositoryIT.java new file mode 100644 index 0000000..c366680 --- /dev/null +++ b/src/test/java/app/repository/JdbcTransactionRepositoryIT.java @@ -0,0 +1,91 @@ +package app.repository; + +import app.domain.Transaction; +import org.hamcrest.CoreMatchers; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import javax.sql.DataSource; +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class JdbcTransactionRepositoryIT { + + private static final String PAYER_ACCOUNT_NUMBER = "12345678901234"; + private static final String BENEFICIARY_ACCOUNT_NUMBER = "12345678909876"; + private static final BigDecimal MONEY_AMOUNT = new BigDecimal("10.00"); + + @Autowired + private TransactionRepository transactionRepository; + + @Autowired + private DataSource dataSource; + + private JdbcTemplate jdbcTemplate; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Test + @DirtiesContext + public void testInsertSuccess() throws Exception { + + transactionRepository.insert(new Transaction(PAYER_ACCOUNT_NUMBER, BENEFICIARY_ACCOUNT_NUMBER, MONEY_AMOUNT)); + + List transactions = jdbcTemplate.query( + "SELECT * FROM t_transaction WHERE payer_account = ? and beneficiary_account = ? and money_amount = ?", + new RowMapper() { + @Override + public Transaction mapRow(ResultSet resultSet, int i) throws SQLException { + Transaction transaction = new Transaction( + resultSet.getString("payer_account"), + resultSet.getString("beneficiary_account"), + resultSet.getBigDecimal("money_amount", 2)); + transaction.setEntityId(resultSet.getLong("id")); + return transaction; + } + }, + PAYER_ACCOUNT_NUMBER, BENEFICIARY_ACCOUNT_NUMBER, MONEY_AMOUNT); + + assertThat(transactions, is(notNullValue())); + assertThat(transactions.size(), is(1)); + + Transaction transaction = transactions.get(0); + assertThat(transaction.getEntityId(), is(0L)); + assertThat(transaction.getPayerAccountNumber(), is(PAYER_ACCOUNT_NUMBER)); + assertThat(transaction.getBeneficiaryAccountNumber(), is(BENEFICIARY_ACCOUNT_NUMBER)); + assertThat(transaction.getMoneyAmount(), is(MONEY_AMOUNT)); + assertThat(transaction.getDate(), is(CoreMatchers.notNullValue())); + } + + @Test + public void testInsertFailed() throws Exception { + exception.expect(DataIntegrityViolationException.class); + + transactionRepository.insert(new Transaction(null, BENEFICIARY_ACCOUNT_NUMBER, MONEY_AMOUNT)); + + } +} diff --git a/src/test/java/app/service/AccountManagerServiceTest.java b/src/test/java/app/service/AccountManagerServiceTest.java index 3449c53..5fe49a1 100644 --- a/src/test/java/app/service/AccountManagerServiceTest.java +++ b/src/test/java/app/service/AccountManagerServiceTest.java @@ -29,7 +29,7 @@ public class AccountManagerServiceTest { private static Account ACCOUNT = new Account(ACCOUNT_NUMBER, ACCOUNT_NAME, ACCOUNT_MONEY_AMOUNT); @InjectMocks - AccountManagerService accountService; + private AccountManagerService accountService; @Mock private AccountRepository accountRepository; diff --git a/src/test/java/app/service/MoneyTransferServiceTest.java b/src/test/java/app/service/MoneyTransferServiceTest.java new file mode 100644 index 0000000..7d432ab --- /dev/null +++ b/src/test/java/app/service/MoneyTransferServiceTest.java @@ -0,0 +1,53 @@ +package app.service; + +import app.domain.Account; +import app.domain.Transaction; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.math.BigDecimal; + +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class MoneyTransferServiceTest { + + private static String PAYER_ACCOUNT_NUMBER = "12345678901234"; + private static String BENEFICIARY_ACCOUNT_NUMBER = "12345678909876"; + private static BigDecimal MONEY_AMOUNT = BigDecimal.TEN; + private static Account PAYER_ACCOUNT = new Account(PAYER_ACCOUNT_NUMBER, "NAME1", new BigDecimal("100.00")); + private static Account BENEFICIARY_ACCOUNT = new Account(BENEFICIARY_ACCOUNT_NUMBER, "NAME2", new BigDecimal("100.00")); + private static Transaction TRANSACTION = new Transaction(PAYER_ACCOUNT_NUMBER, BENEFICIARY_ACCOUNT_NUMBER, MONEY_AMOUNT); + + @InjectMocks + private MoneyTransferService transferService; + + @Mock + private TransactionService transactionService; + + @Mock + private AccountService accountService; + + @Before + public void setUp() throws Exception { + + when(accountService.findByNumber(PAYER_ACCOUNT_NUMBER)).thenReturn(PAYER_ACCOUNT); + when(accountService.findByNumber(BENEFICIARY_ACCOUNT_NUMBER)).thenReturn(BENEFICIARY_ACCOUNT); + } + + @Test + public void testTransferAmount() throws Exception { + + transferService.transferAmount(TRANSACTION); + + verify(accountService,times(1)).updateMoneyAmount(PAYER_ACCOUNT); + verify(accountService,times(1)).updateMoneyAmount(BENEFICIARY_ACCOUNT); + + verify(transactionService, times(1)).save(TRANSACTION); + } + +} diff --git a/src/test/java/app/service/TransactionManagerServiceTest.java b/src/test/java/app/service/TransactionManagerServiceTest.java new file mode 100644 index 0000000..56f6674 --- /dev/null +++ b/src/test/java/app/service/TransactionManagerServiceTest.java @@ -0,0 +1,67 @@ +package app.service; + +import app.domain.Transaction; +import app.repository.TransactionRepository; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.dao.IncorrectResultSizeDataAccessException; + +import java.math.BigDecimal; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class TransactionManagerServiceTest { + + private static final String PAYER_ACCOUNT_NUMBER = "12345678901234"; + private static final String BENEFICIARY_ACCOUNT_NUMBER = "12345678909876"; + private static final BigDecimal MONEY_AMOUNT = new BigDecimal("10.00"); + private static final Transaction TRANSACTION = new Transaction(PAYER_ACCOUNT_NUMBER, BENEFICIARY_ACCOUNT_NUMBER, MONEY_AMOUNT); + + @InjectMocks + private TransactionManagerService transactionService; + + @Mock + private TransactionRepository transactionRepository; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + + @Test + public void testSaveSuccess() throws Exception { + + when(transactionRepository.insert(TRANSACTION)).thenReturn(1); + + transactionService.save(TRANSACTION); + + verify(transactionRepository, times(1)).insert(TRANSACTION); + } + + @Test + public void testSaveFailNoUpdate() throws Exception { + exception.expect(IncorrectResultSizeDataAccessException.class); + exception.expectMessage("Transaction not saved."); + + when(transactionRepository.insert(TRANSACTION)).thenReturn(0); + + transactionService.save(TRANSACTION); + } + + @Test + public void testSaveFailMoreThanOneFieldUpdate() throws Exception { + exception.expect(IncorrectResultSizeDataAccessException.class); + exception.expectMessage("More than once transaction was saved."); + + when(transactionRepository.insert(TRANSACTION)).thenReturn(2); + + transactionService.save(TRANSACTION); + } +} diff --git a/src/test/resources/app/repository/JdbcAccountRepositoryTestIT-context.xml b/src/test/resources/app/repository/JdbcAccountRepositoryIT-context.xml similarity index 100% rename from src/test/resources/app/repository/JdbcAccountRepositoryTestIT-context.xml rename to src/test/resources/app/repository/JdbcAccountRepositoryIT-context.xml diff --git a/src/test/resources/app/repository/JdbcTransactionRepositoryIT-context.xml b/src/test/resources/app/repository/JdbcTransactionRepositoryIT-context.xml new file mode 100644 index 0000000..622b028 --- /dev/null +++ b/src/test/resources/app/repository/JdbcTransactionRepositoryIT-context.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file From 1e75ace325bf93816e6b42f7bd4daf98340a9e43 Mon Sep 17 00:00:00 2001 From: thecodemaker Date: Mon, 31 Mar 2014 21:30:54 +0300 Subject: [PATCH 4/5] Update README.md --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4f67641..fb8e6a2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,10 @@ SpringCore ========== example with xml metadata configuration -//homework - review code, ask questions -//homework - change constructor injection with setter injection -//homework - do validation for AccountMapper class -//homework - do validation for Transaction Validator \ No newline at end of file +homework - review code, ask questions + +homework - change constructor injection with setter injection + +homework - do validation for AccountMapper class + +homework - do validation for Transaction Validator From e8e8f618af7ae231e57aded10dc7e802c2acc6bc Mon Sep 17 00:00:00 2001 From: Bogdan Apetrei Date: Fri, 9 Jan 2015 09:16:06 +0200 Subject: [PATCH 5/5] update readme.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fb8e6a2..213be0b 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,5 @@ homework - change constructor injection with setter injection homework - do validation for AccountMapper class homework - do validation for Transaction Validator + +homework - tbd