package org.sagebionetworks.repo.manager.loginlockout;

import org.sagebionetworks.repo.model.UnsuccessfulLoginLockoutDAO;
import org.sagebionetworks.repo.model.UnsuccessfulLoginLockoutDTO;
import org.sagebionetworks.repo.transactions.MandatoryWriteTransaction;
import org.sagebionetworks.repo.transactions.NewWriteTransaction;
import org.springframework.beans.factory.annotation.Autowired;

public class ExponentialBackoffLoginLockoutStatusImpl implements LoginLockoutStatus {
	@Autowired
	UnsuccessfulLoginLockoutDAO unsuccessfulLoginLockoutDAO;

	//Caller of this should be using a NEW, SEPARATE transaction from their business logic code
	@NewWriteTransaction
	@Override
	public LoginAttemptResultReporter checkIsLockedOut(long userId) {
		// Use database's unix timestamp for expiration check
		// instead of this machine's timestamp to avoid time sync issues across all machines
		UnsuccessfulLoginLockoutDTO lockoutInfo = unsuccessfulLoginLockoutDAO.getUnsuccessfulLoginLockoutInfoIfExist(userId)
				.orElseGet(() -> new UnsuccessfulLoginLockoutDTO(userId));

		final long databaseTime = unsuccessfulLoginLockoutDAO.getDatabaseTimestampMillis();
		if (databaseTime < lockoutInfo.getLockoutExpiration()){
			throw new UnsuccessfulLoginLockoutException(
					databaseTime,
					lockoutInfo.getLockoutExpiration(),
					lockoutInfo.getUnsuccessfulLoginCount());
		}
		return new ExponentialBackoffLoginAttemptReporter(lockoutInfo, unsuccessfulLoginLockoutDAO);
	}

	//Caller should be using this as an additional operation on an existing transaction
	@MandatoryWriteTransaction
	@Override
	public void forceResetLockoutCount(final long userId) {
		unsuccessfulLoginLockoutDAO.createOrUpdateUnsuccessfulLoginLockoutInfo(new UnsuccessfulLoginLockoutDTO(userId)
				.withLockoutExpiration(0)
				.withUnsuccessfulLoginCount(0));
	}
}

@@ -49,16 +49,44 @@
 ckout;%0A%0A
+import java.util.Optional;%0A%0A
 import o
@@ -908,16 +908,25 @@
 hines%0A%09%09
+Optional%3C
 Unsucces
@@ -944,28 +944,29 @@
 ckoutDTO
- lockoutInfo
+%3E dtoOptional
  = unsuc
@@ -1038,29 +1038,149 @@
 rId)
+;
 %0A%09%09
-%09%09.orElseGet(() -%3E
+UnsuccessfulLoginLockoutDTO lockoutInfo;%0A%09%09if (dtoOptional.isPresent()) %7B%0A%09%09%09lockoutInfo = dtoOptional.get();%0A%09%09%7D else %7B%0A%09%09%09lockoutInfo =
  new
@@ -1215,18 +1215,21 @@
 (userId)
-)
 ;
+%0A%09%09%7D
 %0A%0A%09%09fina

Use if/else over functional-style Optional.orElseGet for readability