Search in sources :

Example 11 with ClusterMember

use of org.craftercms.studio.api.v2.dal.ClusterMember 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);
            }
        }
    }
}
Also used : ClusterMember(org.craftercms.studio.api.v2.dal.ClusterMember) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) RemoteRepository(org.craftercms.studio.api.v2.dal.RemoteRepository) IOException(java.io.IOException) InvalidRemoteUrlException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException)

Example 12 with ClusterMember

use of org.craftercms.studio.api.v2.dal.ClusterMember in project studio by craftercms.

the class GitContentRepository method bootstrap.

/**
 * bootstrap the repository
 */
public void bootstrap() throws Exception {
    logger.debug("Bootstrap global repository.");
    boolean bootstrapRepo = Boolean.parseBoolean(studioConfiguration.getProperty(BOOTSTRAP_REPO));
    GitRepositoryHelper helper = GitRepositoryHelper.getHelper(studioConfiguration, securityService, userServiceInternal, encryptor, generalLockService, retryingRepositoryOperationFacade);
    boolean isCreated = false;
    HierarchicalConfiguration<ImmutableNode> registrationData = studioClusterUtils.getClusterConfiguration();
    if (bootstrapRepo && registrationData != null && !registrationData.isEmpty()) {
        String firstCommitId = getRepoFirstCommitId(StringUtils.EMPTY);
        String localAddress = studioClusterUtils.getClusterNodeLocalAddress();
        List<ClusterMember> clusterNodes = studioClusterUtils.getClusterNodes(localAddress);
        if (StringUtils.isEmpty(firstCommitId)) {
            logger.debug("Creating global repository as cluster clone");
            isCreated = studioClusterUtils.cloneGlobalRepository(clusterNodes);
        } else {
            logger.debug("Global repository exists syncing with cluster siblings");
            isCreated = true;
            Repository repo = helper.getRepository(EMPTY, GLOBAL);
            try (Git git = new Git(repo)) {
                for (ClusterMember remoteNode : clusterNodes) {
                    if (remoteNode.getState().equals(ClusterMember.State.ACTIVE)) {
                        syncFromRemote(git, remoteNode);
                    }
                }
            }
        }
    }
    if (bootstrapRepo && !isCreated && helper.createGlobalRepo()) {
        // Copy the global config defaults to the global site
        // Build a path to the bootstrap repo (the repo that ships with Studio)
        String bootstrapFolderPath = this.ctx.getRealPath(FILE_SEPARATOR + BOOTSTRAP_REPO_PATH + FILE_SEPARATOR + BOOTSTRAP_REPO_GLOBAL_PATH);
        Path source = java.nio.file.FileSystems.getDefault().getPath(bootstrapFolderPath);
        logger.info("Bootstrapping with baseline @ " + source.toFile().toString());
        // Copy the bootstrap repo to the global repo
        Path globalConfigPath = helper.buildRepoPath(GLOBAL);
        TreeCopier tc = new TreeCopier(source, globalConfigPath);
        EnumSet<FileVisitOption> opts = EnumSet.of(FOLLOW_LINKS);
        Files.walkFileTree(source, opts, MAX_VALUE, tc);
        String studioManifestLocation = this.ctx.getRealPath(STUDIO_MANIFEST_LOCATION);
        if (Files.exists(Paths.get(studioManifestLocation))) {
            FileUtils.copyFile(Paths.get(studioManifestLocation).toFile(), Paths.get(globalConfigPath.toAbsolutePath().toString(), studioConfiguration.getProperty(BLUE_PRINTS_PATH), "BLUEPRINTS.MF").toFile());
        }
        Repository globalConfigRepo = helper.getRepository(EMPTY, GLOBAL);
        try (Git git = new Git(globalConfigRepo)) {
            Status status = git.status().call();
            if (status.hasUncommittedChanges() || !status.isClean()) {
                // Commit everything
                // TODO: Consider what to do with the commitId in the future
                AddCommand addCommand = git.add().addFilepattern(GIT_COMMIT_ALL_ITEMS);
                retryingRepositoryOperationFacade.call(addCommand);
                CommitCommand commitCommand = git.commit().setMessage(helper.getCommitMessage(REPO_INITIAL_COMMIT_COMMIT_MESSAGE));
                retryingRepositoryOperationFacade.call(commitCommand);
            }
        } catch (GitAPIException err) {
            logger.error("error creating initial commit for global configuration", err);
        }
    }
    // Create global repository object
    if (!helper.buildGlobalRepo()) {
        logger.error("Failed to create global repository!");
    }
}
Also used : Path(java.nio.file.Path) Status(org.eclipse.jgit.api.Status) ImmutableNode(org.apache.commons.configuration2.tree.ImmutableNode) FileVisitOption(java.nio.file.FileVisitOption) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) ClusterMember(org.craftercms.studio.api.v2.dal.ClusterMember) 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) RemoteAddCommand(org.eclipse.jgit.api.RemoteAddCommand) AddCommand(org.eclipse.jgit.api.AddCommand)

Example 13 with ClusterMember

use of org.craftercms.studio.api.v2.dal.ClusterMember in project studio by craftercms.

the class SiteServiceImpl method setSiteState.

@Override
public void setSiteState(String siteId, String state) {
    siteFeedMapper.setSiteState(siteId, state);
    try {
        ClusterMember clusterMember = clusterDao.getMemberByLocalAddress(studioClusterUtils.getClusterNodeLocalAddress());
        if (Objects.nonNull(clusterMember)) {
            SiteFeed siteFeed = getSite(siteId);
            clusterDao.setSiteState(clusterMember.getId(), siteFeed.getId(), state);
        }
    } catch (SiteNotFoundException e) {
        logger.error("Site not found " + siteId);
    }
}
Also used : ClusterMember(org.craftercms.studio.api.v2.dal.ClusterMember) SiteFeed(org.craftercms.studio.api.v1.dal.SiteFeed) SiteNotFoundException(org.craftercms.studio.api.v1.exception.SiteNotFoundException)

Example 14 with ClusterMember

use of org.craftercms.studio.api.v2.dal.ClusterMember in project studio by craftercms.

the class GitContentRepository method insertClusterRemoteRepository.

public void insertClusterRemoteRepository(RemoteRepository remoteRepository) {
    HierarchicalConfiguration<ImmutableNode> registrationData = studioConfiguration.getSubConfig(CLUSTERING_NODE_REGISTRATION);
    if (registrationData != null && !registrationData.isEmpty()) {
        String localAddress = registrationData.getString(CLUSTER_MEMBER_LOCAL_ADDRESS);
        ClusterMember member = clusterDao.getMemberByLocalAddress(localAddress);
        if (member != null) {
            retryingOperationFacade.addClusterRemoteRepository(member.getId(), remoteRepository.getId());
        }
    }
}
Also used : ClusterMember(org.craftercms.studio.api.v2.dal.ClusterMember) ImmutableNode(org.apache.commons.configuration2.tree.ImmutableNode)

Example 15 with ClusterMember

use of org.craftercms.studio.api.v2.dal.ClusterMember in project studio by craftercms.

the class SiteServiceImpl method createSiteFromBlueprint.

@Override
@ValidateParams
public void createSiteFromBlueprint(@ValidateStringParam(name = "blueprintId") String blueprintId, @ValidateNoTagsParam(name = "siteName") String siteName, @ValidateStringParam(name = "siteId", maxLength = 50, whitelistedPatterns = "[a-z0-9\\-]*") String siteId, @ValidateStringParam(name = "sandboxBranch") String sandboxBranch, @ValidateNoTagsParam(name = "desc") String desc, Map<String, String> params, boolean createAsOrphan) throws SiteAlreadyExistsException, SiteCreationException, DeployerTargetException, BlueprintNotFoundException, MissingPluginParameterException {
    if (exists(siteId)) {
        throw new SiteAlreadyExistsException();
    }
    logger.debug("Get blueprint descriptor for: " + blueprintId);
    PluginDescriptor descriptor = sitesServiceInternal.getBlueprintDescriptor(blueprintId);
    if (Objects.isNull(descriptor)) {
        throw new BlueprintNotFoundException();
    }
    logger.debug("Validating blueprint parameters");
    sitesServiceInternal.validateBlueprintParameters(descriptor, params);
    String blueprintLocation = sitesServiceInternal.getBlueprintLocation(blueprintId);
    String searchEngine = descriptor.getPlugin().getSearchEngine();
    logger.debug("Validate site entitlements");
    try {
        entitlementValidator.validateEntitlement(EntitlementType.SITE, 1);
    } catch (EntitlementException e) {
        throw new SiteCreationException("Unable to complete request due to entitlement limits. Please contact " + "your system administrator.", e);
    }
    logger.info("Starting site creation process for site " + siteName + " from " + blueprintId + " blueprint.");
    boolean success = true;
    // We must fail site creation if any of the site creations steps fail and rollback
    // For example: Create site => create Deployer Target (fail) = fail
    // and rollback the whole thing.
    // What we need to do for site creation and the order of execution:
    // 1) deployer target, 2) git repo, 3) database, 4) kick deployer
    String siteUuid = UUID.randomUUID().toString();
    // Create the site in the preview deployer
    logger.info("Creating deployer targets.");
    try {
        deployer.createTargets(siteId, searchEngine);
    } catch (Exception e) {
        success = false;
        String msg = "Error while creating site: " + siteName + " ID: " + siteId + " from blueprint: " + blueprintId + ". The required Deployer targets couldn't be created";
        logger.error(msg, e);
        throw new DeployerTargetException(msg, e);
    }
    if (success) {
        try {
            logger.info("Copying site content from blueprint.");
            success = createSiteFromBlueprintGit(blueprintLocation, siteName, siteId, sandboxBranch, desc, params);
            ZonedDateTime now = ZonedDateTime.now();
            logger.debug("Adding site UUID.");
            addSiteUuidFile(siteId, siteUuid);
            logger.info("Adding site record to database for site " + siteId);
            // insert database records
            SiteFeed siteFeed = new SiteFeed();
            siteFeed.setName(siteName);
            siteFeed.setSiteId(siteId);
            siteFeed.setSiteUuid(siteUuid);
            siteFeed.setDescription(desc);
            siteFeed.setPublishingStatus(READY);
            siteFeed.setPublishingStatusMessage(studioConfiguration.getProperty(JOB_DEPLOY_CONTENT_TO_ENVIRONMENT_STATUS_MESSAGE_DEFAULT));
            siteFeed.setSandboxBranch(sandboxBranch);
            siteFeed.setSearchEngine(searchEngine);
            siteFeedMapper.createSite(siteFeed);
            String localeAddress = studioClusterUtils.getClusterNodeLocalAddress();
            ClusterMember cm = clusterDao.getMemberByLocalAddress(localeAddress);
            if (Objects.nonNull(cm)) {
                SiteFeed s = getSite(siteId);
                clusterDao.insertClusterSiteSyncRepo(cm.getId(), s.getId(), null, null, null);
            }
            logger.info("Upgrading site.");
            upgradeManager.upgradeSite(siteId);
            // Add default groups
            logger.info("Adding default groups");
            addDefaultGroupsForNewSite(siteId);
            String lastCommitId = contentRepositoryV2.getRepoLastCommitId(siteId);
            String creator = securityService.getCurrentUser();
            long startGetChangeSetCreatedFilesMark = logger.isDebugEnabled() ? System.currentTimeMillis() : 0;
            Map<String, String> createdFiles = contentRepositoryV2.getChangeSetPathsFromDelta(siteId, null, lastCommitId);
            if (logger.isDebugEnabled()) {
                logger.debug("Get change set created files finished in " + (System.currentTimeMillis() - startGetChangeSetCreatedFilesMark) + " milliseconds");
            }
            logger.info("Adding audit log");
            insertCreateSiteAuditLog(siteId, siteName, createdFiles);
            processCreatedFiles(siteId, createdFiles, creator, now, lastCommitId);
            contentRepositoryV2.insertGitLog(siteId, lastCommitId, 1, 1);
            updateLastCommitId(siteId, lastCommitId);
            updateLastVerifiedGitlogCommitId(siteId, lastCommitId);
            updateLastSyncedGitlogCommitId(siteId, lastCommitId);
            logger.info("Reload site configuration");
            reloadSiteConfiguration(siteId);
        } catch (Exception e) {
            success = false;
            logger.error("Error while creating site: " + siteName + " ID: " + siteId + " from blueprint: " + blueprintId + ". Rolling back.", e);
            deleteSite(siteId);
            throw new SiteCreationException("Error while creating site: " + siteName + " ID: " + siteId + " from blueprint: " + blueprintId + ". Rolling back.");
        }
    }
    if (success) {
        logger.info("Syncing all content to preview.");
        // Now that everything is created, we can sync the preview deployer with the new content
        try {
            deploymentService.syncAllContentToPreview(siteId, true);
        } catch (ServiceLayerException e) {
            logger.error("Error while syncing site: " + siteName + " ID: " + siteId + " to preview. Site was " + "successfully created otherwise. Ignoring.", e);
            throw new SiteCreationException("Error while syncing site: " + siteName + " ID: " + siteId + " to preview. Site was successfully created, but it won't be preview-able until the Preview " + "Deployer is reachable.");
        }
        setSiteState(siteId, STATE_CREATED);
    } else {
        throw new SiteCreationException("Error while creating site: " + siteName + " ID: " + siteId + ".");
    }
    logger.info("Finished creating site " + siteId);
}
Also used : BlueprintNotFoundException(org.craftercms.studio.api.v1.exception.BlueprintNotFoundException) DeployerTargetException(org.craftercms.studio.api.v1.exception.DeployerTargetException) SiteAlreadyExistsException(org.craftercms.studio.api.v1.exception.SiteAlreadyExistsException) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) SiteConfigNotFoundException(org.craftercms.studio.api.v1.service.site.SiteConfigNotFoundException) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) SiteCreationException(org.craftercms.studio.api.v1.exception.SiteCreationException) MissingPluginParameterException(org.craftercms.studio.api.v2.exception.MissingPluginParameterException) IOException(java.io.IOException) RemoteRepositoryNotFoundException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotFoundException) UserNotFoundException(org.craftercms.studio.api.v1.exception.security.UserNotFoundException) InvalidRemoteUrlException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException) DeployerTargetException(org.craftercms.studio.api.v1.exception.DeployerTargetException) RestServiceException(org.craftercms.commons.rest.RestServiceException) SiteAlreadyExistsException(org.craftercms.studio.api.v1.exception.SiteAlreadyExistsException) GroupAlreadyExistsException(org.craftercms.studio.api.v1.exception.security.GroupAlreadyExistsException) DocumentException(org.dom4j.DocumentException) EntitlementException(org.craftercms.commons.entitlements.exception.EntitlementException) BlueprintNotFoundException(org.craftercms.studio.api.v1.exception.BlueprintNotFoundException) SiteNotFoundException(org.craftercms.studio.api.v1.exception.SiteNotFoundException) CryptoException(org.craftercms.commons.crypto.CryptoException) RemoteRepositoryNotBareException(org.craftercms.studio.api.v1.exception.repository.RemoteRepositoryNotBareException) InvalidRemoteRepositoryCredentialsException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryCredentialsException) InvalidRemoteRepositoryException(org.craftercms.studio.api.v1.exception.repository.InvalidRemoteRepositoryException) PluginDescriptor(org.craftercms.commons.plugin.model.PluginDescriptor) EntitlementException(org.craftercms.commons.entitlements.exception.EntitlementException) ClusterMember(org.craftercms.studio.api.v2.dal.ClusterMember) ZonedDateTime(java.time.ZonedDateTime) SiteFeed(org.craftercms.studio.api.v1.dal.SiteFeed) SiteCreationException(org.craftercms.studio.api.v1.exception.SiteCreationException) ValidateParams(org.craftercms.commons.validation.annotations.param.ValidateParams)

Aggregations

ClusterMember (org.craftercms.studio.api.v2.dal.ClusterMember)26 SiteFeed (org.craftercms.studio.api.v1.dal.SiteFeed)10 IOException (java.io.IOException)9 Path (java.nio.file.Path)9 SiteNotFoundException (org.craftercms.studio.api.v1.exception.SiteNotFoundException)9 Git (org.eclipse.jgit.api.Git)9 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)9 ContentRepository (org.craftercms.studio.api.v1.repository.ContentRepository)8 Repository (org.eclipse.jgit.lib.Repository)8 ImmutableNode (org.apache.commons.configuration2.tree.ImmutableNode)7 RemoteRepository (org.craftercms.studio.api.v2.dal.RemoteRepository)7 FileRepositoryBuilder (org.eclipse.jgit.storage.file.FileRepositoryBuilder)7 HashMap (java.util.HashMap)6 ServiceLayerException (org.craftercms.studio.api.v1.exception.ServiceLayerException)6 InvalidRemoteUrlException (org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException)6 CryptoException (org.craftercms.commons.crypto.CryptoException)5 ClusterSiteRecord (org.craftercms.studio.api.v2.dal.ClusterSiteRecord)5 RemoteAddCommand (org.eclipse.jgit.api.RemoteAddCommand)5 URISyntaxException (java.net.URISyntaxException)4 File (java.io.File)3