package br.gov.servicos.importador; import br.gov.servicos.utils.LogstashProgressMonitor; import lombok.SneakyThrows; import lombok.experimental.FieldDefaults; import lombok.experimental.NonFinal; import lombok.extern.slf4j.Slf4j; import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.PullResult; import org.eclipse.jgit.api.errors.GitAPIException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.stereotype.Component; import java.io.File; import java.io.IOException; import java.nio.file.Files; import static lombok.AccessLevel.PRIVATE; import static org.eclipse.jgit.api.ResetCommand.ResetType.HARD; import static org.eclipse.jgit.lib.Constants.MASTER; import static org.eclipse.jgit.lib.Constants.R_HEADS; import static org.eclipse.jgit.merge.MergeStrategy.THEIRS; import static org.springframework.util.StringUtils.isEmpty; @Slf4j @Component @FieldDefaults(level = PRIVATE, makeFinal = true) public class RepositorioCartasServico { String urlRepositorio; @NonFinal File caminhoLocal; @Autowired public RepositorioCartasServico( @Value("${pds.cartas.repositorio}") String urlRepositorio, @Value("${fallback.pds.cartas.repositorio}") String urlFallbackRepositorio) { this.urlRepositorio = isEmpty(urlRepositorio) ? urlFallbackRepositorio : urlRepositorio; } @SneakyThrows public boolean contemAtualizacoes() { if (caminhoLocal == null) { caminhoLocal = clonarRepositorio(criarDiretorioTemporario()); caminhoLocal.deleteOnExit(); return true; } log.debug("Atualizando repositório de cartas de serviço de {} para {}", urlRepositorio, caminhoLocal); try (Git repositorio = Git.open(caminhoLocal)) { String oldHead = repositorio.getRepository().getRef(R_HEADS + MASTER).getObjectId().getName(); PullResult result = repositorio.pull() .setProgressMonitor(new LogstashProgressMonitor(log)) .setStrategy(THEIRS) .call(); if (!result.isSuccessful()) { log.error("Erro ao atualizar repositório: {}", result); return false; } String head = repositorio.reset() .setMode(HARD) .setRef("refs/remotes/origin/master") .call() .getObjectId() .getName(); if (oldHead.equals(head)) { log.info("Repositório de cartas de serviço em {} já está na versão mais recente: {}", caminhoLocal, head); return false; } log.info("Repositório de cartas de serviço em {} atualizado da versão {} para {}", caminhoLocal, oldHead, head); return true; } } public Resource get(String caminhoDocumento) { return new FileSystemResource(caminhoLocal.toPath().resolve(caminhoDocumento).toFile()); } private File criarDiretorioTemporario() throws IOException { File repositorioCartas = Files.createTempDirectory("portal-de-servicos").toFile(); repositorioCartas.deleteOnExit(); return repositorioCartas; } private File clonarRepositorio(File caminhoLocal) throws GitAPIException { log.debug("Clonando repositório de cartas de serviço de {} para {}", urlRepositorio, caminhoLocal); CloneCommand clone = Git.cloneRepository() .setURI(urlRepositorio) .setProgressMonitor(new LogstashProgressMonitor(log)) .setDirectory(caminhoLocal); try (Git repositorio = clone.call()) { String head = repositorio.log().call().iterator().next().getName(); log.info("Repositório de cartas de serviço clonado na versão {}", head); return repositorio.getRepository().getWorkTree(); } } }