Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redirect Manager: Support for context aware configurations #2564

Merged

Conversation

YegorKozlov
Copy link
Contributor

@YegorKozlov YegorKozlov commented Mar 29, 2021

The patch introduces support for context aware configurations in Redirect Manager. Users can put their redirects in the default storage or create configurations per-context.

UI Changes.

The UI is split into two parts. ACS AEM Commons / Manage Redirects opens the list of redirect configurations, where each config represents a table of redirect rules:
image

The default storage is /conf/global/settings/redirects . This node is created by a repo-init script . The bucket name 'settings' and config name 'redirects' are configurable via OSGi.

Click on a configuration opens the old UI to edit rules. The only change here is that the storage is explicitly passed in the url:
image

Adding rules to the default storage will result in a structure like this;

/conf/global
    + settings
      + redirects
        + rule-1
            - source = "/content/we-retail/page1"
            - target = "/content/we-retail/page2"
            - statusCode = 302
        + rule-2
            - source = "/content/wknd/page1"
            - target = "/content/wknd/page2"
            - statusCode = 302

This requires zero configuration in content sites. Just put your redirects in the global list, replicate them to publish and they will work.

However, there can be cases where user will want to have different configurations for each site, for example, we-retail and wknd would havevtheir own tables of redirects, any other site will fallback to /conf/global :

Redirects for /content/we-retail

/content/we-retail
    + jcr:content
      - cq:conf = "/conf/we-retail"

/conf/we-retail
    + settings
      + redirects
        + rule-1
            - source = "/content/we-retail/page1"
            - target = "/content/we-retail/page2"
            - statusCode = 302

Redirects for /content/wknd

/content/wknd
    + jcr:content
      - cq:conf = "/conf/wknd"

/conf/we-retail
    + settings
      + redirects
        + rule-1
            - source = "/content/wknd/page1"
            - target = "/content/wknd/page2"
            - statusCode = 302

Redirects for other sites

# sites that don't have cq:conf will fallback to this configuration
/conf/global
    + settings
      + redirects
        + rule-1
            - source = "/content/geometrixx/page1"
            - target = "/content/geometrixx/page2"
            - statusCode = 302

Configuration Resolution

The code leverages org.apache.sling.caconfig.resource.ConfigurationResourceResolver#getResource(Resource resource, String bucketName, String configName) to lookup configurations based on context. If context config is not set then /conf/global is used as a fallback. In order to resolve contextual configurations a request needs read access to it, e.g. web request to /content/geometrixx/page1 needs to read /conf/global/settings/redirects This is enabled in the repo-init script

# web requests need read access to redirect configurations, e.g. /conf/global/settings/redirects
set ACL for anonymous
    allow jcr:read on /conf  restriction(rep:glob,/*/settings/redirects)
end

Example:

  1. User requests /content/we-retail/page1
  2. RedirectFilter goes up the content tree until a resource with the _cq:conf_property is found: /content/we-retail
  3. Check if a configuration resource exists at the path the property points to: /conf/we-retail
  4. Check if the redirect configuration exists below the configuration resource: /conf/we-retail/settings/redirects
  5. Use /conf/global as fallback path

Upgrade rules created with v5.0.4

The default storage in v5.0.4 was /conf/acs-commons/redirects which is not compatible with context aware configurations. This means redirects previously defined under /conf/acs-commons/redirects need to be moved to /conf/global/settings/redirects

This is done automatically on first load of the GUI. The redirects are moved and user sees a message:

image
we can reflect it in the release notes too.

Changes in the 'Until Date' field

In v5.0.4 the 'Until Date' field was saved a 'dd MMMM yyyy' string, e.g. '16 February 2001'. This implementation had two issues

  1. not flexible because untilDate was rounded to days
  2. failed on non-english locales, e.g. when user is running their browser in the ES locale and AEM is running EN. The browser will submit '05 abril 2021' but AEM expects '05 April 2021'.
    This patch changes untilDate to be saved as a JCR Date. Any previously saved untilDate are converted. See RedirectManager: problems with non-english locale #2569

Paginated output

Each redirect on http://localhost:4502/apps/acs-commons/content/redirect-manager.html is rendered as a sly-resource which can result in a 'Too Many Includes' exception when the number of redirects is large (greater than 1500, configurable in org.apache.sling.engine.impl.SlingMainServlet) To avoid this error redirects are paginated . The pages size is 1000. If the number of redirects is less than 1000 then user will use the usual UI. If the number of redirects is greater than 100 the user will see the 1st page and a navigation bar below:
image
For now search works within the current page only.

New Optional "Notes" field

See #2571
The "Create Rule" dialog now includes a new optional field "Notes"
image

@coveralls
Copy link

coveralls commented Mar 29, 2021

@davidjgonzalez
Copy link
Contributor

test.xlsx

Here's my test Excel file with ~50k rows if its useful.

private static final long serialVersionUID = -3564475196678277711L;

@Reference
private RedirectFilterMBean redirectFilter;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private RedirectFilterMBean redirectFilter;
private transient RedirectFilterMBean redirectFilter;

@YegorKozlov
Copy link
Contributor Author

The PR is finally in a good shape to get reviewed and applied.

@davidjgonzalez Thanks for the spreadsheet. The tool can now swallow it without chocking. I did some load testing using Apache Benchmark and didn't see any significant performance impact with the ~50K set.

BTW, I see you are using the .html extension in the mappings, e.g.

/this/is/the/original/path/49976.html /this/is/the/new/path/to/redirect/to/49976.html

this is not quite correct. So far the assumption was to use extension-less paths to match request, e.g. the rule below will work but yours won't:

/this/is/the/original/path/49976 /this/is/the/new/path/to/redirect/to/49976

I'm inclined to change it to support both versions, with and without .html. It's a very common habit to append the .html extension and the code should support both.

@davidjgonzalez
Copy link
Contributor

@YegorKozlov awesome! im gonna try to find time this week to check this out! im pumped!

Also, I used the format of the real customer w/ the 50k redirects to mock out the format of this file, FWIW.

@davidjgonzalez davidjgonzalez merged commit fdd9364 into Adobe-Consulting-Services:master May 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants