diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..6ea41f9
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..da2f213
--- /dev/null
+++ b/.project
@@ -0,0 +1,28 @@
+
+
+ interview
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.springframework.ide.eclipse.boot.validation.springbootbuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..36c90d8
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2f5cc74
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/.settings/org.springframework.ide.eclipse.prefs b/.settings/org.springframework.ide.eclipse.prefs
new file mode 100644
index 0000000..a12794d
--- /dev/null
+++ b/.settings/org.springframework.ide.eclipse.prefs
@@ -0,0 +1,2 @@
+boot.validation.initialized=true
+eclipse.preferences.version=1
diff --git a/pom.xml b/pom.xml
index a8ffa1a..e0f256d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,162 +1,178 @@
-
- 4.0.0
+
+ 4.0.0
- com.devexperts
- interview
- 0.1.0
+ com.devexperts
+ interview
+ 0.1.0
-
- 1.8
- 3.8.0
- 2.22.2
- 2.1.6.RELEASE
- 5.5.2
- 1.5.2
- 1.12.3
-
+
+ 1.8
+ 3.8.0
+ 2.22.2
+ 2.1.6.RELEASE
+ 5.5.2
+ 1.5.2
+ 1.12.3
+
-
-
-
-
- org.springframework.boot
- spring-boot-starter-parent
- ${spring.boot.version}
- import
- pom
-
-
-
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ ${spring.boot.version}
+ import
+ pom
+
+
+
-
-
-
- org.junit.jupiter
- junit-jupiter-api
- ${junit.version}
- test
-
-
- org.junit.jupiter
- junit-jupiter-engine
- ${junit.version}
- test
-
-
- org.junit.platform
- junit-platform-commons
- ${junit.platform.version}
- test
-
-
- org.junit.platform
- junit-platform-engine
- ${junit.platform.version}
- test
-
-
- org.junit.platform
- junit-platform-launcher
- ${junit.platform.version}
- test
-
-
-
- org.testcontainers
- junit-jupiter
- ${testcontainers.version}
- test
-
-
- org.testcontainers
- postgresql
- ${testcontainers.version}
- test
-
-
-
- org.postgresql
- postgresql
- 42.2.5
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-actuator
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.version}
+ test
+
+
+ org.junit.platform
+ junit-platform-commons
+ ${junit.platform.version}
+ test
+
+
+ org.junit.platform
+ junit-platform-engine
+ ${junit.platform.version}
+ test
+
+
+ org.junit.platform
+ junit-platform-launcher
+ ${junit.platform.version}
+ test
+
+
+
+ org.testcontainers
+ junit-jupiter
+ ${testcontainers.version}
+ test
+
+
+ org.testcontainers
+ postgresql
+ ${testcontainers.version}
+ test
+
+
+
+ org.postgresql
+ postgresql
+ 42.2.5
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-log4j2
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- ${java.version}
- ${java.version}
- true
- UTF8
- false
-
-
-
-
- default-compile
- none
-
-
-
- default-testCompile
- none
-
-
- java-compile
- compile
-
- compile
-
-
-
- java-test-compile
- test-compile
-
- testCompile
-
-
-
-
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${java.version}
+ ${java.version}
+ true
+ UTF8
+ false
+
+
+
+
+ default-compile
+ none
+
+
+
+ default-testCompile
+ none
+
+
+ java-compile
+ compile
+
+ compile
+
+
+
+ java-test-compile
+ test-compile
+
+ testCompile
+
+
+
+
-
- org.apache.maven.plugins
- maven-surefire-plugin
- ${maven-surefire-plugin.version}
-
-
- org.apache.maven.plugins
- maven-failsafe-plugin
- ${maven-surefire-plugin.version}
-
-
-
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ ${maven-surefire-plugin.version}
+
+
+
-
-
- jcenter-snapshots
- jcenter
- https://jcenter.bintray.com/
-
-
+
+
+ jcenter-snapshots
+ jcenter
+ https://jcenter.bintray.com/
+
+
diff --git a/src/main/java/com/devexperts/account/Account.java b/src/main/java/com/devexperts/account/Account.java
index fb2a3af..a803611 100644
--- a/src/main/java/com/devexperts/account/Account.java
+++ b/src/main/java/com/devexperts/account/Account.java
@@ -1,35 +1,36 @@
package com.devexperts.account;
+import javax.validation.constraints.NotBlank;
+
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+
+@ToString
+@EqualsAndHashCode
+@AllArgsConstructor
+@Getter
public class Account {
- private final AccountKey accountKey;
+ private final long ID;
+
+ @NotBlank
private final String firstName;
+
+ @NotBlank
private final String lastName;
+
private Double balance;
-
- public Account(AccountKey accountKey, String firstName, String lastName, Double balance) {
- this.accountKey = accountKey;
- this.firstName = firstName;
- this.lastName = lastName;
- this.balance = balance;
+
+ public void increaseBalance(double balance) {
+ this.balance += balance;
}
-
- public AccountKey getAccountKey() {
- return accountKey;
- }
-
- public String getFirstName() {
- return firstName;
+
+ public void decreaseBalance(double balance) {
+ this.balance -= balance;
}
- public String getLastName() {
- return lastName;
- }
-
- public Double getBalance() {
- return balance;
- }
-
- public void setBalance(Double balance) {
- this.balance = balance;
- }
+ public void setBalance(Double balance) {
+ this.balance = balance;
+ }
}
diff --git a/src/main/java/com/devexperts/account/AccountKey.java b/src/main/java/com/devexperts/account/AccountKey.java
index 1b0a233..e4e9414 100644
--- a/src/main/java/com/devexperts/account/AccountKey.java
+++ b/src/main/java/com/devexperts/account/AccountKey.java
@@ -1,5 +1,9 @@
package com.devexperts.account;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+
/**
* Unique Account identifier
*
@@ -7,6 +11,9 @@
* NOTE: we suspect that later {@link #accountId} is not going to be uniquely identifying an account,
* as we might add human-readable account representation and some clearing codes for partners.
* */
+@Getter
+@ToString
+@EqualsAndHashCode
public class AccountKey {
private final long accountId;
diff --git a/src/main/java/com/devexperts/exception/AccountNotRegisteredException.java b/src/main/java/com/devexperts/exception/AccountNotRegisteredException.java
new file mode 100644
index 0000000..4393a83
--- /dev/null
+++ b/src/main/java/com/devexperts/exception/AccountNotRegisteredException.java
@@ -0,0 +1,11 @@
+package com.devexperts.exception;
+
+public class AccountNotRegisteredException extends RuntimeException {
+
+ private static final long serialVersionUID = -4875504762856220676L;
+
+ public AccountNotRegisteredException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/com/devexperts/exception/NotEnoughAmountException.java b/src/main/java/com/devexperts/exception/NotEnoughAmountException.java
new file mode 100644
index 0000000..5fd6541
--- /dev/null
+++ b/src/main/java/com/devexperts/exception/NotEnoughAmountException.java
@@ -0,0 +1,11 @@
+package com.devexperts.exception;
+
+public class NotEnoughAmountException extends RuntimeException{
+
+ private static final long serialVersionUID = 8014104003977157184L;
+
+ public NotEnoughAmountException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/com/devexperts/exception/ParametersInvalidException.java b/src/main/java/com/devexperts/exception/ParametersInvalidException.java
new file mode 100644
index 0000000..632a578
--- /dev/null
+++ b/src/main/java/com/devexperts/exception/ParametersInvalidException.java
@@ -0,0 +1,11 @@
+package com.devexperts.exception;
+
+public class ParametersInvalidException extends RuntimeException {
+
+ private static final long serialVersionUID = 3414091812324627216L;
+
+ public ParametersInvalidException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/com/devexperts/rest/AccountController.java b/src/main/java/com/devexperts/rest/AccountController.java
index b300282..2b36c50 100644
--- a/src/main/java/com/devexperts/rest/AccountController.java
+++ b/src/main/java/com/devexperts/rest/AccountController.java
@@ -1,14 +1,28 @@
package com.devexperts.rest;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
+import com.devexperts.service.AccountService;
+
@RestController
@RequestMapping("/api")
public class AccountController extends AbstractAccountController {
- public ResponseEntity transfer(long sourceId, long targetId, double amount) {
- return null;
- }
+ @Autowired
+ private AccountService accountService;
+
+ @PutMapping("/options/transfer")
+ public ResponseEntity transfer(@RequestParam("source_id") long sourceId,
+ @RequestParam("target_id") long targetId, @RequestParam("amount") double amount) {
+
+ accountService.transfer(accountService.getAccount(sourceId), accountService.getAccount(sourceId), amount);
+
+ return ResponseEntity.ok().build();
+ }
+
}
diff --git a/src/main/java/com/devexperts/rest/ExceptionHandler.java b/src/main/java/com/devexperts/rest/ExceptionHandler.java
new file mode 100644
index 0000000..0bd15c0
--- /dev/null
+++ b/src/main/java/com/devexperts/rest/ExceptionHandler.java
@@ -0,0 +1,50 @@
+package com.devexperts.rest;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+import com.devexperts.exception.AccountNotRegisteredException;
+import com.devexperts.exception.NotEnoughAmountException;
+import com.devexperts.exception.ParametersInvalidException;
+
+@ControllerAdvice
+public class ExceptionHandler extends ResponseEntityExceptionHandler{
+
+ @org.springframework.web.bind.annotation.ExceptionHandler(AccountNotRegisteredException.class)
+ protected ResponseEntity