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 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;
@@ -35,6 +36,9 @@ public class AccountInfoUpdateService {
.set("version", version),
AccountInfo.class);
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);

View File

@@ -93,4 +93,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;
@@ -15,15 +16,15 @@ public class CustomerInfoUpdateService {
private Logger logger = LoggerFactory.getLogger(getClass());
private QuerySideCustomerRepository accountInfoRepository;
private QuerySideCustomerRepository querySideCustomerRepository;
public CustomerInfoUpdateService(QuerySideCustomerRepository accountInfoRepository) {
this.accountInfoRepository = accountInfoRepository;
public CustomerInfoUpdateService(QuerySideCustomerRepository querySideCustomerRepository) {
this.querySideCustomerRepository = querySideCustomerRepository;
}
public void create(String id, CustomerInfo customerInfo) {
try {
accountInfoRepository.save(new QuerySideCustomer(id,
querySideCustomerRepository.save(new QuerySideCustomer(id,
customerInfo.getName(),
customerInfo.getEmail(),
customerInfo.getSsn(),
@@ -33,6 +34,8 @@ 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);
@@ -40,9 +43,9 @@ public class CustomerInfoUpdateService {
}
public void addToAccount(String id, ToAccountInfo accountInfo) {
QuerySideCustomer customer = accountInfoRepository.findOne(id);
QuerySideCustomer customer = querySideCustomerRepository.findOne(id);
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) {
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) {