- splitted account deletion to 2 separate endpoints: /api/customers/{customerId}/toaccounts/{accountId} and /api/accounts/{accountId}

- simplified the tests
- cleared the code
This commit is contained in:
dartpopikyardo
2016-09-20 03:55:44 +03:00
parent fe925ac14a
commit 0f21a057b0
56 changed files with 228 additions and 374 deletions

View File

@@ -20,7 +20,7 @@ public class Account extends ReflectiveMutableCommandProcessingAggregate<Account
}
public List<Event> process(DeleteAccountCommand cmd) {
return EventUtil.events(new AccountDeletedEvent(new Date()));
return EventUtil.events(new AccountDeletedEvent());
}
public List<Event> process(DebitAccountCommand cmd) {

View File

@@ -19,4 +19,7 @@ public class AccountService {
return accountRepository.save(new OpenAccountCommand(customerId, title, initialBalance, description));
}
public CompletableFuture<EntityWithIdAndVersion<Account>> deleteAccount(String accountId) {
return accountRepository.update(accountId, new DeleteAccountCommand());
}
}

View File

@@ -5,7 +5,7 @@ import io.eventuate.EntityWithIdAndVersion;
import io.eventuate.EventHandlerContext;
import io.eventuate.EventHandlerMethod;
import io.eventuate.EventSubscriber;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerAccountDeleted;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerToAccountDeleted;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.DebitRecordedEvent;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.transactions.MoneyTransferCreatedEvent;
@@ -37,8 +37,8 @@ public class AccountWorkflow {
}
@EventHandlerMethod
public CompletableFuture<EntityWithIdAndVersion<Account>> deleteAccount(EventHandlerContext<CustomerAccountDeleted> ctx) {
CustomerAccountDeleted event = ctx.getEvent();
public CompletableFuture<EntityWithIdAndVersion<Account>> deleteAccount(EventHandlerContext<CustomerToAccountDeleted> ctx) {
CustomerToAccountDeleted event = ctx.getEvent();
String accountId = event.getAccountId();
return ctx.update(Account.class, accountId, new DeleteAccountCommand());

View File

@@ -1,7 +1,4 @@
package net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts;
/**
* Created by popikyardo on 9/14/16.
*/
public class DeleteAccountCommand implements AccountCommand {
}

View File

@@ -3,6 +3,7 @@ package net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.acco
import net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.accounts.AccountService;
import net.chrisrichardson.eventstore.javaexamples.banking.common.accounts.CreateAccountRequest;
import net.chrisrichardson.eventstore.javaexamples.banking.common.accounts.CreateAccountResponse;
import net.chrisrichardson.eventstore.javaexamples.banking.common.accounts.DeleteAccountResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -23,6 +24,12 @@ public class AccountController {
@RequestMapping(method = RequestMethod.POST)
public CompletableFuture<CreateAccountResponse> createAccount(@Validated @RequestBody CreateAccountRequest request) {
return accountService.openAccount(request.getCustomerId(), request.getTitle(), request.getInitialBalance(), request.getDescription())
.thenApply(entityAndEventInfo -> new CreateAccountResponse(entityAndEventInfo.getEntityId()));
.thenApply(entityAndEventInfo -> new CreateAccountResponse(entityAndEventInfo.getEntityId()));
}
@RequestMapping(value = "{accountId}", method = RequestMethod.DELETE)
public CompletableFuture<DeleteAccountResponse> deleteAccount(@PathVariable String accountId) {
return accountService.deleteAccount(accountId)
.thenApply(entityAndEventInfo -> new DeleteAccountResponse(accountId));
}
}

View File

@@ -59,12 +59,10 @@ public class AccountInfoUpdateService {
public void addTransaction(String accountId, AccountTransactionInfo ti) {
System.out.println("Start addTransaction for: "+ti.toString());
mongoTemplate.upsert(new Query(where("id").is(accountId)),
new Update().
set("transactions." + ti.getTransactionId(), ti),
AccountInfo.class);
System.out.println("End addTransaction for: "+ti.toString());
}
@@ -78,11 +76,9 @@ public class AccountInfoUpdateService {
}
public void updateTransactionStatus(String accountId, String transactionId, TransferState status) {
System.out.println("Start updateTransactionStatus "+accountId +" "+transactionId+" "+status);
mongoTemplate.upsert(new Query(where("id").is(accountId)),
new Update().
set("transactions." + transactionId + ".status", status),
AccountInfo.class);
System.out.println("End updateTransactionStatus "+accountId +" "+transactionId+" "+status);
}
}

View File

@@ -5,9 +5,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
import java.util.List;
/**
* Created by popikyardo on 15.01.16.
*/
@ConfigurationProperties(prefix = "api.gateway")
public class ApiGatewayProperties {

View File

@@ -20,9 +20,6 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
import java.util.Collections;
/**
* Created by popikyardo on 15.01.16.
*/
@Configuration
@ComponentScan
@EnableAutoConfiguration

View File

@@ -2,9 +2,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.apigateway;
import org.springframework.http.HttpStatus;
/**
* Created by popikyardo on 07.12.15.
*/
public class RestUtil {
public static boolean isError(HttpStatus status) {

View File

@@ -33,9 +33,6 @@ import java.util.stream.Stream;
import static org.springframework.web.bind.annotation.RequestMethod.*;
/**
* Created by popikyardo on 15.01.16.
*/
@RestController
public class GatewayController {

View File

@@ -10,9 +10,6 @@ import java.io.IOException;
import java.net.URISyntaxException;
import java.util.stream.Collectors;
/**
* Created by popikyardo on 21.01.16.
*/
public class ContentRequestTransformer extends ProxyRequestTransformer {
@Override

View File

@@ -8,9 +8,6 @@ import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Enumeration;
/**
* Created by popikyardo on 21.01.16.
*/
public class HeadersRequestTransformer extends ProxyRequestTransformer {
@Override

View File

@@ -7,9 +7,6 @@ import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URISyntaxException;
/**
* Created by popikyardo on 21.01.16.
*/
public abstract class ProxyRequestTransformer {
protected ProxyRequestTransformer predecessor;

View File

@@ -9,9 +9,6 @@ import javax.servlet.http.HttpServletRequest;
import java.net.URI;
import java.net.URISyntaxException;
/**
* Created by popikyardo on 21.01.16.
*/
public class URLRequestTransformer extends ProxyRequestTransformer {
private ApiGatewayProperties apiGatewayProperties;

View File

@@ -25,4 +25,7 @@ api.gateway.endpoints[5].method=POST
api.gateway.endpoints[5].location=http://${transfers.commandside.service.host}:8080
api.gateway.endpoints[6].path=[/]*api/customers.*
api.gateway.endpoints[6].method=DELETE
api.gateway.endpoints[6].location=http://${customers.commandside.service.host}:8080
api.gateway.endpoints[6].location=http://${customers.commandside.service.host}:8080\
api.gateway.endpoints[7].path=[/]*api/accounts.*
api.gateway.endpoints[7].method=DELETE
api.gateway.endpoints[7].location=http://${accounts.commandside.service.host}:8080

View File

@@ -61,7 +61,7 @@ public class CustomerQuerySideIntegrationTest {
public void verify(QuerySideCustomer querySideCustomer) {
Assert.assertEquals(customerInfo.getName(), querySideCustomer.getName());
Assert.assertEquals(customerInfo.getSsn(), querySideCustomer.getSsn());
Assert.assertEquals(customerInfo.getEmail(), querySideCustomer.getEmail());
Assert.assertEquals(customerInfo.getUserCredentials().getEmail(), querySideCustomer.getEmail());
Assert.assertEquals(customerInfo.getPhoneNumber(), querySideCustomer.getPhoneNumber());
Assert.assertEquals(customerInfo.getAddress(), querySideCustomer.getAddress());

View File

@@ -2,6 +2,7 @@ package net.chrisrichardson.eventstore.javaexamples.banking.commonauth.controlle
import com.fasterxml.jackson.databind.ObjectMapper;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.QuerySideCustomer;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.UserCredentials;
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.CustomerAuthService;
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.model.AuthRequest;
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.model.ErrorResponse;
@@ -23,9 +24,6 @@ import java.io.IOException;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
/**
* Created by popikyardo on 21.09.15.
*/
@RestController
@Validated
@RequestMapping("/api")
@@ -40,7 +38,7 @@ public class AuthController {
private static ObjectMapper objectMapper = new ObjectMapper();
@RequestMapping(value = "/login", method = POST)
public ResponseEntity<QuerySideCustomer> doAuth(@RequestBody @Valid AuthRequest request) throws IOException {
public ResponseEntity<QuerySideCustomer> doAuth(@RequestBody @Valid UserCredentials request) throws IOException {
QuerySideCustomer customer = customerAuthService.findByEmailAndPassword(request.getEmail(), request.getPassword());
Token token = tokenService.allocateToken(objectMapper.writeValueAsString(new User(request.getEmail())));

View File

@@ -3,9 +3,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.commonauth.model;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotBlank;
/**
* Created by popikyardo on 19.10.15.
*/
public class AuthRequest {
@NotBlank

View File

@@ -19,14 +19,10 @@ import org.springframework.security.core.token.KeyBasedPersistenceTokenService;
import org.springframework.security.core.token.TokenService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import java.security.SecureRandom;
/**
* Created by popikyardo on 21.09.15.
*/
@Configuration
@ComponentScan
@EnableWebSecurity
@@ -45,7 +41,6 @@ public class AuthConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//auth.inMemoryAuthentication();
auth.userDetailsService(userDetailsServiceBean());
}
@@ -53,12 +48,8 @@ public class AuthConfiguration extends WebSecurityConfigurerAdapter {
public UserDetailsService userDetailsServiceBean() {
return email -> {
QuerySideCustomer customer = customerAuthService.findByEmail(email);
if (customer != null) {
return new User(email, customer.getPassword(), true, true, true, true,
AuthorityUtils.createAuthorityList("USER"));
} else {
throw new UsernameNotFoundException(String.format("could not find the customer '%s'", email));
}
return new User(email, customer.getPassword(), true, true, true, true,
AuthorityUtils.createAuthorityList("USER"));
};
}

View File

@@ -2,9 +2,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.commonauth;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Created by popikyardo on 21.09.15.
*/
@ConfigurationProperties(locations = "classpath:auth.properties", ignoreUnknownFields = false, prefix = "auth")
public class AuthProperties {
private String serverSecret;

View File

@@ -1,9 +1,7 @@
package net.chrisrichardson.eventstore.javaexamples.banking.commonauth;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.QuerySideCustomer;
import org.springframework.dao.EmptyResultDataAccessException;
import java.util.List;
import org.springframework.dao.support.DataAccessUtils;
/**
* Created by Main on 15.02.2016.
@@ -16,18 +14,10 @@ public class CustomerAuthService {
}
public QuerySideCustomer findByEmail(String email) {
List<QuerySideCustomer> customers = customerAuthRepository.findByEmail(email);
if (customers.isEmpty())
throw new EmptyResultDataAccessException(1);
else
return customers.get(0);
return DataAccessUtils.uniqueResult(customerAuthRepository.findByEmail(email));
}
public QuerySideCustomer findByEmailAndPassword(String email, String password) {
List<QuerySideCustomer> customers = customerAuthRepository.findByEmailAndPassword(email, password);
if (customers.isEmpty())
throw new EmptyResultDataAccessException(1);
else
return customers.get(0);
return DataAccessUtils.uniqueResult(customerAuthRepository.findByEmailAndPassword(email, password));
}
}

View File

@@ -12,9 +12,6 @@ import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* Created by popikyardo on 23.09.15.
*/
@Service
public class TokenAuthenticationService {

View File

@@ -11,9 +11,6 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* Created by popikyardo on 23.09.15.
*/
public class StatelessAuthenticationFilter extends GenericFilterBean {
private final TokenAuthenticationService tokenAuthenticationService;

View File

@@ -10,9 +10,6 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* Created by popikyardo on 23.09.15.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class User implements UserDetails {

View File

@@ -5,9 +5,6 @@ import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
/**
* Created by popikyardo on 23.09.15.
*/
public class UserAuthentication implements Authentication {
private final User user;

View File

@@ -5,21 +5,4 @@ import io.eventuate.Event;
import java.util.Date;
public class AccountDeletedEvent implements Event {
private Date timestamp;
public AccountDeletedEvent() {
}
public AccountDeletedEvent(Date timestamp) {
this.timestamp = timestamp;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
}

View File

@@ -2,9 +2,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.common.custo
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerInfo;
/**
* Created by popikyardo on 02.02.16.
*/
public class CustomerCreatedEvent extends CustomerEvent {
private CustomerInfo customerInfo;

View File

@@ -1,16 +1,13 @@
package net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers;
/**
* Created by popikyardo on 9/14/16.
*/
public class CustomerAccountDeleted extends CustomerEvent {
public class CustomerToAccountDeleted extends CustomerEvent {
private String accountId;
public CustomerAccountDeleted() {
public CustomerToAccountDeleted() {
}
public CustomerAccountDeleted(String accountId) {
public CustomerToAccountDeleted(String accountId) {
this.accountId = accountId;
}

View File

@@ -5,9 +5,6 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
import java.util.Date;
/**
* Created by popikyardo on 9/1/16.
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,
include = JsonTypeInfo.As.PROPERTY,
property = "entryType")

View File

@@ -2,9 +2,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.common.accounts;
import java.util.List;
/**
* Created by popikyardo on 9/1/16.
*/
public class AccountHistoryResponse {
private List<AccountHistoryEntry> transactionsHistory;

View File

@@ -2,9 +2,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.common.accounts;
import java.util.Date;
/**
* Created by popikyardo on 9/1/16.
*/
public class AccountOpenInfo extends AccountHistoryEntry {
private long initialBalance;

View File

@@ -2,9 +2,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.common.accounts;
import java.util.List;
/**
* Created by popikyardo on 9/1/16.
*/
public class GetAccountsResponse {
private List<GetAccountResponse> accounts;

View File

@@ -1,8 +1,5 @@
package net.chrisrichardson.eventstore.javaexamples.banking.common.customers;
/**
* Created by popikyardo on 24.03.16.
*/
public class AddToAccountResponse {
private String version;

View File

@@ -5,9 +5,6 @@ import org.apache.commons.lang.builder.HashCodeBuilder;
import javax.validation.constraints.NotNull;
/**
* Created by popikyardo on 02.02.16.
*/
public class Address {
@NotNull
private String street1;

View File

@@ -1,19 +1,15 @@
package net.chrisrichardson.eventstore.javaexamples.banking.common.customers;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import javax.validation.constraints.NotNull;
/**
* Created by popikyardo on 03.02.16.
*/
public class CustomerInfo {
private Name name;
@NotNull
protected String email;
@NotNull
protected String password;
@JsonUnwrapped
protected UserCredentials userCredentials;
@NotNull
protected String ssn;
protected String phoneNumber;
@@ -22,10 +18,9 @@ public class CustomerInfo {
public CustomerInfo() {
}
public CustomerInfo(Name name, String email, String password, String ssn, String phoneNumber, Address address) {
public CustomerInfo(Name name, UserCredentials userCredentials, String ssn, String phoneNumber, Address address) {
this.name = name;
this.email = email;
this.password = password;
this.userCredentials = userCredentials;
this.ssn = ssn;
this.phoneNumber = phoneNumber;
this.address = address;
@@ -35,12 +30,8 @@ public class CustomerInfo {
return name;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
public UserCredentials getUserCredentials() {
return userCredentials;
}
public String getSsn() {

View File

@@ -3,9 +3,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.common.customers;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* Created by popikyardo on 03.02.16.
*/
public class CustomerResponse {
private String id;

View File

@@ -0,0 +1,49 @@
package net.chrisrichardson.eventstore.javaexamples.banking.common.customers;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.hibernate.validator.constraints.Email;
import javax.validation.constraints.NotNull;
public class UserCredentials {
@NotNull
@Email
private String email;
@NotNull
private String password;
public UserCredentials() {
}
public UserCredentials(String email, String password) {
this.email = email;
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}

View File

@@ -2,9 +2,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerInfo;
/**
* Created by popikyardo on 02.02.16.
*/
public class CreateCustomerCommand implements CustomerCommand {
private CustomerInfo customerInfo;

View File

@@ -3,16 +3,13 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.
import io.eventuate.Event;
import io.eventuate.EventUtil;
import io.eventuate.ReflectiveMutableCommandProcessingAggregate;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerAccountDeleted;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerToAccountDeleted;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerAddedToAccount;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerCreatedEvent;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerInfo;
import java.util.List;
/**
* Created by popikyardo on 02.02.16.
*/
public class Customer extends ReflectiveMutableCommandProcessingAggregate<Customer, CustomerCommand> {
private CustomerInfo customerInfo;
@@ -24,8 +21,8 @@ public class Customer extends ReflectiveMutableCommandProcessingAggregate<Custom
public List<Event> process(AddToAccountCommand cmd) {
return EventUtil.events(new CustomerAddedToAccount(cmd.getToAccountInfo()));
}
public List<Event> process(DeleteAccountCommand cmd) {
return EventUtil.events(new CustomerAccountDeleted(cmd.getAccountId()));
public List<Event> process(DeleteToAccountCommand cmd) {
return EventUtil.events(new CustomerToAccountDeleted(cmd.getAccountId()));
}
public void apply(CustomerCreatedEvent event) {
@@ -34,7 +31,7 @@ public class Customer extends ReflectiveMutableCommandProcessingAggregate<Custom
public void apply(CustomerAddedToAccount event) {
}
public void apply(CustomerAccountDeleted event) {
public void apply(CustomerToAccountDeleted event) {
}
public CustomerInfo getCustomerInfo() {

View File

@@ -24,7 +24,7 @@ public class CustomerService {
return accountRepository.update(customerId, new AddToAccountCommand(toAccountInfo));
}
public CompletableFuture<EntityWithIdAndVersion<Customer>> deleteAccount(String customerId, String accountId) {
return accountRepository.update(customerId, new DeleteAccountCommand(accountId));
public CompletableFuture<EntityWithIdAndVersion<Customer>> deleteToAccount(String customerId, String accountId) {
return accountRepository.update(customerId, new DeleteToAccountCommand(accountId));
}
}

View File

@@ -1,16 +1,13 @@
package net.chrisrichardson.eventstore.javaexamples.banking.backend.commandside.customers;
/**
* Created by popikyardo on 9/14/16.
*/
public class DeleteAccountCommand implements CustomerCommand {
public class DeleteToAccountCommand implements CustomerCommand {
private String accountId;
public DeleteAccountCommand() {
public DeleteToAccountCommand() {
}
public DeleteAccountCommand(String accountId) {
public DeleteToAccountCommand(String accountId) {
this.accountId = accountId;
}

View File

@@ -13,9 +13,6 @@ import org.springframework.web.bind.annotation.*;
import java.util.concurrent.CompletableFuture;
/**
* Created by popikyardo on 03.02.16.
*/
@RestController
@RequestMapping("/api/customers")
public class CustomerController {
@@ -39,9 +36,9 @@ public class CustomerController {
.thenApply(entityAndEventInfo -> new AddToAccountResponse(entityAndEventInfo.getEntityVersion().toString()));
}
@RequestMapping(value = "/{customerId}/accounts/{accountId}", method = RequestMethod.DELETE)
public CompletableFuture<DeleteAccountResponse> deleteAccount(@PathVariable String customerId, @PathVariable String accountId) {
return customerService.deleteAccount(customerId, accountId)
@RequestMapping(value = "/{customerId}/toaccounts/{accountId}", method = RequestMethod.DELETE)
public CompletableFuture<DeleteAccountResponse> deleteToAccount(@PathVariable String customerId, @PathVariable String accountId) {
return customerService.deleteToAccount(customerId, accountId)
.thenApply(entityAndEventInfo -> new DeleteAccountResponse(accountId));
}

View File

@@ -6,9 +6,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Created by popikyardo on 03.02.16.
*/
@Configuration
@Import({CustomerConfiguration.class})
@ComponentScan

View File

@@ -33,8 +33,8 @@ public class CustomerInfoUpdateService {
try {
querySideCustomerRepository.save(new QuerySideCustomer(id,
customerInfo.getName(),
customerInfo.getEmail(),
customerInfo.getPassword(),
customerInfo.getUserCredentials().getEmail(),
customerInfo.getUserCredentials().getPassword(),
customerInfo.getSsn(),
customerInfo.getPhoneNumber(),
customerInfo.getAddress(),
@@ -44,28 +44,27 @@ public class CustomerInfoUpdateService {
logger.info("Saved in mongo");
} catch (DuplicateKeyException t) {
logger.warn("When saving ", t);
} catch (Throwable t) {
logger.error("Error during saving: ", t);
throw new RuntimeException(t);
}
}
public void addToAccount(String id, ToAccountInfo accountInfo) {
QuerySideCustomer customer = querySideCustomerRepository.findOne(id);
if (customer != null) {
customer.getToAccounts().put(accountInfo.getId(), accountInfo);
querySideCustomerRepository.save(customer);
}
mongoTemplate.upsert(new Query(where("id").is(id)),
new Update().
set("toAccounts." + accountInfo.getId(), accountInfo),
QuerySideCustomer.class);
}
public void deleteFromToAccount(String accountId) {
mongoTemplate.find(new Query(where("toAccounts." + accountId).exists(true)),
QuerySideCustomer.class).stream()
.forEach(querySideCustomer ->
mongoTemplate.upsert(new Query(where("id").is(querySideCustomer.getId())),
new Update().
unset("toAccounts." + accountId),
QuerySideCustomer.class)
);
public void deleteToAccountFromAllCustomers(String accountId) {
mongoTemplate.updateMulti(new Query(where("toAccounts." + accountId).exists(true)),
new Update().
unset("toAccounts." + accountId),
QuerySideCustomer.class);
}
public void deleteToAccount(String customerId, String accountId) {
mongoTemplate.upsert(new Query(where("id").is(customerId)),
new Update().
unset("toAccounts." + accountId),
QuerySideCustomer.class);
}
}

View File

@@ -3,7 +3,8 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.cu
import io.eventuate.DispatchedEvent;
import io.eventuate.EventHandlerMethod;
import io.eventuate.EventSubscriber;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerAccountDeleted;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.accounts.AccountDeletedEvent;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerToAccountDeleted;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerAddedToAccount;
import net.chrisrichardson.eventstore.javaexamples.banking.backend.common.customers.CustomerCreatedEvent;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.ToAccountInfo;
@@ -44,10 +45,18 @@ public class CustomerQueryWorkflow {
}
@EventHandlerMethod
public void deleteToAccounts(DispatchedEvent<CustomerAccountDeleted> de) {
CustomerAccountDeleted event = de.getEvent();
public void deleteToAccount(DispatchedEvent<CustomerToAccountDeleted> de) {
String id = de.getEntityId();
CustomerToAccountDeleted event = de.getEvent();
String accountId = event.getAccountId();
customerInfoUpdateService.deleteFromToAccount(accountId);
customerInfoUpdateService.deleteToAccount(id, accountId);
}
@EventHandlerMethod
public void deleteToAccounts(DispatchedEvent<AccountDeletedEvent> de) {
String accountId = de.getEntityId();
customerInfoUpdateService.deleteToAccountFromAllCustomers(accountId);
}
}

View File

@@ -2,7 +2,6 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.cu
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.QuerySideCustomer;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import java.util.List;

View File

@@ -59,7 +59,7 @@ public class CustomerInfoUpdateServiceTest {
assertEquals(customerInfo.getName(), querySideCustomer.getName());
assertEquals(customerInfo.getAddress(), querySideCustomer.getAddress());
assertEquals(customerInfo.getEmail(), querySideCustomer.getEmail());
assertEquals(customerInfo.getUserCredentials().getEmail(), querySideCustomer.getEmail());
assertEquals(customerInfo.getPhoneNumber(), querySideCustomer.getPhoneNumber());
assertEquals(customerInfo.getSsn(), querySideCustomer.getSsn());
}
@@ -82,7 +82,7 @@ public class CustomerInfoUpdateServiceTest {
assertTrue(querySideCustomer.getToAccounts().containsKey(accountId));
assertEquals(toAccountInfo, querySideCustomer.getToAccounts().get(accountId));
customerInfoUpdateService.deleteFromToAccount(accountId);
customerInfoUpdateService.deleteToAccountFromAllCustomers(accountId);
querySideCustomer = customerQueryService.findByCustomerId(customerId).get();
assertFalse(querySideCustomer.getToAccounts().containsKey(accountId));

View File

@@ -48,10 +48,8 @@ public class CustomersQuerySideServiceIntegrationTest {
final CustomerResponse customerResponse = restTemplate.postForEntity(baseUrl("/customers"), customerInfo, CustomerResponse.class).getBody();
final String customerId = customerResponse.getId();
final String email = customerResponse.getCustomerInfo().getEmail();
final String password = customerResponse.getCustomerInfo().getPassword();
customersTestUtils.assertCustomerResponse(customerId, email, password, customerInfo);
customersTestUtils.assertCustomerResponse(customerId, customerInfo);
}
}

View File

@@ -2,7 +2,6 @@ package net.chrisrichardson.eventstore.examples.bank.web;
import net.chrisrichardson.eventstorestore.javaexamples.testutil.AbstractRestAPITest;
import net.chrisrichardson.eventstorestore.javaexamples.testutil.AuthenticatedRestTemplate;
import net.chrisrichardson.eventstorestore.javaexamples.testutil.CustomersTestUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
@@ -43,11 +42,6 @@ public class EndToEndTest extends AbstractRestAPITest {
return customersTestUtils;
}
@Override
public AuthenticatedRestTemplate getAuthenticatedRestTemplate() {
return new AuthenticatedRestTemplate(restTemplate);
}
@Override
public RestTemplate getRestTemplate() {
return restTemplate;

View File

@@ -5,6 +5,6 @@ eventuateMavenRepoUrl=http://mavenrepo.eventuate.io/release
springBootVersion=1.3.5.RELEASE
eventuateClientVersion=0.8.0.RELEASE
eventuateLocalVersion=0.2.0.RELEASE
eventuateClientVersion=0.10.0.RELEASE
eventuateLocalVersion=0.4.0.RELEASE

View File

@@ -3,6 +3,7 @@ package net.chrisrichardson.eventstore.javaexamples.banking.web;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerInfo;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerResponse;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.QuerySideCustomer;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.UserCredentials;
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.model.AuthRequest;
import net.chrisrichardson.eventstorestore.javaexamples.testutil.CustomersTestUtils;
import org.junit.Assert;
@@ -48,27 +49,18 @@ public class BankingAuthTest {
@Test
public void shouldCreateCustomerAndLogin() {
String email = uniqueEmail();
CustomerInfo customerInfo = generateCustomerInfo(email);
CustomerInfo customerInfo = generateCustomerInfo();
final CustomerResponse customerResponse = restTemplate.postForEntity(baseUrl("/customers"), customerInfo, CustomerResponse.class).getBody();
final String customerId = customerResponse.getId();
final String password = customerResponse.getCustomerInfo().getPassword();
Assert.assertNotNull(customerId);
Assert.assertEquals(customerInfo, customerResponse.getCustomerInfo());
customersTestUtils.assertCustomerResponse(customerId, email, password, customerInfo);
customersTestUtils.assertCustomerResponse(customerId, customerInfo);
AuthRequest authRequest = new AuthRequest(email, password);
final QuerySideCustomer loginQuerySideCustomer = restTemplate.postForEntity(baseUrl("/login"), authRequest, QuerySideCustomer.class).getBody();
final QuerySideCustomer loginQuerySideCustomer = restTemplate.postForEntity(baseUrl("/login"), customerInfo.getUserCredentials(), QuerySideCustomer.class).getBody();
customersTestUtils.assertQuerySideCustomerEqualscCustomerInfo(loginQuerySideCustomer, customerResponse.getCustomerInfo());
}
private String uniqueEmail() {
return System.currentTimeMillis() + "@email.com";
}
}

View File

@@ -43,11 +43,6 @@ public class BankingWebIntegrationTest extends AbstractRestAPITest {
@Autowired
RestTemplate restTemplate;
@Override
public AuthenticatedRestTemplate getAuthenticatedRestTemplate() {
return new AuthenticatedRestTemplate(restTemplate);
}
@Override
public RestTemplate getRestTemplate() {
return restTemplate;

View File

@@ -1,38 +1,33 @@
package net.chrisrichardson.eventstorestore.javaexamples.testutil;
import net.chrisrichardson.eventstore.javaexamples.banking.common.accounts.*;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerInfo;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerResponse;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.QuerySideCustomer;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.ToAccountInfo;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.*;
import net.chrisrichardson.eventstore.javaexamples.banking.common.transactions.CreateMoneyTransferRequest;
import net.chrisrichardson.eventstore.javaexamples.banking.common.transactions.CreateMoneyTransferResponse;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static net.chrisrichardson.eventstorestore.javaexamples.testutil.CustomersTestUtils.generateCustomerInfo;
import static net.chrisrichardson.eventstorestore.javaexamples.testutil.CustomersTestUtils.generateToAccountInfo;
import static net.chrisrichardson.eventstorestore.javaexamples.testutil.TestUtil.eventually;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
public abstract class AbstractRestAPITest {
@Test
public void shouldCreateAccountsAndTransferMoney() {
CustomerInfo customerInfo = generateCustomerInfo();
AuthenticatedRestTemplate authenticatedRestTemplate = getAuthenticatedRestTemplate(customerInfo.getUserCredentials());
final CustomerResponse customerResponse = getRestTemplate().postForEntity(baseUrl("/customers"), customerInfo, CustomerResponse.class).getBody();
final String customerId = customerResponse.getId();
final String email = customerResponse.getCustomerInfo().getEmail();
final String password = customerResponse.getCustomerInfo().getPassword();
BigDecimal initialFromAccountBalance = new BigDecimal(500);
BigDecimal initialToAccountBalance = new BigDecimal(100);
@@ -41,54 +36,46 @@ public abstract class AbstractRestAPITest {
BigDecimal finalFromAccountBalance = initialFromAccountBalance.subtract(amountToTransfer);
BigDecimal finalToAccountBalance = initialToAccountBalance.add(amountToTransfer);
final CreateAccountResponse fromAccount = getAuthenticatedRestTemplate().postForEntity(baseUrl("/accounts"),
final CreateAccountResponse fromAccount = authenticatedRestTemplate.postForEntity(baseUrl("/accounts"),
new CreateAccountRequest(customerId, "My 1 Account", "", initialFromAccountBalance),
CreateAccountResponse.class, email, password);
CreateAccountResponse.class);
final String fromAccountId = fromAccount.getAccountId();
CreateAccountResponse toAccount = getAuthenticatedRestTemplate().postForEntity(baseUrl("/accounts"),
CreateAccountResponse toAccount = authenticatedRestTemplate.postForEntity(baseUrl("/accounts"),
new CreateAccountRequest(customerId, "My 2 Account", "", initialToAccountBalance),
CreateAccountResponse.class, email, password);
CreateAccountResponse.class);
String toAccountId = toAccount.getAccountId();
Assert.assertNotNull(fromAccountId);
Assert.assertNotNull(toAccountId);
assertAccountBalance(email, password, fromAccountId, initialFromAccountBalance);
assertAccountBalance(email, password, toAccountId, initialToAccountBalance);
assertAccountBalance(authenticatedRestTemplate, fromAccountId, initialFromAccountBalance);
assertAccountBalance(authenticatedRestTemplate, toAccountId, initialToAccountBalance);
final CreateMoneyTransferResponse moneyTransfer = getAuthenticatedRestTemplate().postForEntity(baseUrl("/transfers"),
final CreateMoneyTransferResponse moneyTransfer = authenticatedRestTemplate.postForEntity(baseUrl("/transfers"),
new CreateMoneyTransferRequest(fromAccountId, toAccountId, amountToTransfer, ""),
CreateMoneyTransferResponse.class, email, password);
CreateMoneyTransferResponse.class);
assertAccountBalance(email, password, fromAccountId, finalFromAccountBalance);
assertAccountBalance(email, password, toAccountId, finalToAccountBalance);
assertAccountBalance(authenticatedRestTemplate, fromAccountId, finalFromAccountBalance);
assertAccountBalance(authenticatedRestTemplate, toAccountId, finalToAccountBalance);
eventually(
new Producer<AccountHistoryResponse>() {
@Override
public CompletableFuture<AccountHistoryResponse> produce() {
return CompletableFuture.completedFuture(getAuthenticatedRestTemplate().getForEntity(baseUrl("/accounts/" + fromAccountId + "/history"),
AccountHistoryResponse.class, email, password));
}
},
new Verifier<AccountHistoryResponse>() {
@Override
public void verify(AccountHistoryResponse accountHistoryResponse) {
Optional<AccountHistoryEntry> first = accountHistoryResponse.getTransactionsHistory().stream().filter( ahe -> ahe.getEntryType() == AccountHistoryEntry.EntryType.transaction && ((AccountTransactionInfo)ahe).getTransactionId().equals(moneyTransfer.getMoneyTransferId())).findFirst();
() -> CompletableFuture.completedFuture(authenticatedRestTemplate.getForEntity(baseUrl("/accounts/" + fromAccountId + "/history"),
AccountHistoryResponse.class)),
accountHistoryResponse -> {
Optional<AccountHistoryEntry> first = accountHistoryResponse.getTransactionsHistory().stream().filter(ahe -> ahe.getEntryType() == AccountHistoryEntry.EntryType.transaction && ((AccountTransactionInfo) ahe).getTransactionId().equals(moneyTransfer.getMoneyTransferId())).findFirst();
assertTrue(first.isPresent());
assertTrue(first.isPresent());
AccountTransactionInfo ti = (AccountTransactionInfo)first.get();
AccountTransactionInfo ti = (AccountTransactionInfo) first.get();
assertEquals(fromAccountId, ti.getFromAccountId());
assertEquals(toAccountId, ti.getToAccountId());
assertEquals(toAccountId, ti.getToAccountId());
assertEquals(fromAccountId, ti.getFromAccountId());
assertEquals(toCents(amountToTransfer).longValue(), ti.getAmount());
}
assertEquals(fromAccountId, ti.getFromAccountId());
assertEquals(toAccountId, ti.getToAccountId());
assertEquals(toAccountId, ti.getToAccountId());
assertEquals(fromAccountId, ti.getFromAccountId());
assertEquals(toCents(amountToTransfer).longValue(), ti.getAmount());
});
}
@@ -96,126 +83,90 @@ public abstract class AbstractRestAPITest {
public void shouldCreateAndDeleteAccountsAndGetByCustomer() {
BigDecimal initialFromAccountBalance = new BigDecimal(500);
CustomerInfo customerInfo = generateCustomerInfo();
AuthenticatedRestTemplate authenticatedRestTemplate = getAuthenticatedRestTemplate(customerInfo.getUserCredentials());
final CustomerResponse customerResponse = getRestTemplate().postForEntity(baseUrl("/customers"), customerInfo, CustomerResponse.class).getBody();
final String customerId = customerResponse.getId();
final String email = customerResponse.getCustomerInfo().getEmail();
final String password = customerResponse.getCustomerInfo().getPassword();
Assert.assertNotNull(customerId);
assertEquals(customerInfo, customerResponse.getCustomerInfo());
getCustomersTestUtils().assertCustomerResponse(customerId, email, password, customerInfo);
getCustomersTestUtils().assertCustomerResponse(customerId, customerInfo);
final CreateAccountResponse account = getAuthenticatedRestTemplate().postForEntity(baseUrl("/accounts"),
final CreateAccountResponse account = authenticatedRestTemplate.postForEntity(baseUrl("/accounts"),
new CreateAccountRequest(customerId, "My 1 Account", "", initialFromAccountBalance),
CreateAccountResponse.class, email, password);
CreateAccountResponse.class);
final String accountId = account.getAccountId();
Assert.assertNotNull(accountId);
assertAccountBalance(email, password, accountId, initialFromAccountBalance);
assertAccountBalance(authenticatedRestTemplate, accountId, initialFromAccountBalance);
eventually(
new Producer<GetAccountsResponse>() {
@Override
public CompletableFuture<GetAccountsResponse> produce() {
return CompletableFuture.completedFuture(getAuthenticatedRestTemplate().getForEntity(baseUrl("/customers/"+customerId+"/accounts"),
GetAccountsResponse.class, email, password));
}
},
new Verifier<GetAccountsResponse>() {
@Override
public void verify(GetAccountsResponse accountResponses) {
assertTrue(accountResponses.getAccounts().stream().filter(acc -> acc.getAccountId().equals(accountId)).findFirst().isPresent());
}
});
() -> CompletableFuture.completedFuture(authenticatedRestTemplate.getForEntity(baseUrl("/customers/" + customerId + "/accounts"),
GetAccountsResponse.class)),
accountResponses -> assertTrue(accountResponses.getAccounts().stream().filter(acc -> acc.getAccountId().equals(accountId)).findFirst().isPresent()));
final DeleteAccountResponse deleteAccountResponse = getAuthenticatedRestTemplate().deleteEntity(baseUrl("/customers/"+customerId+"/accounts/"+accountId),
DeleteAccountResponse.class, email, password);
authenticatedRestTemplate.deleteEntity(baseUrl("/accounts/" + accountId),
DeleteAccountResponse.class);
eventually(
new Producer<GetAccountsResponse>() {
@Override
public CompletableFuture<GetAccountsResponse> produce() {
return CompletableFuture.completedFuture(getAuthenticatedRestTemplate().getForEntity(baseUrl("/customers/"+customerId+"/accounts"),
GetAccountsResponse.class, email, password));
}
},
new Verifier<GetAccountsResponse>() {
@Override
public void verify(GetAccountsResponse accountResponses) {
assertFalse(accountResponses.getAccounts().stream().filter(acc -> acc.getAccountId().equals(accountId)).findFirst().isPresent());
}
});
() -> CompletableFuture.completedFuture(authenticatedRestTemplate.getForEntity(baseUrl("/customers/" + customerId + "/accounts"),
GetAccountsResponse.class)),
accountResponses -> assertFalse(accountResponses.getAccounts().stream().filter(acc -> acc.getAccountId().equals(accountId)).findFirst().isPresent()));
}
@Test
public void shouldCreateCustomersAndAddToAccount() {
CustomerInfo customerInfo = generateCustomerInfo();
AuthenticatedRestTemplate authenticatedRestTemplate = getAuthenticatedRestTemplate(customerInfo.getUserCredentials());
final CustomerResponse customerResponse = getRestTemplate().postForEntity(baseUrl("/customers"), customerInfo, CustomerResponse.class).getBody();
final String customerId = customerResponse.getId();
final String email = customerResponse.getCustomerInfo().getEmail();
final String password = customerResponse.getCustomerInfo().getPassword();
Assert.assertNotNull(customerId);
assertEquals(customerInfo, customerResponse.getCustomerInfo());
getCustomersTestUtils().assertCustomerResponse(customerId, email, password, customerInfo);
getCustomersTestUtils().assertCustomerResponse(customerId, customerInfo);
ToAccountInfo toAccountInfo = generateToAccountInfo();
getAuthenticatedRestTemplate().postForEntity(baseUrl("/customers/" + customerId + "/toaccounts"),
authenticatedRestTemplate.postForEntity(baseUrl("/customers/" + customerId + "/toaccounts"),
toAccountInfo,
null, email, password);
null);
assertToAccountsContains(customerId, email, password, toAccountInfo);
assertToAccountsContains(customerId, authenticatedRestTemplate, toAccountInfo);
}
private BigDecimal toCents(BigDecimal dollarAmount) {
return dollarAmount.multiply(new BigDecimal(100));
}
private void assertAccountBalance(final String email, final String password, final String fromAccountId, final BigDecimal expectedBalanceInDollars) {
private void assertAccountBalance(AuthenticatedRestTemplate authenticatedRestTemplate, final String fromAccountId, final BigDecimal expectedBalanceInDollars) {
final BigDecimal inCents = toCents(expectedBalanceInDollars);
eventually(
new Producer<GetAccountResponse>() {
@Override
public CompletableFuture<GetAccountResponse> produce() {
return CompletableFuture.completedFuture(getAuthenticatedRestTemplate().getForEntity(baseUrl("/accounts/" + fromAccountId),
GetAccountResponse.class, email, password));
}
},
new Verifier<GetAccountResponse>() {
@Override
public void verify(GetAccountResponse accountInfo) {
assertEquals(fromAccountId, accountInfo.getAccountId());
assertEquals(inCents, accountInfo.getBalance());
}
() -> CompletableFuture.completedFuture(authenticatedRestTemplate.getForEntity(baseUrl("/accounts/" + fromAccountId),
GetAccountResponse.class)),
accountInfo -> {
assertEquals(fromAccountId, accountInfo.getAccountId());
assertEquals(inCents, accountInfo.getBalance());
});
}
private void assertToAccountsContains(final String customerId, final String email, final String password, final ToAccountInfo toAccountInfo) {
private void assertToAccountsContains(final String customerId, AuthenticatedRestTemplate authenticatedRestTemplate, final ToAccountInfo toAccountInfo) {
eventually(
new Producer<QuerySideCustomer>() {
@Override
public CompletableFuture<QuerySideCustomer> produce() {
return CompletableFuture.completedFuture(getAuthenticatedRestTemplate().getForEntity(baseUrl("/customers/" + customerId),
QuerySideCustomer.class, email, password));
}
},
new Verifier<QuerySideCustomer>() {
@Override
public void verify(QuerySideCustomer customerResponse) {
assertEquals(customerId, customerResponse.getId());
assertTrue(customerResponse.getToAccounts().values().stream().anyMatch(t -> t.equals(toAccountInfo)));
}
() -> CompletableFuture.completedFuture(authenticatedRestTemplate.getForEntity(baseUrl("/customers/" + customerId),
QuerySideCustomer.class)),
customerResponse -> {
assertEquals(customerId, customerResponse.getId());
assertTrue(customerResponse.getToAccounts().values().stream().anyMatch(t -> t.equals(toAccountInfo)));
});
}
public abstract AuthenticatedRestTemplate getAuthenticatedRestTemplate();
public AuthenticatedRestTemplate getAuthenticatedRestTemplate(UserCredentials userCredentials) {
return new AuthenticatedRestTemplate(getRestTemplate(), userCredentials);
}
public abstract RestTemplate getRestTemplate();

View File

@@ -1,43 +1,43 @@
package net.chrisrichardson.eventstorestore.javaexamples.testutil;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.UserCredentials;
import org.springframework.http.HttpMethod;
import org.springframework.web.client.RestTemplate;
public class AuthenticatedRestTemplate {
private RestTemplate restTemplate;
private UserCredentials userCredentials;
public AuthenticatedRestTemplate(RestTemplate restTemplate) {
public AuthenticatedRestTemplate(RestTemplate restTemplate, UserCredentials userCredentials) {
this.restTemplate = restTemplate;
this.userCredentials = userCredentials;
}
public <T> T getForEntity(String url, Class<T> clazz, String email, String password) {
public <T> T getForEntity(String url, Class<T> clazz) {
return BasicAuthUtils.doBasicAuthenticatedRequest(restTemplate,
url,
HttpMethod.GET,
clazz,
email,
password);
userCredentials);
}
public <T> T postForEntity(String url, Object requestObject, Class<T> clazz, String email, String password) {
public <T> T postForEntity(String url, Object requestObject, Class<T> clazz) {
return BasicAuthUtils.doBasicAuthenticatedRequest(restTemplate,
url,
HttpMethod.POST,
clazz,
requestObject,
email,
password
userCredentials
);
}
public <T> T deleteEntity(String url, Class<T> clazz, String email, String password) {
public <T> T deleteEntity(String url, Class<T> clazz) {
return BasicAuthUtils.doBasicAuthenticatedRequest(restTemplate,
url,
HttpMethod.DELETE,
clazz,
email,
password
userCredentials
);
}
}

View File

@@ -1,5 +1,6 @@
package net.chrisrichardson.eventstorestore.javaexamples.testutil;
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.UserCredentials;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.http.*;
import org.springframework.util.Assert;
@@ -12,10 +13,10 @@ import java.nio.charset.Charset;
*/
public class BasicAuthUtils {
public static HttpHeaders basicAuthHeaders(String username, String password) {
public static HttpHeaders basicAuthHeaders(UserCredentials userCredentials) {
return new HttpHeaders() {
{
String auth = username + ":" + password;
String auth = userCredentials.getEmail() + ":" + userCredentials.getPassword();
byte[] encodedAuth = Base64.encodeBase64(
auth.getBytes(Charset.forName("US-ASCII")));
String authHeader = "Basic " + new String(encodedAuth);
@@ -24,16 +25,16 @@ public class BasicAuthUtils {
};
}
public static <T> T doBasicAuthenticatedRequest(RestTemplate restTemplate, String url, HttpMethod httpMethod, Class<T> responseType, String email, String password) {
return doBasicAuthenticatedRequest(restTemplate, url, httpMethod, responseType, null, email, password);
public static <T> T doBasicAuthenticatedRequest(RestTemplate restTemplate, String url, HttpMethod httpMethod, Class<T> responseType, UserCredentials userCredentials) {
return doBasicAuthenticatedRequest(restTemplate, url, httpMethod, responseType, null, userCredentials);
}
public static <T> T doBasicAuthenticatedRequest(RestTemplate restTemplate, String url, HttpMethod httpMethod, Class<T> responseType, Object requestObject, String email, String password) {
public static <T> T doBasicAuthenticatedRequest(RestTemplate restTemplate, String url, HttpMethod httpMethod, Class<T> responseType, Object requestObject, UserCredentials userCredentials) {
HttpEntity httpEntity;
if (requestObject != null) {
httpEntity = new HttpEntity<>(requestObject, BasicAuthUtils.basicAuthHeaders(email, password));
httpEntity = new HttpEntity<>(requestObject, BasicAuthUtils.basicAuthHeaders(userCredentials));
} else {
httpEntity = new HttpEntity(BasicAuthUtils.basicAuthHeaders(email, password));
httpEntity = new HttpEntity(BasicAuthUtils.basicAuthHeaders(userCredentials));
}
ResponseEntity<T> responseEntity = restTemplate.exchange(url,

View File

@@ -8,9 +8,6 @@ import java.util.concurrent.CompletableFuture;
import static net.chrisrichardson.eventstorestore.javaexamples.testutil.TestUtil.eventually;
/**
* Created by popikyardo on 02.03.16.
*/
public class CustomersTestUtils {
private RestTemplate restTemplate;
@@ -21,41 +18,32 @@ public class CustomersTestUtils {
this.customersBaseUrl = customersBaseUrl;
}
public void assertCustomerResponse(final String customerId, final String email, final String password, final CustomerInfo customerInfo) {
AuthenticatedRestTemplate art = new AuthenticatedRestTemplate(restTemplate);
public void assertCustomerResponse(final String customerId, final CustomerInfo customerInfo) {
AuthenticatedRestTemplate art = new AuthenticatedRestTemplate(restTemplate, customerInfo.getUserCredentials());
eventually(
new Producer<QuerySideCustomer>() {
@Override
public CompletableFuture<QuerySideCustomer> produce() {
return CompletableFuture.completedFuture(art.getForEntity(customersBaseUrl + customerId, QuerySideCustomer.class, email, password));
}
},
new Verifier<QuerySideCustomer>() {
@Override
public void verify(QuerySideCustomer querySideCustomer) {
Assert.assertEquals(customerId, querySideCustomer.getId());
assertQuerySideCustomerEqualscCustomerInfo(querySideCustomer, customerInfo);
}
() -> CompletableFuture.completedFuture(art.getForEntity(customersBaseUrl + customerId, QuerySideCustomer.class)),
querySideCustomer -> {
Assert.assertEquals(customerId, querySideCustomer.getId());
assertQuerySideCustomerEqualscCustomerInfo(querySideCustomer, customerInfo);
});
}
public void assertQuerySideCustomerEqualscCustomerInfo(QuerySideCustomer querySideCustomer, CustomerInfo customerInfo) {
Assert.assertEquals(querySideCustomer.getName(), customerInfo.getName());
Assert.assertEquals(querySideCustomer.getEmail(), customerInfo.getEmail());
Assert.assertEquals(querySideCustomer.getEmail(), customerInfo.getUserCredentials().getEmail());
Assert.assertEquals(querySideCustomer.getPhoneNumber(), customerInfo.getPhoneNumber());
Assert.assertEquals(querySideCustomer.getSsn(), customerInfo.getSsn());
Assert.assertEquals(querySideCustomer.getAddress(), customerInfo.getAddress());
}
public static CustomerInfo generateCustomerInfo() {
return generateCustomerInfo("current@email.com");
return generateCustomerInfo(uniqueEmail());
}
public static CustomerInfo generateCustomerInfo(String email) {
return new CustomerInfo(
new Name("John", "Doe"),
email,
"simple_password",
new UserCredentials(email, "simple_password"),
"000-00-0000",
"1-111-111-1111",
new Address("street 1",
@@ -69,4 +57,8 @@ public class CustomersTestUtils {
public static ToAccountInfo generateToAccountInfo() {
return new ToAccountInfo("11111111-11111111", "New Account", "John Doe", "");
}
private static String uniqueEmail() {
return System.currentTimeMillis() + "@email.com";
}
}