Skip to content

Commit 1534ba3

Browse files
committed
Import developments of ESB-210 e ESB-658 in entando-engine module:
- DeepDebuger - ReloadConfiguration - jsessionIdSecure Flag
1 parent 1525cee commit 1534ba3

File tree

15 files changed

+600
-67
lines changed

15 files changed

+600
-67
lines changed

engine/src/main/java/com/agiletec/aps/system/ApsSystemUtils.java

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
*/
1414
package com.agiletec.aps.system;
1515

16+
import jakarta.servlet.http.HttpServletRequest;
1617
import org.entando.entando.ent.util.EntLogging.EntLogger;
1718
import org.entando.entando.ent.util.EntLogging.EntLogFactory;
1819
import org.slf4j.Marker;
1920
import org.slf4j.MarkerFactory;
2021

22+
import java.util.Enumeration;
23+
2124
/**
2225
* Utility class for system logger
2326
*
@@ -29,6 +32,12 @@ public class ApsSystemUtils {
2932
private static final Marker startupMarker = MarkerFactory.getMarker("STARTUP");
3033
private static final boolean ENABLE_DIRECT_STDOUT_TRACE =
3134
("" + System.getProperty("org.entando.enableDirectStdoutTrace")).equals("true");
35+
36+
/**
37+
* Comma-separated list of feature flags tags that are enabled.
38+
* See {@link ApsSystemUtils#isTagEnabled} for details about the rules.
39+
*/
40+
public static final String ENTANDO_FEATURE_FLAGS = System.getenv("ENTANDO_FEATURE_FLAGS");
3241

3342
private ApsSystemUtils() {
3443
throw new IllegalStateException("Utility class");
@@ -79,4 +88,170 @@ public static boolean directStdoutTrace(String str, boolean force) {
7988
}
8089
}
8190

91+
/**
92+
* ApsDeepDebug is a utility class for managing and printing deep debug messages.
93+
* This class provides methods to log messages conditionally based on specified tags,
94+
* leveraging the environment variable "ENTANDO_FF_DEEP_DEBUG" to control the output.
95+
*/
96+
public static class ApsDeepDebug {
97+
public static final String FORCE_TAG_PREFIX = "::";
98+
private static final String SEP_LW = "▔▔▔▔▔▔▔▔▔▔";
99+
private static final String SEP_UP = "▁▁▁▁▁▁▁▁▁▁";
100+
private static final String SEP_FL = "▒";
101+
public static final String ENTANDO_FF_DEEP_DEBUG = System.getenv("ENTANDO_FF_DEEP_DEBUG");
102+
103+
/**
104+
* Prints - if allowed by the implicit tag "print" - a single deep debug message
105+
*/
106+
public static boolean print(String message) {
107+
return print(null, "", message);
108+
}
109+
110+
/**
111+
* Prints - if allowed by the given tag - a single deep debug message
112+
*/
113+
public static boolean print(String tag, String message) {
114+
return print(tag, "", message);
115+
}
116+
117+
/**
118+
* Prints - if allowed by the given tag - multiple deep messages
119+
*/
120+
public static boolean print(String tag, String prefix, String... messages) {
121+
return print(tag, prefix, false, messages);
122+
}
123+
124+
/**
125+
* Prints - if allowed by the given tag - multiple deep messages
126+
*/
127+
public synchronized static boolean print(String tag, String prefix, boolean suppressTitle, String... messages) {
128+
if (isTagEnabled(tag)) {
129+
if (prefix == null) prefix = "├ ";
130+
if (tag == null) suppressTitle = true;
131+
132+
try {
133+
StringBuilder sb = new StringBuilder();
134+
if (!suppressTitle) addHeader(tag, sb);
135+
for (String str : messages) {
136+
if (!suppressTitle) {
137+
sb.append(prefix).append(" ");
138+
}
139+
sb.append(str).append("\n");
140+
}
141+
if (!suppressTitle) {
142+
addFooter(sb);
143+
}
144+
System.out.println(sb);
145+
} catch (Throwable t) {
146+
logger.warn(String.format("Error printing the deep debug message"), t);
147+
}
148+
return true;
149+
} else {
150+
return false;
151+
}
152+
}
153+
154+
public static void printHttpRequest(String tag, HttpServletRequest request) {
155+
if (isTagEnabled(tag)) {
156+
Enumeration<String> headerNames = request.getHeaderNames();
157+
StringBuilder sb = new StringBuilder();
158+
addHeader(tag, sb).append("~ ").append(request.getRequestURL()).append("\n");
159+
while (headerNames.hasMoreElements()) {
160+
String headerName = headerNames.nextElement();
161+
Enumeration<String> headerValues = request.getHeaders(headerName);
162+
while (headerValues.hasMoreElements()) {
163+
String headerValue = headerValues.nextElement();
164+
sb.append("~ ").append(headerName).append(": ").append(headerValue).append("\n");
165+
}
166+
}
167+
addFooter(sb);
168+
print(sb.toString());
169+
}
170+
}
171+
172+
private static void addFooter(StringBuilder s) {
173+
s.append(SEP_LW + SEP_LW + SEP_LW + SEP_LW + SEP_LW + SEP_LW + SEP_LW + SEP_LW + SEP_LW + SEP_LW);
174+
}
175+
176+
private static StringBuilder addHeader(String title, StringBuilder s) {
177+
return s.append("\n" + SEP_UP + SEP_UP + SEP_UP + SEP_UP + SEP_UP + SEP_UP + SEP_UP + SEP_UP + SEP_UP + SEP_UP + "\n")
178+
.append(title).append("\n");
179+
}
180+
181+
/**
182+
* Checks if a tag is enabled according to ENTANDO_FF_DEEP_DEBUG
183+
* Check also {@link ApsSystemUtils#isTagEnabled}
184+
*/
185+
public static boolean isTagEnabled(String tag) {
186+
return ApsSystemUtils.isTagEnabled(getDeepDebugFF(), tag);
187+
}
188+
189+
/**
190+
* Prints a feature flare, which is a signal that a feature was enabled
191+
*/
192+
public static void printFeatureFlare(String tag, String flareName, boolean alwaysPrint) {
193+
String sep = SEP_FL.repeat(tag.length() + 4 + 4);
194+
print(
195+
((alwaysPrint) ? FORCE_TAG_PREFIX : "") + "FLARE" + ((flareName != null) ? ":" + tag : ""),
196+
null,
197+
true,
198+
"", sep, SEP_FL + SEP_FL + SEP_FL + " " + tag + " " + SEP_FL + SEP_FL + SEP_FL, sep, ""
199+
);
200+
}
201+
202+
public static void printFeatureFlare(String flareName) {
203+
printFeatureFlare(null, flareName, false);
204+
}
205+
}
206+
207+
public static String getEnv(String name, String def) {
208+
String res = System.getenv(name);
209+
return (res != null) ? res : def;
210+
}
211+
212+
public static boolean getEnvFlag(String name, boolean def) {
213+
String res = System.getenv(name);
214+
return res != null ? Boolean.parseBoolean(res) : def;
215+
}
216+
217+
/**
218+
* Checks if a FEAURE is enabled according to ENTANDO_FF_TAGS
219+
* Check also {@link ApsSystemUtils#isTagEnabled}
220+
*/
221+
public static boolean isFeatureEnabled(String tag) {
222+
return ApsSystemUtils.isTagEnabled(getFeatureFlags(), tag);
223+
}
224+
225+
/**
226+
* Checks if a tag is enabled.
227+
* <pre>
228+
* A tag is enabled if "enabledTags" lists it or one of its subtags.
229+
* A tag is divided in subtags by the char ":"</p>
230+
*
231+
* For instance, if the tag "A-FLAG" is present in enabledTags it would enable:
232+
* - The tag "A-FLAG"
233+
* - The tags like "A-FLAG:SOMETHING" (note that the subtags order doesn't matter)
234+
* </pre>
235+
*/
236+
public static boolean isTagEnabled(String enabledTags, String tag) {
237+
if (enabledTags == null) return false;
238+
if (enabledTags.equals("*") || enabledTags.equals("true")) return true;
239+
if (tag == null) return false;
240+
enabledTags = "," + enabledTags + ",";
241+
if (enabledTags.contains("," + tag + ",")) return true;
242+
for (String subtag : tag.split(":")) {
243+
if (enabledTags.contains("," + subtag + ",")) return true;
244+
}
245+
return false;
246+
}
247+
248+
/* Mockable getter of the constant */
249+
public static String getFeatureFlags() {
250+
return ENTANDO_FEATURE_FLAGS;
251+
}
252+
253+
static public String getDeepDebugFF() {
254+
return ApsDeepDebug.ENTANDO_FF_DEEP_DEBUG;
255+
}
256+
82257
}

engine/src/main/java/com/agiletec/aps/system/common/AbstractGenericCacheWrapper.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Map;
2121
import java.util.stream.Collectors;
2222
import org.entando.entando.aps.system.exception.CacheItemNotFoundException;
23+
import org.entando.entando.aps.system.services.cache.IFCacheWithPipeline;
2324
import org.springframework.cache.Cache;
2425

2526
/**
@@ -62,16 +63,18 @@ protected void insertAndCleanCache(Cache cache, Map<String, O> objects) {
6263
}
6364

6465
protected void insertAndCleanCache(Cache cache, Map<String, O> objects, String codesCacheKey, String cacheKeyPrefix) {
65-
List<String> oldCodes = this.get(cache, codesCacheKey, List.class);
66-
List<String> codes = new ArrayList<>();
67-
for (Map.Entry<String, O> entry: objects.entrySet()) {
68-
cache.put(cacheKeyPrefix + entry.getKey(), entry.getValue());
69-
codes.add(entry.getKey());
70-
}
71-
cache.put(codesCacheKey, codes);
72-
List<String> keysToRelease = oldCodes == null ? null :
73-
oldCodes.stream().filter(c -> !objects.containsKey(c)).collect(Collectors.toList());
74-
this.releaseObjects(cache, keysToRelease, cacheKeyPrefix);
66+
IFCacheWithPipeline.pipelined(cache.getNativeCache(), cp -> {
67+
List<String> oldCodes = this.get(cache, codesCacheKey, List.class);
68+
List<String> codes = new ArrayList<>();
69+
for (Map.Entry<String, O> entry: objects.entrySet()) {
70+
cache.put(cacheKeyPrefix + entry.getKey(), entry.getValue());
71+
codes.add(entry.getKey());
72+
}
73+
cache.put(codesCacheKey, codes);
74+
List<String> keysToRelease = oldCodes == null ? null :
75+
oldCodes.stream().filter(c -> !objects.containsKey(c)).collect(Collectors.toList());
76+
this.releaseObjects(cache, keysToRelease, cacheKeyPrefix);
77+
});
7578
}
7679

7780
private void releaseObjects(Cache cache, List<String> keysToRelease, String cacheKeyPrefix) {

engine/src/main/java/com/agiletec/aps/system/services/baseconfig/cache/ConfigManagerCacheWrapper.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.util.List;
2222
import java.util.Map;
2323
import java.util.stream.Collectors;
24+
25+
import org.entando.entando.aps.system.services.cache.IFCacheWithPipeline;
2426
import org.entando.entando.ent.exception.EntException;
2527
import org.entando.entando.ent.util.EntLogging.EntLogFactory;
2628
import org.entando.entando.ent.util.EntLogging.EntLogger;
@@ -69,16 +71,18 @@ protected void insertAndCleanObjectsOnCache(Cache cache, Map<String, String> con
6971

7072
protected void insertAndCleanCache(Cache cache,
7173
Map<String, String> objects, String codesCacheName, String codeCachePrefix) {
72-
List<String> oldCodes = this.get(cache, codesCacheName, List.class);
73-
List<String> codes = new ArrayList<>();
74-
for (Map.Entry<String, String> entry : objects.entrySet()) {
75-
cache.put(codeCachePrefix + entry.getKey(), entry.getValue());
76-
codes.add(entry.getKey());
77-
}
78-
cache.put(codesCacheName, codes);
79-
List<String> keysToRelease = oldCodes == null ? null :
80-
oldCodes.stream().filter(c -> !objects.containsKey(c)).collect(Collectors.toList());
81-
this.releaseObjects(cache, keysToRelease, codeCachePrefix);
74+
IFCacheWithPipeline.pipelined(cache.getNativeCache(), cp -> {
75+
List<String> oldCodes = this.get(cache, codesCacheName, List.class);
76+
List<String> codes = new ArrayList<>();
77+
for (Map.Entry<String, String> entry : objects.entrySet()) {
78+
cache.put(codeCachePrefix + entry.getKey(), entry.getValue());
79+
codes.add(entry.getKey());
80+
}
81+
cache.put(codesCacheName, codes);
82+
List<String> keysToRelease = oldCodes == null ? null :
83+
oldCodes.stream().filter(c -> !objects.containsKey(c)).collect(Collectors.toList());
84+
this.releaseObjects(cache, keysToRelease, codeCachePrefix);
85+
});
8286
}
8387

8488
private void releaseObjects(Cache cache, List<String> keysToRelease, String prefix) {

engine/src/main/java/com/agiletec/aps/system/services/page/cache/PageManagerCacheWrapper.java

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package com.agiletec.aps.system.services.page.cache;
1515

1616
import com.agiletec.aps.system.common.AbstractCacheWrapper;
17+
import org.entando.entando.aps.system.services.cache.IFCacheWithPipeline;
1718
import org.entando.entando.ent.exception.EntException;
1819
import com.agiletec.aps.system.services.page.IPage;
1920
import com.agiletec.aps.system.services.page.IPageDAO;
@@ -110,17 +111,19 @@ private void cleanUtilizers(Cache cache) {
110111

111112
protected void insertObjectsOnCache(Cache cache, PagesStatus status,
112113
IPage newDraftRoot, IPage newOnLineRoot, List<IPage> pageListD, List<IPage> pageListO) {
113-
cache.put(DRAFT_ROOT_CACHE_NAME, newDraftRoot);
114-
cache.put(ONLINE_ROOT_CACHE_NAME, newOnLineRoot);
115-
cache.put(PAGE_STATUS_CACHE_NAME, status);
116-
for (int i = 0; i < pageListD.size(); i++) {
117-
IPage draftPage = pageListD.get(i);
118-
cache.put(DRAFT_PAGE_CACHE_NAME_PREFIX + draftPage.getCode(), draftPage);
119-
}
120-
for (int i = 0; i < pageListO.size(); i++) {
121-
IPage onLinePage = pageListO.get(i);
122-
cache.put(ONLINE_PAGE_CACHE_NAME_PREFIX + onLinePage.getCode(), onLinePage);
123-
}
114+
IFCacheWithPipeline.pipelined(cache.getNativeCache(), cp -> {
115+
cache.put(DRAFT_ROOT_CACHE_NAME, newDraftRoot);
116+
cache.put(ONLINE_ROOT_CACHE_NAME, newOnLineRoot);
117+
cache.put(PAGE_STATUS_CACHE_NAME, status);
118+
for (int i = 0; i < pageListD.size(); i++) {
119+
IPage draftPage = pageListD.get(i);
120+
cache.put(DRAFT_PAGE_CACHE_NAME_PREFIX + draftPage.getCode(), draftPage);
121+
}
122+
for (int i = 0; i < pageListO.size(); i++) {
123+
IPage onLinePage = pageListO.get(i);
124+
cache.put(ONLINE_PAGE_CACHE_NAME_PREFIX + onLinePage.getCode(), onLinePage);
125+
}
126+
});
124127
}
125128

126129
@Override
@@ -579,7 +582,7 @@ private List<String> getWidgetUtilizers(String widgetTypeCode, boolean draft) th
579582
}
580583

581584
private void getWidgetUtilizers(IPage page, Map<String, List> utilizersMap, boolean draft) {
582-
Widget[] widgets = page.getWidgets();
585+
Widget[] widgets = (page != null) ? page.getWidgets() : null;
583586
if (widgets != null) {
584587
for (Widget widget : widgets) {
585588
if (null != widget && null != widget.getTypeCode()) {
@@ -593,7 +596,7 @@ private void getWidgetUtilizers(IPage page, Map<String, List> utilizersMap, bool
593596
}
594597
}
595598
}
596-
String[] childrenCodes = page.getChildrenCodes();
599+
String[] childrenCodes = (page != null) ? page.getChildrenCodes() : null;
597600
if (childrenCodes != null) {
598601
for (String childrenCode : childrenCodes) {
599602
IPage child = (draft) ? this.getDraftPage(childrenCode) : this.getOnlinePage(childrenCode);

0 commit comments

Comments
 (0)