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

A servlet to export redirects to a TXT file to use with pipeline-free redirects #3484

Merged
merged 9 commits into from
Dec 13, 2024
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com)
<!-- Keep this up to date! After a release, change the tag name to the latest release -->-

## Unreleased ([details][unreleased changes details])
- #3484 - Redirect Manager: A servlet to export redirects to a TXT file to use with pipeline-free redirects

## 6.9.6 - 2024-11-20

Expand Down
2 changes: 1 addition & 1 deletion all/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>com.adobe.acs</groupId>
<artifactId>acs-aem-commons</artifactId>
<version>6.9.7-SNAPSHOT</version>
<version>6.10.0-SNAPSHOT</version>
</parent>

<!-- ====================================================================== -->
Expand Down
2 changes: 1 addition & 1 deletion bundle-cloud/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>com.adobe.acs</groupId>
<artifactId>acs-aem-commons</artifactId>
<version>6.9.7-SNAPSHOT</version>
<version>6.10.0-SNAPSHOT</version>
</parent>

<!-- ====================================================================== -->
Expand Down
2 changes: 1 addition & 1 deletion bundle-onprem/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>com.adobe.acs</groupId>
<artifactId>acs-aem-commons</artifactId>
<version>6.9.7-SNAPSHOT</version>
<version>6.10.0-SNAPSHOT</version>
</parent>

<!-- ====================================================================== -->
Expand Down
2 changes: 1 addition & 1 deletion bundle/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>com.adobe.acs</groupId>
<artifactId>acs-aem-commons</artifactId>
<version>6.9.7-SNAPSHOT</version>
<version>6.10.0-SNAPSHOT</version>
</parent>

<!-- ====================================================================== -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* ACS AEM Commons
*
* Copyright (C) 2013 - 2024 Adobe
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.adobe.acs.commons.redirects.servlets;

import com.adobe.acs.commons.redirects.filter.RedirectFilter;
import com.adobe.acs.commons.redirects.models.RedirectRule;
import org.apache.http.entity.ContentType;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;

import static com.adobe.acs.commons.redirects.servlets.CreateRedirectConfigurationServlet.REDIRECTS_RESOURCE_PATH;


/**
* Servlet for generating an Apache RewriteMap text file to use with
* he Pipeline-free URL Redirects feature in AEM as a Cloud Service
*
* See https://experienceleague.adobe.com/en/docs/experience-manager-cloud-service/content/implementing/content-delivery/pipeline-free-url-redirects
*
*/
@Component(service = Servlet.class, property = {
"sling.servlet.methods=GET",
"sling.servlet.extensions=txt",
"sling.servlet.resourceTypes=" + REDIRECTS_RESOURCE_PATH
})
public class RewriteMapServlet extends SlingSafeMethodsServlet {

private static final long serialVersionUID = -3564475196678277711L;

@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
response.setContentType(ContentType.TEXT_PLAIN.getMimeType());

String[] selectors = request.getRequestPathInfo().getSelectors();
int statusCode = 0;
if(selectors != null && selectors.length > 0) {
statusCode = Integer.parseInt(selectors[0]);
}
Collection<RedirectRule> rules = RedirectFilter.getRules(request.getResource());
PrintWriter out = response.getWriter();
out.printf("# %s Redirects\n", statusCode == 0 ? "All" : "" + statusCode);
for (RedirectRule rule : rules) {
if(statusCode != 0 && rule.getStatusCode() != statusCode) {
continue;
}
String note = rule.getNote();
if(note != null && !note.isEmpty()) {
out.printf("# %s\n", note);
}
out.printf("%s %s\n", rule.getSource(), rule.getTarget());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@org.osgi.annotation.versioning.Version("1.1.0")
@org.osgi.annotation.versioning.Version("1.2.0")
package com.adobe.acs.commons.redirects.servlets;
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* ACS AEM Commons
*
* Copyright (C) 2013 - 2024 Adobe
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.adobe.acs.commons.redirects.servlets;

import com.adobe.acs.commons.redirects.RedirectResourceBuilder;
import org.apache.http.entity.ContentType;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import javax.servlet.ServletException;
import java.io.IOException;
import java.util.Calendar;

import static org.junit.Assert.assertEquals;

/**
* @author Yegor Kozlov
*/
public class RewriteMapServletTest {
@Rule
public SlingContext context = new SlingContext(ResourceResolverType.RESOURCERESOLVER_MOCK);

private RewriteMapServlet servlet;
private final String redirectStoragePath = "/conf/acs-commons/redirects";

@Before
public void setUp() throws PersistenceException {
new RedirectResourceBuilder(context, redirectStoragePath)
.setSource("/content/one")
.setTarget("/content/two")
.setStatusCode(302)
.setUntilDate(new Calendar.Builder().setDate(2022, 9, 9).build())
.setEffectiveFrom(new Calendar.Builder().setDate(2025, 2, 2).build())
.setNotes("note-1")
.setEvaluateURI(true)
.setContextPrefixIgnored(true)
.setTagIds(new String[]{"redirects:tag1"})
.setCreatedBy("john.doe")
.setModifiedBy("jane.doe")
.setCreated(new Calendar.Builder().setDate(1974, 1, 16).build())
.setModified(new Calendar.Builder().setDate(1976, 10, 22).build())
.build();
new RedirectResourceBuilder(context, redirectStoragePath)
.setSource("/content/three")
.setTarget("/content/four")
.setStatusCode(301)
.setTagIds(new String[]{"redirects:tag2"})
.setModifiedBy("john.doe")
.build();

Resource redirects = context.resourceResolver().getResource(redirectStoragePath);
context.request().setResource(redirects);
servlet = new RewriteMapServlet();
}


@Test
public void testGet() throws ServletException, IOException {
MockSlingHttpServletRequest request = context.request();
MockSlingHttpServletResponse response = context.response();

servlet.doGet(request, response);

assertEquals(ContentType.TEXT_PLAIN.getMimeType(), response.getContentType());
String[] lines = response.getOutputAsString().split("\n");
assertEquals(4, lines.length); // header + 2 rules
assertEquals("# All Redirects", lines[0]);
assertEquals("# note-1", lines[1]);

String[] rule1 = lines[2].split(" ");
assertEquals("/content/one", rule1[0]);
assertEquals("/content/two", rule1[1]);

String[] rule2 = lines[3].split(" ");
assertEquals("/content/three", rule2[0]);
assertEquals("/content/four", rule2[1]);
}

@Test
public void test301Selector() throws ServletException, IOException {
MockSlingHttpServletRequest request = context.request();
MockSlingHttpServletResponse response = context.response();

context.requestPathInfo().setSelectorString("301");
servlet.doGet(request, response);

assertEquals(ContentType.TEXT_PLAIN.getMimeType(), response.getContentType());
String[] lines = response.getOutputAsString().split("\n");
assertEquals(2, lines.length); // header + 1 rule
assertEquals("# 301 Redirects", lines[0]);
String[] rule1 = lines[1].split(" ");
assertEquals("/content/three", rule1[0]);
assertEquals("/content/four", rule1[1]);
}

@Test
public void test302Selector() throws ServletException, IOException {
MockSlingHttpServletRequest request = context.request();
MockSlingHttpServletResponse response = context.response();

context.requestPathInfo().setSelectorString("302");
servlet.doGet(request, response);

assertEquals(ContentType.TEXT_PLAIN.getMimeType(), response.getContentType());
String[] lines = response.getOutputAsString().split("\n");
assertEquals(3, lines.length); // header + notes + 1st rule
assertEquals("# 302 Redirects", lines[0]);

String[] rule1 = lines[2].split(" ");
assertEquals("/content/one", rule1[0]);
assertEquals("/content/two", rule1[1]);
}
}
2 changes: 1 addition & 1 deletion oakpal-checks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>com.adobe.acs</groupId>
<artifactId>acs-aem-commons</artifactId>
<version>6.9.7-SNAPSHOT</version>
<version>6.10.0-SNAPSHOT</version>
</parent>

<!-- ====================================================================== -->
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

<groupId>com.adobe.acs</groupId>
<artifactId>acs-aem-commons</artifactId>
<version>6.9.7-SNAPSHOT</version>
<version>6.10.0-SNAPSHOT</version>
<packaging>pom</packaging>

<name>ACS AEM Commons - Reactor Project</name>
Expand Down
2 changes: 1 addition & 1 deletion ui.apps/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>com.adobe.acs</groupId>
<artifactId>acs-aem-commons</artifactId>
<version>6.9.7-SNAPSHOT</version>
<version>6.10.0-SNAPSHOT</version>
</parent>

<!-- ====================================================================== -->
Expand Down
2 changes: 1 addition & 1 deletion ui.config/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>com.adobe.acs</groupId>
<artifactId>acs-aem-commons</artifactId>
<version>6.9.7-SNAPSHOT</version>
<version>6.10.0-SNAPSHOT</version>
</parent>

<!-- ====================================================================== -->
Expand Down
2 changes: 1 addition & 1 deletion ui.content/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<parent>
<groupId>com.adobe.acs</groupId>
<artifactId>acs-aem-commons</artifactId>
<version>6.9.7-SNAPSHOT</version>
<version>6.10.0-SNAPSHOT</version>
</parent>

<!-- ====================================================================== -->
Expand Down
Loading