diff --git a/application/src/main/java/org/thingsboard/server/service/sync/DefaultGitSyncService.java b/application/src/main/java/org/thingsboard/server/service/sync/DefaultGitSyncService.java index 2abf025cda..3f405e145b 100644 --- a/application/src/main/java/org/thingsboard/server/service/sync/DefaultGitSyncService.java +++ b/application/src/main/java/org/thingsboard/server/service/sync/DefaultGitSyncService.java @@ -18,6 +18,7 @@ package org.thingsboard.server.service.sync; import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.eclipse.jgit.revwalk.RevCommit; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.thingsboard.common.util.ThingsBoardExecutors; @@ -47,6 +48,8 @@ public class DefaultGitSyncService implements GitSyncService { private final Map repositories = new ConcurrentHashMap<>(); private final Map updateListeners = new ConcurrentHashMap<>(); + private RevCommit lastCommit; + @Override public void registerSync(String key, String repoUri, String branch, long fetchFrequencyMs, Runnable onUpdate) { RepositorySettings settings = new RepositorySettings(); @@ -84,7 +87,7 @@ public class DefaultGitSyncService implements GitSyncService { @Override public List listFiles(String key, String path, int depth, FileType type) { GitRepository repository = getRepository(key); - return repository.listFilesAtCommit(getBranchRef(repository), path, depth).stream() + return repository.listFilesAtCommit(lastCommit, path, depth).stream() .filter(file -> type == null || file.type() == type) .toList(); } @@ -93,7 +96,7 @@ public class DefaultGitSyncService implements GitSyncService { @Override public byte[] getFileContent(String key, String path) { GitRepository repository = getRepository(key); - return repository.getFileContentAtCommit(path, getBranchRef(repository)); + return repository.getFileContentAtCommit(path, lastCommit); } @Override @@ -137,6 +140,15 @@ public class DefaultGitSyncService implements GitSyncService { } private void onUpdate(String key) { + GitRepository repository = getRepository(key); + String branchRef = getBranchRef(repository); + try { + lastCommit = repository.resolveCommit(branchRef); + } catch (Throwable e) { + log.error("[{}] Failed to resolve commit for ref {}", key, branchRef, e); + return; + } + Runnable listener = updateListeners.get(key); if (listener != null) { log.debug("[{}] Handling repository update", key); diff --git a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java index 434d52a4ca..3602dd55ca 100644 --- a/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java +++ b/common/version-control/src/main/java/org/thingsboard/server/service/sync/vc/GitRepository.java @@ -277,13 +277,17 @@ public class GitRepository { return listFilesAtCommit(commitId, path, -1).stream().map(RepoFile::path).toList(); } - @SneakyThrows public List listFilesAtCommit(String commitId, String path, int depth) { - log.debug("Executing listFilesAtCommit [{}][{}][{}]", settings.getRepositoryUri(), commitId, path); + RevCommit commit = resolveCommit(commitId); + return listFilesAtCommit(commit, path, depth); + } + + @SneakyThrows + public List listFilesAtCommit(RevCommit commit, String path, int depth) { + log.debug("Executing listFilesAtCommit [{}][{}][{}]", settings.getRepositoryUri(), commit, path); List files = new ArrayList<>(); - RevCommit revCommit = resolveCommit(commitId); try (TreeWalk treeWalk = new TreeWalk(git.getRepository())) { - treeWalk.reset(revCommit.getTree().getId()); + treeWalk.reset(commit.getTree().getId()); if (StringUtils.isNotEmpty(path)) { treeWalk.setFilter(PathFilter.create(path)); } @@ -301,11 +305,15 @@ public class GitRepository { return files; } - @SneakyThrows public byte[] getFileContentAtCommit(String file, String commitId) { - log.debug("Executing getFileContentAtCommit [{}][{}][{}]", settings.getRepositoryUri(), commitId, file); - RevCommit revCommit = resolveCommit(commitId); - try (TreeWalk treeWalk = TreeWalk.forPath(git.getRepository(), file, revCommit.getTree())) { + RevCommit commit = resolveCommit(commitId); + return getFileContentAtCommit(file, commit); + } + + @SneakyThrows + public byte[] getFileContentAtCommit(String file, RevCommit commit) { + log.debug("Executing getFileContentAtCommit [{}][{}][{}]", settings.getRepositoryUri(), commit, file); + try (TreeWalk treeWalk = TreeWalk.forPath(git.getRepository(), file, commit.getTree())) { if (treeWalk == null) { throw new IllegalArgumentException("File not found"); } @@ -373,9 +381,9 @@ public class GitRepository { for (RemoteRefUpdate update : pushResult.getRemoteUpdates()) { RemoteRefUpdate.Status status = update.getStatus(); if (status == REJECTED_NONFASTFORWARD || status == REJECTED_NODELETE || - status == REJECTED_REMOTE_CHANGED || status == REJECTED_OTHER_REASON) { + status == REJECTED_REMOTE_CHANGED || status == REJECTED_OTHER_REASON) { throw new RuntimeException("Remote repository answered with error: " + - Optional.ofNullable(update.getMessage()).orElseGet(status::name)); + Optional.ofNullable(update.getMessage()).orElseGet(status::name)); } } }); @@ -450,7 +458,8 @@ public class GitRepository { revCommit.getFullMessage(), revCommit.getAuthorIdent().getName(), revCommit.getAuthorIdent().getEmailAddress()); } - private RevCommit resolveCommit(String id) throws IOException { + @SneakyThrows + public RevCommit resolveCommit(String id) { return git.getRepository().parseCommit(resolve(id)); } @@ -481,8 +490,8 @@ public class GitRepository { private static final Function> revCommitComparatorFunction = pageLink -> { SortOrder sortOrder = pageLink.getSortOrder(); if (sortOrder != null - && sortOrder.getProperty().equals("timestamp") - && SortOrder.Direction.ASC.equals(sortOrder.getDirection())) { + && sortOrder.getProperty().equals("timestamp") + && SortOrder.Direction.ASC.equals(sortOrder.getDirection())) { return Comparator.comparingInt(RevCommit::getCommitTime); } return null;