use of com.mongodb.TransactionOptions in project mongo-java-driver by mongodb.
the class AbstractUnifiedTest method executeOperations.
private void executeOperations(final BsonArray operations, final boolean throwExceptions) {
FailPoint failPoint = null;
ServerAddress currentPrimary = null;
try {
for (BsonValue cur : operations) {
final BsonDocument operation = cur.asDocument();
String operationName = operation.getString("name").getValue();
BsonValue expectedResult = operation.get("result");
String receiver = operation.getString("object").getValue();
ClientSession clientSession = receiver.startsWith("session") ? sessionsMap.get(receiver) : null;
if (clientSession == null) {
clientSession = operation.getDocument("arguments", new BsonDocument()).containsKey("session") ? sessionsMap.get(operation.getDocument("arguments").getString("session").getValue()) : null;
}
try {
if (operationName.equals("startTransaction")) {
BsonDocument arguments = operation.getDocument("arguments", new BsonDocument());
if (arguments.containsKey("options")) {
TransactionOptions transactionOptions = createTransactionOptions(arguments.getDocument("options"));
nonNullClientSession(clientSession).startTransaction(transactionOptions);
} else {
nonNullClientSession(clientSession).startTransaction();
}
} else if (operationName.equals("commitTransaction")) {
nonNullClientSession(clientSession).commitTransaction();
} else if (operationName.equals("abortTransaction")) {
nonNullClientSession(clientSession).abortTransaction();
} else if (operationName.equals("withTransaction")) {
final BsonDocument arguments = operation.getDocument("arguments", new BsonDocument());
TransactionOptions transactionOptions = null;
if (arguments.containsKey("options")) {
transactionOptions = createTransactionOptions(arguments.getDocument("options"));
}
if (transactionOptions == null) {
nonNullClientSession(clientSession).withTransaction(new TransactionBody<Object>() {
@Override
public Void execute() {
executeOperations(arguments.getDocument("callback").getArray("operations"), true);
return null;
}
});
} else {
nonNullClientSession(clientSession).withTransaction(new TransactionBody<Object>() {
@Override
public Void execute() {
executeOperations(arguments.getDocument("callback").getArray("operations"), true);
return null;
}
}, transactionOptions);
}
} else if (operationName.equals("targetedFailPoint")) {
assertNull(failPoint);
failPoint = new TargetedFailPoint(operation);
failPoint.executeFailPoint();
} else if (operationName.equals("configureFailPoint")) {
assertNull(failPoint);
failPoint = new FailPoint(operation);
failPoint.executeFailPoint();
} else if (operationName.equals("startThread")) {
String target = operation.getDocument("arguments").getString("name").getValue();
executorServiceMap.put(target, Executors.newSingleThreadExecutor());
} else if (operationName.equals("runOnThread")) {
String target = operation.getDocument("arguments").getString("name").getValue();
ExecutorService executorService = executorServiceMap.get(target);
Callable<Exception> callable = createCallable(operation.getDocument("arguments").getDocument("operation"));
futureMap.put(target, executorService.submit(callable));
} else if (operationName.equals("wait")) {
Thread.sleep(operation.getDocument("arguments").getNumber("ms").longValue());
} else if (operationName.equals("waitForThread")) {
String target = operation.getDocument("arguments").getString("name").getValue();
Exception exceptionFromFuture = futureMap.remove(target).get(5, SECONDS);
if (exceptionFromFuture != null) {
throw exceptionFromFuture;
}
} else if (operationName.equals("waitForEvent")) {
String event = operation.getDocument("arguments").getString("event").getValue();
int count = operation.getDocument("arguments").getNumber("count").intValue();
long timeoutMillis = TimeUnit.SECONDS.toMillis(5);
switch(event) {
case "PoolClearedEvent":
connectionPoolListener.waitForEvent(ConnectionPoolClearedEvent.class, count, timeoutMillis, MILLISECONDS);
break;
case "PoolReadyEvent":
connectionPoolListener.waitForEvent(ConnectionPoolReadyEvent.class, count, timeoutMillis, MILLISECONDS);
break;
case "ServerMarkedUnknownEvent":
serverListener.waitForEvent(ServerType.UNKNOWN, count, timeoutMillis, MILLISECONDS);
break;
default:
throw new UnsupportedOperationException("Unsupported event type: " + event);
}
} else if (operationName.equals("assertEventCount")) {
String event = operation.getDocument("arguments").getString("event").getValue();
int expectedCount = operation.getDocument("arguments").getNumber("count").intValue();
int actualCount = -1;
switch(event) {
case "PoolClearedEvent":
actualCount = connectionPoolListener.countEvents(ConnectionPoolClearedEvent.class);
break;
case "PoolReadyEvent":
actualCount = connectionPoolListener.countEvents(ConnectionPoolReadyEvent.class);
break;
case "ServerMarkedUnknownEvent":
actualCount = serverListener.countEvents(ServerType.UNKNOWN);
break;
default:
throw new UnsupportedOperationException("Unsupported event type: " + event);
}
assertEquals(event + " counts not equal", expectedCount, actualCount);
} else if (operationName.equals("recordPrimary")) {
currentPrimary = getCurrentPrimary();
} else if (operationName.equals("waitForPrimaryChange")) {
long startTimeMillis = System.currentTimeMillis();
int timeoutMillis = operation.getDocument("arguments").getNumber("timeoutMS").intValue();
ServerAddress newPrimary = getCurrentPrimary();
while (newPrimary == null || newPrimary.equals(currentPrimary)) {
if (startTimeMillis + timeoutMillis <= System.currentTimeMillis()) {
fail("Timed out waiting for primary change");
}
// noinspection BusyWait
Thread.sleep(50);
newPrimary = getCurrentPrimary();
}
} else if (operationName.equals("runAdminCommand")) {
collectionHelper.runAdminCommand(operation.getDocument("arguments").getDocument("command"));
} else if (operationName.equals("assertSessionPinned")) {
final BsonDocument arguments = operation.getDocument("arguments", new BsonDocument());
assertNotNull(sessionsMap.get(arguments.getString("session").getValue()).getPinnedServerAddress());
} else if (operationName.equals("assertSessionUnpinned")) {
final BsonDocument arguments = operation.getDocument("arguments", new BsonDocument());
assertNull(sessionsMap.get(arguments.getString("session").getValue()).getPinnedServerAddress());
} else if (operationName.equals("assertSessionTransactionState")) {
final BsonDocument arguments = operation.getDocument("arguments", new BsonDocument());
ClientSession session = sessionsMap.get(arguments.getString("session").getValue());
String state = arguments.getString("state").getValue();
if (state.equals("starting") || state.equals("in_progress")) {
assertTrue(session.hasActiveTransaction());
} else {
assertFalse(session.hasActiveTransaction());
}
} else if (operationName.equals("endSession")) {
clientSession.close();
} else if (operation.getBoolean("error", BsonBoolean.FALSE).getValue()) {
try {
helper.getOperationResults(operation, clientSession);
fail("Error expected but none thrown");
} catch (Exception e) {
// Expected failure ignore
}
} else if (operationName.equals("assertDifferentLsidOnLastTwoCommands")) {
List<CommandEvent> events = lastTwoCommandEvents();
String eventsJson = commandListener.getCommandStartedEvents().stream().map(e -> ((CommandStartedEvent) e).getCommand().toJson()).collect(Collectors.joining(", "));
assertNotEquals(eventsJson, ((CommandStartedEvent) events.get(0)).getCommand().getDocument("lsid"), ((CommandStartedEvent) events.get(1)).getCommand().getDocument("lsid"));
} else if (operationName.equals("assertSameLsidOnLastTwoCommands")) {
List<CommandEvent> events = lastTwoCommandEvents();
String eventsJson = commandListener.getCommandStartedEvents().stream().map(e -> ((CommandStartedEvent) e).getCommand().toJson()).collect(Collectors.joining(", "));
assertEquals(eventsJson, ((CommandStartedEvent) events.get(0)).getCommand().getDocument("lsid"), ((CommandStartedEvent) events.get(1)).getCommand().getDocument("lsid"));
} else if (operationName.equals("assertSessionDirty")) {
assertNotNull(clientSession);
assertNotNull(clientSession.getServerSession());
assertTrue(clientSession.getServerSession().isMarkedDirty());
} else if (operationName.equals("assertSessionNotDirty")) {
assertNotNull(clientSession);
assertNotNull(clientSession.getServerSession());
assertFalse(clientSession.getServerSession().isMarkedDirty());
} else if (operationName.equals("assertCollectionExists")) {
assertCollectionExists(operation, true);
} else if (operationName.equals("assertCollectionNotExists")) {
assertCollectionExists(operation, false);
} else if (operationName.equals("assertIndexExists")) {
assertIndexExists(operation, true);
} else if (operationName.equals("assertIndexNotExists")) {
assertIndexExists(operation, false);
} else {
BsonDocument actualOutcome = helper.getOperationResults(operation, clientSession);
if (expectedResult != null) {
BsonValue actualResult = actualOutcome.get("result");
if (actualResult.isDocument()) {
if (((BsonDocument) actualResult).containsKey("recoveryToken")) {
((BsonDocument) actualResult).remove("recoveryToken");
}
}
assertEquals("Expected operation result differs from actual", expectedResult, actualResult);
}
}
assertFalse(String.format("Expected error '%s' but none thrown for operation %s", getErrorContainsField(expectedResult), operationName), hasErrorContainsField(expectedResult));
assertFalse(String.format("Expected error code '%s' but none thrown for operation %s", getErrorCodeNameField(expectedResult), operationName), hasErrorCodeNameField(expectedResult));
} catch (RuntimeException e) {
if (!assertExceptionState(e, expectedResult, operationName) || throwExceptions) {
throw e;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} finally {
if (failPoint != null) {
failPoint.disableFailPoint();
}
}
}
use of com.mongodb.TransactionOptions in project mongo-java-driver by mongodb.
the class TransactionExample method updateEmployeeInfoUsingWithTransactionHelper.
@Test
public void updateEmployeeInfoUsingWithTransactionHelper() {
MongoCollection<Document> employeesCollection = client.getDatabase("hr").getCollection("employees");
MongoCollection<Document> eventsCollection = client.getDatabase("reporting").getCollection("events");
TransactionOptions txnOptions = TransactionOptions.builder().readPreference(ReadPreference.primary()).readConcern(ReadConcern.MAJORITY).writeConcern(WriteConcern.MAJORITY).build();
try (ClientSession clientSession = client.startSession()) {
clientSession.withTransaction(() -> {
employeesCollection.updateOne(clientSession, Filters.eq("employee", 3), Updates.set("status", "Inactive"));
eventsCollection.insertOne(clientSession, new Document("employee", 3).append("status", new Document("new", "Inactive").append("old", "Active")));
return null;
}, txnOptions);
} catch (MongoException e) {
System.out.println("Transaction aborted. Caught exception during transaction.");
throw e;
}
}
use of com.mongodb.TransactionOptions in project mongo-java-driver by mongodb.
the class TransactionExample method updateEmployeeInfo.
private void updateEmployeeInfo() {
MongoCollection<Document> employeesCollection = client.getDatabase("hr").getCollection("employees");
MongoCollection<Document> eventsCollection = client.getDatabase("reporting").getCollection("events");
TransactionOptions txnOptions = TransactionOptions.builder().readPreference(ReadPreference.primary()).readConcern(ReadConcern.MAJORITY).writeConcern(WriteConcern.MAJORITY).build();
try (ClientSession clientSession = client.startSession()) {
clientSession.startTransaction(txnOptions);
employeesCollection.updateOne(clientSession, Filters.eq("employee", 3), Updates.set("status", "Inactive"));
eventsCollection.insertOne(clientSession, new Document("employee", 3).append("status", new Document("new", "Inactive").append("old", "Active")));
commitWithRetry(clientSession);
}
}
Aggregations