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;
}
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);
}
}
}
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;
}
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;
}
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;
}
Aggregations