Merge remote-tracking branch 'remotes/upstream/wip-eventuate-local' into wip-customer

This commit is contained in:
dartpopikyardo
2016-09-01 02:39:47 +03:00
4 changed files with 69 additions and 86 deletions

View File

@@ -4,6 +4,7 @@ import com.mongodb.WriteResult;
import net.chrisrichardson.eventstore.javaexamples.banking.common.accounts.AccountTransactionInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
@@ -38,6 +39,9 @@ public class AccountInfoUpdateService {
Collections.<AccountTransactionInfo>emptyList(),
version));
logger.info("Saved in mongo");
} catch (DuplicateKeyException t) {
logger.warn("When saving ", t);
} catch (Throwable t) {
logger.error("Error during saving: ");
logger.error("Error during saving: ", t);

View File

@@ -94,4 +94,20 @@ public class AccountInfoUpdateServiceTest {
assertEquals(ti, accountInfo.getTransactions().get(0));
}
@Test
public void shouldHandleDuplicateSaveAccountInfo() throws ExecutionException, InterruptedException {
IdGenerator x = new IdGeneratorImpl();
String accountId = x.genId().asString();
String customerId = x.genId().asString();
String version = x.genId().asString();
String title = "Checking account";
BigDecimal initialBalance = new BigDecimal("1345");
String description = "Some account";
accountInfoUpdateService.create(accountId, customerId, title, initialBalance, description, version);
accountInfoUpdateService.create(accountId, customerId, title, initialBalance, description, version);
}
}

View File

@@ -5,6 +5,7 @@ import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.Quer
import net.chrisrichardson.eventstore.javaexamples.banking.common.customers.ToAccountInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import java.util.Collections;
@@ -13,36 +14,38 @@ import java.util.Collections;
*/
public class CustomerInfoUpdateService {
private Logger logger = LoggerFactory.getLogger(getClass());
private Logger logger = LoggerFactory.getLogger(getClass());
private QuerySideCustomerRepository accountInfoRepository;
private QuerySideCustomerRepository querySideCustomerRepository;
public CustomerInfoUpdateService(QuerySideCustomerRepository accountInfoRepository) {
this.accountInfoRepository = accountInfoRepository;
}
public void create(String id, CustomerInfo customerInfo) {
try {
accountInfoRepository.save(new QuerySideCustomer(id,
customerInfo.getName(),
customerInfo.getEmail(),
customerInfo.getSsn(),
customerInfo.getPhoneNumber(),
customerInfo.getAddress(),
Collections.<String, ToAccountInfo>emptyMap()
)
);
logger.info("Saved in mongo");
} catch (Throwable t) {
logger.error("Error during saving: ", t);
throw new RuntimeException(t);
public CustomerInfoUpdateService(QuerySideCustomerRepository querySideCustomerRepository) {
this.querySideCustomerRepository = querySideCustomerRepository;
}
}
public void addToAccount(String id, ToAccountInfo accountInfo) {
QuerySideCustomer customer = accountInfoRepository.findOne(id);
customer.getToAccounts().put(accountInfo.getId(), accountInfo);
accountInfoRepository.save(customer);
}
public void create(String id, CustomerInfo customerInfo) {
try {
querySideCustomerRepository.save(new QuerySideCustomer(id,
customerInfo.getName(),
customerInfo.getEmail(),
customerInfo.getSsn(),
customerInfo.getPhoneNumber(),
customerInfo.getAddress(),
Collections.<String, ToAccountInfo>emptyMap()
)
);
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);
customer.getToAccounts().put(accountInfo.getId(), accountInfo);
querySideCustomerRepository.save(customer);
}
}

View File

@@ -1,7 +1,5 @@
package net.chrisrichardson.eventstorestore.javaexamples.testutil;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Action1;
@@ -13,7 +11,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;
public class TestUtil {
@@ -25,18 +22,6 @@ public class TestUtil {
}
}
public static <T> T awaitSuccessfulRequest(Supplier<ResponseEntity<T>> func, Func1<T, Boolean> predicate) {
try {
return Observable.interval(400, TimeUnit.MILLISECONDS)
.take(50)
.map(x -> func.get())
.filter(re -> re.getStatusCode().equals(HttpStatus.OK) && re.getBody() != null && predicate.call(re.getBody()))
.toBlocking().first().getBody();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static class Tuple2<A, B> {
private A first;
@@ -52,7 +37,7 @@ public class TestUtil {
}
static class Success<T> implements Outcome<T> {
static class Success<T> implements Outcome<T> {
T value;
@@ -69,51 +54,26 @@ public class TestUtil {
}
}
public static <T> void eventually(final Producer<T> producer, final Verifier<T> verifier) {
final int n = 150;
Object possibleException = Observable.timer(0, 200, TimeUnit.MILLISECONDS).flatMap(new Func1<Long, Observable<Outcome<T>>>() {
@Override
public Observable<Outcome<T>> call(Long aLong) {
try {
return fromCompletableFuture(producer.produce()).map(new Func1<T, Outcome<T>>() {
@Override
public Outcome<T> call(T t) {
return new Success<T>(t);
}
});
} catch (Exception e) {
Outcome<T> value = new Failure<T>(e);
return Observable.just(value);
}
public static <T> void eventually(Producer<T> producer, Verifier<T> predicate) {
Throwable laste = null;
for (int i = 0; i < 30 ; i++) {
try {
T x = producer.produce().get(30, TimeUnit.SECONDS);
predicate.verify(x);
return;
} catch (Throwable t) {
laste = t;
}
}).map(new Func1<Outcome<T>, Throwable>() {
@Override
public Throwable call(Outcome<T> t) {
try {
if (t instanceof Success) {
verifier.verify(((Success<T>) t).value);
return null;
} else
return ((Failure<T>) t).t;
} catch (Throwable e) {
return e;
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).take(n).zipWith(Observable.range(0, n), new Func2<Throwable, Integer, Tuple2<Throwable, Integer>>() {
@Override
public Tuple2<Throwable, Integer> call(Throwable e, Integer idx) {
return new Tuple2<Throwable, Integer>(e, idx);
}
}).skipWhile(new Func1<Tuple2<Throwable, Integer>, Boolean>() {
@Override
public Boolean call(Tuple2<Throwable, Integer> tuple2) {
return tuple2.first != null && tuple2.second < n - 1;
}
}).first().toBlocking().getIterator().next().first;
if (possibleException != null)
throw new RuntimeException((Throwable) possibleException);
}
if (laste != null)
throw new RuntimeException("Last exception was", laste);
else
throw new RuntimeException("predicate never satisfied");
}
private static <T> Observable<T> fromCompletableFuture(CompletableFuture<T> future) {