Search in sources :

Example 26 with GeneralLockService

use of org.craftercms.studio.api.v1.service.GeneralLockService in project studio by craftercms.

the class GitContentRepository method moveContent.

@Override
public Map<String, String> moveContent(String site, String fromPath, String toPath, String newName) {
    Map<String, String> toRet = new TreeMap<String, String>();
    String commitId;
    String gitLockKey = SITE_SANDBOX_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, site);
    generalLockService.lock(gitLockKey);
    try {
        GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
        synchronized (helper.getRepository(site, StringUtils.isEmpty(site) ? GLOBAL : SANDBOX)) {
            Repository repo = helper.getRepository(site, StringUtils.isEmpty(site) ? GLOBAL : SANDBOX);
            String gitFromPath = helper.getGitPath(fromPath);
            String gitToPath;
            if (StringUtils.isEmpty(newName)) {
                gitToPath = helper.getGitPath(toPath);
            } else {
                gitToPath = helper.getGitPath(toPath + FILE_SEPARATOR + newName);
            }
            try (Git git = new Git(repo)) {
                // Check if destination is a file, then this is a rename operation
                // Perform rename and exit
                Path sourcePath = Paths.get(repo.getDirectory().getParent(), gitFromPath);
                File sourceFile = sourcePath.toFile();
                Path targetPath = Paths.get(repo.getDirectory().getParent(), gitToPath);
                File targetFile = targetPath.toFile();
                if (sourceFile.getCanonicalFile().equals(targetFile.getCanonicalFile())) {
                    sourceFile.renameTo(targetFile);
                } else {
                    if (targetFile.isFile()) {
                        if (sourceFile.isFile()) {
                            sourceFile.renameTo(targetFile);
                        } else {
                            // This is not a valid operation
                            logger.error("Invalid move operation: Trying to rename a directory to a file " + "for site: " + site + " fromPath: " + fromPath + " toPath: " + toPath + " newName: " + newName);
                        }
                    } else if (sourceFile.isDirectory()) {
                        // Check if we're moving a single file or whole subtree
                        File[] dirList = sourceFile.listFiles();
                        for (File child : dirList) {
                            if (!child.equals(sourceFile)) {
                                FileUtils.moveToDirectory(child, targetFile, true);
                            }
                        }
                        FileUtils.deleteDirectory(sourceFile);
                    } else {
                        if (sourceFile.isFile()) {
                            FileUtils.moveFile(sourceFile, targetFile);
                        } else {
                            FileUtils.moveToDirectory(sourceFile, targetFile, true);
                        }
                    }
                }
                // The operation is done on disk, now it's time to commit
                AddCommand addCommand = git.add().addFilepattern(gitToPath);
                retryingRepositoryOperationFacade.call(addCommand);
                StatusCommand statusCommand = git.status().addPath(gitToPath);
                Status gitStatus = retryingRepositoryOperationFacade.call(statusCommand);
                Set<String> changeSet = gitStatus.getAdded();
                for (String pathToCommit : changeSet) {
                    String pathRemoved = pathToCommit.replace(gitToPath, gitFromPath);
                    CommitCommand commitCommand = git.commit().setOnly(pathToCommit).setOnly(pathRemoved).setAuthor(helper.getCurrentUserIdent()).setCommitter(helper.getCurrentUserIdent()).setMessage(helper.getCommitMessage(REPO_MOVE_CONTENT_COMMIT_MESSAGE).replaceAll(PATTERN_FROM_PATH, fromPath).replaceAll(PATTERN_TO_PATH, toPath + (StringUtils.isNotEmpty(newName) ? newName : EMPTY)));
                    RevCommit commit = retryingRepositoryOperationFacade.call(commitCommand);
                    commitId = commit.getName();
                    toRet.put(pathToCommit, commitId);
                }
            }
        }
    } catch (IOException | GitAPIException | ServiceLayerException | UserNotFoundException | CryptoException e) {
        logger.error("Error while moving content for site: " + site + " fromPath: " + fromPath + " toPath: " + toPath + " newName: " + newName);
    } finally {
        generalLockService.unlock(gitLockKey);
    }
    return toRet;
}
Also used : Path(java.nio.file.Path) Status(org.eclipse.jgit.api.Status) UserNotFoundException(org.craftercms.studio.api.v1.exception.security.UserNotFoundException) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) IOException(java.io.IOException) TreeMap(java.util.TreeMap) StatusCommand(org.eclipse.jgit.api.StatusCommand) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) Git(org.eclipse.jgit.api.Git) CommitCommand(org.eclipse.jgit.api.CommitCommand) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) CryptoException(org.craftercms.commons.crypto.CryptoException) File(java.io.File) LockFile(org.eclipse.jgit.internal.storage.file.LockFile) RemoteAddCommand(org.eclipse.jgit.api.RemoteAddCommand) AddCommand(org.eclipse.jgit.api.AddCommand) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 27 with GeneralLockService

use of org.craftercms.studio.api.v1.service.GeneralLockService in project studio by craftercms.

the class GitContentRepository method initialPublish.

@Override
public void initialPublish(String site, String sandboxBranch, String environment, String author, String comment) throws DeploymentException, CryptoException {
    String gitLockKey = SITE_PUBLISHED_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, site);
    GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
    Repository repo = helper.getRepository(site, PUBLISHED);
    String commitId = EMPTY;
    String sandboxBranchName = sandboxBranch;
    if (StringUtils.isEmpty(sandboxBranchName)) {
        sandboxBranchName = studioConfiguration.getProperty(REPO_SANDBOX_BRANCH);
    }
    generalLockService.lock(gitLockKey);
    synchronized (repo) {
        try (Git git = new Git(repo)) {
            // fetch "origin/master"
            logger.debug("Fetch from sandbox for site " + site);
            git.fetch().call();
            // checkout master and pull from sandbox
            logger.debug("Checkout published/master branch for site " + site);
            try {
                CheckoutCommand checkoutCommand = git.checkout().setName(sandboxBranchName);
                retryingRepositoryOperationFacade.call(checkoutCommand);
                PullCommand pullCommand = git.pull().setRemote(DEFAULT_REMOTE_NAME).setRemoteBranchName(sandboxBranchName).setStrategy(THEIRS);
                retryingRepositoryOperationFacade.call(pullCommand);
            } catch (RefNotFoundException e) {
                logger.error("Failed to checkout published master and to pull content from sandbox for site " + site, e);
                throw new DeploymentException("Failed to checkout published master and to pull content from " + "sandbox for site " + site);
            }
            // checkout environment branch
            logger.debug("Checkout environment branch " + environment + " for site " + site);
            try {
                CheckoutCommand checkoutCommand = git.checkout().setCreateBranch(true).setForce(true).setStartPoint(sandboxBranchName).setUpstreamMode(TRACK).setName(environment);
                retryingRepositoryOperationFacade.call(checkoutCommand);
            } catch (RefNotFoundException e) {
                logger.info("Not able to find branch " + environment + " for site " + site + ". Creating new branch");
            }
            // tag
            PersonIdent authorIdent = helper.getAuthorIdent(author);
            ZonedDateTime publishDate = ZonedDateTime.now(UTC);
            String tagName = publishDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HHmmssSSSX")) + "_published_on_" + publishDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HHmmssSSSX"));
            TagCommand tagCommand = git.tag().setTagger(authorIdent).setName(tagName).setMessage(comment);
            retryingRepositoryOperationFacade.call(tagCommand);
        } catch (Exception e) {
            logger.error("Error when publishing site " + site + " to environment " + environment, e);
            throw new DeploymentException("Error when publishing site " + site + " to environment " + environment + " [commit ID = " + commitId + "]");
        } finally {
            generalLockService.unlock(gitLockKey);
        }
    }
}
Also used : RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) CheckoutCommand(org.eclipse.jgit.api.CheckoutCommand) PullCommand(org.eclipse.jgit.api.PullCommand) Git(org.eclipse.jgit.api.Git) RefNotFoundException(org.eclipse.jgit.api.errors.RefNotFoundException) PersonIdent(org.eclipse.jgit.lib.PersonIdent) ZonedDateTime(java.time.ZonedDateTime) DeploymentException(org.craftercms.studio.api.v1.service.deployment.DeploymentException) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) JSchException(com.jcraft.jsch.JSchException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) RefNotFoundException(org.eclipse.jgit.api.errors.RefNotFoundException) RemoteRepositoryNotFoundException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotFoundException) URISyntaxException(java.net.URISyntaxException) UserNotFoundException(org.craftercms.studio.api.v1.exception.security.UserNotFoundException) InvalidRemoteUrlException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException) ContentNotFoundException(org.craftercms.studio.api.v1.exception.ContentNotFoundException) RemoteAlreadyExistsException(org.craftercms.studio.api.v1.exception.repository.RemoteAlreadyExistsException) DeploymentException(org.craftercms.studio.api.v1.service.deployment.DeploymentException) CryptoException(org.craftercms.commons.crypto.CryptoException) TransportException(org.eclipse.jgit.api.errors.TransportException) RemoteRepositoryNotBareException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotBareException) InvalidRemoteException(org.eclipse.jgit.api.errors.InvalidRemoteException) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException) InvalidRemoteRepositoryCredentialsException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryCredentialsException) InvalidRemoteRepositoryException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryException) TagCommand(org.eclipse.jgit.api.TagCommand)

Example 28 with GeneralLockService

use of org.craftercms.studio.api.v1.service.GeneralLockService in project studio by craftercms.

the class GitContentRepository method createSitePushToRemote.

@Override
public boolean createSitePushToRemote(String siteId, String remoteName, String remoteUrl, String authenticationType, String remoteUsername, String remotePassword, String remoteToken, String remotePrivateKey, boolean createAsOrphan) throws InvalidRemoteRepositoryException, InvalidRemoteRepositoryCredentialsException, RemoteRepositoryNotFoundException, RemoteRepositoryNotBareException, ServiceLayerException {
    boolean toRet = true;
    String gitLockKey = SITE_SANDBOX_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, siteId);
    generalLockService.lock(gitLockKey);
    try {
        GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
        try (Repository repo = helper.getRepository(siteId, SANDBOX)) {
            try (Git git = new Git(repo)) {
                boolean pkauth = false;
                final Path tempKey = Files.createTempFile(UUID.randomUUID().toString(), ".tmp");
                PushCommand pushCommand = git.push();
                switch(authenticationType) {
                    case NONE:
                        logger.debug("No authentication");
                        break;
                    case BASIC:
                        logger.debug("Basic authentication");
                        pushCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(remoteUsername, remotePassword));
                        break;
                    case TOKEN:
                        logger.debug("Token based authentication");
                        pushCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(remoteToken, EMPTY));
                        break;
                    case PRIVATE_KEY:
                        logger.debug("Private key authentication");
                        tempKey.toFile().deleteOnExit();
                        pushCommand.setTransportConfigCallback(new TransportConfigCallback() {

                            @Override
                            public void configure(Transport transport) {
                                SshTransport sshTransport = (SshTransport) transport;
                                sshTransport.setSshSessionFactory(getSshSessionFactory(remotePrivateKey, tempKey));
                            }
                        });
                        pkauth = true;
                        break;
                    default:
                        throw new ServiceLayerException("Unsupported authentication type " + authenticationType);
                }
                logger.debug("Push site " + siteId + " to remote repository " + remoteName + "(" + remoteUrl + ")");
                pushCommand.setPushAll().setRemote(remoteName);
                Iterable<PushResult> result = retryingRepositoryOperationFacade.call(pushCommand);
                if (pkauth)
                    Files.delete(tempKey);
                logger.debug("Check push result to verify it was success");
                Iterator<PushResult> resultIter = result.iterator();
                if (resultIter.hasNext()) {
                    PushResult pushResult = resultIter.next();
                    Iterator<RemoteRefUpdate> remoteRefUpdateIterator = pushResult.getRemoteUpdates().iterator();
                    if (remoteRefUpdateIterator.hasNext()) {
                        RemoteRefUpdate update = remoteRefUpdateIterator.next();
                        if (update.getStatus().equals(REJECTED_NONFASTFORWARD)) {
                            logger.error("Remote repository: " + remoteName + " (" + remoteUrl + ") is not bare repository");
                            throw new RemoteRepositoryNotBareException("Remote repository: " + remoteName + " (" + remoteUrl + ") is not bare repository");
                        }
                    }
                }
            } catch (InvalidRemoteException e) {
                logger.error("Invalid remote repository: " + remoteName + " (" + remoteUrl + ")", e);
                throw new InvalidRemoteRepositoryException("Invalid remote repository: " + remoteName + " (" + remoteUrl + ")");
            } catch (TransportException e) {
                if (StringUtils.endsWithIgnoreCase(e.getMessage(), "not authorized")) {
                    logger.error("Bad credentials or read only repository: " + remoteName + " (" + remoteUrl + ")", e);
                    throw new InvalidRemoteRepositoryCredentialsException("Bad credentials or read only repository: " + remoteName + " (" + remoteUrl + ") for username " + remoteUsername, e);
                } else {
                    logger.error("Remote repository not found: " + remoteName + " (" + remoteUrl + ")", e);
                    throw new RemoteRepositoryNotFoundException("Remote repository not found: " + remoteName + " (" + remoteUrl + ")");
                }
            } catch (ClassCastException e) {
                logger.error("Wrong protocol used to access repository: " + remoteName + " (" + remoteUrl + ")", e);
                throw new InvalidRemoteRepositoryCredentialsException("Wrong protocol used to access repository: " + remoteName + " (" + remoteUrl + ")", e);
            } catch (ServiceLayerException | IOException e) {
                logger.error("Failed to push newly created site " + siteId + " to remote repository " + remoteUrl, e);
                throw new ServiceLayerException(e);
            }
        }
    } catch (GitAPIException | CryptoException e) {
        logger.error("Failed to push newly created site " + siteId + " to remote repository " + remoteUrl, e);
        toRet = false;
    } finally {
        generalLockService.unlock(gitLockKey);
    }
    return toRet;
}
Also used : GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) TransportConfigCallback(org.eclipse.jgit.api.TransportConfigCallback) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) RemoteRepositoryNotBareException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotBareException) Path(java.nio.file.Path) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate) UsernamePasswordCredentialsProvider(org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider) InvalidRemoteRepositoryCredentialsException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryCredentialsException) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) InvalidRemoteRepositoryException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryException) PushResult(org.eclipse.jgit.transport.PushResult) IOException(java.io.IOException) TransportException(org.eclipse.jgit.api.errors.TransportException) PushCommand(org.eclipse.jgit.api.PushCommand) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) Git(org.eclipse.jgit.api.Git) RemoteRepositoryNotFoundException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotFoundException) InvalidRemoteException(org.eclipse.jgit.api.errors.InvalidRemoteException) SshTransport(org.eclipse.jgit.transport.SshTransport) Transport(org.eclipse.jgit.transport.Transport) CryptoException(org.craftercms.commons.crypto.CryptoException) SshTransport(org.eclipse.jgit.transport.SshTransport)

Example 29 with GeneralLockService

use of org.craftercms.studio.api.v1.service.GeneralLockService in project studio by craftercms.

the class GitContentRepository method getRepoFirstCommitId.

@Override
public String getRepoFirstCommitId(final String site) {
    String toReturn = EMPTY;
    try {
        GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
        Repository repository = helper.getRepository(site, StringUtils.isEmpty(site) ? GLOBAL : SANDBOX);
        if (repository != null) {
            synchronized (repository) {
                Repository repo = helper.getRepository(site, StringUtils.isEmpty(site) ? GLOBAL : SANDBOX);
                if (repo != null) {
                    try (RevWalk rw = new RevWalk(repo)) {
                        ObjectId head = repo.resolve(HEAD);
                        if (head != null) {
                            RevCommit root = rw.parseCommit(head);
                            rw.sort(REVERSE);
                            rw.markStart(root);
                            ObjectId first = rw.next();
                            toReturn = first.getName();
                            logger.debug("getRepoFirstCommitId for site: " + site + " First commit ID: " + toReturn);
                        }
                    }
                }
            }
        }
    } catch (IOException | CryptoException e) {
        logger.error("Error getting first commit ID for site " + site, e);
    }
    return toReturn;
}
Also used : RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) ObjectId(org.eclipse.jgit.lib.ObjectId) IOException(java.io.IOException) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) RevWalk(org.eclipse.jgit.revwalk.RevWalk) CryptoException(org.craftercms.commons.crypto.CryptoException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 30 with GeneralLockService

use of org.craftercms.studio.api.v1.service.GeneralLockService in project studio by craftercms.

the class GitContentRepository method getContentVersion.

@Override
public InputStream getContentVersion(String site, String path, String version) throws ContentNotFoundException {
    InputStream toReturn = null;
    try {
        GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
        Repository repo = helper.getRepository(site, StringUtils.isEmpty(site) ? GLOBAL : SANDBOX);
        RevTree tree = helper.getTreeForCommit(repo, version);
        if (tree != null) {
            try (TreeWalk tw = TreeWalk.forPath(repo, helper.getGitPath(path), tree)) {
                if (tw != null) {
                    ObjectId id = tw.getObjectId(0);
                    ObjectLoader objectLoader = repo.open(id);
                    toReturn = objectLoader.openStream();
                    tw.close();
                }
            } catch (IOException e) {
                logger.error("Error while getting content for file at site: " + site + " path: " + path + " version: " + version, e);
            }
        }
    } catch (IOException | CryptoException e) {
        logger.error("Failed to create RevTree for site: " + site + " path: " + path + " version: " + version, e);
    }
    return toReturn;
}
Also used : RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) Repository(org.eclipse.jgit.lib.Repository) ContentRepository(org.craftercms.studio.api.v1.repository.ContentRepository) ObjectId(org.eclipse.jgit.lib.ObjectId) InputStream(java.io.InputStream) ObjectLoader(org.eclipse.jgit.lib.ObjectLoader) IOException(java.io.IOException) GitRepositoryHelper(org.craftercms.studio.api.v2.utils.GitRepositoryHelper) CryptoException(org.craftercms.commons.crypto.CryptoException) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk) RevTree(org.eclipse.jgit.revwalk.RevTree)

Aggregations

GitRepositoryHelper (org.craftercms.studio.api.v2.utils.GitRepositoryHelper)49 Repository (org.eclipse.jgit.lib.Repository)48 RemoteRepository (org.craftercms.studio.api.v2.dal.RemoteRepository)47 ContentRepository (org.craftercms.studio.api.v1.repository.ContentRepository)42 CryptoException (org.craftercms.commons.crypto.CryptoException)39 IOException (java.io.IOException)38 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)35 Git (org.eclipse.jgit.api.Git)33 ServiceLayerException (org.craftercms.studio.api.v1.exception.ServiceLayerException)30 Path (java.nio.file.Path)17 UserNotFoundException (org.craftercms.studio.api.v1.exception.security.UserNotFoundException)17 ArrayList (java.util.ArrayList)14 RevTree (org.eclipse.jgit.revwalk.RevTree)13 InvalidRemoteUrlException (org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException)11 ObjectId (org.eclipse.jgit.lib.ObjectId)11 RevCommit (org.eclipse.jgit.revwalk.RevCommit)11 File (java.io.File)10 InvalidRemoteException (org.eclipse.jgit.api.errors.InvalidRemoteException)10 TreeWalk (org.eclipse.jgit.treewalk.TreeWalk)10 HashMap (java.util.HashMap)8