diff --git a/account-service/pom.xml b/account-service/pom.xml index 7c42097ca7..9f45cbf1c5 100644 --- a/account-service/pom.xml +++ b/account-service/pom.xml @@ -16,6 +16,12 @@ + + org.projectlombok + lombok + 1.18.20 + provided + org.springframework.cloud spring-cloud-starter-oauth2 diff --git a/account-service/src/main/java/com/piggymetrics/account/application/util/Utility.java b/account-service/src/main/java/com/piggymetrics/account/application/util/Utility.java new file mode 100644 index 0000000000..863a802f6a --- /dev/null +++ b/account-service/src/main/java/com/piggymetrics/account/application/util/Utility.java @@ -0,0 +1,12 @@ +package com.piggymetrics.account.application.util; + +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@UtilityClass +public class Utility { + public static void printErrorMessage(final String errorMessage) { + log.error(errorMessage); + } +} diff --git a/account-service/src/main/java/com/piggymetrics/account/client/AuthServiceClient.java b/account-service/src/main/java/com/piggymetrics/account/client/AuthServiceClient.java index e6a4a4da45..19659ae8aa 100644 --- a/account-service/src/main/java/com/piggymetrics/account/client/AuthServiceClient.java +++ b/account-service/src/main/java/com/piggymetrics/account/client/AuthServiceClient.java @@ -2,14 +2,14 @@ import com.piggymetrics.account.domain.User; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE; @FeignClient(name = "auth-service") public interface AuthServiceClient { - @RequestMapping(method = RequestMethod.POST, value = "/uaa/users", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) + @RequestMapping(method = RequestMethod.POST, value = "/uaa/users", consumes = APPLICATION_JSON_UTF8_VALUE) void createUser(User user); } diff --git a/account-service/src/main/java/com/piggymetrics/account/client/StatisticsServiceClient.java b/account-service/src/main/java/com/piggymetrics/account/client/StatisticsServiceClient.java index 7943fb5844..14dfb66d72 100644 --- a/account-service/src/main/java/com/piggymetrics/account/client/StatisticsServiceClient.java +++ b/account-service/src/main/java/com/piggymetrics/account/client/StatisticsServiceClient.java @@ -2,15 +2,18 @@ import com.piggymetrics.account.domain.Account; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE; + @FeignClient(name = "statistics-service", fallback = StatisticsServiceClientFallback.class) public interface StatisticsServiceClient { - @RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) - void updateStatistics(@PathVariable("accountName") String accountName, Account account); - + @RequestMapping( + method = RequestMethod.PUT, + value = "/statistics/{accountName}", + consumes = APPLICATION_JSON_UTF8_VALUE) + void updateStatistics(@PathVariable("accountName") String accountName, Account account); } diff --git a/account-service/src/main/java/com/piggymetrics/account/client/StatisticsServiceClientFallback.java b/account-service/src/main/java/com/piggymetrics/account/client/StatisticsServiceClientFallback.java index 21c916702d..20eb54db29 100644 --- a/account-service/src/main/java/com/piggymetrics/account/client/StatisticsServiceClientFallback.java +++ b/account-service/src/main/java/com/piggymetrics/account/client/StatisticsServiceClientFallback.java @@ -1,18 +1,17 @@ package com.piggymetrics.account.client; import com.piggymetrics.account.domain.Account; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; /** * @author cdov */ @Component +@Slf4j public class StatisticsServiceClientFallback implements StatisticsServiceClient { - private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsServiceClientFallback.class); @Override public void updateStatistics(String accountName, Account account) { - LOGGER.error("Error during update statistics for account: {}", accountName); + log.error("Error during update statistics for account: {}", accountName); } } diff --git a/account-service/src/main/java/com/piggymetrics/account/controller/AccountController.java b/account-service/src/main/java/com/piggymetrics/account/controller/AccountController.java index 2361a912cb..05d8a26940 100644 --- a/account-service/src/main/java/com/piggymetrics/account/controller/AccountController.java +++ b/account-service/src/main/java/com/piggymetrics/account/controller/AccountController.java @@ -3,37 +3,47 @@ import com.piggymetrics.account.domain.Account; import com.piggymetrics.account.domain.User; import com.piggymetrics.account.service.AccountService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.web.bind.annotation.*; - +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import javax.validation.Valid; import java.security.Principal; @RestController public class AccountController { - @Autowired - private AccountService accountService; - - @PreAuthorize("#oauth2.hasScope('server') or #name.equals('demo')") - @RequestMapping(path = "/{name}", method = RequestMethod.GET) - public Account getAccountByName(@PathVariable String name) { - return accountService.findByName(name); - } - - @RequestMapping(path = "/current", method = RequestMethod.GET) - public Account getCurrentAccount(Principal principal) { - return accountService.findByName(principal.getName()); - } - - @RequestMapping(path = "/current", method = RequestMethod.PUT) - public void saveCurrentAccount(Principal principal, @Valid @RequestBody Account account) { - accountService.saveChanges(principal.getName(), account); - } - - @RequestMapping(path = "/", method = RequestMethod.POST) - public Account createNewAccount(@Valid @RequestBody User user) { - return accountService.create(user); - } + private final AccountService accountService; + + public AccountController(AccountService accountService) { + this.accountService = accountService; + } + + @PreAuthorize("#oauth2.hasScope('server') or #name.equals('demo')") + @GetMapping( + path = "/{name}", + consumes = APPLICATION_JSON_VALUE, + produces = APPLICATION_JSON_VALUE) + public Account getAccountByName(@PathVariable String name) { + return accountService.findByName(name); + } + + @GetMapping(path = "/current") + public Account getCurrentAccount(Principal principal) { + return accountService.findByName(principal.getName()); + } + + @PutMapping(path = "/current") + public void saveCurrentAccount(Principal principal, @Valid @RequestBody Account account) { + accountService.saveChanges(principal.getName(), account); + } + + @PostMapping(path = "/") + public Account createNewAccount(@Valid @RequestBody User user) { + return accountService.create(user); + } } diff --git a/account-service/src/main/java/com/piggymetrics/account/controller/ErrorHandler.java b/account-service/src/main/java/com/piggymetrics/account/controller/ErrorHandler.java deleted file mode 100644 index 02ac059ef7..0000000000 --- a/account-service/src/main/java/com/piggymetrics/account/controller/ErrorHandler.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.piggymetrics.account.controller; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ControllerAdvice -public class ErrorHandler { - - private final Logger log = LoggerFactory.getLogger(getClass()); - - // TODO add MethodArgumentNotValidException handler - // TODO remove such general handler - @ExceptionHandler(IllegalArgumentException.class) - @ResponseStatus(HttpStatus.BAD_REQUEST) - public void processValidationError(IllegalArgumentException e) { - log.info("Returning HTTP 400 Bad Request", e); - } -} diff --git a/account-service/src/main/java/com/piggymetrics/account/domain/Account.java b/account-service/src/main/java/com/piggymetrics/account/domain/Account.java index 59d98acde7..d19dd19f51 100644 --- a/account-service/src/main/java/com/piggymetrics/account/domain/Account.java +++ b/account-service/src/main/java/com/piggymetrics/account/domain/Account.java @@ -1,5 +1,8 @@ package com.piggymetrics.account.domain; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import org.codehaus.jackson.annotate.JsonIgnoreProperties; import org.hibernate.validator.constraints.Length; import org.springframework.data.annotation.Id; @@ -7,12 +10,15 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; +import java.io.Serializable; import java.util.Date; import java.util.List; @Document(collection = "accounts") @JsonIgnoreProperties(ignoreUnknown = true) -public class Account { +@Data +@NoArgsConstructor +public class Account implements Serializable { @Id private String name; @@ -31,52 +37,4 @@ public class Account { @Length(min = 0, max = 20_000) private String note; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Date getLastSeen() { - return lastSeen; - } - - public void setLastSeen(Date lastSeen) { - this.lastSeen = lastSeen; - } - - public List getIncomes() { - return incomes; - } - - public void setIncomes(List incomes) { - this.incomes = incomes; - } - - public List getExpenses() { - return expenses; - } - - public void setExpenses(List expenses) { - this.expenses = expenses; - } - - public Saving getSaving() { - return saving; - } - - public void setSaving(Saving saving) { - this.saving = saving; - } - - public String getNote() { - return note; - } - - public void setNote(String note) { - this.note = note; - } } diff --git a/account-service/src/main/java/com/piggymetrics/account/domain/Item.java b/account-service/src/main/java/com/piggymetrics/account/domain/Item.java index 5670371bd7..f1aecc23a4 100644 --- a/account-service/src/main/java/com/piggymetrics/account/domain/Item.java +++ b/account-service/src/main/java/com/piggymetrics/account/domain/Item.java @@ -1,11 +1,17 @@ package com.piggymetrics.account.domain; + +import lombok.Data; +import lombok.NoArgsConstructor; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotNull; +import java.io.Serializable; import java.math.BigDecimal; -public class Item { +@Data +@NoArgsConstructor +public class Item implements Serializable { @NotNull @Length(min = 1, max = 20) @@ -22,44 +28,4 @@ public class Item { @NotNull private String icon; - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public BigDecimal getAmount() { - return amount; - } - - public void setAmount(BigDecimal amount) { - this.amount = amount; - } - - public Currency getCurrency() { - return currency; - } - - public void setCurrency(Currency currency) { - this.currency = currency; - } - - public TimePeriod getPeriod() { - return period; - } - - public void setPeriod(TimePeriod period) { - this.period = period; - } - - public String getIcon() { - return icon; - } - - public void setIcon(String icon) { - this.icon = icon; - } } diff --git a/account-service/src/main/java/com/piggymetrics/account/domain/Saving.java b/account-service/src/main/java/com/piggymetrics/account/domain/Saving.java index bb9c4907c0..213e902f97 100644 --- a/account-service/src/main/java/com/piggymetrics/account/domain/Saving.java +++ b/account-service/src/main/java/com/piggymetrics/account/domain/Saving.java @@ -1,9 +1,16 @@ package com.piggymetrics.account.domain; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + import javax.validation.constraints.NotNull; +import java.io.Serializable; import java.math.BigDecimal; - -public class Saving { +@Getter +@Setter +@NoArgsConstructor +public class Saving implements Serializable { @NotNull private BigDecimal amount; @@ -19,44 +26,4 @@ public class Saving { @NotNull private Boolean capitalization; - - public BigDecimal getAmount() { - return amount; - } - - public void setAmount(BigDecimal amount) { - this.amount = amount; - } - - public Currency getCurrency() { - return currency; - } - - public void setCurrency(Currency currency) { - this.currency = currency; - } - - public BigDecimal getInterest() { - return interest; - } - - public void setInterest(BigDecimal interest) { - this.interest = interest; - } - - public Boolean getDeposit() { - return deposit; - } - - public void setDeposit(Boolean deposit) { - this.deposit = deposit; - } - - public Boolean getCapitalization() { - return capitalization; - } - - public void setCapitalization(Boolean capitalization) { - this.capitalization = capitalization; - } } diff --git a/account-service/src/main/java/com/piggymetrics/account/domain/User.java b/account-service/src/main/java/com/piggymetrics/account/domain/User.java index 448dc4bf44..edf89d7b76 100644 --- a/account-service/src/main/java/com/piggymetrics/account/domain/User.java +++ b/account-service/src/main/java/com/piggymetrics/account/domain/User.java @@ -1,10 +1,16 @@ package com.piggymetrics.account.domain; +import lombok.Data; +import lombok.NoArgsConstructor; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotNull; +import java.io.Serializable; -public class User { + +@Data +@NoArgsConstructor +public class User implements Serializable { @NotNull @Length(min = 3, max = 20) @@ -13,20 +19,4 @@ public class User { @NotNull @Length(min = 6, max = 40) private String password; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } } diff --git a/account-service/src/main/java/com/piggymetrics/account/exceptions/ErrorHandler.java b/account-service/src/main/java/com/piggymetrics/account/exceptions/ErrorHandler.java new file mode 100644 index 0000000000..1f2b09c46d --- /dev/null +++ b/account-service/src/main/java/com/piggymetrics/account/exceptions/ErrorHandler.java @@ -0,0 +1,21 @@ +package com.piggymetrics.account.exceptions; + +import com.piggymetrics.account.exceptions.personalized.HttpErrorResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import static com.piggymetrics.account.application.util.Utility.printErrorMessage; +import static org.springframework.http.HttpStatus.BAD_REQUEST; + +@ControllerAdvice +@Slf4j +public class ErrorHandler { + + @ExceptionHandler(IllegalArgumentException.class) + @ResponseStatus(BAD_REQUEST) + public HttpErrorResponse processValidationError(IllegalArgumentException e) { + printErrorMessage(e.getMessage()); + return HttpErrorResponse.builder().message(e.getMessage()).httpStatus(BAD_REQUEST).build(); + } +} diff --git a/account-service/src/main/java/com/piggymetrics/account/exceptions/personalized/HttpErrorResponse.java b/account-service/src/main/java/com/piggymetrics/account/exceptions/personalized/HttpErrorResponse.java new file mode 100644 index 0000000000..6c0d856a43 --- /dev/null +++ b/account-service/src/main/java/com/piggymetrics/account/exceptions/personalized/HttpErrorResponse.java @@ -0,0 +1,12 @@ +package com.piggymetrics.account.exceptions.personalized; + +import lombok.Builder; +import org.springframework.http.HttpStatus; + +import java.io.Serializable; +/** @author Jhooomn */ +@Builder +public class HttpErrorResponse implements Serializable { + private HttpStatus httpStatus; + private String message; +} diff --git a/account-service/src/main/java/com/piggymetrics/account/service/AccountServiceImpl.java b/account-service/src/main/java/com/piggymetrics/account/service/AccountServiceImpl.java index 8594bf5713..61e7e1afab 100644 --- a/account-service/src/main/java/com/piggymetrics/account/service/AccountServiceImpl.java +++ b/account-service/src/main/java/com/piggymetrics/account/service/AccountServiceImpl.java @@ -7,9 +7,8 @@ import com.piggymetrics.account.domain.Saving; import com.piggymetrics.account.domain.User; import com.piggymetrics.account.repository.AccountRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.util.Assert; @@ -17,18 +16,28 @@ import java.util.Date; @Service +@Slf4j public class AccountServiceImpl implements AccountService { - private final Logger log = LoggerFactory.getLogger(getClass()); + public static final String COM_PIGGYMETRICS_ACCOUNT_CLIENT_STATISTICS_SERVICE_CLIENT = + "com.piggymetrics.account.client.StatisticsServiceClient"; - @Autowired - private StatisticsServiceClient statisticsClient; + @Qualifier(COM_PIGGYMETRICS_ACCOUNT_CLIENT_STATISTICS_SERVICE_CLIENT) + private final StatisticsServiceClient statisticsClient; - @Autowired - private AuthServiceClient authClient; + private final AuthServiceClient authClient; - @Autowired - private AccountRepository repository; + private final AccountRepository repository; + + public AccountServiceImpl( + @Qualifier(COM_PIGGYMETRICS_ACCOUNT_CLIENT_STATISTICS_SERVICE_CLIENT) + StatisticsServiceClient statisticsClient, + AuthServiceClient authClient, + AccountRepository repository) { + this.statisticsClient = statisticsClient; + this.authClient = authClient; + this.repository = repository; + } /** * {@inheritDoc} diff --git a/account-service/src/main/java/com/piggymetrics/account/service/security/CustomUserInfoTokenServices.java b/account-service/src/main/java/com/piggymetrics/account/service/security/CustomUserInfoTokenServices.java index c50777b393..d385d56be6 100644 --- a/account-service/src/main/java/com/piggymetrics/account/service/security/CustomUserInfoTokenServices.java +++ b/account-service/src/main/java/com/piggymetrics/account/service/security/CustomUserInfoTokenServices.java @@ -1,7 +1,6 @@ package com.piggymetrics.account.service.security; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.security.oauth2.resource.AuthoritiesExtractor; import org.springframework.boot.autoconfigure.security.oauth2.resource.FixedAuthoritiesExtractor; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -17,7 +16,13 @@ import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.LinkedHashSet; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; /** * Extended implementation of {@link org.springframework.boot.autoconfigure.security.oauth2.resource.UserInfoTokenServices} @@ -25,10 +30,9 @@ * By default, it designed to return only user details. This class provides {@link #getRequest(Map)} method, which * returns clientId and scope of calling service. This information used in controller's security checks. */ - +@Slf4j public class CustomUserInfoTokenServices implements ResourceServerTokenServices { - protected final Log logger = LogFactory.getLog(getClass()); private static final String[] PRINCIPAL_KEYS = new String[] { "user", "username", "userid", "user_id", "login", "id", "name" }; @@ -48,24 +52,12 @@ public CustomUserInfoTokenServices(String userInfoEndpointUrl, String clientId) this.clientId = clientId; } - public void setTokenType(String tokenType) { - this.tokenType = tokenType; - } - - public void setRestTemplate(OAuth2RestOperations restTemplate) { - this.restTemplate = restTemplate; - } - - public void setAuthoritiesExtractor(AuthoritiesExtractor authoritiesExtractor) { - this.authoritiesExtractor = authoritiesExtractor; - } - @Override public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException { Map map = getMap(this.userInfoEndpointUrl, accessToken); if (map.containsKey("error")) { - this.logger.debug("userinfo returned error: " + map.get("error")); + log.debug("userinfo returned error: " + map.get("error")); throw new InvalidTokenException(accessToken); } return extractAuthentication(map); @@ -110,7 +102,7 @@ public OAuth2AccessToken readAccessToken(String accessToken) { @SuppressWarnings({ "unchecked" }) private Map getMap(String path, String accessToken) { - this.logger.debug("Getting user info from: " + path); + log.debug("Getting user info from: " + path); try { OAuth2RestOperations restTemplate = this.restTemplate; if (restTemplate == null) { @@ -129,7 +121,7 @@ private Map getMap(String path, String accessToken) { return restTemplate.getForEntity(path, Map.class).getBody(); } catch (Exception ex) { - this.logger.info("Could not fetch user details: " + ex.getClass() + ", " + log.info("Could not fetch user details: " + ex.getClass() + ", " + ex.getMessage()); return Collections.singletonMap("error", "Could not fetch user details"); diff --git a/account-service/src/test/java/com/piggymetrics/account/client/StatisticsServiceClientFallbackTest.java b/account-service/src/test/java/com/piggymetrics/account/client/StatisticsServiceClientFallbackTest.java index 4e21343b01..4e238cf49c 100644 --- a/account-service/src/test/java/com/piggymetrics/account/client/StatisticsServiceClientFallbackTest.java +++ b/account-service/src/test/java/com/piggymetrics/account/client/StatisticsServiceClientFallbackTest.java @@ -6,6 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.rule.OutputCapture; import org.springframework.test.context.junit4.SpringRunner; @@ -20,6 +21,7 @@ "feign.hystrix.enabled=true" }) public class StatisticsServiceClientFallbackTest { + @Qualifier("com.piggymetrics.account.client.StatisticsServiceClient") @Autowired private StatisticsServiceClient statisticsServiceClient;