Problem

You have an existing AEM application which is abed on wcm.io Handler 0.x, and you want to migrate to the latest wcm.io Handler version.

Solution

The biggest differences between wcm.io Handler 0.x and 1.x are:

Besides this there are minor API changes. This page contains a step-to-step list to migrate existing projects.

An example project where all these steps are already done is: https://github.com/wcm-io/wcm-io-samples

Step 1 - Update POM dependencies

Remove these bundles from you deployment:

And instead deploy these bundles:

In your project you need only a compile dependency to org.apache.sling:org.apache.sling.caconfig.api - the other bundles are only required at runtime.

If you are using AEM Mock-based unit tests in your application together with wcm.io Configuration and wcm.io Handler you have to do the following steps in your Maven poms - remove these dependencies:

And instead add (with test scope):

Make sure you have configured the Context-Aware Configuration bnd plugin in your pom hierarchy - or inherit from io.wcm.maven:io.wcm.maven.global-parent where it is already configured.

Additionally update all other wcm.io Bundles to the latest version - in most cases this involves an update of the major version from 0.x to 1.x. In case of AEM Mocks update to the latest 1.x version for AEM 6.2, and to the latest 2.x version if you are using AEM 6.2 or higher.

Step 2 - Migrate Application Provider

Remove the OSGi service implementing the io.wcm.config.spi.ApplicationProvider interface.

Instead, add a Bundle header you pom containing the regular expression describing which paths are matching for the application - example:

<plugin>
  <groupId>org.apache.felix</groupId>
  <artifactId>maven-bundle-plugin</artifactId>
  <configuration>
    <instructions>
      <!-- All wcm.io Handler SPI implementation only get active for the resource paths of this application -->
      <Wcmio-CAService-ContextPathRegex>^/content/(dam/)?myapp(/.*)?$</Wcmio-CAService-ContextPathRegex>
    </instructions>
  </configuration>
</plugin>

This pattern applies to all context-aware services (e.g. URL, Link, Media Handler configuration) contained in the bundle.

Step 3 - Migrate Configuration Customization

Remove the OSGi service implementing io.wcm.config.spi.ConfigurationFinderStrategy (e.g. extending AbstractAbsoluteParentConfigurationFinderStrategy or AbstractRootTemplateConfigurationFinderStrategy).

Instead, add a corresponding OSGi configuration based on the Context Path Strategies from wcm.io Context-Aware Configuration Extensions - example:

  io.wcm.caconfig.extensions.contextpath.impl.AbsoluteParentContextPathStrategy-example
    levels=I["2","3"]
    contextPathRegex="^/content(/.+)$"
    configPathPatterns=["/conf$1","/content$1/tools/config/jcr:content"]

This example defines /content$1/tools/config/jcr:content as additional context path - this only makes sense when you also use the "Tools Config Page" persistence strategy as described here. This was the default recommended setup strategy in wcm.io Configuration 0.x:

  io.wcm.caconfig.extensions.persistence.impl.ToolsConfigPagePersistenceStrategy
    enabled=B"true"
    configPageTemplate="/apps/myapp/templates/admin/configEditor"
    structurePageTemplate="/apps/myapp/templates/framework/structureElement"

Additionally it is recommeded to disable the configuration editor on publish:

[configurations runModes=publish]

  # Disable Configuration Editor on publish
  io.wcm.caconfig.editor.impl.EditorConfig
    enabled=B"false"

Step 4 - Migrate parameter definitions

Remove OSGi services implementing io.wcm.config.spi.ParameterProvider and the associated class with constants holding the parameter definitions.

Instead, add annotation classes with @Configuration annotation as described in the Sling Context-Aware Configuration documentation for your parameter. You can create one single annotation class, or multiple grouping the parameters in logical units.

This changes the content structure how the configuration is stored in the repository. If you have existing configuration content you have to migrate it manually or via a script.
Example of the configuration storage change when the ToolsConfigPagePersistenceStrategy is used:

  • Old configuration data location: tools/config/jcr:content/config
  • New location: tools/config/jcr:content/sling:configs/<your-annotation-class-name>

Step 5 - Switch to Context-Aware Configuration Editor

In your configuration editor template definition change the resource type /apps/wcm-io/config/editor/components/page/editor to /apps/wcm-io/caconfig/editor/components/page/editor.

If you used this resource type directly in your template and not created your own resource type to inherit from it you have to replace the resource type in all existing config content pages in the repository as well.

Step 6 - Migrate to latest URL Handler SPI

If you have implemented io.wcm.handler.url.spi.UrlHandlerConfig (e.g. by extending io.wcm.handler.url.spi.helpers.AbstractUrlHandlerConfig):

Step 7 - Migrate to latest Media Handler SPI

Media Formats:

If you have implemented io.wcm.handler.media.spi.MediaHandlerConfig (e.g. by extending io.wcm.handler.media.spi.helpers.AbstractMediaHandlerConfig):

Step 8 - Migrate to latest Link Handler SPI

If you have implemented io.wcm.handler.link.spi.LinkHandlerConfig (e.g. by extending io.wcm.handler.link.spi.helpers.AbstractLinkHandlerConfig):

Step 9 - Migrate unit test context

Remove the following statements from your unit test setup code:

And instead use the new Mock context plugins like this:

import static io.wcm.testing.mock.wcmio.caconfig.ContextPlugins.WCMIO_CACONFIG;
import static io.wcm.testing.mock.wcmio.handler.ContextPlugins.WCMIO_HANDLER;
import static io.wcm.testing.mock.wcmio.sling.ContextPlugins.WCMIO_SLING;
import static org.apache.sling.testing.mock.caconfig.ContextPlugins.CACONFIG;

@Rule
public AemContext = new AemContextBuilder()
        .plugin(CACONFIG)
        .plugin(WCMIO_SLING, WCMIO_CACONFIG, WCMIO_HANDLER)
        .build();

Register the configuration classes you have created for your application - example:

MockContextAwareConfig.registerAnnotationClasses(context, MyConfig.class);

If you want to read and write configurations in your unit test code, or have code that depends on context paths (e.g. for detecting the site root level for the URL handler), it is recommended to also register a context path strategy for convenience - example:

MockCAConfig.contextPathStrategyAbsoluteParent(context, 2, 3);

The strategy should match what you've defined in step 2.

For setting up OSGi services in your test context setup:

Step 10 - Check for Handler API changes

There are only small API changes between Handler 0.x and 1.x. If you encounter a compile error you have to change your code slightly.

The changes are listed in the changelog for the 1.0.0 version:

Step 11 - Optional: Update CONGA configuration

If you are using CONGA you may have defined a override rule like this in your AEM system configuration template:

{{#if configOverrides}}
  # Override site configuration
  io.wcm.config.core.override.impl.OsgiConfigOverrideProvider-override
    enabled=B"true"
    description="Site URL Config Overrides"
    overrides=[
      {{~#each configOverrides ~}}
        {{~#each this ~}}
          "[{{../@key}}]{{@key}}\={{this}}",
        {{~/each ~}}
      {{~/each ~}}
    ]
{{/if}}

Change it to:

{{#if configOverrides}}
  # Override site configuration
  org.apache.sling.caconfig.impl.override.OsgiConfigurationOverrideProvider-override
    enabled=B"true"
    description="Site URL Config Overrides"
    overrides=[
      {{~#each configOverrides ~}}
        {{~#each this ~}}
          "[{{../@key}}]{{this}}",
        {{~/each ~}}
      {{~/each ~}}
    ]
{{/if}}

and use a syntax like this in the environment definitions to configure overrides:

  # Force-Override site URLs in all site configs on the system
  configOverrides:
    "/content/myapp":
    - io.wcm.handler.url.SiteConfig/siteUrl="http://www.myapp.net"
    - io.wcm.handler.url.SiteConfig/siteUrlSecure="https://www.myapp.net"
    - io.wcm.handler.url.SiteConfig/siteUrlAuthor="https://author.myapp.net"


Related articles



Related issues