Publishing module

Collaboration Bundled: Community Edition

Edition

CE

License

MLA, GPL

Issues

Maven site

Latest

1.3.20

The module handles publishing of content from an author instance to a public instance. In DX Core, the functionality of this module is extended by the Publishing Transactional module, which ensures synchronization of content between multiple public instances.

Content publishing and content synchronization

Always wait with content publishing actions until all content synchronization tasks have been finished.

If you attempt to publish a page while the Synchronization module is mid-sync and hasn’t yet synchronized the page’s parent, the publishing process will fail.

Module structure

The module (parent) consists of four submodules. All of the submodules are required for the correct functioning of the publishing feature.

artifactID

magnolia-publishing-parent

Parent reactor.

     magnolia-publishing-core

Provides the main functionality.

     magnolia-publishing-sender

Handles send operations to the public instance.

     magnolia-publishing-receiver

Handles receive requests on the public instance.

     magnolia-publishing-app

Generates new publishing keys and provides a publishing monitor.

Installing with Maven

Bundled modules are automatically installed for you.

If the module is unbundled, add the following to your bundle including your project’s <dependencyManagement> section and your webapp’s <dependencies> section. If the module is unbundled but the parent POM manages the version, add the following to your webapp’s <dependencies> section.

<dependency>
  <groupId>info.magnolia.publishing</groupId>
  <artifactId>magnolia-publishing-core</artifactId>
  <version>1.3.20</version> (1)
</dependency>
1 Should you need to specify the module version, do it using <version>.
<dependency>
  <groupId>info.magnolia.publishing</groupId>
  <artifactId>magnolia-publishing-sender</artifactId>
  <version>1.3.20</version> (1)
</dependency>
1 Should you need to specify the module version, do it using <version>.
<dependency>
  <groupId>info.magnolia.publishing</groupId>
  <artifactId>magnolia-publishing-receiver</artifactId>
  <version>1.3.20</version> (1)
</dependency>
1 Should you need to specify the module version, do it using <version>.
<dependency>
  <groupId>info.magnolia.publishing</groupId>
  <artifactId>magnolia-publishing-app</artifactId>
  <version>1.3.20</version> (1)
</dependency>
1 Should you need to specify the module version, do it using <version>.

Configuration

Publishing is configured in Configuration > /modules/publishing-core.

Be very careful when modifying the configuration of publishing and always test the changes thoroughly before applying them to a live environment. Sometimes there may exist a better way of solving a publishing-related problem than by tweaking a publishing configuration.

Main part

The main part of the configuration is under /modules/publishing-core/config.

Node name

πŸ“ modules

     πŸ“ publishing-core

         πŸ“ config

             βΈ¬ publicationByPathVoters

             βΈ¬ publishingLogStorage

             βΈ¬ receivers

             βΈ¬ operations

publicationByPathVoters

Sets publication by path (default is by uuid) to configured workspaces.

Node name Value

βΈ¬ publicationByPathVoters

     ⬩ op

OR

     βΈ¬ config

         ⬩ op

AND

         βΈ¬ mgnlExchangeWorkspaceName

             ⬩ pattern

config

             ⬩ keyName

mgnlExchangeWorkspaceName

             ⬩ class

info.magnolia.publishing.voter.MapKeyPatternVoter

         βΈ¬ 1stAnd2ndLevelNodes

             ⬩ op

OR

             ⬩ class

info.magnolia.voting.voters.VoterSet

             βΈ¬ mgnlExchangeParentPath

                 ⬩ pattern

^\/[^\/]*$

                 ⬩ keyName

mgnlExchangeParentPath

                 ⬩ class

info.magnolia.publishing.voter.MapKeyPatternVoter

             βΈ¬ mgnlExchangePath

                 ⬩ pattern

^\/[^\/]*(\/[^\/]*)?$

                 ⬩ keyName

mgnlExchangePath

                 ⬩ class

info.magnolia.publishing.voter.MapKeyPatternVoter

     βΈ¬ resources

         βΈ¬ workspace

             ⬩ pattern

resources

             ⬩ keyName

mgnlExchangeWorkspaceName

             ⬩ class

info.magnolia.publishing.voter.MapKeyPatternVoter

publishingLogStorage

Defines where the information about publishing is logged. The default implementation (info.magnolia.publishing.monitor.MemoryPublishingStorage) keeps the information in memory.

Node name Value

βΈ¬ publishingLogStorage

     ⬩ class

info.magnolia.publishing.monitor.MemoryPublishingStorage

receivers

Contains the list of receivers where content will be published.

Node name Value

βΈ¬ receivers

     βΈ¬ magnoliaPublic8080

         ⬩ url

http://localhost:8080/magnoliaPublic

         ⬩ enabled

true

operations

Contains the list of operations provided by Magnolia and the respective operation classes:

  • publish

  • unpublish

  • commit (DX Core only)

  • rollback (DX Core only)

    You can define your own operations and add them to the list, but in this case, you will also have to implement your own send and receive operations. info.magnolia.publishing.operation.SendOperation is a base interface that all send operations must implement.

With a custom-defined operation, you can publish content to something that’s not a Magnolia public instance, for example to a custom API or a Content Delivery Network.

Node name Value

βΈ¬ operations

     βΈ¬ publish

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrTransactionPublicationOperation

         ⬩ sendOperationClass

info.magnolia.publishing.sender.operation.HttpPublicationOperation

     βΈ¬ unpublish

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrTransactionUnpublicationOperation

         ⬩ sendOperationClass

info.magnolia.publishing.sender.operation.HttpUnpublicationOperation

     βΈ¬ activate

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrTransactionPublicationOperation

     βΈ¬ deactivate

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrTransactionUnpublicationOperation

     βΈ¬ commit

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrCommitOperation

         ⬩ sendOperationClass

info.magnolia.publishing.transactional.sender.operation.HttpCommitOperation

     βΈ¬ rollback

         ⬩ receiveOperationClass

info.magnolia.publishing.transactional.receiver.operation.jcr.JcrRollbackOperation

         ⬩ sendOperationClass

info.magnolia.publishing.transactional.sender.operation.HttpRollbackOperation

lockManagerMode property

The property has been introduced with module version 1.2.6. By default, path-based locking is configured using lockManagerMode=path. Node-based locking can be set with lockManagerMode=compatibility.

The setting is applicable only on public instances. Changing the property on the author instance has no effect.

Publish and unpublish commands

Users typically publish content by clicking Publish in the Action bar. The click executes a publish command which pushes the content from the author instance to the public instance(s). Conversely, when users click Unpublish the system executes an unpublish command which deletes the content from the public instance(s).

The publish and unpublish commands are configured in /modules/publishing-core/commands. The default catalog contains the commands which just publish the content without versioning. Magnolia also provides a versioned command catalog. It contains identically named publish and unpublish commands which first version the content and then delegate to the default commands.

Both in the default catalog and in the versioned catalog, the command tree contains also the activate and deactivate commands (not shown below), which extend the publish and unpublish commands, respectively. The two commands are included in the configuration for compatibility reasons.

To use one of these commands, define the catalog and the command name in the action definition. See an example in Executing commands with actions.

Property Description

params

optional

     rule

optional

The rule property is useful when recursively performing a command. Adding the allowedTypes property under the rule property lets you define what should be included on each page. In particular, you can specify nodes such as areas and components, but not subpages.

Available classes:

  • info.magnolia.cms.util.Rule

For example, let’s take the recursive publishing action defined in the configuration below. Using the recursive property means a version is created for every page in the tree. On each page, only objects below page level, such as area or component, are included in the new page versions because of the node type mgnl:contentNode.

Example configuration
...
  publish:
    icon: icon-publish
    $type: jcrCommandAction
    command: publish
    catalog: versioned
    availability:
      rules:
        notDeleted: *notDeleted
          isPublishable: &publishableRule
            $type: jcrPublishableRule
    params:
      recursive: true (1)
      rule:
        class: info.magnolia.cms.util.Rule
        allowedTypes: (2)
          contentNode: mgnl:contentNode (3)
1 Recursive publishing command.
2 The allowedTypes property determines what is included in each page version.
3 Allowed node types set to mgnl:contentNode.

     modifiedOnly

optional, default is false

Option to publish only unpublished or modified pages when publishing pages including subnodes.

     recursive

optional, default is false

When you publish a node and its children, you often end up publishing content whose status is already Published.

Such nodes don’t need to be published, but it’s often more convenient to just publish the whole tree than node-by-node.

To improve the performance of the author instance:

  • Exclude the already-published nodes from the action.

  • Publish the modified nodes only.

This may also help improve scalability, especially in cases where the author instance has a high concurrent load, typically with many editors activating large amounts of content at the same time.

     version

optional

Version of the node to be published.

If not specified, the current state of the node will be published. The property can only be used with recursive=false.

     versionMap

optional

Versions of the node to be published.

If not specified, the current state of the nodes will be published. The property can only be used with recursive=true.

     itemsPerRequest

optional

If defined, instead of transferring nodes one-by-one, the publication process transfers the subtrees that have fewer descendants in one transaction than defined using the itemsPerRequest property.

If the number of descendants is higher, each child will be published one-by-one, which is the same as when itemsPerRequest isn’t defined at all.

It’s therefore better to split flat structures into sub-folders for itemsPerRequest to take effect.

For more suggestions regarding the itemsPerRequest property, see the Configuring itemsPerRequest section below this table.

Setting the itemsPerRequest property causes the modifiedOnly property to be ignored.

     ordering

optional, default is fast

Defines the order in which nodes and their siblings are published on a public instance.

For further details, see Optimizing ordering on the public instance.

Configuring itemsPerRequest

Determining the value of itemsPerRequest depends on how much data you want to send in one HTTP transaction.

It could be, for example, 100 nodes for workspaces without binary data. For the assets workspace, 100 assets might be too much though, depending on the average size of your assets.

You can get an approximate size of data in one transaction by exporting the trees and checking the size of the exported files.
This doesn’t support publishing versions. Therefore, it’s not supported for apps with a publication workflow.


How does itemsPerRequest work?

Consider the following tree structure.

'tour-types':
  'active': {}
  'destinations':
    'europe': {}
    'asia': {}

If you publish /tour-types without itemsPerRequest defined, each node is sent to public instances separately:

INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/destinations].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/destinations/asia].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/destinations/europe].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/active].

Now, for the publish action in the tourCategories.yaml app, let’s set itemsPerRequest to a very small number (just for demonstration purposes):

subApps:
  browser:
    actions:
      publish:
        params:
          itemsPerRequest: 2

Publish /tour-types again.

  • It first tries to publish the whole /tour-types subtree, but it has too many descendants compared to the itemsPerRequest. So, the /tour-types folder has to be published separately.

  • /tour-types/destination has two descendants, and so fits the itemsPerRequest. Therefore, it will be published including its children in one transaction.

  • /tour-types/active doesn’t have children, so it’s published separately. The itemsPerRequest param doesn’t have any effect.

INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/destinations].
INFO  ing.receiver.operation.jcr.JcrPublicationOperation: About to update content under path [/tour-types/active].

In this example, we decreased the number of transactions to just a few. In practice, you can reduce the number of transactions from thousands to dozens, provided the workspace structure has been created as a more or less balanced tree.

Detection of publication failures

The configuration settings in this section are designed to enhance the resilience of all publication requests sent by the publishing module. They address intermittent connection issues by enabling automatic retries, preventing the need to roll back entire publishing transactions.

You can configure the number of retries, the interval period between retries, and header conditions for retry. Configuration is via a .yaml decoration, as shown in the example below. The properties and their default values are described in detail in the properties table.

light-module/decorations/publishing-core/config.yaml
retryConfig:
  retryWait: 3
  retries: 20
  retryHeader: <HEADER_1>, <HEADER_2> (1)
1 Comma-separated response headers.
Property Description

retryConfig

optional

If a publication attempt results in a 5xx code (server error) and the response header contains something listed in the retryHeader property, then the publication attempt is repeated.

     retryWait

optional, default is 2 seconds

The interval period between successive retry attempts.

     retries

optional, default is 10

The maximum number of retries before a publishing request fails and is rolled back.

     retryHeader

optional, default is l5d-proxy-error

A 5xx server error code and any header listed in this property cause the publication request to be retried.

Thread pool size

Optionally, administrators can configure several pool size values in the magnolia.properties file. The default thread pool is sufficient for most setups.

Modifying these settings is only recommended when publishing substantially large assets concurrently. Finding a balance for your system’s resources is necessary to ensure optimal performance when multiple editors work simultaneously and those substantially large asset sizes are published over more public instances.
Property Description

magnolia.publishing.pool.size

optional, default is 10

Size of the default thread pool handling all publication operations in the Publishing module.

magnolia.publishing.prioritizedPool.size

optional

You can initialize a prioritized thread pool if there’s high and heavy traffic in the default thread pool. It helps free up the default thread pool for other regular publication operations. The most active workspaces should also be specified using the magnolia.publishing.prioritizedWorkspaces property below.

By default, this property is disabled; specifying the property enables it.

magnolia.publishing.prioritizedWorkspaces

optional

A list of comma-separated workspace names that have publication tasks handled by a prioritized thread pool. It’s not specified by default.

Disabling publishing

If necessary, you can disable publishing on the public instance(s) by adding the enabled node in Configuration > /server/filters/publishing and setting its value to false.

Publishing on the author instance

The author instance doesn’t serve content directly. When you publish content on an author instance, it must be collected and packaged before the content is sent to public instances. The technical details involved in these steps are described in the following sections.

Collecting

The PublishingCommand collects the content that needs to be (un)published. It then creates a new instance of Sender containing the collected content. The Sender component is responsible for content packaging.

Node collection for different publishing scenarios is outlined below.

  • Publication is recursive:

    • itemsPerRequest is set and if the number of child nodes is less than 1000: nodes are batched into chunks to improve publication speed (however, this does not work with versions).

    • Publishing versions: node versions are collected, and nodes are ordered bottom-up for publishing.

  • Publication isn’t recursive (Default):

    • The current node is taken.

    • Publishing a version: the node’s current version is taken.

Large flat content repositories can negatively impact overall performance, particularly search. For this reason, you must organize pages into a folder hierarchy to ensure optimal performance. Also, features that constantly create content (such as messages, tasks, and versions) should be checked regularly to clean up old content.

Versioning

Upon publication, all nodes are copied to the magnolia-mgnlVersion workspace on the author instance. Depending on how the publication command chain is configured, the content is usually copied before packaging and sending. If no version command is present in the publication command chain, no versions are created. The maxVersionIndex, which defines version limits, is configured in /server/versions and affects the number of versions stored in the mgnlVersion workspace.

Packaging

A Package consists of properties and files that will be sent to the public instance. Packages are only used with a publication and are created by the Packager, which adds the properties and XML exports of the content to a Package.

Sending

The Sender creates an instance of SenderOperation and passes either a Package or a Node to the instance, together with a ReceiverDefinition. Whether a package or node is passed depends on the action involved.

  • Package upon publication

  • Node when unpublishing content

The SendOperation executes the transfer to the public instance.

Publishing on the public instance

Public instances serve content to visitors. Content is received from the author instance and ordered before it becomes accessible on the public instance. Optionally, you can roll back published content; these operations are described in detail in the following sections.

Receiving

The PublicationFilter receives a sender’s request. The request is then sent to the Dispatcher which decides what to do with the request depending on the request headers. The Dispatcher extracts the data from the request and creates a ReceiveOperation responsible for creating/updating/deleting the content.

Ordering of siblings

Published nodes are included before the nearest next sibling existing on all author and public instances. The order of siblings of the published node on public instances isn’t otherwise affected.

Go to the optimize ordering section for more information on adapting the ordering to fulfill your needs.

This default behavior doesn’t take into account the order at any other point in time (such as the time of creating the published version).

Rollback

The magnolia-mgnlSystem workspace is used on public instances in case rollback is necessary if publication failure occurs. Existing published content is copied there before new content is published to the target workspace (for example, website). In case of failure, rollback is initiated, copying content from mgnlSystem back to the target workspace.

Feedback

DX Core

×

Location

This widget lets you know where you are on the docs site.

You are currently perusing through the DX Core docs.

Main doc sections

DX Core Headless PaaS Legacy Cloud Incubator modules