added simultaneous token-based and http basic authentication
This commit is contained in:
@@ -2,8 +2,8 @@ package net.chrisrichardson.eventstore.javaexamples.banking.commonauth;
|
|||||||
|
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.QuerySideCustomer;
|
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.QuerySideCustomer;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.filter.StatelessAuthenticationFilter;
|
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.filter.StatelessAuthenticationFilter;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.model.User;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.security.SecurityProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
@@ -15,8 +15,10 @@ import org.springframework.security.config.annotation.authentication.builders.Au
|
|||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
import org.springframework.security.core.token.KeyBasedPersistenceTokenService;
|
import org.springframework.security.core.token.KeyBasedPersistenceTokenService;
|
||||||
import org.springframework.security.core.token.TokenService;
|
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.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||||
@@ -51,13 +53,16 @@ public class AuthConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public UserDetailsService userDetailsServiceBean() {
|
public UserDetailsService userDetailsServiceBean() {
|
||||||
return email -> {
|
return email -> {
|
||||||
QuerySideCustomer customer = customerAuthService.findByEmail(email);
|
/* QuerySideCustomer customer = customerAuthService.findByEmail(email);
|
||||||
if (customer != null) {
|
if (customer != null) {
|
||||||
return new User(email);
|
return new User(email);
|
||||||
} else {
|
} else {
|
||||||
throw new UsernameNotFoundException(String.format("could not find the customer '%s'", email));
|
throw new UsernameNotFoundException(String.format("could not find the customer '%s'", email));
|
||||||
}
|
}*/
|
||||||
};
|
//authorize everyone with basic authentication
|
||||||
|
return new User(email, "", true, true, true, true,
|
||||||
|
AuthorityUtils.createAuthorityList("USER"));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ public class CustomerAuthService {
|
|||||||
List<QuerySideCustomer> customers = customerAuthRepository.findByEmail(email);
|
List<QuerySideCustomer> customers = customerAuthRepository.findByEmail(email);
|
||||||
if (customers.isEmpty())
|
if (customers.isEmpty())
|
||||||
throw new EmptyResultDataAccessException(1);
|
throw new EmptyResultDataAccessException(1);
|
||||||
else if(customers.size()>1)
|
//TODO: add unique email constraint
|
||||||
throw new IncorrectResultSizeDataAccessException(1, customers.size());
|
/* else if(customers.size()>1)
|
||||||
|
throw new IncorrectResultSizeDataAccessException(1, customers.size());*/
|
||||||
else
|
else
|
||||||
return customers.get(0);
|
return customers.get(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package net.chrisrichardson.eventstore.javaexamples.banking.commonauth.utils;
|
||||||
|
|
||||||
|
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerResponse;
|
||||||
|
import org.apache.tomcat.util.codec.binary.Base64;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Main on 18.02.2016.
|
||||||
|
*/
|
||||||
|
public class BasicAuthUtils {
|
||||||
|
|
||||||
|
public static HttpHeaders basicAuthHeaders(String username) {
|
||||||
|
return new HttpHeaders() {
|
||||||
|
{
|
||||||
|
String auth = username + ":";
|
||||||
|
byte[] encodedAuth = Base64.encodeBase64(
|
||||||
|
auth.getBytes(Charset.forName("US-ASCII")));
|
||||||
|
String authHeader = "Basic " + new String(encodedAuth);
|
||||||
|
set("Authorization", authHeader);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T doRestTemplateRequest(RestTemplate restTemplate, String url, HttpMethod httpMethod, Class<T> responseType) {
|
||||||
|
return doRestTemplateRequest(restTemplate, url, httpMethod, responseType, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T doRestTemplateRequest(RestTemplate restTemplate, String url, HttpMethod httpMethod, Class<T> responseType, Object requestObject) {
|
||||||
|
HttpEntity httpEntity;
|
||||||
|
if(requestObject!=null) {
|
||||||
|
httpEntity = new HttpEntity(requestObject, BasicAuthUtils.basicAuthHeaders("test_user@mail.com"));
|
||||||
|
} else {
|
||||||
|
httpEntity = new HttpEntity(BasicAuthUtils.basicAuthHeaders("test_user@mail.com"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return restTemplate.exchange(url,
|
||||||
|
httpMethod,
|
||||||
|
httpEntity,
|
||||||
|
responseType).getBody();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package net.chrisrichardson.eventstore.javaexamples.banking.common.customers;
|
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.
|
* Created by popikyardo on 03.02.16.
|
||||||
*/
|
*/
|
||||||
@@ -31,4 +34,14 @@ public class CustomerResponse {
|
|||||||
public void setCustomerInfo(CustomerInfo customerInfo) {
|
public void setCustomerInfo(CustomerInfo customerInfo) {
|
||||||
this.customerInfo = customerInfo;
|
this.customerInfo = customerInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return EqualsBuilder.reflectionEquals(this, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return HashCodeBuilder.reflectionHashCode(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ dependencies {
|
|||||||
testCompile project(":accounts-query-side-web")
|
testCompile project(":accounts-query-side-web")
|
||||||
|
|
||||||
testCompile project(":testutil")
|
testCompile project(":testutil")
|
||||||
|
testCompile project(":common-auth")
|
||||||
testCompile "junit:junit:4.11"
|
testCompile "junit:junit:4.11"
|
||||||
testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
|
testCompile "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
|
||||||
testCompile scalaTestDependency
|
testCompile scalaTestDependency
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.Addr
|
|||||||
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerInfo;
|
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.CustomerResponse;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.Name;
|
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.Name;
|
||||||
|
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.utils.BasicAuthUtils;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest;
|
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse;
|
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions.CreateMoneyTransferRequest;
|
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions.CreateMoneyTransferRequest;
|
||||||
@@ -15,6 +16,7 @@ import net.chrisrichardson.eventstorestore.javaexamples.testutil.Producer;
|
|||||||
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Verifier;
|
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Verifier;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
@@ -81,10 +83,21 @@ public class EndToEndTest {
|
|||||||
assertCustomerResponse(customerId, customerInfo);
|
assertCustomerResponse(customerId, customerInfo);
|
||||||
|
|
||||||
|
|
||||||
final CreateAccountResponse fromAccount = restTemplate.postForEntity(accountsCommandSideBaseUrl("/accounts"), new CreateAccountRequest(customerId, "My #1 Account", initialFromAccountBalance), CreateAccountResponse.class).getBody();
|
final CreateAccountResponse fromAccount = BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
|
accountsCommandSideBaseUrl("/accounts"),
|
||||||
|
HttpMethod.POST,
|
||||||
|
CreateAccountResponse.class,
|
||||||
|
new CreateAccountRequest(customerId, "My #1 Account", initialFromAccountBalance)
|
||||||
|
);
|
||||||
final String fromAccountId = fromAccount.getAccountId();
|
final String fromAccountId = fromAccount.getAccountId();
|
||||||
|
|
||||||
CreateAccountResponse toAccount = restTemplate.postForEntity(accountsCommandSideBaseUrl("/accounts"), new CreateAccountRequest(customerId, "My #2 Account", initialToAccountBalance), CreateAccountResponse.class).getBody();
|
CreateAccountResponse toAccount = BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
|
accountsCommandSideBaseUrl("/accounts"),
|
||||||
|
HttpMethod.POST,
|
||||||
|
CreateAccountResponse.class,
|
||||||
|
new CreateAccountRequest(customerId, "My #2 Account", initialToAccountBalance)
|
||||||
|
);
|
||||||
|
|
||||||
String toAccountId = toAccount.getAccountId();
|
String toAccountId = toAccount.getAccountId();
|
||||||
|
|
||||||
Assert.assertNotNull(fromAccountId);
|
Assert.assertNotNull(fromAccountId);
|
||||||
@@ -94,8 +107,12 @@ public class EndToEndTest {
|
|||||||
assertAccountBalance(toAccountId, initialToAccountBalance);
|
assertAccountBalance(toAccountId, initialToAccountBalance);
|
||||||
|
|
||||||
|
|
||||||
final CreateMoneyTransferResponse moneyTransfer = restTemplate.postForEntity(transactionsCommandSideBaseUrl("/transfers"),
|
final CreateMoneyTransferResponse moneyTransfer = BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
new CreateMoneyTransferRequest(fromAccountId, toAccountId, amountToTransfer), CreateMoneyTransferResponse.class).getBody();
|
transactionsCommandSideBaseUrl("/transfers"),
|
||||||
|
HttpMethod.POST,
|
||||||
|
CreateMoneyTransferResponse.class,
|
||||||
|
new CreateMoneyTransferRequest(fromAccountId, toAccountId, amountToTransfer)
|
||||||
|
);
|
||||||
|
|
||||||
assertAccountBalance(fromAccountId, finalFromAccountBalance);
|
assertAccountBalance(fromAccountId, finalFromAccountBalance);
|
||||||
assertAccountBalance(toAccountId, finalToAccountBalance);
|
assertAccountBalance(toAccountId, finalToAccountBalance);
|
||||||
@@ -113,7 +130,10 @@ public class EndToEndTest {
|
|||||||
new Producer<GetAccountResponse>() {
|
new Producer<GetAccountResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public Observable<GetAccountResponse> produce() {
|
public Observable<GetAccountResponse> produce() {
|
||||||
return Observable.just(restTemplate.getForEntity(accountsQuerySideBaseUrl("/accounts/" + fromAccountId), GetAccountResponse.class).getBody());
|
return Observable.just(BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
|
accountsQuerySideBaseUrl("/accounts/" + fromAccountId),
|
||||||
|
HttpMethod.GET,
|
||||||
|
GetAccountResponse.class));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Verifier<GetAccountResponse>() {
|
new Verifier<GetAccountResponse>() {
|
||||||
@@ -130,7 +150,10 @@ public class EndToEndTest {
|
|||||||
new Producer<CustomerResponse>() {
|
new Producer<CustomerResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public Observable<CustomerResponse> produce() {
|
public Observable<CustomerResponse> produce() {
|
||||||
return Observable.just(restTemplate.getForEntity(customersQuerySideBaseUrl("/customers/" + customerId), CustomerResponse.class).getBody());
|
return Observable.just(BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
|
customersQuerySideBaseUrl("/customers/" + customerId),
|
||||||
|
HttpMethod.GET,
|
||||||
|
CustomerResponse.class));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Verifier<CustomerResponse>() {
|
new Verifier<CustomerResponse>() {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.Cust
|
|||||||
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerResponse;
|
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.CustomerResponse;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.Name;
|
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.Name;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.model.AuthRequest;
|
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.model.AuthRequest;
|
||||||
|
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.utils.BasicAuthUtils;
|
||||||
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Producer;
|
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Producer;
|
||||||
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Verifier;
|
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Verifier;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
@@ -14,6 +15,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.test.IntegrationTest;
|
import org.springframework.boot.test.IntegrationTest;
|
||||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.web.WebAppConfiguration;
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
@@ -42,7 +45,8 @@ public class BankingAuthTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCreateCustomerAndLogin() {
|
public void shouldCreateCustomerAndLogin() {
|
||||||
CustomerInfo customerInfo = generateCustomerInfo();
|
String email = uniqueEmail();
|
||||||
|
CustomerInfo customerInfo = generateCustomerInfo(email);
|
||||||
|
|
||||||
final CustomerResponse customerResponse = restTemplate.postForEntity(baseUrl("/customers"), customerInfo, CustomerResponse.class).getBody();
|
final CustomerResponse customerResponse = restTemplate.postForEntity(baseUrl("/customers"), customerInfo, CustomerResponse.class).getBody();
|
||||||
final String customerId = customerResponse.getId();
|
final String customerId = customerResponse.getId();
|
||||||
@@ -52,7 +56,7 @@ public class BankingAuthTest {
|
|||||||
|
|
||||||
assertCustomerResponse(customerId, customerInfo);
|
assertCustomerResponse(customerId, customerInfo);
|
||||||
|
|
||||||
AuthRequest authRequest = new AuthRequest("current@email.com");
|
AuthRequest authRequest = new AuthRequest(email);
|
||||||
|
|
||||||
final CustomerResponse loginCustomerResponse = restTemplate.postForEntity(baseUrl("/login"), authRequest, CustomerResponse.class).getBody();
|
final CustomerResponse loginCustomerResponse = restTemplate.postForEntity(baseUrl("/login"), authRequest, CustomerResponse.class).getBody();
|
||||||
|
|
||||||
@@ -64,7 +68,10 @@ public class BankingAuthTest {
|
|||||||
new Producer<CustomerResponse>() {
|
new Producer<CustomerResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public Observable<CustomerResponse> produce() {
|
public Observable<CustomerResponse> produce() {
|
||||||
return Observable.just(restTemplate.getForEntity(baseUrl("/customers/" + customerId), CustomerResponse.class).getBody());
|
return Observable.just(BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
|
baseUrl("/customers/" + customerId),
|
||||||
|
HttpMethod.GET,
|
||||||
|
CustomerResponse.class));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new Verifier<CustomerResponse>() {
|
new Verifier<CustomerResponse>() {
|
||||||
@@ -76,10 +83,10 @@ public class BankingAuthTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private CustomerInfo generateCustomerInfo() {
|
private CustomerInfo generateCustomerInfo(String email) {
|
||||||
return new CustomerInfo(
|
return new CustomerInfo(
|
||||||
new Name("John", "Doe"),
|
new Name("John", "Doe"),
|
||||||
"current@email.com",
|
email,
|
||||||
"000-00-0000",
|
"000-00-0000",
|
||||||
"1-111-111-1111",
|
"1-111-111-1111",
|
||||||
new Address("street 1",
|
new Address("street 1",
|
||||||
@@ -89,4 +96,8 @@ public class BankingAuthTest {
|
|||||||
"1111111")
|
"1111111")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String uniqueEmail() {
|
||||||
|
return System.currentTimeMillis() + "@email.com";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
package net.chrisrichardson.eventstore.javaexamples.banking.web;
|
package net.chrisrichardson.eventstore.javaexamples.banking.web;
|
||||||
|
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.*;
|
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.*;
|
||||||
|
import net.chrisrichardson.eventstore.javaexamples.banking.commonauth.utils.BasicAuthUtils;
|
||||||
|
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest;
|
||||||
|
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions.CreateMoneyTransferRequest;
|
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions.CreateMoneyTransferRequest;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions.CreateMoneyTransferResponse;
|
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.transactions.CreateMoneyTransferResponse;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.web.queryside.accounts.GetAccountResponse;
|
import net.chrisrichardson.eventstore.javaexamples.banking.web.queryside.accounts.GetAccountResponse;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest;
|
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Producer;
|
||||||
import net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse;
|
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Verifier;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -13,16 +16,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.test.IntegrationTest;
|
import org.springframework.boot.test.IntegrationTest;
|
||||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.context.web.WebAppConfiguration;
|
import org.springframework.test.context.web.WebAppConfiguration;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import rx.Observable;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Producer;
|
|
||||||
import net.chrisrichardson.eventstorestore.javaexamples.testutil.Verifier;
|
|
||||||
import rx.Observable;
|
|
||||||
|
|
||||||
import static net.chrisrichardson.eventstorestore.javaexamples.testutil.TestUtil.eventually;
|
import static net.chrisrichardson.eventstorestore.javaexamples.testutil.TestUtil.eventually;
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@@ -31,114 +33,137 @@ import static net.chrisrichardson.eventstorestore.javaexamples.testutil.TestUtil
|
|||||||
@IntegrationTest({"server.port=0", "management.port=0"})
|
@IntegrationTest({"server.port=0", "management.port=0"})
|
||||||
public class BankingWebIntegrationTest {
|
public class BankingWebIntegrationTest {
|
||||||
|
|
||||||
@Value("${local.server.port}")
|
@Value("${local.server.port}")
|
||||||
private int port;
|
private int port;
|
||||||
|
|
||||||
private String baseUrl(String path) {
|
private String baseUrl(String path) {
|
||||||
return "http://localhost:" + port + "/" + path;
|
return "http://localhost:" + port + "/" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RestTemplate restTemplate;
|
RestTemplate restTemplate;
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCreateAccountsAndTransferMoney() {
|
public void shouldCreateAccountsAndTransferMoney() {
|
||||||
BigDecimal initialFromAccountBalance = new BigDecimal(500);
|
BigDecimal initialFromAccountBalance = new BigDecimal(500);
|
||||||
BigDecimal initialToAccountBalance = new BigDecimal(100);
|
BigDecimal initialToAccountBalance = new BigDecimal(100);
|
||||||
BigDecimal amountToTransfer = new BigDecimal(150);
|
BigDecimal amountToTransfer = new BigDecimal(150);
|
||||||
|
|
||||||
BigDecimal finalFromAccountBalance = initialFromAccountBalance.subtract(amountToTransfer);
|
BigDecimal finalFromAccountBalance = initialFromAccountBalance.subtract(amountToTransfer);
|
||||||
BigDecimal finalToAccountBalance = initialToAccountBalance.add(amountToTransfer);
|
BigDecimal finalToAccountBalance = initialToAccountBalance.add(amountToTransfer);
|
||||||
|
|
||||||
final CreateAccountResponse fromAccount = restTemplate.postForEntity(baseUrl("/accounts"), new CreateAccountRequest("00000000-00000000", "My Account", initialFromAccountBalance), CreateAccountResponse.class).getBody();
|
final CreateAccountResponse fromAccount = BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
final String fromAccountId = fromAccount.getAccountId();
|
baseUrl("/accounts"),
|
||||||
|
HttpMethod.POST,
|
||||||
|
CreateAccountResponse.class,
|
||||||
|
new CreateAccountRequest("00000000-00000000", "My 1 Account", initialFromAccountBalance)
|
||||||
|
);
|
||||||
|
final String fromAccountId = fromAccount.getAccountId();
|
||||||
|
|
||||||
CreateAccountResponse toAccount = restTemplate.postForEntity(baseUrl("/accounts"), new CreateAccountRequest("00000000-00000000", "My Account", initialToAccountBalance), CreateAccountResponse.class).getBody();
|
CreateAccountResponse toAccount = BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
String toAccountId = toAccount.getAccountId();
|
baseUrl("/accounts"),
|
||||||
|
HttpMethod.POST,
|
||||||
|
CreateAccountResponse.class,
|
||||||
|
new CreateAccountRequest("00000000-00000000", "My 2 Account", initialToAccountBalance)
|
||||||
|
);
|
||||||
|
|
||||||
Assert.assertNotNull(fromAccountId);
|
String toAccountId = toAccount.getAccountId();
|
||||||
Assert.assertNotNull(toAccountId);
|
|
||||||
|
|
||||||
assertAccountBalance(fromAccountId, initialFromAccountBalance);
|
Assert.assertNotNull(fromAccountId);
|
||||||
assertAccountBalance(toAccountId, initialToAccountBalance);
|
Assert.assertNotNull(toAccountId);
|
||||||
|
|
||||||
|
assertAccountBalance(fromAccountId, initialFromAccountBalance);
|
||||||
|
assertAccountBalance(toAccountId, initialToAccountBalance);
|
||||||
|
|
||||||
|
|
||||||
final CreateMoneyTransferResponse moneyTransfer = restTemplate.postForEntity(baseUrl("/transfers"),
|
final CreateMoneyTransferResponse moneyTransfer = BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
new CreateMoneyTransferRequest(fromAccountId, toAccountId, amountToTransfer), CreateMoneyTransferResponse.class).getBody();
|
baseUrl("/transfers"),
|
||||||
|
HttpMethod.POST,
|
||||||
|
CreateMoneyTransferResponse.class,
|
||||||
|
new CreateMoneyTransferRequest(fromAccountId, toAccountId, amountToTransfer)
|
||||||
|
);
|
||||||
|
|
||||||
assertAccountBalance(fromAccountId, finalFromAccountBalance);
|
assertAccountBalance(fromAccountId, finalFromAccountBalance);
|
||||||
assertAccountBalance(toAccountId, finalToAccountBalance);
|
assertAccountBalance(toAccountId, finalToAccountBalance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCreateCustomers() {
|
public void shouldCreateCustomers() {
|
||||||
CustomerInfo customerInfo = generateCustomerInfo();
|
CustomerInfo customerInfo = generateCustomerInfo();
|
||||||
|
|
||||||
final CustomerResponse customerResponse = restTemplate.postForEntity(baseUrl("/customers"), customerInfo, CustomerResponse.class).getBody();
|
final CustomerResponse customerResponse = restTemplate.postForEntity(baseUrl("/customers"), customerInfo, CustomerResponse.class).getBody();
|
||||||
final String customerId = customerResponse.getId();
|
final String customerId = customerResponse.getId();
|
||||||
|
|
||||||
Assert.assertNotNull(customerId);
|
Assert.assertNotNull(customerId);
|
||||||
Assert.assertEquals(customerInfo, customerResponse.getCustomerInfo());
|
Assert.assertEquals(customerInfo, customerResponse.getCustomerInfo());
|
||||||
|
|
||||||
assertCustomerResponse(customerId, customerInfo);
|
assertCustomerResponse(customerId, customerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal toCents(BigDecimal dollarAmount) {
|
private BigDecimal toCents(BigDecimal dollarAmount) {
|
||||||
return dollarAmount.multiply(new BigDecimal(100));
|
return dollarAmount.multiply(new BigDecimal(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertAccountBalance(final String fromAccountId, final BigDecimal expectedBalanceInDollars) {
|
private void assertAccountBalance(final String fromAccountId, final BigDecimal expectedBalanceInDollars) {
|
||||||
final BigDecimal inCents = toCents(expectedBalanceInDollars);
|
final BigDecimal inCents = toCents(expectedBalanceInDollars);
|
||||||
eventually(
|
eventually(
|
||||||
new Producer<GetAccountResponse>() {
|
new Producer<GetAccountResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public Observable<GetAccountResponse> produce() {
|
public Observable<GetAccountResponse> produce() {
|
||||||
return Observable.just(restTemplate.getForEntity(baseUrl("/accounts/" + fromAccountId), GetAccountResponse.class).getBody());
|
return Observable.just(BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
}
|
baseUrl("/accounts/" + fromAccountId),
|
||||||
},
|
HttpMethod.GET,
|
||||||
new Verifier<GetAccountResponse>() {
|
GetAccountResponse.class));
|
||||||
@Override
|
}
|
||||||
public void verify(GetAccountResponse accountInfo) {
|
},
|
||||||
Assert.assertEquals(fromAccountId, accountInfo.getAccountId());
|
new Verifier<GetAccountResponse>() {
|
||||||
Assert.assertEquals(inCents, accountInfo.getBalance());
|
@Override
|
||||||
}
|
public void verify(GetAccountResponse accountInfo) {
|
||||||
});
|
Assert.assertEquals(fromAccountId, accountInfo.getAccountId());
|
||||||
}
|
Assert.assertEquals(inCents, accountInfo.getBalance());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void assertCustomerResponse(final String customerId, final CustomerInfo customerInfo) {
|
private void assertCustomerResponse(final String customerId, final CustomerInfo customerInfo) {
|
||||||
eventually(
|
eventually(
|
||||||
new Producer<CustomerResponse>() {
|
new Producer<CustomerResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public Observable<CustomerResponse> produce() {
|
public Observable<CustomerResponse> produce() {
|
||||||
return Observable.just(restTemplate.getForEntity(baseUrl("/customers/" + customerId), CustomerResponse.class).getBody());
|
return Observable.just(BasicAuthUtils.doRestTemplateRequest(restTemplate,
|
||||||
}
|
baseUrl("/customers/" + customerId),
|
||||||
},
|
HttpMethod.GET,
|
||||||
new Verifier<CustomerResponse>() {
|
CustomerResponse.class));
|
||||||
@Override
|
}
|
||||||
public void verify(CustomerResponse customerResponse) {
|
},
|
||||||
Assert.assertEquals(customerId, customerResponse.getId());
|
new Verifier<CustomerResponse>() {
|
||||||
Assert.assertEquals(customerInfo, customerResponse.getCustomerInfo());
|
@Override
|
||||||
}
|
public void verify(CustomerResponse customerResponse) {
|
||||||
});
|
Assert.assertEquals(customerId, customerResponse.getId());
|
||||||
}
|
Assert.assertEquals(customerInfo, customerResponse.getCustomerInfo());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private CustomerInfo generateCustomerInfo() {
|
||||||
|
return new CustomerInfo(
|
||||||
|
new Name("John", "Doe"),
|
||||||
|
"current@email.com",
|
||||||
|
"000-00-0000",
|
||||||
|
"1-111-111-1111",
|
||||||
|
new Address("street 1",
|
||||||
|
"street 2",
|
||||||
|
"City",
|
||||||
|
"State",
|
||||||
|
"1111111")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ToAccountInfo generateToAccountInfo() {
|
||||||
|
return new ToAccountInfo("11111111-11111111", "New Account", "John Doe");
|
||||||
|
}
|
||||||
|
|
||||||
private CustomerInfo generateCustomerInfo() {
|
|
||||||
return new CustomerInfo(
|
|
||||||
new Name("John", "Doe"),
|
|
||||||
"current@email.com",
|
|
||||||
"000-00-0000",
|
|
||||||
"1-111-111-1111",
|
|
||||||
new Address("street 1",
|
|
||||||
"street 2",
|
|
||||||
"City",
|
|
||||||
"State",
|
|
||||||
"1111111")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ToAccountInfo generateToAccountInfo() {
|
|
||||||
return new ToAccountInfo("11111111-11111111", "New Account", "John Doe");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user