Skip to content

Commit c6b64e2

Browse files
authored
#3551 - added logic to check the correct parent node if the redirect … (#3552)
* #3551 - added logic to check the correct parent node if the redirect belongs to a sharded collection.
1 parent 81d3d57 commit c6b64e2

File tree

6 files changed

+77
-9
lines changed

6 files changed

+77
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com)
1010

1111
## Unreleased ([details][unreleased changes details])
1212

13+
- #3536 Granite Include Obscures included Resource Type
1314
- #3537 Content Sync: preserve mix:referenceable mixin on Assets and Content Fragments
15+
- #3551 Redirect Manager: correctly determine the redirect rules publication status for sharded and non-sharded redirects.
1416
- #3555 Content Sync: prevent timeout errors when sync-ing AEM cloud instances with large volumes of data
1517
- #3560 Redirect Manager: url-encode search terms in Full Text search mode
16-
- #3536 Granite Include Obscures included Resource Type
1718
- #3562 Fixed compilation errors in iscurrentusermemberof render condition
1819

1920
## 6.11.0 - 2025-03-14

bundle/src/main/java/com/adobe/acs/commons/redirects/models/RedirectRule.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@
3232
import javax.annotation.PostConstruct;
3333
import javax.inject.Named;
3434
import java.lang.invoke.MethodHandles;
35-
import java.util.List;
3635
import java.util.ArrayList;
37-
import java.util.Collections;
3836
import java.util.Arrays;
39-
import java.util.Objects;
4037
import java.util.Calendar;
38+
import java.util.Collections;
39+
import java.util.List;
40+
import java.util.Objects;
4141
import java.util.regex.Matcher;
4242
import java.util.regex.Pattern;
4343
import java.util.regex.PatternSyntaxException;
@@ -63,6 +63,7 @@ public class RedirectRule {
6363
public static final String CASE_INSENSITIVE_PROPERTY_NAME = "caseInsensitive";
6464
public static final String REDIRECT_RESOURCE_REQUEST_ATTRIBUTE = "redirectResource";
6565
public static final String PRESERVE_QUERY_STRING = "preserveQueryString";
66+
public static final String SHARD_NAME_PREFIX = "shard-";
6667

6768
@ValueMapValue
6869
private String source;
@@ -333,7 +334,9 @@ public RedirectState getState() {
333334
* @return whether the redirect is published
334335
*/
335336
public boolean isPublished() {
336-
Calendar lastReplicated = resource.getParent().getValueMap().get("cq:lastReplicated", Calendar.class);
337+
Calendar lastReplicated = isSharded()
338+
? Objects.requireNonNull(Objects.requireNonNull(resource.getParent()).getParent()).getValueMap().get("cq:lastReplicated", Calendar.class)
339+
: Objects.requireNonNull(resource.getParent()).getValueMap().get("cq:lastReplicated", Calendar.class);
337340
boolean isPublished = lastReplicated != null;
338341
boolean modifiedAfterPublication = isPublished
339342
&& ((modified != null && modified.after(lastReplicated)) || (created != null && created.after(lastReplicated)));
@@ -344,4 +347,11 @@ public String getPreserveQueryString() {
344347
return preserveQueryString;
345348
}
346349

350+
/**
351+
* @return whether the resource path contains {@link RedirectRule#SHARD_NAME_PREFIX}
352+
*/
353+
public boolean isSharded() {
354+
return resource.getPath().contains(SHARD_NAME_PREFIX);
355+
}
356+
347357
}

bundle/src/main/java/com/adobe/acs/commons/redirects/models/package-info.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515
* See the License for the specific language governing permissions and
1616
* limitations under the License.
1717
*/
18-
@org.osgi.annotation.versioning.Version("6.11.0")
18+
@org.osgi.annotation.versioning.Version("6.12.0")
1919
package com.adobe.acs.commons.redirects.models;

bundle/src/main/java/com/adobe/acs/commons/redirects/servlets/ImportRedirectMapServlet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void update(Resource root, Collection<Map<String, Object>> xlsRedirects, Map<Str
153153
for (Map<String, Object> props : xlsRedirects) {
154154
count++;
155155

156-
String shardName = "shard-" + count / SHARD_SIZE;
156+
String shardName = RedirectRule.SHARD_NAME_PREFIX + count / SHARD_SIZE;
157157
String sourcePath = (String) props.get(SOURCE_PROPERTY_NAME);
158158
Resource shard = root.getChild(shardName);
159159
if(shard == null){

bundle/src/test/java/com/adobe/acs/commons/redirects/RedirectResourceBuilder.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,22 @@ public class RedirectResourceBuilder {
3838
private final String configPath;
3939
private final Map<String, Object> props;
4040
private String nodeName;
41+
private boolean sharded;
4142

42-
public RedirectResourceBuilder(SlingContext context, String configPath) {
43+
public RedirectResourceBuilder(SlingContext context, String configPath, boolean sharded) {
4344
this.context = context;
4445
this.configPath = configPath;
4546
this.props = new HashMap<>();
47+
this.sharded = sharded;
4648
this.props.put("sling:resourceType", REDIRECT_RULE_RESOURCE_TYPE);
4749
}
4850

51+
public RedirectResourceBuilder(SlingContext context, String configPath) {
52+
this(context, configPath, false);
53+
}
54+
4955
public RedirectResourceBuilder(SlingContext context) {
50-
this(context, DEFAULT_CONF_PATH);
56+
this(context, DEFAULT_CONF_PATH, false);
5157
}
5258

5359
public RedirectResourceBuilder setSource(String source) {
@@ -144,6 +150,11 @@ public Resource build() throws PersistenceException {
144150
ContentBuilder cb = context.create();
145151
Resource configResource = ResourceUtil.getOrCreateResource(
146152
context.resourceResolver(), configPath, REDIRECTS_RESOURCE_PATH, null, true);
153+
if (sharded) {
154+
configResource = ResourceUtil.getOrCreateResource(
155+
context.resourceResolver(), configPath + "/shard-0", (String) null, null, true
156+
);
157+
}
147158
if(nodeName == null) {
148159
nodeName = ResourceUtil.createUniqueChildName(configResource, "rule");
149160
}

bundle/src/test/java/com/adobe/acs/commons/redirects/models/RedirectRuleTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ public void testIsPublished() throws PersistenceException {
207207
Calendar dateInPast = GregorianCalendar.from(ZonedDateTime.now().minusDays(1));
208208
res1.getParent().adaptTo(ModifiableValueMap.class).put("cq:lastReplicated", dateInPast);
209209
assertTrue(rule1.isPublished());
210+
assertFalse(rule1.isSharded());
210211

211212
Resource res2 = new RedirectResourceBuilder(context)
212213
.setSource("/content/geometrixx/en/1")
@@ -216,6 +217,7 @@ public void testIsPublished() throws PersistenceException {
216217
.build();
217218
RedirectRule rule2 = res2.adaptTo(RedirectRule.class);
218219
assertFalse(rule2.isPublished()); // jcr:created after lastReplicated
220+
assertFalse(rule1.isSharded());
219221

220222
Resource res3 = new RedirectResourceBuilder(context)
221223
.setSource("/content/geometrixx/en/1")
@@ -226,13 +228,57 @@ public void testIsPublished() throws PersistenceException {
226228
.build();
227229
RedirectRule rule3 = res3.adaptTo(RedirectRule.class);
228230
assertFalse(rule3.isPublished()); // jcr:lastModified after lastReplicated
231+
assertFalse(rule1.isSharded());
229232

230233
// update cq:lastReplicated, all child redirects should become active
231234
res1.getParent().adaptTo(ModifiableValueMap.class).put("cq:lastReplicated", Calendar.getInstance());
232235
assertTrue(rule1.isPublished());
233236
assertTrue(rule2.isPublished());
234237
assertTrue(rule3.isPublished());
235238
}
239+
240+
@Test
241+
public void testIsPublishedUnderShard() throws PersistenceException {
242+
Resource res1 = new RedirectResourceBuilder(context, RedirectResourceBuilder.DEFAULT_CONF_PATH, true)
243+
.setSource("/content/geometrixx/en/contact-us")
244+
.setTarget("/content/geometrixx/en/contact-them")
245+
.setStatusCode(302).build();
246+
247+
RedirectRule rule1 = res1.adaptTo(RedirectRule.class);
248+
assertFalse(rule1.isPublished()); // never published
249+
250+
Calendar dateInPast = GregorianCalendar.from(ZonedDateTime.now().minusDays(1));
251+
res1.getParent().getParent().adaptTo(ModifiableValueMap.class).put("cq:lastReplicated", dateInPast);
252+
assertTrue(rule1.isPublished());
253+
assertTrue(rule1.isSharded());
254+
255+
Resource res2 = new RedirectResourceBuilder(context, RedirectResourceBuilder.DEFAULT_CONF_PATH, true)
256+
.setSource("/content/geometrixx/en/1")
257+
.setTarget("/content/geometrixx/en/2")
258+
.setStatusCode(302)
259+
.setCreated(GregorianCalendar.from(ZonedDateTime.now().minusMinutes(60)))
260+
.build();
261+
RedirectRule rule2 = res2.adaptTo(RedirectRule.class);
262+
assertFalse(rule2.isPublished()); // jcr:created after lastReplicated
263+
assertTrue(rule1.isSharded());
264+
265+
Resource res3 = new RedirectResourceBuilder(context, RedirectResourceBuilder.DEFAULT_CONF_PATH, true)
266+
.setSource("/content/geometrixx/en/1")
267+
.setTarget("/content/geometrixx/en/2")
268+
.setStatusCode(302)
269+
.setCreated(GregorianCalendar.from(ZonedDateTime.now().minusMinutes(120)))
270+
.setModified(GregorianCalendar.from(ZonedDateTime.now().minusMinutes(60)))
271+
.build();
272+
RedirectRule rule3 = res3.adaptTo(RedirectRule.class);
273+
assertFalse(rule3.isPublished()); // jcr:lastModified after lastReplicated
274+
assertTrue(rule1.isSharded());
275+
276+
// update cq:lastReplicated, all child redirects should become active
277+
res1.getParent().getParent().adaptTo(ModifiableValueMap.class).put("cq:lastReplicated", Calendar.getInstance());
278+
assertTrue(rule1.isPublished());
279+
assertTrue(rule2.isPublished());
280+
assertTrue(rule3.isPublished());
281+
}
236282

237283
@Test
238284
public void testRedirectRuleFromRequestAttribute() {

0 commit comments

Comments
 (0)