private BatchMetaDataUpdate saveToBatch( ChangeControl ctl, ChangeUpdate callerUpdate, LabelNormalizer.Result normalized, Timestamp timestamp) throws IOException { Table<Account.Id, String, Optional<Short>> byUser = HashBasedTable.create(); for (PatchSetApproval psa : normalized.updated()) { byUser.put(psa.getAccountId(), psa.getLabel(), Optional.of(psa.getValue())); } for (PatchSetApproval psa : normalized.deleted()) { byUser.put(psa.getAccountId(), psa.getLabel(), Optional.<Short>absent()); } BatchMetaDataUpdate batch = callerUpdate.openUpdate(); for (Account.Id accountId : byUser.rowKeySet()) { if (!accountId.equals(callerUpdate.getUser().getAccountId())) { ChangeUpdate update = updateFactory.create(ctl.forUser(identifiedUserFactory.create(accountId)), timestamp); update.setSubject("Finalize approvals at submit"); putApprovals(update, byUser.row(accountId)); CommitBuilder commit = new CommitBuilder(); commit.setCommitter(new PersonIdent(serverIdent, timestamp)); batch.write(update, commit); } } putApprovals(callerUpdate, byUser.row(callerUpdate.getUser().getAccountId())); return batch; }
private void setApproval(ChangeData cd, IdentifiedUser user) throws OrmException, IOException { Timestamp timestamp = TimeUtil.nowTs(); ChangeControl control = cd.changeControl(); PatchSet.Id psId = cd.currentPatchSet().getId(); PatchSet.Id psIdNewRev = commits.get(cd.change().getId()).change().currentPatchSetId(); logDebug("Add approval for " + cd + " from user " + user); ChangeUpdate update = updateFactory.create(control, timestamp); update.putReviewer(user.getAccountId(), REVIEWER); List<SubmitRecord> record = records.get(cd.change().getId()); if (record != null) { update.merge(record); } db.changes().beginTransaction(cd.change().getId()); try { BatchMetaDataUpdate batch = approve(control, psId, user, update, timestamp); batch.write(update, new CommitBuilder()); // If the submit strategy created a new revision (rebase, cherry-pick) // approve that as well if (!psIdNewRev.equals(psId)) { update.setPatchSetId(psId); update.commit(); // Create a new ChangeUpdate instance because we need to store meta data // on another patch set (psIdNewRev). update = updateFactory.create(control, timestamp); batch = approve(control, psIdNewRev, user, update, timestamp); // Write update commit after all normalized label commits. batch.write(update, new CommitBuilder()); } db.commit(); } finally { db.rollback(); } update.commit(); indexer.index(db, cd.change()); }
@Override protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException { Repository git; try { git = mgr.openRepository(allProjects); } catch (IOException e) { throw new OrmException(e); } try { MetaDataUpdate md = new MetaDataUpdate(GitReferenceUpdated.DISABLED, allProjects, git); ProjectConfig config = ProjectConfig.read(md); Map<Integer, ContributorAgreement> agreements = getAgreementToAdd(db, config); if (agreements.isEmpty()) { return; } ui.message("Moved contributor agreements to project.config"); // Create the auto verify groups. List<AccountGroup.UUID> adminGroupUUIDs = getAdministrateServerGroups(db, config); for (ContributorAgreement agreement : agreements.values()) { if (agreement.getAutoVerify() != null) { getOrCreateGroupForIndividuals(db, config, adminGroupUUIDs, agreement); } } // Scan AccountAgreement long minTime = addAccountAgreements(db, config, adminGroupUUIDs, agreements); ProjectConfig base = ProjectConfig.read(md, null); for (ContributorAgreement agreement : agreements.values()) { base.replace(agreement); } base.getAccountsSection() .setSameGroupVisibility(config.getAccountsSection().getSameGroupVisibility()); BatchMetaDataUpdate batch = base.openUpdate(md); try { // Scan AccountGroupAgreement List<AccountGroupAgreement> groupAgreements = getAccountGroupAgreements(db, agreements); // Find the earliest change for (AccountGroupAgreement aga : groupAgreements) { minTime = Math.min(minTime, aga.getTime()); } minTime -= 60 * 1000; // 1 Minute CommitBuilder commit = new CommitBuilder(); commit.setAuthor(new PersonIdent(serverUser, new Date(minTime))); commit.setCommitter(new PersonIdent(serverUser, new Date(minTime))); commit.setMessage( "Add the ContributorAgreements for upgrade to Gerrit Code Review schema 65\n"); batch.write(commit); for (AccountGroupAgreement aga : groupAgreements) { AccountGroup group = db.accountGroups().get(aga.groupId); if (group == null) { continue; } ContributorAgreement agreement = agreements.get(aga.claId); agreement.getAccepted().add(new PermissionRule(config.resolve(group))); base.replace(agreement); PersonIdent ident = null; if (aga.reviewedBy != null) { Account ua = db.accounts().get(aga.reviewedBy); if (ua != null) { String name = ua.getFullName(); String email = ua.getPreferredEmail(); if (email == null || email.isEmpty()) { // No preferred email is configured. Use a generic identity so we // don't leak an address the user may have given us, but doesn't // necessarily want to publish through Git records. // String user = ua.getUserName(); if (user == null || user.isEmpty()) { user = "******" + ua.getId().toString(); } String host = SystemReader.getInstance().getHostname(); email = user + "@" + host; } if (name == null || name.isEmpty()) { final int at = email.indexOf('@'); if (0 < at) { name = email.substring(0, at); } else { name = anonymousCowardName; } } ident = new PersonIdent(name, email, new Date(aga.getTime()), TimeZone.getDefault()); } } if (ident == null) { ident = new PersonIdent(serverUser, new Date(aga.getTime())); } // Build the commits such that it keeps track of the date added and // who added it. commit = new CommitBuilder(); commit.setAuthor(ident); commit.setCommitter(new PersonIdent(serverUser, new Date(aga.getTime()))); String msg = String.format( "Accept %s contributor agreement for %s\n", agreement.getName(), group.getName()); if (!Strings.isNullOrEmpty(aga.reviewComments)) { msg += "\n" + aga.reviewComments + "\n"; } commit.setMessage(msg); batch.write(commit); } // Merge the agreements with the other data in project.config. commit = new CommitBuilder(); commit.setAuthor(serverUser); commit.setCommitter(serverUser); commit.setMessage("Upgrade to Gerrit Code Review schema 65\n"); commit.addParentId(config.getRevision()); batch.write(config, commit); // Save the the final metadata. batch.commitAt(config.getRevision()); } finally { batch.close(); } } catch (IOException e) { throw new OrmException(e); } catch (ConfigInvalidException e) { throw new OrmException(e); } finally { git.close(); } }