@Test void testUpdatePutTimeout() { MongoCollection<Document> collection = mock(MongoCollection.class); FindIterable<Document> findIterable = mock(FindIterable.class); var exception = mock(MongoWriteException.class); var error = mock(WriteError.class); when(findIterable.first()).thenReturn(DOCUMENT); when(exception.getError()).thenReturn(error); when(error.getCategory()).thenReturn(ErrorCategory.EXECUTION_TIMEOUT); doReturn(findIterable).when(collection).find(any(Bson.class)); doThrow(exception).when(collection).updateOne(any(Bson.class), any(Bson.class)); MongoDbUsersDao usersDao = new MongoDbUsersDao(collection, MAPPER); DatabaseException e = assertThrows(DatabaseException.class, () -> usersDao.update(null, USER)); assertEquals(DatabaseError.DATABASE_DOWN, e.getErrorKind()); verify(collection, times(1)).find(any(Bson.class)); verify(collection, times(1)).updateOne(argThat((Bson bson) -> { BsonDocument doc = bson.toBsonDocument( BsonDocument.class, MongoClientSettings.getDefaultCodecRegistry()); return doc.containsKey("version"); }), any(Bson.class)); }
@Override public User update(@Nullable String existingEmail, User user) { Objects.requireNonNull(user); if (existingEmail != null && !existingEmail.equals(user.getEmail().getAddress())) { LOG.info("User to update has new email. The user will be deleted and then reinserted."); return updateEmail(existingEmail, user); } Document existingUser; try { existingUser = mongoCollection.find(eq("_id", user.getEmail().getAddress())).first(); } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to lookup.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The find request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } if (existingUser == null) { LOG.warn("The user {} was not found in the database.", user.getEmail().getAddress()); throw new DatabaseException("The user was not found.", DatabaseError.USER_NOT_FOUND); } long now = Instant.now().toEpochMilli(); String newVersion = UUID.randomUUID().toString(); String document = UsersDao.toJson(mapper, user); try { mongoCollection.updateOne( eq("version", existingUser.getString("version")), Updates.combine( Updates.set("version", newVersion), Updates.set("update_time", String.valueOf(now)), Updates.set("document", document))); } catch (MongoWriteException e) { switch (e.getError().getCategory()) { case EXECUTION_TIMEOUT: LOG.error("The update operation for user {} timed out.", user.getEmail(), e); throw new DatabaseException("The update operation timed out.", DatabaseError.DATABASE_DOWN); case UNCATEGORIZED: default: LOG.error("The update for {} was rejected for an unknown reason.", user.getEmail(), e); throw new DatabaseException("The update request was rejected for an unknown reason.", DatabaseError.REQUEST_REJECTED); } } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to update.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The update request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } return user; }
MongoDbUsersDao implements UsersDao { @Override public User update(@Nullable String existingEmail, User user) { Objects.requireNonNull(user); if (existingEmail != null && !existingEmail.equals(user.getEmail().getAddress())) { LOG.info("User to update has new email. The user will be deleted and then reinserted."); return updateEmail(existingEmail, user); } Document existingUser; try { existingUser = mongoCollection.find(eq("_id", user.getEmail().getAddress())).first(); } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to lookup.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The find request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } if (existingUser == null) { LOG.warn("The user {} was not found in the database.", user.getEmail().getAddress()); throw new DatabaseException("The user was not found.", DatabaseError.USER_NOT_FOUND); } long now = Instant.now().toEpochMilli(); String newVersion = UUID.randomUUID().toString(); String document = UsersDao.toJson(mapper, user); try { mongoCollection.updateOne( eq("version", existingUser.getString("version")), Updates.combine( Updates.set("version", newVersion), Updates.set("update_time", String.valueOf(now)), Updates.set("document", document))); } catch (MongoWriteException e) { switch (e.getError().getCategory()) { case EXECUTION_TIMEOUT: LOG.error("The update operation for user {} timed out.", user.getEmail(), e); throw new DatabaseException("The update operation timed out.", DatabaseError.DATABASE_DOWN); case UNCATEGORIZED: default: LOG.error("The update for {} was rejected for an unknown reason.", user.getEmail(), e); throw new DatabaseException("The update request was rejected for an unknown reason.", DatabaseError.REQUEST_REJECTED); } } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to update.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The update request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } return user; } }
MongoDbUsersDao implements UsersDao { @Override public User update(@Nullable String existingEmail, User user) { Objects.requireNonNull(user); if (existingEmail != null && !existingEmail.equals(user.getEmail().getAddress())) { LOG.info("User to update has new email. The user will be deleted and then reinserted."); return updateEmail(existingEmail, user); } Document existingUser; try { existingUser = mongoCollection.find(eq("_id", user.getEmail().getAddress())).first(); } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to lookup.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The find request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } if (existingUser == null) { LOG.warn("The user {} was not found in the database.", user.getEmail().getAddress()); throw new DatabaseException("The user was not found.", DatabaseError.USER_NOT_FOUND); } long now = Instant.now().toEpochMilli(); String newVersion = UUID.randomUUID().toString(); String document = UsersDao.toJson(mapper, user); try { mongoCollection.updateOne( eq("version", existingUser.getString("version")), Updates.combine( Updates.set("version", newVersion), Updates.set("update_time", String.valueOf(now)), Updates.set("document", document))); } catch (MongoWriteException e) { switch (e.getError().getCategory()) { case EXECUTION_TIMEOUT: LOG.error("The update operation for user {} timed out.", user.getEmail(), e); throw new DatabaseException("The update operation timed out.", DatabaseError.DATABASE_DOWN); case UNCATEGORIZED: default: LOG.error("The update for {} was rejected for an unknown reason.", user.getEmail(), e); throw new DatabaseException("The update request was rejected for an unknown reason.", DatabaseError.REQUEST_REJECTED); } } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to update.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The update request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } return user; } @Inject  MongoDbUsersDao(MongoCollection<Document> mongoCollection, ObjectMapper mapper); }
MongoDbUsersDao implements UsersDao { @Override public User update(@Nullable String existingEmail, User user) { Objects.requireNonNull(user); if (existingEmail != null && !existingEmail.equals(user.getEmail().getAddress())) { LOG.info("User to update has new email. The user will be deleted and then reinserted."); return updateEmail(existingEmail, user); } Document existingUser; try { existingUser = mongoCollection.find(eq("_id", user.getEmail().getAddress())).first(); } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to lookup.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The find request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } if (existingUser == null) { LOG.warn("The user {} was not found in the database.", user.getEmail().getAddress()); throw new DatabaseException("The user was not found.", DatabaseError.USER_NOT_FOUND); } long now = Instant.now().toEpochMilli(); String newVersion = UUID.randomUUID().toString(); String document = UsersDao.toJson(mapper, user); try { mongoCollection.updateOne( eq("version", existingUser.getString("version")), Updates.combine( Updates.set("version", newVersion), Updates.set("update_time", String.valueOf(now)), Updates.set("document", document))); } catch (MongoWriteException e) { switch (e.getError().getCategory()) { case EXECUTION_TIMEOUT: LOG.error("The update operation for user {} timed out.", user.getEmail(), e); throw new DatabaseException("The update operation timed out.", DatabaseError.DATABASE_DOWN); case UNCATEGORIZED: default: LOG.error("The update for {} was rejected for an unknown reason.", user.getEmail(), e); throw new DatabaseException("The update request was rejected for an unknown reason.", DatabaseError.REQUEST_REJECTED); } } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to update.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The update request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } return user; } @Inject  MongoDbUsersDao(MongoCollection<Document> mongoCollection, ObjectMapper mapper); @Override User insert(User user); @Override User findByEmail(String email); @Override User update(@Nullable String existingEmail, User user); @Override User delete(String email); }
MongoDbUsersDao implements UsersDao { @Override public User update(@Nullable String existingEmail, User user) { Objects.requireNonNull(user); if (existingEmail != null && !existingEmail.equals(user.getEmail().getAddress())) { LOG.info("User to update has new email. The user will be deleted and then reinserted."); return updateEmail(existingEmail, user); } Document existingUser; try { existingUser = mongoCollection.find(eq("_id", user.getEmail().getAddress())).first(); } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to lookup.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The find request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } if (existingUser == null) { LOG.warn("The user {} was not found in the database.", user.getEmail().getAddress()); throw new DatabaseException("The user was not found.", DatabaseError.USER_NOT_FOUND); } long now = Instant.now().toEpochMilli(); String newVersion = UUID.randomUUID().toString(); String document = UsersDao.toJson(mapper, user); try { mongoCollection.updateOne( eq("version", existingUser.getString("version")), Updates.combine( Updates.set("version", newVersion), Updates.set("update_time", String.valueOf(now)), Updates.set("document", document))); } catch (MongoWriteException e) { switch (e.getError().getCategory()) { case EXECUTION_TIMEOUT: LOG.error("The update operation for user {} timed out.", user.getEmail(), e); throw new DatabaseException("The update operation timed out.", DatabaseError.DATABASE_DOWN); case UNCATEGORIZED: default: LOG.error("The update for {} was rejected for an unknown reason.", user.getEmail(), e); throw new DatabaseException("The update request was rejected for an unknown reason.", DatabaseError.REQUEST_REJECTED); } } catch (MongoTimeoutException e) { LOG.error("The database is currently unresponsive.", e); throw new DatabaseException("The database is currently unavailable.", DatabaseError.DATABASE_DOWN); } catch (MongoCommandException e) { LOG.error("There was a MongoDB exception (code: {}, reason: {}) when attempting to update.", e.getErrorCode(), e.getErrorMessage(), e); throw new DatabaseException("The update request was rejected for the following reason: " + e.getErrorMessage(), DatabaseError.REQUEST_REJECTED); } return user; } @Inject  MongoDbUsersDao(MongoCollection<Document> mongoCollection, ObjectMapper mapper); @Override User insert(User user); @Override User findByEmail(String email); @Override User update(@Nullable String existingEmail, User user); @Override User delete(String email);  }