diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteActive.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteActive.java index 8710e91c2d..d013120119 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteActive.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteActive.java @@ -25,12 +25,13 @@ import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.account.DeleteActive.Input; +import com.google.gwtorm.server.AtomicUpdate; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import java.io.IOException; -import java.util.Collections; +import java.util.concurrent.atomic.AtomicBoolean; @RequiresCapability(GlobalCapability.MODIFY_ACCOUNT) @Singleton @@ -52,18 +53,34 @@ public class DeleteActive implements RestModifyView { @Override public Response apply(AccountResource rsrc, Input input) throws RestApiException, OrmException, IOException { - Account a = dbProvider.get().accounts().get(rsrc.getUser().getAccountId()); - if (a == null) { - throw new ResourceNotFoundException("account not found"); - } - if (!a.isActive()) { - throw new ResourceConflictException("account not active"); - } if (self.get() == rsrc.getUser()) { throw new ResourceConflictException("cannot deactivate own account"); } - a.setActive(false); - dbProvider.get().accounts().update(Collections.singleton(a)); + + AtomicBoolean alreadyInactive = new AtomicBoolean(false); + Account a = + dbProvider + .get() + .accounts() + .atomicUpdate( + rsrc.getUser().getAccountId(), + new AtomicUpdate() { + @Override + public Account update(Account a) { + if (!a.isActive()) { + alreadyInactive.set(true); + } else { + a.setActive(false); + } + return a; + } + }); + if (a == null) { + throw new ResourceNotFoundException("account not found"); + } + if (alreadyInactive.get()) { + throw new ResourceConflictException("account not active"); + } byIdCache.evict(a.getId()); return Response.none(); } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutActive.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutActive.java index cbddefdc9a..32c5345c72 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutActive.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutActive.java @@ -22,12 +22,14 @@ import com.google.gerrit.extensions.restapi.RestModifyView; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.account.PutActive.Input; +import com.google.gwtorm.server.AtomicUpdate; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import java.io.IOException; import java.util.Collections; +import java.util.concurrent.atomic.AtomicBoolean; @RequiresCapability(GlobalCapability.MODIFY_ACCOUNT) @Singleton @@ -46,16 +48,29 @@ public class PutActive implements RestModifyView { @Override public Response apply(AccountResource rsrc, Input input) throws ResourceNotFoundException, OrmException, IOException { - Account a = dbProvider.get().accounts().get(rsrc.getUser().getAccountId()); + AtomicBoolean alreadyActive = new AtomicBoolean(false); + Account a = + dbProvider + .get() + .accounts() + .atomicUpdate( + rsrc.getUser().getAccountId(), + new AtomicUpdate() { + @Override + public Account update(Account a) { + if (a.isActive()) { + alreadyActive.set(true); + } else { + a.setActive(true); + } + return a; + } + }); if (a == null) { throw new ResourceNotFoundException("account not found"); } - if (a.isActive()) { - return Response.ok(""); - } - a.setActive(true); dbProvider.get().accounts().update(Collections.singleton(a)); byIdCache.evict(a.getId()); - return Response.created(""); + return alreadyActive.get() ? Response.ok("") : Response.created(""); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutName.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutName.java index 726508f8d4..443a549729 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutName.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutName.java @@ -27,12 +27,12 @@ import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.account.PutName.Input; +import com.google.gwtorm.server.AtomicUpdate; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import java.io.IOException; -import java.util.Collections; @Singleton public class PutName implements RestModifyView { @@ -77,12 +77,23 @@ public class PutName implements RestModifyView { throw new MethodNotAllowedException("realm does not allow editing name"); } - Account a = dbProvider.get().accounts().get(user.getAccountId()); + String newName = input.name; + Account a = + dbProvider + .get() + .accounts() + .atomicUpdate( + user.getAccountId(), + new AtomicUpdate() { + @Override + public Account update(Account a) { + a.setFullName(newName); + return a; + } + }); if (a == null) { throw new ResourceNotFoundException("account not found"); } - a.setFullName(input.name); - dbProvider.get().accounts().update(Collections.singleton(a)); byIdCache.evict(a.getId()); return Strings.isNullOrEmpty(a.getFullName()) ? Response.none() diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutPreferred.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutPreferred.java index 3c80d2cd9d..ec60fb31de 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutPreferred.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutPreferred.java @@ -23,12 +23,14 @@ import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.account.PutPreferred.Input; +import com.google.gwtorm.server.AtomicUpdate; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import java.io.IOException; import java.util.Collections; +import java.util.concurrent.atomic.AtomicBoolean; @Singleton public class PutPreferred implements RestModifyView { @@ -56,16 +58,29 @@ public class PutPreferred implements RestModifyView apply(IdentifiedUser user, String email) throws ResourceNotFoundException, OrmException, IOException { - Account a = dbProvider.get().accounts().get(user.getAccountId()); + AtomicBoolean alreadyPreferred = new AtomicBoolean(false); + Account a = + dbProvider + .get() + .accounts() + .atomicUpdate( + user.getAccountId(), + new AtomicUpdate() { + @Override + public Account update(Account a) { + if (email.equals(a.getPreferredEmail())) { + alreadyPreferred.set(true); + } else { + a.setPreferredEmail(email); + } + return a; + } + }); if (a == null) { throw new ResourceNotFoundException("account not found"); } - if (email.equals(a.getPreferredEmail())) { - return Response.ok(""); - } - a.setPreferredEmail(email); dbProvider.get().accounts().update(Collections.singleton(a)); byIdCache.evict(a.getId()); - return Response.created(""); + return alreadyPreferred.get() ? Response.ok("") : Response.created(""); } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutStatus.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutStatus.java index d82689970d..ff541fdae4 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutStatus.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutStatus.java @@ -25,12 +25,12 @@ import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.account.PutStatus.Input; +import com.google.gwtorm.server.AtomicUpdate; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import java.io.IOException; -import java.util.Collections; @Singleton public class PutStatus implements RestModifyView { @@ -70,12 +70,23 @@ public class PutStatus implements RestModifyView { input = new Input(); } - Account a = dbProvider.get().accounts().get(user.getAccountId()); + String newStatus = input.status; + Account a = + dbProvider + .get() + .accounts() + .atomicUpdate( + user.getAccountId(), + new AtomicUpdate() { + @Override + public Account update(Account a) { + a.setStatus(Strings.nullToEmpty(newStatus)); + return a; + } + }); if (a == null) { throw new ResourceNotFoundException("account not found"); } - a.setStatus(Strings.nullToEmpty(input.status)); - dbProvider.get().accounts().update(Collections.singleton(a)); byIdCache.evict(a.getId()); return Strings.isNullOrEmpty(a.getStatus()) ? Response.none() : Response.ok(a.getStatus()); }