Simplified TestUtil, Fixed MongoDB update issue

This commit is contained in:
Chris Richardson
2016-08-31 13:02:44 -07:00
parent f4e070e7bd
commit 29d42fda9a
4 changed files with 47 additions and 49 deletions

View File

@@ -3,6 +3,7 @@ package net.chrisrichardson.eventstore.javaexamples.banking.backend.queryside.ac
import com.mongodb.WriteResult; import com.mongodb.WriteResult;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update; import org.springframework.data.mongodb.core.query.Update;
@@ -35,6 +36,9 @@ public class AccountInfoUpdateService {
.set("version", version), .set("version", version),
AccountInfo.class); AccountInfo.class);
logger.info("Saved in mongo"); logger.info("Saved in mongo");
} catch (DuplicateKeyException t) {
logger.warn("When saving ", t);
} catch (Throwable t) { } catch (Throwable t) {
logger.error("Error during saving: ", t); logger.error("Error during saving: ", t);
throw new RuntimeException(t); throw new RuntimeException(t);

View File

@@ -93,4 +93,20 @@ public class AccountInfoUpdateServiceTest {
assertEquals(ti, accountInfo.getTransactions().get(0)); 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 net.chrisrichardson.eventstore.javaexamples.banking.common.customers.ToAccountInfo;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import java.util.Collections; import java.util.Collections;
@@ -15,15 +16,15 @@ 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) { public CustomerInfoUpdateService(QuerySideCustomerRepository querySideCustomerRepository) {
this.accountInfoRepository = accountInfoRepository; this.querySideCustomerRepository = querySideCustomerRepository;
} }
public void create(String id, CustomerInfo customerInfo) { public void create(String id, CustomerInfo customerInfo) {
try { try {
accountInfoRepository.save(new QuerySideCustomer(id, querySideCustomerRepository.save(new QuerySideCustomer(id,
customerInfo.getName(), customerInfo.getName(),
customerInfo.getEmail(), customerInfo.getEmail(),
customerInfo.getSsn(), customerInfo.getSsn(),
@@ -33,6 +34,8 @@ public class CustomerInfoUpdateService {
) )
); );
logger.info("Saved in mongo"); logger.info("Saved in mongo");
} catch (DuplicateKeyException t) {
logger.warn("When saving ", t);
} catch (Throwable t) { } catch (Throwable t) {
logger.error("Error during saving: ", t); logger.error("Error during saving: ", t);
throw new RuntimeException(t); throw new RuntimeException(t);
@@ -40,9 +43,9 @@ public class CustomerInfoUpdateService {
} }
public void addToAccount(String id, ToAccountInfo accountInfo) { public void addToAccount(String id, ToAccountInfo accountInfo) {
QuerySideCustomer customer = accountInfoRepository.findOne(id); QuerySideCustomer customer = querySideCustomerRepository.findOne(id);
customer.getToAccounts().put(accountInfo.getId(), accountInfo); customer.getToAccounts().put(accountInfo.getId(), accountInfo);
accountInfoRepository.save(customer); querySideCustomerRepository.save(customer);
} }
} }

View File

@@ -54,51 +54,26 @@ public class TestUtil {
} }
} }
public static <T> void eventually(final Producer<T> producer, final Verifier<T> verifier) { public static <T> void eventually(Producer<T> producer, Verifier<T> predicate) {
final int n = 150; Throwable laste = null;
Object possibleException = Observable.timer(0, 200, TimeUnit.MILLISECONDS).flatMap(new Func1<Long, Observable<Outcome<T>>>() { for (int i = 0; i < 30 ; i++) {
try {
@Override T x = producer.produce().get(30, TimeUnit.SECONDS);
public Observable<Outcome<T>> call(Long aLong) { predicate.verify(x);
try { return;
return fromCompletableFuture(producer.produce()).map(new Func1<T, Outcome<T>>() { } catch (Throwable t) {
@Override laste = t;
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);
}
} }
}).map(new Func1<Outcome<T>, Throwable>() { try {
@Override TimeUnit.SECONDS.sleep(1);
public Throwable call(Outcome<T> t) { } catch (InterruptedException e) {
try { throw new RuntimeException(e);
if (t instanceof Success) {
verifier.verify(((Success<T>) t).value);
return null;
} else
return ((Failure<T>) t).t;
} catch (Throwable e) {
return e;
}
} }
}).take(n).zipWith(Observable.range(0, n), new Func2<Throwable, Integer, Tuple2<Throwable, Integer>>() { }
@Override if (laste != null)
public Tuple2<Throwable, Integer> call(Throwable e, Integer idx) { throw new RuntimeException("Last exception was", laste);
return new Tuple2<Throwable, Integer>(e, idx); else
} throw new RuntimeException("predicate never satisfied");
}).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);
} }
private static <T> Observable<T> fromCompletableFuture(CompletableFuture<T> future) { private static <T> Observable<T> fromCompletableFuture(CompletableFuture<T> future) {