private void persistUpdatedIssues(IssueStatistics statistics, List<DefaultIssue> updatedIssues, IssueMapper mapper, IssueChangeMapper changeMapper) { if (updatedIssues.isEmpty()) { return; } long now = system2.now(); updatedIssues.forEach(i -> { IssueDto dto = IssueDto.toDtoForUpdate(i, now); mapper.updateIfBeforeSelectedDate(dto); statistics.updates++; }); // retrieve those of the updatedIssues which have not been updated and apply conflictResolver on them List<String> updatedIssueKeys = updatedIssues.stream().map(DefaultIssue::key).collect(toList(updatedIssues.size())); List<IssueDto> conflictIssueKeys = mapper.selectByKeysIfNotUpdatedAt(updatedIssueKeys, now); if (!conflictIssueKeys.isEmpty()) { Map<String, DefaultIssue> issuesByKeys = updatedIssues.stream().collect(uniqueIndex(DefaultIssue::key, updatedIssues.size())); conflictIssueKeys .forEach(dbIssue -> { DefaultIssue updatedIssue = issuesByKeys.get(dbIssue.getKey()); conflictResolver.resolve(updatedIssue, dbIssue, mapper); statistics.merged++; }); } updatedIssues.forEach(i -> issueStorage.insertChanges(changeMapper, i)); }
@Before public void setup() throws Exception { issueCache = new IssueCache(temp.newFile(), System2.INSTANCE); reportReader.setMetadata(ScannerReport.Metadata.getDefaultInstance()); underTest = new PersistIssuesStep(dbClient, system2, conflictResolver, new RuleRepositoryImpl(adHocRuleCreator, dbClient, analysisMetadataHolder), issueCache, new IssueStorage()); }
private Collection<IssueDto> doSave(DbSession dbSession, Iterable<DefaultIssue> issues) { // Batch session can not be used for updates. It does not return the number of updated rows, // required for detecting conflicts. long now = system2.now(); Map<Boolean, List<DefaultIssue>> issuesNewOrUpdated = StreamSupport.stream(issues.spliterator(), true).collect(Collectors.groupingBy(DefaultIssue::isNew)); List<DefaultIssue> issuesToInsert = firstNonNull(issuesNewOrUpdated.get(true), emptyList()); List<DefaultIssue> issuesToUpdate = firstNonNull(issuesNewOrUpdated.get(false), emptyList()); Collection<IssueDto> inserted = insert(dbSession, issuesToInsert, now); Collection<IssueDto> updated = update(issuesToUpdate, now); doAfterSave(dbSession, Stream.concat(inserted.stream(), updated.stream()) .collect(toSet(issuesToInsert.size() + issuesToUpdate.size()))); return Stream.concat(inserted.stream(), updated.stream()) .collect(toSet(issuesToInsert.size() + issuesToUpdate.size())); }
/** * @return the keys of the updated issues */ private Collection<IssueDto> update(List<DefaultIssue> issuesToUpdate, long now) { Collection<IssueDto> updated = new ArrayList<>(); if (!issuesToUpdate.isEmpty()) { try (DbSession dbSession = dbClient.openSession(false)) { IssueChangeMapper issueChangeMapper = dbSession.getMapper(IssueChangeMapper.class); for (DefaultIssue issue : issuesToUpdate) { IssueDto issueDto = doUpdate(dbSession, now, issue); updated.add(issueDto); insertChanges(issueChangeMapper, issue); } dbSession.commit(); } } return updated; }
/** * @return the keys of the inserted issues */ private Collection<IssueDto> insert(DbSession session, Iterable<DefaultIssue> issuesToInsert, long now) { List<IssueDto> inserted = newArrayList(); int count = 0; IssueChangeMapper issueChangeMapper = session.getMapper(IssueChangeMapper.class); for (DefaultIssue issue : issuesToInsert) { IssueDto issueDto = doInsert(session, now, issue); inserted.add(issueDto); insertChanges(issueChangeMapper, issue); if (count > BatchSession.MAX_BATCH_SIZE) { session.commit(); count = 0; } count++; } session.commit(); return inserted; }
public void save(DefaultIssue issue) { save(newArrayList(issue)); }
public IssueDto save(DbSession session, DefaultIssue issue) { return doSave(session, newArrayList(issue)).iterator().next(); }
private BulkChangeResult executeBulkChange(DbSession dbSession, Request request) { BulkChangeData bulkChangeData = new BulkChangeData(dbSession, request); BulkChangeResult result = new BulkChangeResult(bulkChangeData.issues.size()); IssueChangeContext issueChangeContext = IssueChangeContext.createUser(new Date(system2.now()), userSession.getUuid()); List<DefaultIssue> items = bulkChangeData.issues.stream() .filter(bulkChange(issueChangeContext, bulkChangeData, result)) .collect(MoreCollectors.toList()); issueStorage.save(items); refreshLiveMeasures(dbSession, bulkChangeData, result); Set<String> assigneeUuids = items.stream().map(DefaultIssue::assignee).filter(Objects::nonNull).collect(toSet()); Map<String, UserDto> userDtoByUuid = dbClient.userDao().selectByUuids(dbSession, assigneeUuids).stream().collect(toMap(UserDto::getUuid, u -> u)); String authorUuid = requireNonNull(userSession.getUuid(), "User uuid cannot be null"); UserDto author = dbClient.userDao().selectByUuid(dbSession, authorUuid); checkState(author != null, "User with uuid '%s' does not exist"); items.forEach(sendNotification(bulkChangeData, userDtoByUuid, author)); return result; }
public Collection<IssueDto> save(Iterable<DefaultIssue> issues) { try (DbSession session = dbClient.openSession(true)) { return doSave(session, issues); } }
private void persistNewIssues(IssueStatistics statistics, List<DefaultIssue> addedIssues, IssueMapper mapper, IssueChangeMapper changeMapper) { if (addedIssues.isEmpty()) { return; } long now = system2.now(); addedIssues.forEach(i -> { int ruleId = ruleRepository.getByKey(i.ruleKey()).getId(); IssueDto dto = IssueDto.toDtoForComputationInsert(i, ruleId, now); mapper.insert(dto); statistics.inserts++; }); addedIssues.forEach(i -> issueStorage.insertChanges(changeMapper, i)); }
private IssueDto doSaveIssue(DbSession session, DefaultIssue issue, IssueChangeContext context, @Nullable String comment, Optional<RuleDefinitionDto> rule, ComponentDto project, ComponentDto component) { IssueDto issueDto = issueStorage.save(session, issue); String assigneeUuid = issue.assignee(); UserDto assignee = assigneeUuid == null ? null : dbClient.userDao().selectByUuid(session, assigneeUuid); String authorUuid = context.userUuid(); UserDto author = authorUuid == null ? null : dbClient.userDao().selectByUuid(session, authorUuid); notificationService.scheduleForSending(new IssueChangeNotification() .setIssue(issue) .setAssignee(assignee) .setChangeAuthor(author) .setRuleName(rule.map(RuleDefinitionDto::getName).orElse(null)) .setProject(project) .setComponent(component) .setComment(comment)); return issueDto; }
@Override public void execute() { try (DbSession dbSession = dbClient.openSession(true); CloseableIterator<DefaultIssue> issues = issueCache.traverse()) { IssueMapper mapper = dbSession.getMapper(IssueMapper.class); IssueChangeMapper changeMapper = dbSession.getMapper(IssueChangeMapper.class); while (issues.hasNext()) { DefaultIssue issue = issues.next(); boolean saved = persistIssueIfRequired(mapper, issue); if (saved) { IssueStorage.insertChanges(changeMapper, issue); } } dbSession.flushStatements(); dbSession.commit(); } }