-
Notifications
You must be signed in to change notification settings - Fork 605
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
davidjgonzalez
merged 9 commits into
Adobe-Consulting-Services:master
from
YegorKozlov:develop
Dec 13, 2024
Merged
Changes from 8 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
3be28e1
A servlet to export redirects to a TXT file to use with pipeline-free…
YegorKozlov d747a74
update changelog
YegorKozlov d7ff41d
#3484 add selector to filter redirects by status code
YegorKozlov 858fda6
code climate issues
YegorKozlov dd8862c
fix failing text on win
YegorKozlov 0b631d5
code climate issues
YegorKozlov ef591ba
touch the code to re-trigger build
YegorKozlov be4f170
Merge branch 'master' into develop
davidjgonzalez 0f103df
Merge branch 'master' into develop
davidjgonzalez File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
bundle/src/main/java/com/adobe/acs/commons/redirects/servlets/RewriteMapServlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/*- | ||
* #%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.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 | ||
* | ||
* Usage: http://localhost:4502/conf/my-site/settings/redirects.txt | ||
* To filter by status code: http://localhost:4502/conf/my-site/settings/redirects.301.txt | ||
* | ||
* 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()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
bundle/src/test/java/com/adobe/acs/commons/redirects/servlets/RewriteMapServletTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 2018Yep. We have quite a bit of the header variations across the project.