Search in sources :

Example 16 with PUBLISHED

use of org.craftercms.studio.api.v1.constant.GitRepositories.PUBLISHED in project studio by craftercms.

the class PublishingManagerImpl method processItem.

@Override
public DeploymentItemTO processItem(PublishRequest item) throws DeploymentException, SiteNotFoundException {
    if (item == null) {
        throw new DeploymentException("Cannot process item, item is null.");
    }
    DeploymentItemTO deploymentItem = new DeploymentItemTO();
    deploymentItem.setSite(item.getSite());
    deploymentItem.setPath(item.getPath());
    deploymentItem.setCommitId(item.getCommitId());
    deploymentItem.setPackageId(item.getPackageId());
    String site = item.getSite();
    String path = item.getPath();
    String oldPath = item.getOldPath();
    String environment = item.getEnvironment();
    String action = item.getAction();
    String user = item.getUser();
    String liveEnvironment = LIVE_ENVIRONMENT;
    if (servicesConfig.isStagingEnvironmentEnabled(site)) {
        liveEnvironment = servicesConfig.getLiveEnvironment(site);
    }
    boolean isLive = false;
    if (StringUtils.isNotEmpty(liveEnvironment)) {
        if (liveEnvironment.equals(environment)) {
            isLive = true;
        }
    } else if (StringUtils.equalsIgnoreCase(LIVE_ENVIRONMENT, item.getEnvironment()) || StringUtils.equalsIgnoreCase(PRODUCTION_ENVIRONMENT, environment)) {
        isLive = true;
    }
    if (StringUtils.equals(action, PublishRequest.Action.DELETE)) {
        if (oldPath != null && oldPath.length() > 0) {
            contentService.deleteContent(site, oldPath, user);
            boolean hasRenamedChildren = false;
            if (oldPath.endsWith(FILE_SEPARATOR + DmConstants.INDEX_FILE)) {
                if (contentService.contentExists(site, oldPath.replace(FILE_SEPARATOR + DmConstants.INDEX_FILE, ""))) {
                    // TODO: SJ: This bypasses the Content Service, fix
                    RepositoryItem[] children = contentRepository.getContentChildren(site, oldPath.replace(FILE_SEPARATOR + DmConstants.INDEX_FILE, ""));
                    if (children.length > 1) {
                        hasRenamedChildren = true;
                    }
                }
                if (!hasRenamedChildren) {
                    deleteFolder(site, oldPath.replace(FILE_SEPARATOR + DmConstants.INDEX_FILE, ""), user);
                }
            }
            deploymentItem.setMove(true);
            deploymentItem.setOldPath(oldPath);
            objectMetadataManager.clearRenamed(site, path);
        }
        boolean haschildren = false;
        if (item.getPath().endsWith(FILE_SEPARATOR + DmConstants.INDEX_FILE)) {
            if (contentService.contentExists(site, path.replace(FILE_SEPARATOR + DmConstants.INDEX_FILE, ""))) {
                // TODO: SJ: This bypasses the Content Service, fix
                RepositoryItem[] children = contentRepository.getContentChildren(site, path.replace(FILE_SEPARATOR + DmConstants.INDEX_FILE, ""));
                if (children.length > 1) {
                    haschildren = true;
                }
            }
        }
        if (contentService.contentExists(site, path)) {
            contentService.deleteContent(site, path, user);
            if (!haschildren) {
                deleteFolder(site, path.replace(FILE_SEPARATOR + DmConstants.INDEX_FILE, ""), user);
            }
        }
        deploymentItem.setDelete(true);
    } else {
        if (StringUtils.equals(action, PublishRequest.Action.MOVE)) {
            deploymentItem.setMove(true);
            deploymentItem.setOldPath(oldPath);
            if (oldPath != null && oldPath.length() > 0) {
                if (isLive) {
                    objectMetadataManager.clearRenamed(site, path);
                }
            }
        }
        ItemMetadata itemMetadata = objectMetadataManager.getProperties(site, path);
        if (itemMetadata == null) {
            if (contentService.contentExists(site, path)) {
                LOGGER.warn("Content item: '" + site + "':'" + path + "' doesn't exists in " + "the database, but does exist in git. This may cause problems " + "in the environment: '" + environment + "'");
            } else {
                LOGGER.warn("Content item: '" + site + "':'" + path + "' cannot be published. " + "Content does not exist in git nor in the database. Skipping...");
                return null;
            }
        } else {
            ContentItemTO contentItem = contentService.getContentItem(site, path);
            if (isLive) {
                // should consider what should be done if this does not work.
                // Currently the method will bail and the item is stuck in processing.
                LOGGER.debug("Environment is live, transition item to LIVE state {0}:{1}", site, path);
                // check if commit id from workflow and from object state match
                if (Objects.isNull(itemMetadata.getCommitId()) || itemMetadata.getCommitId().equals(item.getCommitId())) {
                    objectStateService.transition(site, contentItem, TransitionEvent.DEPLOYMENT);
                }
            } else {
                objectStateService.transition(site, contentItem, TransitionEvent.SAVE);
            }
            itemMetadata.setSubmittedBy(StringUtils.EMPTY);
            itemMetadata.setSendEmail(0);
            itemMetadata.setSubmittedForDeletion(0);
            itemMetadata.setSubmissionComment(StringUtils.EMPTY);
            itemMetadata.setSubmittedToEnvironment(StringUtils.EMPTY);
            itemMetadata.setLaunchDate(null);
            objectMetadataManager.updateObjectMetadata(itemMetadata);
        }
        String blacklistConfig = studioConfiguration.getProperty(CONFIGURATION_PUBLISHING_BLACKLIST_REGEX);
        if (StringUtils.isNotEmpty(blacklistConfig) && ContentUtils.matchesPatterns(item.getPath(), Arrays.asList(StringUtils.split(blacklistConfig, ",")))) {
            LOGGER.debug("File " + item.getPath() + " of the site " + site + " will not be published because it " + "matches the configured publishing blacklist regex patterns.");
            markItemsCompleted(site, item.getEnvironment(), Arrays.asList(item));
            deploymentItem = null;
        }
    }
    return deploymentItem;
}
Also used : RepositoryItem(org.craftercms.studio.api.v1.repository.RepositoryItem) ContentItemTO(org.craftercms.studio.api.v1.to.ContentItemTO) DeploymentItemTO(org.craftercms.studio.api.v1.to.DeploymentItemTO) DeploymentException(org.craftercms.studio.api.v1.service.deployment.DeploymentException) ItemMetadata(org.craftercms.studio.api.v1.dal.ItemMetadata)

Example 17 with PUBLISHED

use of org.craftercms.studio.api.v1.constant.GitRepositories.PUBLISHED in project studio by craftercms.

the class ContentServiceImpl method writeContent.

@Override
@ValidateParams
public void writeContent(@ValidateStringParam(name = "site") String site, @ValidateSecurePathParam(name = "path") String path, @ValidateStringParam(name = "fileName") String fileName, @ValidateStringParam(name = "contentType") String contentType, InputStream input, @ValidateStringParam(name = "createFolders") String createFolders, @ValidateStringParam(name = "edit") String edit, @ValidateStringParam(name = "unlock") String unlock, boolean skipAuditLogInsert) throws ServiceLayerException {
    try {
        entitlementValidator.validateEntitlement(EntitlementType.ITEM, 1);
    } catch (EntitlementException e) {
        throw new ServiceLayerException("Unable to complete request due to entitlement limits. Please contact your " + "system administrator.");
    }
    Map<String, String> params = new HashMap<String, String>();
    params.put(DmConstants.KEY_SITE, site);
    params.put(DmConstants.KEY_PATH, path);
    params.put(DmConstants.KEY_FILE_NAME, fileName);
    params.put(DmConstants.KEY_CONTENT_TYPE, contentType);
    params.put(DmConstants.KEY_CREATE_FOLDERS, createFolders);
    params.put(DmConstants.KEY_EDIT, edit);
    params.put(DmConstants.KEY_UNLOCK, unlock);
    params.put(DmConstants.KEY_SKIP_AUDIT_LOG_INSERT, String.valueOf(skipAuditLogInsert));
    String id = site + ":" + path + ":" + fileName + ":" + contentType;
    String relativePath = path;
    boolean contentExists = contentExists(site, path);
    String lockKey = id;
    if (contentExists) {
        lockKey = site + ":" + path;
    }
    try {
        // Check if the user is saving and closing (releasing the lock) or just saving and will continue to edit
        // If "unlock" is empty, it means it's a save and close operation
        // if "unlock" is set to "false", it also means it's a save and continue operation
        boolean isSaveAndClose = (StringUtils.isNotEmpty(unlock) && !unlock.equalsIgnoreCase("false"));
        if (contentExists) {
            ItemState itemState = objectStateService.getObjectState(site, path);
            if (itemState == null) {
                // This file is either new or someone created it outside of our system, we must create a state
                // for it
                ContentItemTO item = getContentItem(site, path, 0);
                objectStateService.insertNewEntry(site, item);
                itemState = objectStateService.getObjectState(site, path);
            }
            if (itemState != null) {
                if (itemState.getSystemProcessing() != 0) {
                    // TODO: SJ: Review and refactor/redo
                    logger.error("Error Content {0} is being processed (Object State is system " + "processing);", path);
                    throw new ServiceLayerException("Content " + path + " is in system processing, we can't write " + "it");
                }
                objectStateService.setSystemProcessing(site, path, true);
            } else {
                logger.error("the object state is still null even after attempting to create it for site {0} " + "path {1} fileName {2} contentType {3}" + ".", site, path, fileName, contentType);
            }
        } else {
            // Content does not exist; check for moved content and deleted content
            if (objectStateService.deletedPathExists(site, path) || objectMetadataManager.movedPathExists(site, path)) {
                throw new ServiceLayerException("Content " + path + " for site " + site + ", cannot be created " + "because this name/URL was in use by another content item that has been moved or" + " deleted by not yet published.");
            }
        }
        // TODO: SJ: Item processing pipeline needs to be configurable without hardcoded paths
        // TODO: SJ: We need to consider various mechanics for pipeline choice other than path
        // TODO: SJ: Furthermore, we already have similar machinery in Crafter Core that might be a fit for some
        // TODO: SJ: of this work
        // default chain is asset type
        String chainID = DmConstants.CONTENT_CHAIN_ASSET;
        if (path.startsWith("/site")) {
            // anything inside site is a form based XML
            // example /site/website
            // /site/components
            // /site/books
            chainID = DmConstants.CONTENT_CHAIN_FORM;
        }
        // TODO: SJ: Content is being written here via the pipeline, this is not the best design and will be
        // TODO: SJ: refactored in 2.7.x
        processContent(id, input, true, params, chainID);
        // Item has been processed and persisted, set system processing state to off
        objectStateService.setSystemProcessing(site, path, false);
        // TODO: SJ: The path sent from the UI is inconsistent, hence the acrobatics below. Fix in 2.7.x
        String savedFileName = params.get(DmConstants.KEY_FILE_NAME);
        String savedPath = params.get(DmConstants.KEY_PATH);
        relativePath = savedPath;
        if (!savedPath.endsWith(savedFileName)) {
            relativePath = savedPath + FILE_SEPARATOR + savedFileName;
        }
        // TODO: SJ: Why is the item being loaded again? Why is the state being set to system not processing
        // TODO: SJ: again? Why would we insert the item into objectStateService again?
        // TODO: SJ: Refactor for 2.7.x
        ContentItemTO itemTo = getContentItem(site, relativePath, 0);
        if (itemTo != null) {
            if (isSaveAndClose) {
                objectStateService.transition(site, itemTo, SAVE);
            } else {
                objectStateService.transition(site, itemTo, SAVE_FOR_PREVIEW);
            }
            objectStateService.setSystemProcessing(site, itemTo.getUri(), false);
        } else {
            // TODO: SJ: the line below doesn't make any sense, itemTo == null => insert? Investigate and fix in
            // TODO: SJ: 2.7.x
            objectStateService.insertNewEntry(site, itemTo);
        }
        // Sync preview
        PreviewEventContext context = new PreviewEventContext();
        context.setSite(site);
        eventService.publish(EVENT_PREVIEW_SYNC, context);
    } catch (RuntimeException e) {
        logger.error("error writing content", e);
        // TODO: SJ: Why setting two things? Are we guessing? Fix in 2.7.x
        objectStateService.setSystemProcessing(site, relativePath, false);
        objectStateService.setSystemProcessing(site, path, false);
        throw e;
    }
}
Also used : EntitlementException(org.craftercms.commons.entitlements.exception.EntitlementException) ContentItemTO(org.craftercms.studio.api.v1.to.ContentItemTO) HashMap(java.util.HashMap) ItemState(org.craftercms.studio.api.v1.dal.ItemState) ServiceLayerException(org.craftercms.studio.api.v1.exception.ServiceLayerException) PreviewEventContext(org.craftercms.studio.api.v1.ebus.PreviewEventContext) ValidateParams(org.craftercms.commons.validation.annotations.param.ValidateParams)

Example 18 with PUBLISHED

use of org.craftercms.studio.api.v1.constant.GitRepositories.PUBLISHED in project studio by craftercms.

the class BlobAwareContentRepositoryTest method publishMixFilesTest.

@Test
public void publishMixFilesTest() throws DeploymentException {
    DeploymentItemTO remoteItem = new DeploymentItemTO();
    remoteItem.setSite(SITE);
    remoteItem.setPath(ORIGINAL_PATH);
    DeploymentItemTO localItem = new DeploymentItemTO();
    localItem.setSite(SITE);
    localItem.setPath(LOCAL_PATH);
    DeploymentItemTO pointerItem = new DeploymentItemTO();
    pointerItem.setSite(SITE);
    pointerItem.setPath(POINTER_PATH);
    List<DeploymentItemTO> items = Arrays.asList(remoteItem, localItem);
    proxy.publish(SITE, EMPTY, items, ENV, USER, COMMENT);
    verify(store).publish(eq(SITE), eq(EMPTY), itemsCaptor.capture(), eq(ENV), eq(USER), eq(COMMENT));
    assertTrue(itemsCaptor.getValue().contains(remoteItem), "remote file should have been published");
    verify(localV2).publish(eq(SITE), eq(EMPTY), itemsCaptor.capture(), eq(ENV), eq(USER), eq(COMMENT));
    assertTrue(itemsCaptor.getValue().contains(pointerItem), "pointer file should have been published");
    verify(localV2).publish(eq(SITE), eq(EMPTY), itemsCaptor.capture(), eq(ENV), eq(USER), eq(COMMENT));
    assertTrue(itemsCaptor.getValue().contains(localItem), "local file should have been published");
}
Also used : DeploymentItemTO(org.craftercms.studio.api.v1.to.DeploymentItemTO) Test(org.testng.annotations.Test)

Aggregations

Repository (org.eclipse.jgit.lib.Repository)14 ContentRepository (org.craftercms.studio.api.v1.repository.ContentRepository)11 IOException (java.io.IOException)10 CryptoException (org.craftercms.commons.crypto.CryptoException)10 GitRepositoryHelper (org.craftercms.studio.api.v2.utils.GitRepositoryHelper)10 ServiceLayerException (org.craftercms.studio.api.v1.exception.ServiceLayerException)9 RemoteRepository (org.craftercms.studio.api.v2.dal.RemoteRepository)9 Git (org.eclipse.jgit.api.Git)9 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)9 Path (java.nio.file.Path)7 CheckoutCommand (org.eclipse.jgit.api.CheckoutCommand)5 InvalidRemoteUrlException (org.craftercms.studio.api.v1.exception.repository.InvalidRemoteUrlException)4 UserNotFoundException (org.craftercms.studio.api.v1.exception.security.UserNotFoundException)4 PullCommand (org.eclipse.jgit.api.PullCommand)4 Ref (org.eclipse.jgit.lib.Ref)4 File (java.io.File)3 URISyntaxException (java.net.URISyntaxException)3 SiteNotFoundException (org.craftercms.studio.api.v1.exception.SiteNotFoundException)3 DeploymentException (org.craftercms.studio.api.v1.service.deployment.DeploymentException)3 ContentItemTO (org.craftercms.studio.api.v1.to.ContentItemTO)3