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,80 @@
/*-
* #%L
* ACS AEM Commons Bundle
* %%
* Copyright (C) 2013 - 2024 Adobe
* %%
Copy link
Contributor

Choose a reason for hiding this comment

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

@YegorKozlov I'm not sure if that makes sense - or should rather https://github.com/Adobe-Consulting-Services/acs-aem-commons/blob/master/.codeclimate/header.txt be tuned instead? Also the other Java files do not seem to adhere to this pattern.

@kwin @joerghoh @davidjgonzalez WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@krystiannowak this %% thing does not make much sense to me, but I believe we've always had it, since the header check was introduced in #1345 back in 2018

Also the other Java files do not seem to adhere to this pattern.

Yep. We have quite a bit of the header variations across the project.

* 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.
* #L%
*/
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
@SuppressWarnings("java:S3457")
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,137 @@
/*-
* #%L
* ACS AEM Commons Bundle
* %%
* 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.
* #L%
*/
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