use of org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException in project studio by craftercms.
the class RepositoryManagementServiceInternalImpl method pullFromRemote.
@Override
public boolean pullFromRemote(String siteId, String remoteName, String remoteBranch, String mergeStrategy) throws InvalidRemoteUrlException, ServiceLayerException, CryptoException {
logger.debug("Get remote data from database for remote " + remoteName + " and site " + siteId);
String gitLockKey = SITE_SANDBOX_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, siteId);
RemoteRepository remoteRepository = getRemoteRepository(siteId, remoteName);
logger.debug("Prepare pull command");
GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
Repository repo = helper.getRepository(siteId, SANDBOX);
generalLockService.lock(gitLockKey);
try (Git git = new Git(repo)) {
PullResult pullResult = null;
PullCommand pullCommand = git.pull();
logger.debug("Set remote " + remoteName);
pullCommand.setRemote(remoteRepository.getRemoteName());
logger.debug("Set branch to be " + remoteBranch);
pullCommand.setRemoteBranchName(remoteBranch);
Path tempKey = Files.createTempFile(UUID.randomUUID().toString(), ".tmp");
pullCommand = helper.setAuthenticationForCommand(pullCommand, remoteRepository.getAuthenticationType(), remoteRepository.getRemoteUsername(), remoteRepository.getRemotePassword(), remoteRepository.getRemoteToken(), remoteRepository.getRemotePrivateKey(), tempKey, true);
switch(mergeStrategy) {
case THEIRS:
pullCommand.setStrategy(MergeStrategy.THEIRS);
break;
case OURS:
pullCommand.setStrategy(MergeStrategy.OURS);
break;
default:
break;
}
pullCommand.setFastForward(MergeCommand.FastForwardMode.NO_FF);
pullResult = retryingRepositoryOperationFacade.call(pullCommand);
String pullResultMessage = pullResult.toString();
if (StringUtils.isNotEmpty(pullResultMessage)) {
logger.info(pullResultMessage);
}
Files.delete(tempKey);
if (!pullResult.isSuccessful() && conflictNotificationEnabled()) {
List<String> conflictFiles = new ArrayList<String>();
if (pullResult.getMergeResult() != null) {
pullResult.getMergeResult().getConflicts().forEach((m, v) -> {
conflictFiles.add(m);
});
}
notificationService.notifyRepositoryMergeConflict(siteId, conflictFiles, Locale.ENGLISH);
}
if (pullResult.isSuccessful()) {
String lastCommitId = contentRepository.getRepoLastCommitId(siteId);
contentRepositoryV2.upsertGitLogList(siteId, Arrays.asList(lastCommitId), false, false);
List<String> newMergedCommits = extractCommitIdsFromPullResult(siteId, repo, pullResult);
List<String> commitIds = new ArrayList<String>();
if (Objects.nonNull(newMergedCommits) && newMergedCommits.size() > 0) {
logger.debug("Really pulled commits:");
int cnt = 0;
for (int i = 0; i < newMergedCommits.size(); i++) {
String commitId = newMergedCommits.get(i);
logger.debug(commitId);
if (!StringUtils.equals(lastCommitId, commitId)) {
commitIds.add(commitId);
if (cnt++ >= batchSizeGitLog) {
contentRepositoryV2.upsertGitLogList(siteId, commitIds, true, true);
cnt = 0;
commitIds.clear();
}
}
}
if (Objects.nonNull(commitIds) && commitIds.size() > 0) {
contentRepositoryV2.upsertGitLogList(siteId, commitIds, true, true);
}
}
siteService.updateLastCommitId(siteId, lastCommitId);
}
return pullResult != null && pullResult.isSuccessful();
} catch (InvalidRemoteException e) {
logger.error("Remote is invalid " + remoteName, e);
throw new InvalidRemoteUrlException();
} catch (GitAPIException e) {
logger.error("Error while pulling from remote " + remoteName + " branch " + remoteBranch + " for site " + siteId, e);
throw new ServiceLayerException("Error while pulling from remote " + remoteName + " branch " + remoteBranch + " for site " + siteId, e);
} catch (CryptoException | IOException e) {
throw new ServiceLayerException(e);
} finally {
generalLockService.unlock(gitLockKey);
}
}
use of org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException in project studio by craftercms.
the class StudioClusterPublishedRepoSyncTask method executeInternal.
@Override
protected void executeInternal(String siteId) {
// Log start time
long startTime = System.currentTimeMillis();
logger.debug("Worker starts syncing cluster node published for site " + siteId);
try {
HierarchicalConfiguration<ImmutableNode> registrationData = studioClusterUtils.getClusterConfiguration();
if (registrationData != null && !registrationData.isEmpty()) {
String localAddress = studioClusterUtils.getClusterNodeLocalAddress();
ClusterMember localNode = clusterDao.getMemberByLocalAddress(localAddress);
List<ClusterMember> clusterNodes = studioClusterUtils.getClusterNodes(localAddress);
SiteFeed siteFeed = siteService.getSite(siteId);
List<ClusterSiteRecord> clusterSiteRecords = clusterDao.getSiteStateAcrossCluster(siteId);
Optional<ClusterSiteRecord> localNodeRecord = clusterSiteRecords.stream().filter(x -> x.getClusterNodeId() == localNode.getId() && StringUtils.equals(x.getState(), STATE_CREATED)).findFirst();
if (!localNodeRecord.isPresent()) {
return;
}
long nodesCreated = clusterSiteRecords.stream().filter(x -> StringUtils.equals(x.getState(), STATE_CREATED)).count();
if (nodesCreated < 1) {
return;
}
// Check if site exists
logger.debug("Check if site " + siteId + " exists in local repository");
boolean success = true;
int publishedReposCreated = clusterSiteRecords.stream().mapToInt(ClusterSiteRecord::getPublishedRepoCreated).sum();
if (publishedReposCreated > 0 || siteFeed.getPublishedRepoCreated() > 0) {
boolean siteCheck = checkIfSiteRepoExists(siteId);
if (!siteCheck) {
// Site doesn't exist locally, create it
success = createSite(localNode.getId(), siteFeed.getId(), siteId, siteFeed.getSandboxBranch());
} else {
clusterDao.setPublishedRepoCreated(localNode.getId(), siteFeed.getId());
}
} else {
success = false;
}
if (success) {
try {
// Add the remote repositories to the local repository to sync from if not added already
logger.debug("Add remotes for site " + siteId);
addRemotes(siteId, clusterNodes);
} catch (InvalidRemoteUrlException | ServiceLayerException | CryptoException e) {
logger.error("Error while adding remotes on cluster node for site " + siteId);
}
try {
// Sync with remote and update the local cache with the last commit ID to speed things up
logger.debug("Update content for site " + siteId);
updateContent(siteFeed.getId(), siteId, clusterNodes, clusterSiteRecords);
} catch (IOException | CryptoException | ServiceLayerException e) {
logger.error("Error while updating content for site " + siteId + " on cluster node.", e);
}
}
}
} catch (SiteNotFoundException e) {
logger.error("Error while executing Cluster Node Sync Published for site " + siteId, e);
}
// Compute execution duration and log it
long duration = System.currentTimeMillis() - startTime;
logger.debug("Worker finished syncing cluster node for site " + siteId);
logger.debug("Worker performed cluster node sync for site " + siteId + " in " + duration + "ms");
logger.debug("Finished Cluster Node Sync task for site " + siteId);
}
use of org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException in project studio by craftercms.
the class StudioClusterSandboxRepoSyncTask method executeInternal.
@Override
protected void executeInternal(String siteId) {
// Log start time
long startTime = System.currentTimeMillis();
logger.debug("Worker starts syncing cluster node sandbox for site " + siteId);
try {
HierarchicalConfiguration<ImmutableNode> registrationData = studioClusterUtils.getClusterConfiguration();
if (registrationData != null && !registrationData.isEmpty()) {
String localAddress = studioClusterUtils.getClusterNodeLocalAddress();
ClusterMember localNode = clusterDao.getMemberByLocalAddress(localAddress);
List<ClusterMember> clusterNodes = studioClusterUtils.getClusterNodes(localAddress);
SiteFeed siteFeed = siteService.getSite(siteId);
List<ClusterSiteRecord> clusterSiteRecords = clusterDao.getSiteStateAcrossCluster(siteId);
long nodesCreated = clusterSiteRecords.stream().filter(x -> StringUtils.equals(x.getState(), STATE_CREATED)).count();
if (nodesCreated < 1 && !StringUtils.equals(siteFeed.getState(), STATE_CREATED)) {
return;
}
// Check if site exists
logger.debug("Check if site " + siteId + " exists in local repository");
boolean success = true;
boolean siteCheck = checkIfSiteRepoExists(siteId);
if (!siteCheck) {
// Site doesn't exist locally, create it
success = createSite(localNode.getId(), siteFeed.getId(), siteId, siteFeed.getSiteUuid(), siteFeed.getSearchEngine(), clusterNodes, clusterSiteRecords);
}
if (success && clusterDao.existsClusterSiteSyncRepo(localNode.getId(), siteFeed.getId()) < 1) {
String commitId = contentRepository.getRepoLastCommitId(siteId);
clusterDao.insertClusterSiteSyncRepo(localNode.getId(), siteFeed.getId(), commitId, commitId, siteFeed.getLastSyncedGitlogCommitId());
clusterDao.setSiteState(localNode.getId(), siteFeed.getId(), STATE_CREATED);
addSiteUuidFile(siteId, siteFeed.getSiteUuid());
}
if (success) {
syncRemoteRepositories(siteId, localAddress);
// Check if the site needs to be synced
boolean syncRequired = isSyncRequired(siteId, siteFeed.getLastCommitId());
if (syncRequired) {
try {
// Add the remote repositories to the local repository to sync from if not added already
logger.debug("Add remotes for site " + siteId);
addRemotes(siteId, clusterNodes);
} catch (InvalidRemoteUrlException | ServiceLayerException e) {
logger.error("Error while adding remotes on cluster node for site " + siteId);
}
try {
// Sync with remote and update the local cache with the last commit ID to speed things up
logger.debug("Update content for site " + siteId);
updateContent(localNode.getId(), siteFeed.getId(), siteId, siteFeed.getSandboxBranch(), clusterNodes);
} catch (IOException | CryptoException | ServiceLayerException e) {
logger.error("Error while updating content for site " + siteId + " on cluster node.", e);
}
}
}
}
} catch (SiteNotFoundException | IOException e) {
logger.error("Error while executing Cluster Node Sync Sandbox for site " + siteId, e);
}
// Compute execution duration and log it
long duration = System.currentTimeMillis() - startTime;
logger.debug("Worker finished syncing cluster node for site " + siteId);
logger.debug("Worker performed cluster node sync for site " + siteId + " in " + duration + "ms");
logger.debug("Finished Cluster Node Sync task for site " + siteId);
}
use of org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException in project studio by craftercms.
the class StudioClusterSandboxRepoSyncTask method syncRemoteRepositories.
private void syncRemoteRepositories(String siteId, String localAddress) {
List<RemoteRepository> remoteRepositories = clusterDao.getMissingClusterNodeRemoteRepositories(localAddress, siteId);
if (CollectionUtils.isNotEmpty(remoteRepositories)) {
ClusterMember currentNode = clusterDao.getMemberByLocalAddress(localAddress);
for (RemoteRepository remoteRepository : remoteRepositories) {
try {
addRemoteRepository(siteId, remoteRepository);
clusterDao.addClusterRemoteRepository(currentNode.getId(), remoteRepository.getId());
} catch (IOException | InvalidRemoteUrlException | ServiceLayerException e) {
logger.error("Error while adding remote " + remoteRepository.getRemoteName() + " (url: " + remoteRepository.getRemoteUrl() + ") for site " + siteId, e);
}
}
}
}
use of org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException in project studio by craftercms.
the class GitContentRepository method pullFromRemote.
@Override
public boolean pullFromRemote(String siteId, String remoteName, String remoteBranch) throws ServiceLayerException, InvalidRemoteUrlException, CryptoException {
logger.debug("Get remote data from database for remote " + remoteName + " and site " + siteId);
Map<String, String> params = new HashMap<String, String>();
params.put("siteId", siteId);
params.put("remoteName", remoteName);
RemoteRepository remoteRepository = remoteRepositoryDAO.getRemoteRepository(params);
logger.debug("Prepare pull command");
GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
Repository repo = helper.getRepository(siteId, SANDBOX);
String gitLockKey = SITE_SANDBOX_REPOSITORY_GIT_LOCK.replaceAll(PATTERN_SITE, siteId);
generalLockService.lock(gitLockKey);
try (Git git = new Git(repo)) {
PullResult pullResult = null;
PullCommand pullCommand = git.pull();
logger.debug("Set remote " + remoteName);
pullCommand.setRemote(remoteRepository.getRemoteName());
logger.debug("Set branch to be " + remoteBranch);
pullCommand.setRemoteBranchName(remoteBranch);
switch(remoteRepository.getAuthenticationType()) {
case NONE:
logger.debug("No authentication");
pullResult = pullCommand.call();
break;
case BASIC:
logger.debug("Basic authentication");
String hashedPassword = remoteRepository.getRemotePassword();
String password = encryptor.decrypt(hashedPassword);
pullCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(remoteRepository.getRemoteUsername(), password));
pullResult = pullCommand.call();
break;
case TOKEN:
logger.debug("Token based authentication");
String hashedToken = remoteRepository.getRemoteToken();
String token = encryptor.decrypt(hashedToken);
pullCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(token, EMPTY));
pullResult = pullCommand.call();
break;
case PRIVATE_KEY:
logger.debug("Private key authentication");
final Path tempKey = Files.createTempFile(UUID.randomUUID().toString(), ".tmp");
String hashedPrivateKey = remoteRepository.getRemotePrivateKey();
String privateKey = encryptor.decrypt(hashedPrivateKey);
tempKey.toFile().deleteOnExit();
pullCommand.setTransportConfigCallback(new TransportConfigCallback() {
@Override
public void configure(Transport transport) {
SshTransport sshTransport = (SshTransport) transport;
sshTransport.setSshSessionFactory(getSshSessionFactory(privateKey, tempKey));
}
});
pullResult = retryingRepositoryOperationFacade.call(pullCommand);
Files.delete(tempKey);
break;
default:
throw new ServiceLayerException("Unsupported authentication type " + remoteRepository.getAuthenticationType());
}
return pullResult != null ? pullResult.isSuccessful() : false;
} catch (InvalidRemoteException e) {
logger.error("Remote is invalid " + remoteName, e);
throw new InvalidRemoteUrlException();
} catch (GitAPIException e) {
logger.error("Error while pulling from remote " + remoteName + " branch " + remoteBranch + " for site " + siteId, e);
throw new ServiceLayerException("Error while pulling from remote " + remoteName + " branch " + remoteBranch + " for site " + siteId, e);
} catch (CryptoException | IOException e) {
throw new ServiceLayerException(e);
} finally {
generalLockService.unlock(gitLockKey);
}
}
Aggregations