From 3b3ddb1317644c1f7cc0cf51a2ee6fbaa6f99795 Mon Sep 17 00:00:00 2001
From: Ksiona
Date: Thu, 14 May 2026 14:03:28 +0400
Subject: [PATCH 1/9] fix: documentation mismatch
---
core-context-propagation-quarkus/README.md | 22 +++++++++-------------
core-context-propagation/README.md | 2 +-
2 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/core-context-propagation-quarkus/README.md b/core-context-propagation-quarkus/README.md
index 198fa4944..7d2a2f34c 100644
--- a/core-context-propagation-quarkus/README.md
+++ b/core-context-propagation-quarkus/README.md
@@ -29,6 +29,7 @@ Design overview: [context-propagation diagram](./design.png)
- [Allowed headers](#allowed-headers)
- [API version](#api-version)
- [X-Request-Id](#x-request-id)
+ - [X-Channel-Request-Id](#x-channel-request-id)
- [X-Version](#x-version)
- [X-Version-Name](#x-version-name)
- [X-Nc-Client-Ip](#x-nc-client-ip)
@@ -130,7 +131,7 @@ String xRequestId = xRequestIdContextObject.getRequestId();
Propagates and allows to get `X-Channel-Request-Id` value. If an incoming request does not contain the `X-Channel-Request-Id` header then a random value is not generated and the value defaults to placeholder "-". This context is **blocked by default** and will not be propagated to outgoing requests.
-**Default behavior:** `X-Channel-Request-Id` is NOT propagated to outgoing responses.
+**Default behavior:** `X-Channel-Request-Id` is NOT propagated to outgoing requests.
**Enabling propagation:** To allow `X-Channel-Request-Id` to be propagated to outgoing requests, remove it from the
blacklist using one of the following methods:
@@ -140,23 +141,18 @@ blacklist using one of the following methods:
HEADERS_BLOCKED=
```
-2. **Via system property:**
-```text
--Dheaders.blocked=
-```
-
-3. **Via application.properties (Quarkus):**
+2. **Via application.properties (Quarkus):**
```properties
-headers.blocked=
+quarkus.headers.blocked
```
-**`headers.blocked` rules and limitations**
+**`quarkus.headers.blocked` rules and limitations**
-- Source priority: system property `headers.blocked` overrides environment variable `HEADERS_BLOCKED`.
+- Source priority: system property `quarkus.headers.blocked` overrides environment variable `HEADERS_BLOCKED`.
- Default when not configured at all: `X-Channel-Request-Id` is blocked.
-- Explicit empty value (`headers.blocked=` / `HEADERS_BLOCKED=`): blacklist is empty (nothing is blocked).
-- Explicit non-empty value with valid headers (for example `headers.blocked=Some-Header`): only listed headers are blocked.
-- `X-Request-Id` is non-blockable: if it is listed in `headers.blocked`/`HEADERS_BLOCKED`, it is ignored.
+- Explicit empty value (`quarkus.headers.blocked=` / `HEADERS_BLOCKED=`): blacklist is empty (nothing is blocked).
+- Explicit non-empty value with valid headers (for example `quarkus.headers.blocked=Some-Header`): only listed headers are blocked.
+- `X-Request-Id` is non-blockable: if it is listed in `quarkus.headers.blocked`/`HEADERS_BLOCKED`, it is ignored.
- If configured value contains only non-blockable entries (for example only `X-Request-Id`), default block is applied and `X-Channel-Request-Id` remains blocked.
**MDC Integration:** The channel request ID is automatically stored in MDC under the key `x_channel_request_id` for use in
diff --git a/core-context-propagation/README.md b/core-context-propagation/README.md
index c7a8c6301..40f550846 100644
--- a/core-context-propagation/README.md
+++ b/core-context-propagation/README.md
@@ -145,7 +145,7 @@ Access:
Propagates and allows to get `X-Channel-Request-Id` value. If an incoming request does not contain the `X-Channel-Request-Id` header then a random value is not generated and the value defaults to placeholder "-". This context is **blocked by default** and will not be propagated to outgoing requests.
-**Default behavior:** `X-Channel-Request-Id` is NOT propagated to outgoing responses.
+**Default behavior:** `X-Channel-Request-Id` is NOT propagated to outgoing requests.
**Enabling propagation:** To allow `X-Channel-Request-Id` to be propagated to outgoing requests, remove it from the
blacklist using one of the following methods:
From 3bba46267d00c0ac668e057e16e9026d0f1cdb75 Mon Sep 17 00:00:00 2001
From: Ksiona
Date: Thu, 14 May 2026 16:00:46 +0400
Subject: [PATCH 2/9] fix: documentation mismatch
---
core-context-propagation-quarkus/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core-context-propagation-quarkus/README.md b/core-context-propagation-quarkus/README.md
index 7d2a2f34c..d156f5320 100644
--- a/core-context-propagation-quarkus/README.md
+++ b/core-context-propagation-quarkus/README.md
@@ -143,7 +143,7 @@ HEADERS_BLOCKED=
2. **Via application.properties (Quarkus):**
```properties
-quarkus.headers.blocked
+quarkus.headers.blocked=
```
**`quarkus.headers.blocked` rules and limitations**
From 39c9234130cd30172a850d26eb31527fa3157d93 Mon Sep 17 00:00:00 2001
From: Ksiona
Date: Thu, 14 May 2026 16:29:47 +0400
Subject: [PATCH 3/9] fix: documentation mismatch
---
core-context-propagation-quarkus/README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/core-context-propagation-quarkus/README.md b/core-context-propagation-quarkus/README.md
index d156f5320..6ab77d25c 100644
--- a/core-context-propagation-quarkus/README.md
+++ b/core-context-propagation-quarkus/README.md
@@ -84,7 +84,7 @@ String acceptLanguage = acceptLanguageContextObject.getAcceptedLanguages();
#### Allowed headers
Allows propagating any specified headers. To set a list of headers you should put either
-`HEADERS_ALLOWED` environment or set the `headers.allowed` property. Property has more precedence than env.
+`HEADERS_ALLOWED` environment or set the `quarkus.headers.allowed` property. Property has more precedence than env.
Access:
@@ -94,10 +94,10 @@ Map allowedHeaders = allowedHeadersContextObject.getHeaders();
```
You just need to specify a list of headers in `application.properties`
-in the `headers.allowed` property. For example:
+in the `quarkus.headers.allowed` property. For example:
```properties
-headers.allowed=myheader1,myheader2,...
+quarkus.headers.allowed=myheader1,myheader2,...
```
Otherwise, you need to take care that this parameter is in System#property or environment.
From e384b69ec8d85d2066fd67f541942a3ed1603ef3 Mon Sep 17 00:00:00 2001
From: Ksiona
Date: Fri, 15 May 2026 23:54:41 +0400
Subject: [PATCH 4/9] fix: empty value is equal to "not set" for quarkus.
---
core-context-propagation-quarkus/README.md | 4 +-
.../allowedheaders/HeadersAllowedConfig.java | 32 ++++++++-
.../HeadersAllowedRecorder.java | 5 +-
.../allowedheaders/RawStringConverter.java | 10 +++
.../HeadersAllowedConfigTest.java | 9 ++-
.../src/test/resources/application.properties | 2 +
core-context-propagation/README.md | 4 +-
.../HeaderPropagationConfiguration.java | 24 ++++---
.../HeaderPropagationConfigurationTest.java | 34 ++++++++--
.../context-propagation-spring-common/pom.xml | 6 ++
...ContextProviderConfigurationEmptyTest.java | 52 +++++++++++++++
...xtProviderConfigurationFromEnvVarTest.java | 66 +++++++++++++++++++
...roviderConfigurationNotConfiguredTest.java | 48 ++++++++++++++
...iderConfigurationOnlyNonBlockableTest.java | 54 +++++++++++++++
...extProviderConfigurationWithValueTest.java | 52 +++++++++++++++
15 files changed, 378 insertions(+), 24 deletions(-)
create mode 100644 core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/RawStringConverter.java
create mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
create mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
create mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
create mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java
create mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
diff --git a/core-context-propagation-quarkus/README.md b/core-context-propagation-quarkus/README.md
index 6ab77d25c..4be422ff0 100644
--- a/core-context-propagation-quarkus/README.md
+++ b/core-context-propagation-quarkus/README.md
@@ -152,8 +152,8 @@ quarkus.headers.blocked=
- Default when not configured at all: `X-Channel-Request-Id` is blocked.
- Explicit empty value (`quarkus.headers.blocked=` / `HEADERS_BLOCKED=`): blacklist is empty (nothing is blocked).
- Explicit non-empty value with valid headers (for example `quarkus.headers.blocked=Some-Header`): only listed headers are blocked.
-- `X-Request-Id` is non-blockable: if it is listed in `quarkus.headers.blocked`/`HEADERS_BLOCKED`, it is ignored.
-- If configured value contains only non-blockable entries (for example only `X-Request-Id`), default block is applied and `X-Channel-Request-Id` remains blocked.
+- `X-Request-Id` is non-blockable: if it is listed in `quarkus.headers.blocked`/`HEADERS_BLOCKED`, it is silently dropped from the configured list.
+- If the configured value contains only non-blockable entries (for example only `X-Request-Id`), the resulting blocked list is **empty** — the default is **not** restored. Any explicit configuration (even one that effectively blocks nothing) is treated as the user's deliberate override of the default.
**MDC Integration:** The channel request ID is automatically stored in MDC under the key `x_channel_request_id` for use in
logging.
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java
index ff956700c..c59ddce43 100644
--- a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java
@@ -3,6 +3,8 @@
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
+import io.smallrye.config.WithConverter;
+import io.smallrye.config.WithDefault;
import io.smallrye.config.WithName;
import java.util.Optional;
@@ -10,15 +12,41 @@
@ConfigMapping(prefix = "quarkus")
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
public interface HeadersAllowedConfig {
+
+ /**
+ * Sentinel value used to distinguish "property not set" from "property explicitly set to empty".
+ * Starts with a NUL character so users cannot accidentally type it.
+ */
+ String UNSET = "\0__unset__";
+
/**
- * Allowed headers to propagate in contexts
+ * Allowed headers to propagate in contexts.
*/
@WithName("headers.allowed")
Optional allowedHeaders();
/**
* Blocked headers for context propagation. X-Channel-Request-Id is blocked by default.
+ *
+ * Three distinct states are supported:
+ *
+ * - property not set — value equals {@link #UNSET}; the default blocked list applies.
+ * - property set to empty — value equals "" (empty string); the default is erased.
+ * - property set to a value — value is the raw configured string.
+ *
+ * The custom {@link RawStringConverter} is required so that an empty value is preserved
+ * instead of being collapsed to {@code null} by SmallRye's default String converter.
*/
@WithName("headers.blocked")
- Optional blockedHeaders();
+ @WithConverter(RawStringConverter.class)
+ @WithDefault(UNSET)
+ String blockedHeaders();
+
+ /**
+ * @return {@code true} if the user explicitly configured {@code quarkus.headers.blocked}
+ * (including to an empty value); {@code false} if the property was not set at all.
+ */
+ default boolean isBlockedHeadersSet() {
+ return !UNSET.equals(blockedHeaders());
+ }
}
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java
index e795f9919..99cec85df 100644
--- a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java
@@ -9,6 +9,9 @@ public class HeadersAllowedRecorder {
public void setAllowedHeadersToSystemProperty() {
HeadersAllowedConfig allowedConfig = Arc.container().instance(HeadersAllowedConfig.class).get();
allowedConfig.allowedHeaders().ifPresent(allowedHeaders -> System.setProperty("headers.allowed", allowedHeaders));
- allowedConfig.blockedHeaders().ifPresent(blockedHeaders -> System.setProperty("headers.blocked", blockedHeaders));
+
+ if (allowedConfig.isBlockedHeadersSet()) {
+ System.setProperty("headers.blocked", allowedConfig.blockedHeaders());
+ }
}
}
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/RawStringConverter.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/RawStringConverter.java
new file mode 100644
index 000000000..12ac744ff
--- /dev/null
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/RawStringConverter.java
@@ -0,0 +1,10 @@
+package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
+
+import org.eclipse.microprofile.config.spi.Converter;
+
+public class RawStringConverter implements Converter {
+ @Override
+ public String convert(String value) {
+ return value;
+ }
+}
\ No newline at end of file
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java
index 0d5618251..fcece6b33 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java
@@ -10,6 +10,7 @@
@QuarkusTest
class HeadersAllowedConfigTest {
+
@Inject
HeadersAllowedConfig headersAllowedConfig;
@@ -21,5 +22,11 @@ void shouldReadHeadersAllowedFromProperty() {
assertEquals("test-quarkus.headers.allowed", value.get());
}
+ @Test
+ void shouldReadHeadersBlockedAsExplicitlyEmpty() {
+ assertTrue(headersAllowedConfig.isBlockedHeadersSet(),
+ "quarkus.headers.blocked must be considered explicitly set");
+ assertEquals("", headersAllowedConfig.blockedHeaders(),
+ "quarkus.headers.blocked must be preserved as an empty string");
+ }
}
-
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties
index 6fecc5866..209ea103f 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties
@@ -4,4 +4,6 @@ quarkus.devservices.enabled=false
quarkus.rest-client.my-client.url=http://localhost:${quarkus.http.test-port}
quarkus.headers.allowed=test-quarkus.headers.allowed
+quarkus.headers.blocked=
headers.allowed=test-headers.allowed
+headers.blocked=test-headers.blocked
diff --git a/core-context-propagation/README.md b/core-context-propagation/README.md
index 40f550846..2e968cb92 100644
--- a/core-context-propagation/README.md
+++ b/core-context-propagation/README.md
@@ -171,8 +171,8 @@ headers.blocked=
- Default when not configured at all: `X-Channel-Request-Id` is blocked.
- Explicit empty value (`headers.blocked=` / `HEADERS_BLOCKED=`): blacklist is empty (nothing is blocked).
- Explicit non-empty value with valid headers (for example `headers.blocked=Some-Header`): only listed headers are blocked.
-- `X-Request-Id` is non-blockable: if it is listed in `headers.blocked`/`HEADERS_BLOCKED`, it is ignored.
-- If configured value contains only non-blockable entries (for example only `X-Request-Id`), default block is applied and `X-Channel-Request-Id` remains blocked.
+- `X-Request-Id` is non-blockable: if it is listed in `headers.blocked`/`HEADERS_BLOCKED`, it is silently dropped from the configured list.
+- If the configured value contains only non-blockable entries (for example only `X-Request-Id`), the resulting blocked list is **empty** — the default is **not** restored. Any explicit configuration (even one that effectively blocks nothing) is treated as the user's deliberate override of the default.
**MDC Integration:**
The `X-Channel-Request-Id` is automatically integrated with SLF4J's Mapped Diagnostic Context (MDC) for seamless logging.
diff --git a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java
index aa9de6028..e3d9a301a 100644
--- a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java
+++ b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java
@@ -69,23 +69,29 @@ private static List readBlockedHeaders() {
String envValue = System.getenv(HEADERS_BLOCKED_ENV);
boolean envSpecified = envValue != null;
- String blockedHeaders = propertySpecified
+ // No source set at all → fall back to the built-in default.
+ if (!propertySpecified && !envSpecified) {
+ return DEFAULT_BLOCKED_HEADERS;
+ }
+
+ // Property wins over env when both are set.
+ String raw = propertySpecified
? System.getProperty(HEADERS_BLOCKED_PROPERTY)
: envValue;
- boolean anySourceSpecified = propertySpecified || envSpecified;
-
- if (blockedHeaders == null || blockedHeaders.isBlank()) {
- return anySourceSpecified ? Collections.emptyList() : DEFAULT_BLOCKED_HEADERS;
+ // Source is set but empty/blank → explicit "erase the default".
+ if (raw == null || raw.isBlank()) {
+ return Collections.emptyList();
}
-
- List configured = Arrays.stream(blockedHeaders.split(","))
+
+ // Source is set with a value → parse, trim, drop non-blockable entries.
+ // If everything filters out, we still respect the user's explicit override
+ // and return an empty list — we do NOT silently restore the default.
+ return Arrays.stream(raw.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.filter(s -> NON_BLOCKABLE_HEADERS.stream()
.noneMatch(s::equalsIgnoreCase))
.toList();
-
- return configured.isEmpty() ? DEFAULT_BLOCKED_HEADERS : configured;
}
}
diff --git a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
index cf5944adf..fed20c41a 100644
--- a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
+++ b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
@@ -67,31 +67,51 @@ void shouldNotBlacklistXChannelRequestIdWhenBlockedHeadersExplicitlyEmpty() {
@Test
void shouldNotBlacklistXChannelRequestIdWhenOtherHeadersExplicitlyBlocked() {
+ // The property is explicitly set to a non-blockable header; the default
+ // blocked list must NOT silently kick in.
System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, "X-Request-Id");
HeaderPropagationConfiguration.resetCache();
Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
}
@Test
- void shouldApplyDefaultBlacklistWhenOnlyNonBlockableHeadersConfigured() {
+ void shouldReturnEmptyListWhenOnlyNonBlockableHeadersConfigured() {
System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, "X-Request-Id, x-request-id");
HeaderPropagationConfiguration.resetCache();
Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- Assertions.assertEquals(HeaderPropagationConfiguration.DEFAULT_BLOCKED_HEADERS,
- HeaderPropagationConfiguration.blockedHeaders());
+ Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
+ Assertions.assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty());
}
@Test
- void shouldBlacklistHeaderByEnvWhenPropertyNotSet() throws Exception {
+ void shouldReadEnvWhenPropertyNotSet() throws Exception {
+ // Env value is read when no system property is set. The configured value
+ // is only X-Request-Id (non-blockable), so the resulting list must be empty —
+ // we deliberately do NOT fall back to the default blocked list here.
environmentVariables.set(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV, "X-Request-Id");
try {
HeaderPropagationConfiguration.resetCache();
Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
+ Assertions.assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty());
+ } finally {
+ environmentVariables.remove(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV);
+ HeaderPropagationConfiguration.resetCache();
+ }
+ }
+
+ @Test
+ void shouldBlacklistHeaderByEnvWhenPropertyNotSet() throws Exception {
+ // Sanity check that env-sourced configuration actually drives the blocked list
+ // when the system property is absent.
+ environmentVariables.set(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV, "Custom-Header");
+ try {
+ HeaderPropagationConfiguration.resetCache();
+ Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("Custom-Header"));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
} finally {
environmentVariables.remove(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV);
HeaderPropagationConfiguration.resetCache();
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/pom.xml b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/pom.xml
index 3694ec174..c208c3358 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/pom.xml
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/pom.xml
@@ -56,6 +56,12 @@
spring-test
test
+
+ uk.org.webcompere
+ system-stubs-jupiter
+ 2.1.8
+ test
+
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
new file mode 100644
index 000000000..ce5a5721b
--- /dev/null
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
@@ -0,0 +1,52 @@
+package com.netcracker.cloud.context.propagation.spring.common.configuration;
+
+import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Spring integration scenario: {@code headers.blocked=} (set explicitly to empty).
+ * Verifies that {@link SpringContextProviderConfiguration#init()} propagates the
+ * empty value to the system property, which downstream code interprets as
+ * "erase the default blocked list".
+ */
+@SpringJUnitConfig(classes = SpringContextProviderConfiguration.class)
+@TestPropertySource(properties = {
+ "headers.allowed=custom-header",
+ "headers.blocked="
+})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+class SpringContextProviderConfigurationEmptyTest {
+
+ @BeforeAll
+ static void setup() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @AfterAll
+ static void teardown() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @Test
+ void shouldSetEmptySystemPropertyAndEraseDefaultBlockedList() {
+ assertEquals("", System.getProperty("headers.blocked"),
+ "Spring init() must propagate explicit empty value to the system property");
+
+ HeaderPropagationConfiguration.resetCache();
+ assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
+ "explicit empty value must erase the default blocked list");
+ assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ "X-Channel-Request-Id must no longer be blocked");
+ }
+}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
new file mode 100644
index 000000000..96851f99c
--- /dev/null
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
@@ -0,0 +1,66 @@
+package com.netcracker.cloud.context.propagation.spring.common.configuration;
+
+import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
+import uk.org.webcompere.systemstubs.jupiter.SystemStub;
+import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Spring integration scenario: {@code headers.blocked} is configured only via the
+ * {@code HEADERS_BLOCKED} environment variable. Verifies that Spring's relaxed
+ * binding picks up the env var as the {@code headers.blocked} property, that
+ * {@link SpringContextProviderConfiguration#init()} propagates it to the system
+ * property, and that the downstream blocked list reflects the env-sourced value.
+ *
+ * {@link SystemStubsExtension} must be registered before {@link SpringExtension}
+ * so that the env var is set before Spring's {@code SystemEnvironmentPropertySource}
+ * is consulted during context initialization.
+ */
+@ExtendWith({SystemStubsExtension.class, SpringExtension.class})
+@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
+@TestPropertySource(properties = {
+ // headers.blocked deliberately not declared here — it must come from the env var
+ "headers.allowed=custom-header"
+})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+class SpringContextProviderConfigurationFromEnvVarTest {
+
+ @SystemStub
+ static EnvironmentVariables envVars = new EnvironmentVariables("HEADERS_BLOCKED", "Custom-Header");
+
+ @BeforeAll
+ static void setup() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @AfterAll
+ static void teardown() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @Test
+ void shouldReadHeadersBlockedFromEnvVar() {
+ assertEquals("Custom-Header", System.getProperty("headers.blocked"),
+ "Spring init() must propagate env-sourced value to the system property");
+
+ HeaderPropagationConfiguration.resetCache();
+ assertTrue(HeaderPropagationConfiguration.isBlacklisted("Custom-Header"),
+ "env-sourced header must be blocked");
+ assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ "explicit env-sourced configuration overrides the default");
+ }
+}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
new file mode 100644
index 000000000..664859f6a
--- /dev/null
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
@@ -0,0 +1,48 @@
+package com.netcracker.cloud.context.propagation.spring.common.configuration;
+
+import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Spring integration scenario: {@code headers.blocked} is not set anywhere.
+ * Verifies that {@link SpringContextProviderConfiguration#init()} does NOT touch
+ * the {@code headers.blocked} system property, so downstream code falls back to
+ * the built-in default blocked list (which contains {@code X-Channel-Request-Id}).
+ */
+@SpringJUnitConfig(classes = SpringContextProviderConfiguration.class)
+@TestPropertySource(properties = {
+ "headers.allowed=custom-header"
+})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+class SpringContextProviderConfigurationNotConfiguredTest {
+
+ @BeforeAll
+ static void setup() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @AfterAll
+ static void teardown() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @Test
+ void shouldNotSetSystemPropertyAndApplyDefaultBlockedList() {
+ assertNull(System.getProperty("headers.blocked"),
+ "headers.blocked must remain unset when no source configures it");
+
+ HeaderPropagationConfiguration.resetCache();
+ assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ "default blocked list must apply when nothing is configured");
+ }
+}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java
new file mode 100644
index 000000000..e97020668
--- /dev/null
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java
@@ -0,0 +1,54 @@
+package com.netcracker.cloud.context.propagation.spring.common.configuration;
+
+import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Spring integration scenario: {@code headers.blocked=X-Request-Id} — the configured
+ * value consists exclusively of a non-blockable header. The resulting blocked list
+ * must be empty, NOT the built-in default. This locks in the behavior change made
+ * to {@link HeaderPropagationConfiguration} (no silent fallback to default when the
+ * user explicitly configured something).
+ */
+@SpringJUnitConfig(classes = SpringContextProviderConfiguration.class)
+@TestPropertySource(properties = {
+ "headers.allowed=custom-header",
+ "headers.blocked=X-Request-Id"
+})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+class SpringContextProviderConfigurationOnlyNonBlockableTest {
+
+ @BeforeAll
+ static void setup() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @AfterAll
+ static void teardown() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @Test
+ void shouldRespectExplicitOverrideEvenWhenItFiltersToEmpty() {
+ assertEquals("X-Request-Id", System.getProperty("headers.blocked"));
+
+ HeaderPropagationConfiguration.resetCache();
+ assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
+ "the resulting blocked list must be empty — the default must NOT be restored");
+ assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"),
+ "X-Request-Id is non-blockable and must never be blocked");
+ assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ "explicit (even if filter-emptied) configuration overrides the default");
+ }
+}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
new file mode 100644
index 000000000..45480ca94
--- /dev/null
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
@@ -0,0 +1,52 @@
+package com.netcracker.cloud.context.propagation.spring.common.configuration;
+
+import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Spring integration scenario: {@code headers.blocked} is set to a concrete blockable header.
+ * Verifies that the listed header is blocked and the default's
+ * {@code X-Channel-Request-Id} entry no longer applies.
+ */
+@SpringJUnitConfig(classes = SpringContextProviderConfiguration.class)
+@TestPropertySource(properties = {
+ "headers.allowed=custom-header",
+ "headers.blocked=Custom-Header"
+})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+class SpringContextProviderConfigurationWithValueTest {
+
+ @BeforeAll
+ static void setup() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @AfterAll
+ static void teardown() {
+ System.clearProperty("headers.blocked");
+ HeaderPropagationConfiguration.resetCache();
+ }
+
+ @Test
+ void shouldSetSystemPropertyAndBlockConfiguredHeader() {
+ assertEquals("Custom-Header", System.getProperty("headers.blocked"));
+
+ HeaderPropagationConfiguration.resetCache();
+ assertTrue(HeaderPropagationConfiguration.isBlacklisted("Custom-Header"),
+ "configured header must be blocked");
+ assertTrue(HeaderPropagationConfiguration.isBlacklisted("custom-header"),
+ "blocking must be case-insensitive");
+ assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ "explicit configuration overrides the default blocked list");
+ }
+}
From 934ad6392675eb5d6e2de3742563e0e85b8aa1fc Mon Sep 17 00:00:00 2001
From: Ksiona
Date: Mon, 18 May 2026 10:40:55 +0400
Subject: [PATCH 5/9] chore: review improvements
---
.../HeaderPropagationConfigurationTest.java | 2 +-
.../HeaderPropagationStateReset.java | 18 ++++++++++++++++
...ContextProviderConfigurationEmptyTest.java | 21 +++++--------------
...xtProviderConfigurationFromEnvVarTest.java | 16 +-------------
...roviderConfigurationNotConfiguredTest.java | 21 +++++--------------
...iderConfigurationOnlyNonBlockableTest.java | 21 +++++--------------
...extProviderConfigurationWithValueTest.java | 21 +++++--------------
7 files changed, 40 insertions(+), 80 deletions(-)
create mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java
diff --git a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
index fed20c41a..68247fa37 100644
--- a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
+++ b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
@@ -87,7 +87,7 @@ void shouldReturnEmptyListWhenOnlyNonBlockableHeadersConfigured() {
}
@Test
- void shouldReadEnvWhenPropertyNotSet() throws Exception {
+ void shouldReadEnvWhenPropertyNotSet() {
// Env value is read when no system property is set. The configured value
// is only X-Request-Id (non-blockable), so the resulting list must be empty —
// we deliberately do NOT fall back to the default blocked list here.
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java
new file mode 100644
index 000000000..8c0a30297
--- /dev/null
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java
@@ -0,0 +1,18 @@
+package com.netcracker.cloud.context.propagation.spring.common.configuration;
+
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+
+public class HeaderPropagationStateReset implements BeforeAllCallback, AfterAllCallback {
+ @Override public void beforeAll(ExtensionContext ctx) { reset(); }
+ @Override public void afterAll(ExtensionContext ctx) { reset(); }
+
+ private static void reset() {
+ System.clearProperty("headers.blocked");
+ System.clearProperty("headers.allowed");
+ HeaderPropagationConfiguration.resetCache();
+ }
+}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
index ce5a5721b..f9c0905ad 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
@@ -1,12 +1,12 @@
package com.netcracker.cloud.context.propagation.spring.common.configuration;
import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -18,7 +18,8 @@
* empty value to the system property, which downstream code interprets as
* "erase the default blocked list".
*/
-@SpringJUnitConfig(classes = SpringContextProviderConfiguration.class)
+@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
+@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
"headers.allowed=custom-header",
"headers.blocked="
@@ -26,18 +27,6 @@
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationEmptyTest {
- @BeforeAll
- static void setup() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
- @AfterAll
- static void teardown() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
@Test
void shouldSetEmptySystemPropertyAndEraseDefaultBlockedList() {
assertEquals("", System.getProperty("headers.blocked"),
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
index 96851f99c..4b56a696f 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
@@ -1,8 +1,6 @@
package com.netcracker.cloud.context.propagation.spring.common.configuration;
import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.annotation.DirtiesContext;
@@ -28,7 +26,7 @@
* so that the env var is set before Spring's {@code SystemEnvironmentPropertySource}
* is consulted during context initialization.
*/
-@ExtendWith({SystemStubsExtension.class, SpringExtension.class})
+@ExtendWith({HeaderPropagationStateReset.class, SystemStubsExtension.class, SpringExtension.class})
@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
// headers.blocked deliberately not declared here — it must come from the env var
@@ -40,18 +38,6 @@ class SpringContextProviderConfigurationFromEnvVarTest {
@SystemStub
static EnvironmentVariables envVars = new EnvironmentVariables("HEADERS_BLOCKED", "Custom-Header");
- @BeforeAll
- static void setup() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
- @AfterAll
- static void teardown() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
@Test
void shouldReadHeadersBlockedFromEnvVar() {
assertEquals("Custom-Header", System.getProperty("headers.blocked"),
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
index 664859f6a..1d4ba15fa 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
@@ -1,12 +1,12 @@
package com.netcracker.cloud.context.propagation.spring.common.configuration;
import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -17,25 +17,14 @@
* the {@code headers.blocked} system property, so downstream code falls back to
* the built-in default blocked list (which contains {@code X-Channel-Request-Id}).
*/
-@SpringJUnitConfig(classes = SpringContextProviderConfiguration.class)
+@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
+@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
"headers.allowed=custom-header"
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationNotConfiguredTest {
- @BeforeAll
- static void setup() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
- @AfterAll
- static void teardown() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
@Test
void shouldNotSetSystemPropertyAndApplyDefaultBlockedList() {
assertNull(System.getProperty("headers.blocked"),
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java
index e97020668..b6649f58b 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java
@@ -1,12 +1,12 @@
package com.netcracker.cloud.context.propagation.spring.common.configuration;
import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -19,7 +19,8 @@
* to {@link HeaderPropagationConfiguration} (no silent fallback to default when the
* user explicitly configured something).
*/
-@SpringJUnitConfig(classes = SpringContextProviderConfiguration.class)
+@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
+@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
"headers.allowed=custom-header",
"headers.blocked=X-Request-Id"
@@ -27,18 +28,6 @@
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationOnlyNonBlockableTest {
- @BeforeAll
- static void setup() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
- @AfterAll
- static void teardown() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
@Test
void shouldRespectExplicitOverrideEvenWhenItFiltersToEmpty() {
assertEquals("X-Request-Id", System.getProperty("headers.blocked"));
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
index 45480ca94..88e48709d 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
@@ -1,12 +1,12 @@
package com.netcracker.cloud.context.propagation.spring.common.configuration;
import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -17,7 +17,8 @@
* Verifies that the listed header is blocked and the default's
* {@code X-Channel-Request-Id} entry no longer applies.
*/
-@SpringJUnitConfig(classes = SpringContextProviderConfiguration.class)
+@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
+@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
"headers.allowed=custom-header",
"headers.blocked=Custom-Header"
@@ -25,18 +26,6 @@
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationWithValueTest {
- @BeforeAll
- static void setup() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
- @AfterAll
- static void teardown() {
- System.clearProperty("headers.blocked");
- HeaderPropagationConfiguration.resetCache();
- }
-
@Test
void shouldSetSystemPropertyAndBlockConfiguredHeader() {
assertEquals("Custom-Header", System.getProperty("headers.blocked"));
From 85ae957b7daba24e26a394503c5538a3008f044c Mon Sep 17 00:00:00 2001
From: Ksiona
Date: Mon, 18 May 2026 19:38:30 +0400
Subject: [PATCH 6/9] fix: x-channel-request-id feature redesign
---
core-context-propagation-quarkus/README.md | 89 ++++++++++--
.../allowedheaders/HeadersAllowedConfig.java | 51 +++----
.../HeadersAllowedRecorder.java | 10 +-
.../allowedheaders/RawStringConverter.java | 10 --
...HeadersAllowBlockedRecorderEffectTest.java | 33 +++++
.../HeadersAllowedConfigNotSetTest.java | 34 +++++
.../HeadersAllowedConfigTest.java | 16 ++-
.../src/test/resources/application.properties | 4 +-
core-context-propagation/README.md | 84 ++++++++---
.../HeaderPropagationConfiguration.java | 73 ++++++----
.../HeaderPropagationConfigurationTest.java | 133 ++++--------------
...RequestIdContextObjectPropagationTest.java | 23 ++-
.../RequestPropagationSpringCommonTest.java | 2 +-
.../requests/RequestPropagationTest.java | 10 +-
...opagationXChannelRequestIdAllowedTest.java | 6 +-
...pagationXChannelRequestIdResponseTest.java | 6 +-
.../SpringContextProviderConfiguration.java | 14 +-
.../HeaderPropagationStateReset.java | 14 +-
...ContextProviderConfigurationEmptyTest.java | 20 +--
...xtProviderConfigurationFromEnvVarTest.java | 25 +---
...roviderConfigurationNotConfiguredTest.java | 15 +-
...iderConfigurationOnlyNonBlockableTest.java | 43 ------
...iderConfigurationUnknownExemptionTest.java | 34 +++++
...extProviderConfigurationWithValueTest.java | 19 +--
.../spring/kafka/ContextPropagationTest.java | 10 +-
.../spring/rabbit/PropagationTest.java | 24 +++-
.../kafka/KafkaContextPropagationTest.java | 6 +-
27 files changed, 447 insertions(+), 361 deletions(-)
delete mode 100644 core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/RawStringConverter.java
create mode 100644 core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowBlockedRecorderEffectTest.java
create mode 100644 core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigNotSetTest.java
delete mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java
create mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownExemptionTest.java
diff --git a/core-context-propagation-quarkus/README.md b/core-context-propagation-quarkus/README.md
index 4be422ff0..28a01dcf2 100644
--- a/core-context-propagation-quarkus/README.md
+++ b/core-context-propagation-quarkus/README.md
@@ -133,27 +133,86 @@ Propagates and allows to get `X-Channel-Request-Id` value. If an incoming reques
**Default behavior:** `X-Channel-Request-Id` is NOT propagated to outgoing requests.
-**Enabling propagation:** To allow `X-Channel-Request-Id` to be propagated to outgoing requests, remove it from the
-blacklist using one of the following methods:
+#### Internal blocklist
-1. **Via environment variable:**
-```text
-HEADERS_BLOCKED=
-```
+The framework owns a hard-coded internal blocklist of headers that are not propagated to outgoing
+requests. It currently contains:
+
+- `X-Channel-Request-Id`
+
+The blocklist itself cannot be changed from configuration. The only externally visible knob is the
+`quarkus.context.propagation.allow-blocked-headers` property, which lists header names that should be **exempted** from
+this blocklist (i.e. allowed to propagate).
+
+#### `quarkus.context.propagation.allow-blocked-headers` property
+
+The property carries a comma-separated list of header names. Every name that matches an entry of
+the internal blocklist is removed from the effective blocklist. Names that are not in the
+internal blocklist have no effect.
+
+Examples:
+
+| Property value | Effect |
+|---|---|
+| not set / empty | Internal blocklist applies in full. `X-Channel-Request-Id` is not propagated. |
+| `X-Channel-Request-Id` | `X-Channel-Request-Id` is propagated to outgoing requests. |
+| `Some-Other-Header` | No effect — the header is not in the internal blocklist. |
+| `X-Channel-Request-Id, Some-Other-Header` | `X-Channel-Request-Id` is propagated; the second entry is ignored. |
+
+Comparison is case-insensitive. Whitespace around comma-separated entries is trimmed.
+
+#### How to set the property
+
+**Via `application.properties`:**
-2. **Via application.properties (Quarkus):**
```properties
-quarkus.headers.blocked=
+quarkus.context.propagation.allow-blocked-headers=X-Channel-Request-Id
+```
+
+**Via `application.yaml`:**
+
+```yaml
+quarkus:
+ context:
+ propagation:
+ allow-blocked-headers: X-Channel-Request-Id
+```
+
+**Via JVM system property:**
+
+```text
+-Dquarkus.context.propagation.allow-blocked-headers=X-Channel-Request-Id
```
-**`quarkus.headers.blocked` rules and limitations**
+**Via container ENV (recommended, Qubership pattern)**
+
+In Qubership deployments configuration values are typically wired from container ENV variables
+through `application.yaml` placeholders. The full chain looks like this:
+
+1. The container declares an ENV variable, for example in the deployment manifest:
+
+ ```yaml
+ env:
+ - name: CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS
+ value: "X-Channel-Request-Id"
+ ```
+
+2. The application's `application.yaml` reads it via a `${VAR}` placeholder:
+
+ ```yaml
+ quarkus:
+ context:
+ propagation:
+ allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+ ```
+
+ The trailing `:` (empty default) lets the property gracefully fall through to "not set" when
+ the ENV variable is absent — the internal blocklist then applies in full.
-- Source priority: system property `quarkus.headers.blocked` overrides environment variable `HEADERS_BLOCKED`.
-- Default when not configured at all: `X-Channel-Request-Id` is blocked.
-- Explicit empty value (`quarkus.headers.blocked=` / `HEADERS_BLOCKED=`): blacklist is empty (nothing is blocked).
-- Explicit non-empty value with valid headers (for example `quarkus.headers.blocked=Some-Header`): only listed headers are blocked.
-- `X-Request-Id` is non-blockable: if it is listed in `quarkus.headers.blocked`/`HEADERS_BLOCKED`, it is silently dropped from the configured list.
-- If the configured value contains only non-blockable entries (for example only `X-Request-Id`), the resulting blocked list is **empty** — the default is **not** restored. Any explicit configuration (even one that effectively blocks nothing) is treated as the user's deliberate override of the default.
+3. Quarkus also recognises the ENV variable directly under the canonical name
+ `CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS` (via MicroProfile Config relaxed env-to-property mapping), so
+ the same ENV variable works even without the `application.yaml` indirection. The placeholder
+ form is preferred because it makes the dependency explicit in source control.
**MDC Integration:** The channel request ID is automatically stored in MDC under the key `x_channel_request_id` for use in
logging.
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java
index c59ddce43..68e2a77b6 100644
--- a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java
@@ -3,22 +3,15 @@
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
-import io.smallrye.config.WithConverter;
-import io.smallrye.config.WithDefault;
import io.smallrye.config.WithName;
+import java.util.List;
import java.util.Optional;
@ConfigMapping(prefix = "quarkus")
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
public interface HeadersAllowedConfig {
- /**
- * Sentinel value used to distinguish "property not set" from "property explicitly set to empty".
- * Starts with a NUL character so users cannot accidentally type it.
- */
- String UNSET = "\0__unset__";
-
/**
* Allowed headers to propagate in contexts.
*/
@@ -26,27 +19,29 @@ public interface HeadersAllowedConfig {
Optional allowedHeaders();
/**
- * Blocked headers for context propagation. X-Channel-Request-Id is blocked by default.
- *
- * Three distinct states are supported:
+ * Headers that should be allowed to propagate even though they appear in the framework's
+ * internal blocklist. The blocklist itself is hard-coded and cannot be changed from
+ * configuration.
+ *
+ *
Semantics:
*
- * - property not set — value equals {@link #UNSET}; the default blocked list applies.
- * - property set to empty — value equals "" (empty string); the default is erased.
- * - property set to a value — value is the raw configured string.
+ * - Property not set or empty: the internal blocklist is applied as-is. Any header
+ * in the blocklist (for example {@code X-Channel-Request-Id}) is not propagated.
+ * - Property contains a comma-separated list of header names: each listed name is
+ * removed from the effective blocklist and is allowed to propagate. Names that
+ * are not in the internal blocklist have no effect.
*
- * The custom {@link RawStringConverter} is required so that an empty value is preserved
- * instead of being collapsed to {@code null} by SmallRye's default String converter.
- */
- @WithName("headers.blocked")
- @WithConverter(RawStringConverter.class)
- @WithDefault(UNSET)
- String blockedHeaders();
-
- /**
- * @return {@code true} if the user explicitly configured {@code quarkus.headers.blocked}
- * (including to an empty value); {@code false} if the property was not set at all.
+ *
+ * Example {@code application.yaml} with a container ENV indirection:
+ *
+ * quarkus:
+ * context:
+ * propagation:
+ * allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+ *
+ * The container then sets {@code CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS=X-Channel-Request-Id} when it needs
+ * that header to be propagated.
*/
- default boolean isBlockedHeadersSet() {
- return !UNSET.equals(blockedHeaders());
- }
+ @WithName("context.propagation.allow-blocked-headers")
+ Optional> allowedHeadersFromBlocklist();
}
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java
index 99cec85df..c0dabdb9e 100644
--- a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java
@@ -8,10 +8,12 @@ public class HeadersAllowedRecorder {
public void setAllowedHeadersToSystemProperty() {
HeadersAllowedConfig allowedConfig = Arc.container().instance(HeadersAllowedConfig.class).get();
- allowedConfig.allowedHeaders().ifPresent(allowedHeaders -> System.setProperty("headers.allowed", allowedHeaders));
- if (allowedConfig.isBlockedHeadersSet()) {
- System.setProperty("headers.blocked", allowedConfig.blockedHeaders());
- }
+ allowedConfig.allowedHeaders()
+ .ifPresent(allowedHeaders -> System.setProperty("headers.allowed", allowedHeaders));
+
+ allowedConfig.allowedHeadersFromBlocklist()
+ .filter(list -> !list.isEmpty())
+ .ifPresent(list -> System.setProperty("context.propagation.allow-blocked-headers", String.join(",", list)));
}
}
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/RawStringConverter.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/RawStringConverter.java
deleted file mode 100644
index 12ac744ff..000000000
--- a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/RawStringConverter.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
-
-import org.eclipse.microprofile.config.spi.Converter;
-
-public class RawStringConverter implements Converter {
- @Override
- public String convert(String value) {
- return value;
- }
-}
\ No newline at end of file
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowBlockedRecorderEffectTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowBlockedRecorderEffectTest.java
new file mode 100644
index 000000000..0d6f17fb1
--- /dev/null
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowBlockedRecorderEffectTest.java
@@ -0,0 +1,33 @@
+package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
+
+import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@QuarkusTest
+class HeadersAllowBlockedRecorderEffectTest {
+
+ @Test
+ void shouldExposeAllowBlockedValueAsSystemProperty() {
+ assertEquals("X-Channel-Request-Id",
+ System.getProperty("context.propagation.allow-blocked-headers"),
+ "Recorder must propagate the quarkus.context.propagation.allow-blocked-headers value " +
+ "to the context.propagation.allow-blocked-headers system property.");
+ }
+
+ @Test
+ void shouldRemoveExemptedHeaderFromInternalBlocklist() {
+ // The blocked list is cached on first access; ensure we read the post-recorder state.
+ HeaderPropagationConfiguration.resetCache();
+
+ assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
+ "The only entry of the internal blocklist (X-Channel-Request-Id) must be removed " +
+ "by the exemption configured in application.properties.");
+ assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ "X-Channel-Request-Id must not be blocked when explicitly exempted.");
+ }
+}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigNotSetTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigNotSetTest.java
new file mode 100644
index 000000000..61f016c4d
--- /dev/null
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigNotSetTest.java
@@ -0,0 +1,34 @@
+package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import jakarta.inject.Inject;
+import org.junit.jupiter.api.Test;
+
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+@QuarkusTest
+@TestProfile(HeadersAllowedConfigNotSetTest.NotSetProfile.class)
+class HeadersAllowedConfigNotSetTest {
+
+ @Inject
+ HeadersAllowedConfig headersAllowedConfig;
+
+ @Test
+ void shouldReportAllowedFromBlocklistAsEmptyWhenNotConfigured() {
+ assertFalse(headersAllowedConfig.allowedHeadersFromBlocklist().isPresent(),
+ "quarkus.context.propagation.allow-blocked-headers must resolve to Optional.empty() " +
+ "when no exemption value is configured");
+ }
+
+ public static class NotSetProfile implements QuarkusTestProfile {
+
+ @Override
+ public Map getConfigOverrides() {
+ return Map.of("quarkus.context.propagation.allow-blocked-headers", "");
+ }
+ }
+}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java
index fcece6b33..cf03260d5 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java
@@ -4,9 +4,11 @@
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
+import java.util.List;
import java.util.Optional;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
@QuarkusTest
class HeadersAllowedConfigTest {
@@ -23,10 +25,12 @@ void shouldReadHeadersAllowedFromProperty() {
}
@Test
- void shouldReadHeadersBlockedAsExplicitlyEmpty() {
- assertTrue(headersAllowedConfig.isBlockedHeadersSet(),
- "quarkus.headers.blocked must be considered explicitly set");
- assertEquals("", headersAllowedConfig.blockedHeaders(),
- "quarkus.headers.blocked must be preserved as an empty string");
+ void shouldReadAllowedHeadersFromBlocklist() {
+ Optional> value = headersAllowedConfig.allowedHeadersFromBlocklist();
+
+ assertTrue(value.isPresent(),
+ "quarkus.context.propagation.allow-blocked-headers must be present when configured");
+ assertEquals(List.of("X-Channel-Request-Id"), value.get(),
+ "SmallRye must parse the comma-separated value into a list");
}
}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties
index 209ea103f..544d085e0 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties
@@ -4,6 +4,6 @@ quarkus.devservices.enabled=false
quarkus.rest-client.my-client.url=http://localhost:${quarkus.http.test-port}
quarkus.headers.allowed=test-quarkus.headers.allowed
-quarkus.headers.blocked=
+
+quarkus.context.propagation.allow-blocked-headers=X-Channel-Request-Id
headers.allowed=test-headers.allowed
-headers.blocked=test-headers.blocked
diff --git a/core-context-propagation/README.md b/core-context-propagation/README.md
index 2e968cb92..ff5d3e453 100644
--- a/core-context-propagation/README.md
+++ b/core-context-propagation/README.md
@@ -147,32 +147,82 @@ Propagates and allows to get `X-Channel-Request-Id` value. If an incoming reques
**Default behavior:** `X-Channel-Request-Id` is NOT propagated to outgoing requests.
-**Enabling propagation:** To allow `X-Channel-Request-Id` to be propagated to outgoing requests, remove it from the
-blacklist using one of the following methods:
+#### Internal blocklist
-1. **Via environment variable:**
-```text
-HEADERS_BLOCKED=
+The framework owns a hard-coded internal blocklist of headers that are not propagated to outgoing
+requests. It currently contains:
+
+- `X-Channel-Request-Id`
+
+The blocklist itself cannot be changed from configuration. The only externally visible knob is the
+`context.propagation.allow-blocked-headers` property, which lists header names that should be **exempted** from this
+blocklist (i.e. allowed to propagate).
+
+#### `context.propagation.allow-blocked-headers` property
+
+The property carries a comma-separated list of header names. Every name that matches an entry of
+the internal blocklist is removed from the effective blocklist. Names that are not in the
+internal blocklist have no effect.
+
+Examples:
+
+| Property value | Effect |
+|---|---|
+| not set / empty | Internal blocklist applies in full. `X-Channel-Request-Id` is not propagated. |
+| `X-Channel-Request-Id` | `X-Channel-Request-Id` is propagated to outgoing requests. |
+| `Some-Other-Header` | No effect — the header is not in the internal blocklist. |
+| `X-Channel-Request-Id, Some-Other-Header` | `X-Channel-Request-Id` is propagated; the second entry is ignored. |
+
+Comparison is case-insensitive. Whitespace around comma-separated entries is trimmed.
+
+#### How to set the property
+
+**Spring (`application.properties` / `application.yml`):**
+
+```properties
+context.propagation.allow-blocked-headers=X-Channel-Request-Id
```
-2. **Via system property:**
-```text
--Dheaders.blocked=
+```yaml
+context:
+ propagation:
+ allow-blocked-headers: X-Channel-Request-Id
```
-3. **Via application.properties (Spring):**
+**Via JVM system property:**
+
```text
-headers.blocked=
+-Dcontext.propagation.allow-blocked-headers=X-Channel-Request-Id
```
-**`headers.blocked` rules and limitations**
+**Via container ENV (recommended, Qubership pattern)**
+
+In Qubership deployments configuration values are typically wired from container ENV variables
+through `application.yaml` placeholders. The full chain looks like this:
+
+1. The container declares an ENV variable, for example in the deployment manifest:
+
+ ```yaml
+ env:
+ - name: CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS
+ value: "X-Channel-Request-Id"
+ ```
+
+2. The application's `application.yaml` reads it via a `${VAR}` placeholder:
+
+ ```yaml
+ context:
+ propagation:
+ allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+ ```
+
+ The trailing `:` (empty default) lets the property gracefully fall through to "not set" when
+ the ENV variable is absent — the internal blocklist then applies in full.
-- Source priority: system property `headers.blocked` overrides environment variable `HEADERS_BLOCKED`.
-- Default when not configured at all: `X-Channel-Request-Id` is blocked.
-- Explicit empty value (`headers.blocked=` / `HEADERS_BLOCKED=`): blacklist is empty (nothing is blocked).
-- Explicit non-empty value with valid headers (for example `headers.blocked=Some-Header`): only listed headers are blocked.
-- `X-Request-Id` is non-blockable: if it is listed in `headers.blocked`/`HEADERS_BLOCKED`, it is silently dropped from the configured list.
-- If the configured value contains only non-blockable entries (for example only `X-Request-Id`), the resulting blocked list is **empty** — the default is **not** restored. Any explicit configuration (even one that effectively blocks nothing) is treated as the user's deliberate override of the default.
+3. Spring's relaxed binding also recognises the ENV variable directly under the property name
+ `context.propagation.allow-blocked-headers` (i.e. without an explicit placeholder), so the same ENV variable works
+ even without the `application.yaml` indirection. The placeholder form is preferred because it
+ makes the dependency explicit in source control.
**MDC Integration:**
The `X-Channel-Request-Id` is automatically integrated with SLF4J's Mapped Diagnostic Context (MDC) for seamless logging.
diff --git a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java
index e3d9a301a..6e2291cb5 100644
--- a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java
+++ b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java
@@ -1,21 +1,43 @@
package com.netcracker.cloud.framework.contexts.allowedheaders;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
+/**
+ * Computes the effective set of headers that must not be propagated to outgoing requests.
+ *
+ * Model
+ *
+ * - The framework owns an internal blocklist ({@link #INTERNAL_BLOCKED_HEADERS}). It is
+ * hard-coded and cannot be changed from configuration. By default it blocks
+ * {@code X-Channel-Request-Id}.
+ * - A user-facing system property {@value #ALLOW_BLOCKED_PROPERTY} carries a
+ * comma-separated list of header names that should be exempted from the internal
+ * blocklist (i.e. allowed to propagate). Names that are not in the internal
+ * blocklist have no effect.
+ *
+ *
+ * How the property is supplied
+ * The Quarkus extension copies {@code quarkus.context.propagation.allow-blocked-headers} into this system property
+ * at {@code RUNTIME_INIT}; the Spring configuration does the same for the Spring-style
+ * {@code context.propagation.allow-blocked-headers} property. In both cases standard env-to-property mapping
+ * applies, so a container ENV variable like {@code CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS=X-Channel-Request-Id}
+ * propagates all the way through to this class.
+ */
public final class HeaderPropagationConfiguration {
- public static final String HEADERS_BLOCKED_PROPERTY = "headers.blocked";
- public static final String HEADERS_BLOCKED_ENV = "HEADERS_BLOCKED";
- public static final List DEFAULT_BLOCKED_HEADERS =
- List.of("X-Channel-Request-Id");
- public static final List NON_BLOCKABLE_HEADERS =
- List.of("X-Request-Id");
+ /** System property carrying exempted-from-blocklist header names, comma-separated. */
+ public static final String ALLOW_BLOCKED_PROPERTY = "context.propagation.allow-blocked-headers";
+
+ /**
+ * Hard-coded internal blocklist of headers that the framework refuses to propagate
+ * unless explicitly exempted via {@link #ALLOW_BLOCKED_PROPERTY}.
+ */
+ public static final List INTERNAL_BLOCKED_HEADERS = List.of("X-Channel-Request-Id");
private static final AtomicReference cachedHeaders = new AtomicReference<>(null);
@@ -41,7 +63,7 @@ private static CachedHeaders getOrInit() {
synchronized (HeaderPropagationConfiguration.class) {
local = cachedHeaders.get();
if (local == null) {
- local = new CachedHeaders(readBlockedHeaders());
+ local = new CachedHeaders(computeEffectiveBlocklist());
cachedHeaders.set(local);
}
}
@@ -64,34 +86,25 @@ public static boolean isBlacklisted(String headerName) {
return getOrInit().lowerSet.contains(headerName.toLowerCase(Locale.ROOT));
}
- private static List readBlockedHeaders() {
- boolean propertySpecified = System.getProperties().containsKey(HEADERS_BLOCKED_PROPERTY);
- String envValue = System.getenv(HEADERS_BLOCKED_ENV);
- boolean envSpecified = envValue != null;
-
- // No source set at all → fall back to the built-in default.
- if (!propertySpecified && !envSpecified) {
- return DEFAULT_BLOCKED_HEADERS;
+ private static List computeEffectiveBlocklist() {
+ Set exemptions = readExemptions();
+ if (exemptions.isEmpty()) {
+ return INTERNAL_BLOCKED_HEADERS;
}
+ return INTERNAL_BLOCKED_HEADERS.stream()
+ .filter(h -> !exemptions.contains(h.toLowerCase(Locale.ROOT)))
+ .toList();
+ }
- // Property wins over env when both are set.
- String raw = propertySpecified
- ? System.getProperty(HEADERS_BLOCKED_PROPERTY)
- : envValue;
-
- // Source is set but empty/blank → explicit "erase the default".
+ private static Set readExemptions() {
+ String raw = System.getProperty(ALLOW_BLOCKED_PROPERTY);
if (raw == null || raw.isBlank()) {
- return Collections.emptyList();
+ return Set.of();
}
-
- // Source is set with a value → parse, trim, drop non-blockable entries.
- // If everything filters out, we still respect the user's explicit override
- // and return an empty list — we do NOT silently restore the default.
return Arrays.stream(raw.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
- .filter(s -> NON_BLOCKABLE_HEADERS.stream()
- .noneMatch(s::equalsIgnoreCase))
- .toList();
+ .map(s -> s.toLowerCase(Locale.ROOT))
+ .collect(Collectors.toUnmodifiableSet());
}
}
diff --git a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
index 68247fa37..de57edc09 100644
--- a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
+++ b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
@@ -1,157 +1,84 @@
package com.netcracker.cloud.framework.contexts.allowedheaders;
-import java.util.List;
-
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
-import uk.org.webcompere.systemstubs.jupiter.SystemStub;
-import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
-@ExtendWith(SystemStubsExtension.class)
class HeaderPropagationConfigurationTest {
- @SystemStub
- private EnvironmentVariables environmentVariables = new EnvironmentVariables("TEST_PROP_FOR_ENV_SETUP", "1");
@BeforeEach
void setup() {
- System.clearProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY);
+ System.clearProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY);
HeaderPropagationConfiguration.resetCache();
}
@AfterEach
void cleanup() {
- System.clearProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY);
- HeaderPropagationConfiguration.resetCache();
- }
-
- @Test
- void shouldBlacklistHeaderByPropertyName() {
- System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, "X-Channel-Request-Id");
+ System.clearProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY);
HeaderPropagationConfiguration.resetCache();
-
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("x-channel-request-id"));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
- }
-
- @Test
- void shouldParseCommaSeparatedBlacklistedHeaders() {
- System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, "X-Channel-Request-Id, X-Request-Id");
- HeaderPropagationConfiguration.resetCache();
-
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("x-channel-request-id"));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("Custom-Header"));
}
@Test
- void shouldBlacklistXChannelRequestIdByDefault() {
+ void shouldBlockXChannelRequestIdByDefault() {
Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("x-channel-request-id"));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
+ Assertions.assertEquals(HeaderPropagationConfiguration.INTERNAL_BLOCKED_HEADERS,
+ HeaderPropagationConfiguration.blockedHeaders());
}
@Test
- void shouldNotBlacklistXChannelRequestIdWhenBlockedHeadersExplicitlyEmpty() {
- System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, "");
+ void shouldNotBlockXChannelRequestIdWhenExempted() {
+ System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, "X-Channel-Request-Id");
HeaderPropagationConfiguration.resetCache();
Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("x-channel-request-id"));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
+ Assertions.assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty());
}
@Test
- void shouldNotBlacklistXChannelRequestIdWhenOtherHeadersExplicitlyBlocked() {
- // The property is explicitly set to a non-blockable header; the default
- // blocked list must NOT silently kick in.
- System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, "X-Request-Id");
+ void shouldApplyExemptionsCaseInsensitively() {
+ System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, "x-channel-request-id");
HeaderPropagationConfiguration.resetCache();
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
}
@Test
- void shouldReturnEmptyListWhenOnlyNonBlockableHeadersConfigured() {
- System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, "X-Request-Id, x-request-id");
+ void shouldIgnoreUnknownExemptionEntries() {
+ // Names that are not in the internal blocklist must not change anything.
+ System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, "Custom-Header, X-Request-Id");
HeaderPropagationConfiguration.resetCache();
+ Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ "Internal blocklist must remain unchanged when no exemption matches it");
+ Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("Custom-Header"));
Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty());
}
@Test
- void shouldReadEnvWhenPropertyNotSet() {
- // Env value is read when no system property is set. The configured value
- // is only X-Request-Id (non-blockable), so the resulting list must be empty —
- // we deliberately do NOT fall back to the default blocked list here.
- environmentVariables.set(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV, "X-Request-Id");
- try {
- HeaderPropagationConfiguration.resetCache();
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty());
- } finally {
- environmentVariables.remove(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV);
- HeaderPropagationConfiguration.resetCache();
- }
- }
+ void shouldTreatEmptyExemptionPropertyAsNoExemption() {
+ System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, "");
+ HeaderPropagationConfiguration.resetCache();
- @Test
- void shouldBlacklistHeaderByEnvWhenPropertyNotSet() throws Exception {
- // Sanity check that env-sourced configuration actually drives the blocked list
- // when the system property is absent.
- environmentVariables.set(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV, "Custom-Header");
- try {
- HeaderPropagationConfiguration.resetCache();
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("Custom-Header"));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- } finally {
- environmentVariables.remove(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV);
- HeaderPropagationConfiguration.resetCache();
- }
+ Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
+ Assertions.assertEquals(HeaderPropagationConfiguration.INTERNAL_BLOCKED_HEADERS,
+ HeaderPropagationConfiguration.blockedHeaders());
}
@Test
- void shouldNotBlockXRequestIdEvenWhenExplicitlyListed() {
- System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, "X-Channel-Request-Id, X-Request-Id");
+ void shouldTreatBlankAndCommaOnlyExemptionPropertyAsNoExemption() {
+ System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, " , ,, ");
HeaderPropagationConfiguration.resetCache();
-
- // X-Request-Id is never blocked
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
- // X-Channel-Request-Id blocked
+
Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- // there is no X-Request-Id in a list
- Assertions.assertFalse(HeaderPropagationConfiguration.blockedHeaders()
- .stream().anyMatch(h -> h.equalsIgnoreCase("X-Request-Id")));
}
-
- @Test
- void shouldReturnEmptyListWhenEnvExplicitlyEmpty() throws Exception {
- environmentVariables.set(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV, "");
- try {
- HeaderPropagationConfiguration.resetCache();
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty());
- } finally {
- environmentVariables.remove(HeaderPropagationConfiguration.HEADERS_BLOCKED_ENV);
- HeaderPropagationConfiguration.resetCache();
- }
- }
-
+
@Test
- void shouldBlockedHeadersReturnCorrectList() {
- System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, "Custom-Header, X-Request-Id");
- HeaderPropagationConfiguration.resetCache();
-
- List blocked = HeaderPropagationConfiguration.blockedHeaders();
- Assertions.assertTrue(blocked.contains("Custom-Header"));
- Assertions.assertFalse(blocked.stream().anyMatch(h -> h.equalsIgnoreCase("X-Request-Id")));
+ void isBlacklistedShouldReturnFalseForNullAndBlank() {
+ Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted(null));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted(""));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted(" "));
}
}
diff --git a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObjectPropagationTest.java b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObjectPropagationTest.java
index e806c6573..c26e5c2a3 100644
--- a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObjectPropagationTest.java
+++ b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObjectPropagationTest.java
@@ -69,20 +69,17 @@ void testXChannelRequestIdPropagationWithResponsePropagatableData() {
}
@Test
- void testXChannelRequestIdPropagationIsBlockedWhenConfigured() {
- System.setProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY, X_CHANNEL_REQUEST_ID);
+ void testXChannelRequestIdPropagationIsBlockedByInternalBlocklist() {
+ System.clearProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY);
HeaderPropagationConfiguration.resetCache();
- try {
- RequestContextPropagation.initRequestContext(new ContextDataRequest()); // filter
- ContextDataResponse responseContextData = new ContextDataResponse();
- RequestContextPropagation.setResponsePropagatableData(responseContextData);
- Assertions.assertEquals("-", responseContextData.getResponseHeaders().get(X_CHANNEL_REQUEST_ID));
-
- Map> serializableContextData = ContextManager.getSerializableContextData();
- Assertions.assertTrue(serializableContextData.getOrDefault(X_CHANNEL_REQUEST_ID_CONTEXT_NAME, Collections.emptyMap()).isEmpty());
- } finally {
- System.clearProperty(HeaderPropagationConfiguration.HEADERS_BLOCKED_PROPERTY);
- }
+
+ RequestContextPropagation.initRequestContext(new ContextDataRequest()); // filter
+ ContextDataResponse responseContextData = new ContextDataResponse();
+ RequestContextPropagation.setResponsePropagatableData(responseContextData);
+ Assertions.assertEquals("-", responseContextData.getResponseHeaders().get(X_CHANNEL_REQUEST_ID));
+
+ Map> serializableContextData = ContextManager.getSerializableContextData();
+ Assertions.assertTrue(serializableContextData.getOrDefault(X_CHANNEL_REQUEST_ID_CONTEXT_NAME, Collections.emptyMap()).isEmpty());
}
@Test
diff --git a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationSpringCommonTest.java b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationSpringCommonTest.java
index 50cfdc264..01bbb10e9 100644
--- a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationSpringCommonTest.java
+++ b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationSpringCommonTest.java
@@ -30,7 +30,7 @@ class RequestPropagationSpringCommonTest {
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).addFilter(filter).build();
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
}
@Test
diff --git a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationTest.java b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationTest.java
index a9f9fb421..e62da4eba 100644
--- a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationTest.java
+++ b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationTest.java
@@ -34,7 +34,8 @@
TestController.class, RequestPropagationTestConfig.class})
@TestPropertySource(properties = {
"headers.allowed=custom-header",
- "headers.blocked=",
+ // context.propagation.allow-blocked-headers deliberately not set — the internal blocklist applies and
+ // X-Channel-Request-Id should not propagate to outgoing requests.
"cloud-core.context-propagation.url=/test_url/v111/test"
})
class RequestPropagationTest {
@@ -64,7 +65,7 @@ class RequestPropagationTest {
@BeforeEach
void setUp() {
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
mockMvc = MockMvcBuilders.webAppContextSetup(context).addFilters(preAuthnFilter, postAuthnFilter).build();
@@ -107,15 +108,14 @@ void testRequestPropagation() throws Exception {
}
@Test
- void testXRequestIdStillPropagatesWhenAddedToBlockedList() throws Exception {
- System.setProperty("headers.blocked", X_REQUEST_ID_NAME);
+ void testXRequestIdNotAffectedByExemptionConfig() throws Exception {
+ System.setProperty("context.propagation.allow-blocked-headers", X_REQUEST_ID_NAME);
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/chain_request"))
.andExpect(header(HttpHeaders.ACCEPT_LANGUAGE, ACCEPT_LANGUAGE_VALUE))
- // X-Request-Id is non-blockable and must still be propagated.
.andExpect(header(X_REQUEST_ID_NAME, X_REQUEST_ID_VALUE))
.andExpect(header(CUSTOM_NAME, CUSTOM_VALUE))
.andRespond(withSuccess());
diff --git a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdAllowedTest.java b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdAllowedTest.java
index fa47551a4..3c567f1fb 100644
--- a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdAllowedTest.java
+++ b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdAllowedTest.java
@@ -33,7 +33,7 @@
TestController.class, RequestPropagationTestConfig.class})
@TestPropertySource(properties = {
"headers.allowed=custom-header",
- "headers.blocked=",
+ "context.propagation.allow-blocked-headers=X-Channel-Request-Id",
"cloud-core.context-propagation.url=/test_url/v111/test"
})
class RequestPropagationXChannelRequestIdAllowedTest {
@@ -64,7 +64,7 @@ class RequestPropagationXChannelRequestIdAllowedTest {
@BeforeAll
static void beforeAll() {
System.setProperty("headers.allowed", "custom-header");
- System.setProperty("headers.blocked", "");
+ System.setProperty("context.propagation.allow-blocked-headers", "X-Channel-Request-Id");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
@@ -72,7 +72,7 @@ static void beforeAll() {
@AfterAll
static void afterAll() {
System.clearProperty("headers.allowed");
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
diff --git a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdResponseTest.java b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdResponseTest.java
index d60295141..19d649a2c 100644
--- a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdResponseTest.java
+++ b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdResponseTest.java
@@ -31,7 +31,7 @@
@TestPropertySource(properties = {
"headers.allowed=custom-header",
"cloud-core.context-propagation.url=/test_url/v111/test"
- // headers.blocked is not set, X-Channel-Request-Id blocked for outgoing requests
+ // context.propagation.allow-blocked-headers is not set, internal blocklist applies → X-Channel-Request-Id blocked for outgoing requests
})
class RequestPropagationXChannelRequestIdResponseTest {
@@ -55,14 +55,14 @@ class RequestPropagationXChannelRequestIdResponseTest {
@BeforeAll
static void beforeAll() {
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
@AfterAll
static void afterAll() {
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/main/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfiguration.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/main/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfiguration.java
index 3166e2397..b06fc1b31 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/main/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfiguration.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/main/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfiguration.java
@@ -13,12 +13,14 @@
@Configuration
public class SpringContextProviderConfiguration {
+
@Bean
- public SpringPostAuthnContextProviderFilter springPostAuthnContextProviderFilter(){
+ public SpringPostAuthnContextProviderFilter springPostAuthnContextProviderFilter() {
return new SpringPostAuthnContextProviderFilter();
}
+
@Bean
- public SpringPreAuthnContextProviderFilter springPreAuthnContextProviderFilter(){
+ public SpringPreAuthnContextProviderFilter springPreAuthnContextProviderFilter() {
return new SpringPreAuthnContextProviderFilter();
}
@@ -29,14 +31,14 @@ public SpringPreAuthnContextProviderFilter springPreAuthnContextProviderFilter()
@Value("${headers.allowed:}")
private String allowedHeaders;
- @Value("${headers.blocked:}")
- private String blockedHeaders;
+ @Value("${context.propagation.allow-blocked-headers:}")
+ private String allowedFromBlocklist;
@PostConstruct
public void init() {
System.setProperty("headers.allowed", allowedHeaders);
- if (environment.containsProperty("headers.blocked")) {
- System.setProperty("headers.blocked", blockedHeaders);
+ if (environment.containsProperty("context.propagation.allow-blocked-headers")) {
+ System.setProperty("context.propagation.allow-blocked-headers", allowedFromBlocklist);
}
}
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java
index 8c0a30297..3f92991b4 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java
@@ -7,11 +7,19 @@
import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
public class HeaderPropagationStateReset implements BeforeAllCallback, AfterAllCallback {
- @Override public void beforeAll(ExtensionContext ctx) { reset(); }
- @Override public void afterAll(ExtensionContext ctx) { reset(); }
+
+ @Override
+ public void beforeAll(ExtensionContext ctx) {
+ reset();
+ }
+
+ @Override
+ public void afterAll(ExtensionContext ctx) {
+ reset();
+ }
private static void reset() {
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
System.clearProperty("headers.allowed");
HeaderPropagationConfiguration.resetCache();
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
index f9c0905ad..b5fe96476 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
@@ -1,6 +1,7 @@
package com.netcracker.cloud.context.propagation.spring.common.configuration;
import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.annotation.DirtiesContext;
@@ -9,33 +10,24 @@
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-/**
- * Spring integration scenario: {@code headers.blocked=} (set explicitly to empty).
- * Verifies that {@link SpringContextProviderConfiguration#init()} propagates the
- * empty value to the system property, which downstream code interprets as
- * "erase the default blocked list".
- */
@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
"headers.allowed=custom-header",
- "headers.blocked="
+ "context.propagation.allow-blocked-headers="
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationEmptyTest {
@Test
- void shouldSetEmptySystemPropertyAndEraseDefaultBlockedList() {
- assertEquals("", System.getProperty("headers.blocked"),
+ void shouldSetEmptySystemPropertyAndStillApplyInternalBlocklist() {
+ assertEquals("", System.getProperty("context.propagation.allow-blocked-headers"),
"Spring init() must propagate explicit empty value to the system property");
HeaderPropagationConfiguration.resetCache();
- assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
- "explicit empty value must erase the default blocked list");
- assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "X-Channel-Request-Id must no longer be blocked");
+ assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ "Internal blocklist must still apply when the exemption property is blank");
}
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
index 4b56a696f..121acc73b 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
@@ -15,38 +15,27 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-/**
- * Spring integration scenario: {@code headers.blocked} is configured only via the
- * {@code HEADERS_BLOCKED} environment variable. Verifies that Spring's relaxed
- * binding picks up the env var as the {@code headers.blocked} property, that
- * {@link SpringContextProviderConfiguration#init()} propagates it to the system
- * property, and that the downstream blocked list reflects the env-sourced value.
- *
- * {@link SystemStubsExtension} must be registered before {@link SpringExtension}
- * so that the env var is set before Spring's {@code SystemEnvironmentPropertySource}
- * is consulted during context initialization.
- */
@ExtendWith({HeaderPropagationStateReset.class, SystemStubsExtension.class, SpringExtension.class})
@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
- // headers.blocked deliberately not declared here — it must come from the env var
+ // context.propagation.allow-blocked-headers deliberately NOT declared here — it must come from the env var
"headers.allowed=custom-header"
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationFromEnvVarTest {
@SystemStub
- static EnvironmentVariables envVars = new EnvironmentVariables("HEADERS_BLOCKED", "Custom-Header");
+ static EnvironmentVariables envVars = new EnvironmentVariables("CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS", "X-Channel-Request-Id");
@Test
- void shouldReadHeadersBlockedFromEnvVar() {
- assertEquals("Custom-Header", System.getProperty("headers.blocked"),
+ void shouldReadHeadersAllowBlockedFromEnvVar() {
+ assertEquals("X-Channel-Request-Id", System.getProperty("context.propagation.allow-blocked-headers"),
"Spring init() must propagate env-sourced value to the system property");
HeaderPropagationConfiguration.resetCache();
- assertTrue(HeaderPropagationConfiguration.isBlacklisted("Custom-Header"),
- "env-sourced header must be blocked");
assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "explicit env-sourced configuration overrides the default");
+ "Env-sourced exemption must take effect");
+ assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
+ "The only entry of the internal blocklist must be removed by the exemption");
}
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
index 1d4ba15fa..a9da90895 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
@@ -11,27 +11,22 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
-/**
- * Spring integration scenario: {@code headers.blocked} is not set anywhere.
- * Verifies that {@link SpringContextProviderConfiguration#init()} does NOT touch
- * the {@code headers.blocked} system property, so downstream code falls back to
- * the built-in default blocked list (which contains {@code X-Channel-Request-Id}).
- */
@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
+ // context.propagation.allow-blocked-headers intentionally absent
"headers.allowed=custom-header"
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationNotConfiguredTest {
@Test
- void shouldNotSetSystemPropertyAndApplyDefaultBlockedList() {
- assertNull(System.getProperty("headers.blocked"),
- "headers.blocked must remain unset when no source configures it");
+ void shouldNotTouchSystemPropertyAndKeepInternalBlocklist() {
+ assertNull(System.getProperty("context.propagation.allow-blocked-headers"),
+ "context.propagation.allow-blocked-headers must remain unset when no source configures it");
HeaderPropagationConfiguration.resetCache();
assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "default blocked list must apply when nothing is configured");
+ "Internal blocklist must apply when no exemption is configured");
}
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java
deleted file mode 100644
index b6649f58b..000000000
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationOnlyNonBlockableTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.netcracker.cloud.context.propagation.spring.common.configuration;
-
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-/**
- * Spring integration scenario: {@code headers.blocked=X-Request-Id} — the configured
- * value consists exclusively of a non-blockable header. The resulting blocked list
- * must be empty, NOT the built-in default. This locks in the behavior change made
- * to {@link HeaderPropagationConfiguration} (no silent fallback to default when the
- * user explicitly configured something).
- */
-@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
-@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
-@TestPropertySource(properties = {
- "headers.allowed=custom-header",
- "headers.blocked=X-Request-Id"
-})
-@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-class SpringContextProviderConfigurationOnlyNonBlockableTest {
-
- @Test
- void shouldRespectExplicitOverrideEvenWhenItFiltersToEmpty() {
- assertEquals("X-Request-Id", System.getProperty("headers.blocked"));
-
- HeaderPropagationConfiguration.resetCache();
- assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
- "the resulting blocked list must be empty — the default must NOT be restored");
- assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"),
- "X-Request-Id is non-blockable and must never be blocked");
- assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "explicit (even if filter-emptied) configuration overrides the default");
- }
-}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownExemptionTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownExemptionTest.java
new file mode 100644
index 000000000..1a8a766c1
--- /dev/null
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownExemptionTest.java
@@ -0,0 +1,34 @@
+package com.netcracker.cloud.context.propagation.spring.common.configuration;
+
+import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
+@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
+@TestPropertySource(properties = {
+ "headers.allowed=custom-header",
+ "context.propagation.allow-blocked-headers=Custom-Header, X-Some-Other-Header"
+})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+class SpringContextProviderConfigurationUnknownExemptionTest {
+
+ @Test
+ void shouldLeaveInternalBlocklistIntactWhenExemptionsDontMatch() {
+ assertEquals("Custom-Header, X-Some-Other-Header",
+ System.getProperty("context.propagation.allow-blocked-headers"));
+
+ HeaderPropagationConfiguration.resetCache();
+ assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ "Internal blocklist must remain intact when no exemption matches it");
+ assertEquals(HeaderPropagationConfiguration.INTERNAL_BLOCKED_HEADERS,
+ HeaderPropagationConfiguration.blockedHeaders());
+ }
+}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
index 88e48709d..b496265a1 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
@@ -12,30 +12,23 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
-/**
- * Spring integration scenario: {@code headers.blocked} is set to a concrete blockable header.
- * Verifies that the listed header is blocked and the default's
- * {@code X-Channel-Request-Id} entry no longer applies.
- */
@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
"headers.allowed=custom-header",
- "headers.blocked=Custom-Header"
+ "context.propagation.allow-blocked-headers=X-Channel-Request-Id"
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationWithValueTest {
@Test
- void shouldSetSystemPropertyAndBlockConfiguredHeader() {
- assertEquals("Custom-Header", System.getProperty("headers.blocked"));
+ void shouldExemptListedHeaderFromInternalBlocklist() {
+ assertEquals("X-Channel-Request-Id", System.getProperty("context.propagation.allow-blocked-headers"));
HeaderPropagationConfiguration.resetCache();
- assertTrue(HeaderPropagationConfiguration.isBlacklisted("Custom-Header"),
- "configured header must be blocked");
- assertTrue(HeaderPropagationConfiguration.isBlacklisted("custom-header"),
- "blocking must be case-insensitive");
assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "explicit configuration overrides the default blocked list");
+ "Exempted header must not be blocked");
+ assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
+ "The only entry of the internal blocklist (X-Channel-Request-Id) must be removed");
}
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/src/test/java/com/netcracker/cloud/context/propagation/spring/kafka/ContextPropagationTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/src/test/java/com/netcracker/cloud/context/propagation/spring/kafka/ContextPropagationTest.java
index afe9ff138..62a134218 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/src/test/java/com/netcracker/cloud/context/propagation/spring/kafka/ContextPropagationTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/src/test/java/com/netcracker/cloud/context/propagation/spring/kafka/ContextPropagationTest.java
@@ -61,7 +61,7 @@ public class ContextPropagationTest {
@BeforeAll
static void setup() {
System.setProperty("headers.allowed", CUSTOM_HEADER.toLowerCase());
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
HeaderPropagationConfiguration.resetCache();
}
@@ -73,7 +73,7 @@ void beforeEach() {
@AfterEach
void afterEach() {
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
HeaderPropagationConfiguration.resetCache();
}
@@ -100,8 +100,10 @@ void testContextPropagationBlocksXChannelRequestIdByDefault() throws Exception {
@Test
@Timeout(30)
- public void testContextPropagationAllowsXChannelRequestIdWhenHeadersBlockedEmpty() throws Exception {
- System.setProperty("headers.blocked", "");
+ public void testContextPropagationAllowsXChannelRequestIdWhenExempted() throws Exception {
+ System.setProperty("context.propagation.allow-blocked-headers", X_CHANNEL_REQUEST_ID_NAME);
+ HeaderPropagationConfiguration.resetCache();
+
ChannelRequestIdContext.set(X_CHANNEL_REQUEST_ID_VALUE);
AcceptLanguageContext.set(TEST_LANG);
AllowedHeadersContext.set(Map.of(CUSTOM_HEADER, CUSTOM_HEADER_VALUE));
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/src/test/java/com/netcracker/cloud/context/propagation/spring/rabbit/PropagationTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/src/test/java/com/netcracker/cloud/context/propagation/spring/rabbit/PropagationTest.java
index bc539c6e5..581b06fd8 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/src/test/java/com/netcracker/cloud/context/propagation/spring/rabbit/PropagationTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/src/test/java/com/netcracker/cloud/context/propagation/spring/rabbit/PropagationTest.java
@@ -87,7 +87,7 @@ public static void setup() throws Exception {
channel.queueBind("orders", "orders", "invoice");
}
System.setProperty("headers.allowed", CUSTOM_HEADER.toLowerCase());
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
}
@AfterAll
@@ -103,7 +103,7 @@ void beforeEach() {
@AfterEach
void afterEach() {
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
HeaderPropagationConfiguration.resetCache();
}
@@ -125,8 +125,11 @@ public void testXChannelRequestIdBlockedByDefault() throws InterruptedException
@Test
@Timeout(value = 20, unit = TimeUnit.SECONDS)
- public void testXChannelRequestIdAllowedWhenHeadersBlockedEmpty() throws InterruptedException {
- System.setProperty("headers.blocked", "");
+ public void testXChannelRequestIdAllowedWhenExempted() throws InterruptedException {
+ // Exempt X-Channel-Request-Id from the internal blocklist — it must propagate.
+ System.setProperty("context.propagation.allow-blocked-headers", X_CHANNEL_REQUEST_ID_NAME);
+ HeaderPropagationConfiguration.resetCache();
+
AcceptLanguageContext.set("ZULU");
AllowedHeadersContext.set(Map.of(CUSTOM_HEADER, CUSTOM_HEADER_VALUE));
ChannelRequestIdContext.set(X_CHANNEL_REQUEST_ID_VALUE);
@@ -142,12 +145,17 @@ public void testXChannelRequestIdAllowedWhenHeadersBlockedEmpty() throws Interru
@Test
@Timeout(value = 20, unit = TimeUnit.SECONDS)
- public void testCustomHeaderBlockedWhenConfiguredByProperty() throws InterruptedException {
- System.setProperty("headers.blocked", ANOTHER_HEADER);
+ public void testUnknownExemptionDoesNotAffectInternalBlocklist() throws InterruptedException {
+ // Listing a header that is NOT in the internal blocklist has no effect — the
+ // internal blocklist (containing X-Channel-Request-Id) still applies.
+ System.setProperty("context.propagation.allow-blocked-headers", ANOTHER_HEADER);
+ HeaderPropagationConfiguration.resetCache();
+
AcceptLanguageContext.set("ZULU");
AllowedHeadersContext.set(Map.of(
CUSTOM_HEADER, CUSTOM_HEADER_VALUE,
ANOTHER_HEADER, ANOTHER_HEADER_VALUE));
+ ChannelRequestIdContext.set(X_CHANNEL_REQUEST_ID_VALUE);
template.convertAndSend("orders", "invoice", "rye wheat");
ContextManager.clearAll();
@@ -155,8 +163,10 @@ public void testCustomHeaderBlockedWhenConfiguredByProperty() throws Interrupted
fail("Message listener failed or message doesn't even arrived in 10 seconds");
}
- assertNull(getHeaderIgnoreCase(receivedHeaders.get(), ANOTHER_HEADER));
+ assertNull(getHeaderIgnoreCase(receivedHeaders.get(), X_CHANNEL_REQUEST_ID_NAME),
+ "Internal blocklist must remain intact when no exemption matches it");
assertEquals(CUSTOM_HEADER_VALUE, getHeaderIgnoreCase(receivedHeaders.get(), CUSTOM_HEADER));
+ assertEquals(ANOTHER_HEADER_VALUE, getHeaderIgnoreCase(receivedHeaders.get(), ANOTHER_HEADER));
}
diff --git a/maas-client/kafka-context-propagation/src/test/java/com/netcracker/cloud/maas/client/context/kafka/KafkaContextPropagationTest.java b/maas-client/kafka-context-propagation/src/test/java/com/netcracker/cloud/maas/client/context/kafka/KafkaContextPropagationTest.java
index addb62f3b..a5ee8744c 100644
--- a/maas-client/kafka-context-propagation/src/test/java/com/netcracker/cloud/maas/client/context/kafka/KafkaContextPropagationTest.java
+++ b/maas-client/kafka-context-propagation/src/test/java/com/netcracker/cloud/maas/client/context/kafka/KafkaContextPropagationTest.java
@@ -103,8 +103,8 @@ void testDumpDoesNotContainXChannelRequestIdByDefault() {
}
@Test
- void testDumpContainsXChannelRequestIdWhenNotBlocked() {
- System.setProperty("headers.blocked", "");
+ void testDumpContainsXChannelRequestIdWhenExempted() {
+ System.setProperty("context.propagation.allow-blocked-headers", X_CHANNEL_REQUEST_ID);
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
@@ -117,7 +117,7 @@ void testDumpContainsXChannelRequestIdWhenNotBlocked() {
assertEquals("ch-456", dumped.get(X_CHANNEL_REQUEST_ID));
} finally {
- System.clearProperty("headers.blocked");
+ System.clearProperty("context.propagation.allow-blocked-headers");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
From f35dfd710b57fad7a9bc099e10cc0da155f6ba29 Mon Sep 17 00:00:00 2001
From: Ksiona
Date: Tue, 19 May 2026 08:41:09 +0400
Subject: [PATCH 7/9] chore: docs correction
---
core-context-propagation-quarkus/README.md | 45 +++++++++++----------
core-context-propagation/README.md | 46 +++++++++++-----------
2 files changed, 44 insertions(+), 47 deletions(-)
diff --git a/core-context-propagation-quarkus/README.md b/core-context-propagation-quarkus/README.md
index 28a01dcf2..80e4cc4da 100644
--- a/core-context-propagation-quarkus/README.md
+++ b/core-context-propagation-quarkus/README.md
@@ -184,35 +184,34 @@ quarkus:
-Dquarkus.context.propagation.allow-blocked-headers=X-Channel-Request-Id
```
-**Via container ENV (recommended, Qubership pattern)**
+**Sourcing the value from an environment variable**
-In Qubership deployments configuration values are typically wired from container ENV variables
-through `application.yaml` placeholders. The full chain looks like this:
+Instead of hard-coding the list of exempted headers in `application.properties` / `application.yaml`,
+the value can be sourced from an environment variable using a standard `${ENV_VAR:default}` placeholder.
+This way the file structure stays the same across environments and the actual list is controlled
+externally — through an ENV variable that is set somewhere outside Quarkus (a container manifest,
+a Helm chart, `systemd` unit, CI variable, local shell, etc.).
-1. The container declares an ENV variable, for example in the deployment manifest:
-
- ```yaml
- env:
- - name: CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS
- value: "X-Channel-Request-Id"
- ```
+```properties
+quarkus.context.propagation.allow-blocked-headers=${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+```
-2. The application's `application.yaml` reads it via a `${VAR}` placeholder:
+or, equivalently, in `application.yaml`:
- ```yaml
- quarkus:
- context:
- propagation:
- allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
- ```
+```yaml
+quarkus:
+ context:
+ propagation:
+ allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+```
- The trailing `:` (empty default) lets the property gracefully fall through to "not set" when
- the ENV variable is absent — the internal blocklist then applies in full.
+The trailing `:` (empty default) lets the property gracefully resolve to an empty value when the ENV
+variable is absent — under our model that is equivalent to "not configured" and the internal blocklist
+applies in full. Setting `CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS=X-Channel-Request-Id` in the runtime
+environment turns the exemption on without touching the YAML.
-3. Quarkus also recognises the ENV variable directly under the canonical name
- `CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS` (via MicroProfile Config relaxed env-to-property mapping), so
- the same ENV variable works even without the `application.yaml` indirection. The placeholder
- form is preferred because it makes the dependency explicit in source control.
+The ENV variable name in the placeholder is just a contract between the application file and the runtime
+environment — it can be any name, as long as both sides agree.
**MDC Integration:** The channel request ID is automatically stored in MDC under the key `x_channel_request_id` for use in
logging.
diff --git a/core-context-propagation/README.md b/core-context-propagation/README.md
index ff5d3e453..2981f6fab 100644
--- a/core-context-propagation/README.md
+++ b/core-context-propagation/README.md
@@ -161,8 +161,7 @@ blocklist (i.e. allowed to propagate).
#### `context.propagation.allow-blocked-headers` property
The property carries a comma-separated list of header names. Every name that matches an entry of
-the internal blocklist is removed from the effective blocklist. Names that are not in the
-internal blocklist have no effect.
+the internal blocklist is removed from the effective blocklist. Names that are not in the internal blocklist have no effect.
Examples:
@@ -195,34 +194,33 @@ context:
-Dcontext.propagation.allow-blocked-headers=X-Channel-Request-Id
```
-**Via container ENV (recommended, Qubership pattern)**
+**Sourcing the value from an environment variable**
-In Qubership deployments configuration values are typically wired from container ENV variables
-through `application.yaml` placeholders. The full chain looks like this:
+Instead of hard-coding the list of exempted headers in `application.properties` / `application.yml`,
+the value can be sourced from an environment variable using a standard `${ENV_VAR:default}` placeholder.
+This way the file structure stays the same across environments and the actual list is controlled
+externally — through an ENV variable that is set somewhere outside Spring (a container manifest,
+a Helm chart, `systemd` unit, CI variable, local shell, etc.).
-1. The container declares an ENV variable, for example in the deployment manifest:
-
- ```yaml
- env:
- - name: CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS
- value: "X-Channel-Request-Id"
- ```
+```properties
+context.propagation.allow-blocked-headers=${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+```
-2. The application's `application.yaml` reads it via a `${VAR}` placeholder:
+or, equivalently, in `application.yml`:
- ```yaml
- context:
- propagation:
- allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
- ```
+```yaml
+context:
+ propagation:
+ allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+```
- The trailing `:` (empty default) lets the property gracefully fall through to "not set" when
- the ENV variable is absent — the internal blocklist then applies in full.
+The trailing `:` (empty default) lets the property gracefully resolve to an empty value when the ENV
+variable is absent — under our model that is equivalent to "not configured" and the internal blocklist
+applies in full. Setting `CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS=X-Channel-Request-Id` in the runtime
+environment turns the exemption on without touching the YAML.
-3. Spring's relaxed binding also recognises the ENV variable directly under the property name
- `context.propagation.allow-blocked-headers` (i.e. without an explicit placeholder), so the same ENV variable works
- even without the `application.yaml` indirection. The placeholder form is preferred because it
- makes the dependency explicit in source control.
+The ENV variable name in the placeholder is just a contract between the application file and the runtime
+environment — it can be any name, as long as both sides agree.
**MDC Integration:**
The `X-Channel-Request-Id` is automatically integrated with SLF4J's Mapped Diagnostic Context (MDC) for seamless logging.
From e190b269602f177ec947926d8b8bf830b33a519b Mon Sep 17 00:00:00 2001
From: Ksiona
Date: Tue, 19 May 2026 20:59:27 +0400
Subject: [PATCH 8/9] chore: fix review requested + version bump
---
core-context-propagation-quarkus/README.md | 51 ++++----
.../context-propagation-bom-internal/pom.xml | 4 +-
.../bom/context-propagation-bom/pom.xml | 2 +-
core-context-propagation-quarkus/bom/pom.xml | 2 +-
.../build-parent/pom.xml | 2 +-
.../context-propagation/deployment/pom.xml | 2 +-
.../context-propagation/pom.xml | 2 +-
.../context-propagation/runtime/pom.xml | 2 +-
...tProviderHandlerXChannelRequestIdTest.java | 3 +-
.../framework-contexts/deployment/pom.xml | 2 +-
.../FrameworkContextsQuarkusProcessor.java | 19 ++-
.../framework-contexts/pom.xml | 2 +-
.../framework-contexts/runtime/pom.xml | 2 +-
.../allowedheaders/HeadersAllowedConfig.java | 28 -----
.../HeadersAllowedRecorder.java | 4 -
.../HeadersOptionalConfig.java | 33 ++++++
.../HeadersOptionalRecorder.java | 25 ++++
.../context-propagation-reactive-test/pom.xml | 2 +-
...HeadersAllowBlockedRecorderEffectTest.java | 33 ------
.../HeadersAllowedConfigNotSetTest.java | 34 ------
.../HeadersAllowedConfigTest.java | 11 --
...adersEnableOptionalRecorderEffectTest.java | 49 ++++++++
.../HeadersOptionalConfigNotSetTest.java | 47 ++++++++
.../HeadersOptionalConfigTest.java | 31 +++++
.../src/test/resources/application.properties | 2 +-
.../integration-tests/pom.xml | 2 +-
core-context-propagation-quarkus/pom.xml | 2 +-
.../report-aggregate/pom.xml | 2 +-
core-context-propagation/README.md | 55 ++++-----
core-context-propagation/api-tests/pom.xml | 2 +-
.../contexts/IncomingContextDataFactory.java | 3 +-
...XChannelRequestIdContextObjectApiTest.java | 5 +-
.../XChannelRequestIdProviderApiTest.java | 8 +-
.../context-propagation-bom/pom.xml | 2 +-
.../context-propagation-core/pom.xml | 2 +-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
.../framework-contexts/pom.xml | 2 +-
.../AllowedHeadersContextObject.java | 17 +--
.../HeaderPropagationConfiguration.java | 110 -----------------
.../HeaderPropagationConfiguration.java | 112 ++++++++++++++++++
.../XChannelRequestIdContextObject.java | 8 +-
.../AllowedHeadersPropertyTest.java | 2 +
.../HeaderPropagationConfigurationTest.java | 60 +++++-----
.../AbstractContextTestWithProperties.java | 2 +-
...RequestIdContextObjectPropagationTest.java | 33 +++---
.../filters/context/AbstractContextTest.java | 2 +-
core-context-propagation/pom.xml | 2 +-
.../sample-context-tests/pom.xml | 2 +-
.../RequestPropagationSpringCommonTest.java | 6 +-
.../requests/RequestPropagationTest.java | 8 +-
...opagationXChannelRequestIdAllowedTest.java | 9 +-
...pagationXChannelRequestIdResponseTest.java | 9 +-
.../context-propagation-spring-common/pom.xml | 2 +-
.../SpringContextProviderConfiguration.java | 8 +-
.../HeaderPropagationStateReset.java | 10 +-
...ContextProviderConfigurationEmptyTest.java | 15 +--
...xtProviderConfigurationFromEnvVarTest.java | 41 -------
...roviderConfigurationNotConfiguredTest.java | 16 +--
...ProviderConfigurationUnknownEntryTest.java | 41 +++++++
...iderConfigurationUnknownExemptionTest.java | 34 ------
...extProviderConfigurationWithValueTest.java | 16 +--
.../SpringContextProviderFilterTest.java | 7 +-
.../context-propagation-spring-kafka/pom.xml | 2 +-
.../spring/kafka/ContextPropagationTest.java | 16 +--
.../context-propagation-spring-rabbit/pom.xml | 2 +-
.../spring/rabbit/PropagationTest.java | 17 ++-
.../pom.xml | 2 +-
.../pom.xml | 2 +-
.../spring-context-aggregator/pom.xml | 2 +-
.../cloud-core-java-bom/pom.xml | 2 +-
.../cloud-core-quarkus-bom-internal/pom.xml | 2 +-
.../cloud-core-quarkus-bom-parent/pom.xml | 2 +-
core-rest-libraries/rest-third-party/pom.xml | 2 +-
.../dbaas-client-bom-internal/pom.xml | 2 +-
.../kafka/KafkaContextPropagationTest.java | 6 +-
maas-client/pom.xml | 2 +-
77 files changed, 583 insertions(+), 533 deletions(-)
create mode 100644 core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfig.java
create mode 100644 core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalRecorder.java
delete mode 100644 core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowBlockedRecorderEffectTest.java
delete mode 100644 core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigNotSetTest.java
create mode 100644 core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersEnableOptionalRecorderEffectTest.java
create mode 100644 core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigNotSetTest.java
create mode 100644 core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigTest.java
delete mode 100644 core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java
create mode 100644 core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/HeaderPropagationConfiguration.java
delete mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
create mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownEntryTest.java
delete mode 100644 core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownExemptionTest.java
diff --git a/core-context-propagation-quarkus/README.md b/core-context-propagation-quarkus/README.md
index 80e4cc4da..b86f30d09 100644
--- a/core-context-propagation-quarkus/README.md
+++ b/core-context-propagation-quarkus/README.md
@@ -133,30 +133,30 @@ Propagates and allows to get `X-Channel-Request-Id` value. If an incoming reques
**Default behavior:** `X-Channel-Request-Id` is NOT propagated to outgoing requests.
-#### Internal blocklist
+#### Restricted contexts
-The framework owns a hard-coded internal blocklist of headers that are not propagated to outgoing
-requests. It currently contains:
+The framework owns a hard-coded list of restricted contexts — headers that are not propagated
+to outgoing requests by default. It currently contains:
- `X-Channel-Request-Id`
-The blocklist itself cannot be changed from configuration. The only externally visible knob is the
-`quarkus.context.propagation.allow-blocked-headers` property, which lists header names that should be **exempted** from
-this blocklist (i.e. allowed to propagate).
+The list itself cannot be changed from configuration. The only externally visible knob is the
+`quarkus.context.propagation.headers.enable.optional` property, which names headers from that list
+that should be enabled for propagation.
-#### `quarkus.context.propagation.allow-blocked-headers` property
+#### `quarkus.context.propagation.headers.enable.optional` property
-The property carries a comma-separated list of header names. Every name that matches an entry of
-the internal blocklist is removed from the effective blocklist. Names that are not in the
-internal blocklist have no effect.
+The property carries a comma-separated list of header names. Every name that matches a restricted
+context is dropped from the effective restricted list (and thus becomes eligible for propagation).
+Names that are not in the restricted list have no effect.
Examples:
| Property value | Effect |
|---|---|
-| not set / empty | Internal blocklist applies in full. `X-Channel-Request-Id` is not propagated. |
+| not set / empty | Restricted list applies in full. `X-Channel-Request-Id` is not propagated. |
| `X-Channel-Request-Id` | `X-Channel-Request-Id` is propagated to outgoing requests. |
-| `Some-Other-Header` | No effect — the header is not in the internal blocklist. |
+| `Some-Other-Header` | No effect — the header is not in the restricted list. |
| `X-Channel-Request-Id, Some-Other-Header` | `X-Channel-Request-Id` is propagated; the second entry is ignored. |
Comparison is case-insensitive. Whitespace around comma-separated entries is trimmed.
@@ -166,7 +166,7 @@ Comparison is case-insensitive. Whitespace around comma-separated entries is tri
**Via `application.properties`:**
```properties
-quarkus.context.propagation.allow-blocked-headers=X-Channel-Request-Id
+quarkus.context.propagation.headers.enable.optional=X-Channel-Request-Id
```
**Via `application.yaml`:**
@@ -175,25 +175,27 @@ quarkus.context.propagation.allow-blocked-headers=X-Channel-Request-Id
quarkus:
context:
propagation:
- allow-blocked-headers: X-Channel-Request-Id
+ headers:
+ enable:
+ optional: X-Channel-Request-Id
```
**Via JVM system property:**
```text
--Dquarkus.context.propagation.allow-blocked-headers=X-Channel-Request-Id
+-Dquarkus.context.propagation.headers.enable.optional=X-Channel-Request-Id
```
**Sourcing the value from an environment variable**
-Instead of hard-coding the list of exempted headers in `application.properties` / `application.yaml`,
+Instead of hard-coding the list of enabled headers in `application.properties` / `application.yaml`,
the value can be sourced from an environment variable using a standard `${ENV_VAR:default}` placeholder.
This way the file structure stays the same across environments and the actual list is controlled
externally — through an ENV variable that is set somewhere outside Quarkus (a container manifest,
a Helm chart, `systemd` unit, CI variable, local shell, etc.).
```properties
-quarkus.context.propagation.allow-blocked-headers=${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+quarkus.context.propagation.headers.enable.optional=${CONTEXT_PROPAGATION_HEADERS_ENABLE_OPTIONAL:}
```
or, equivalently, in `application.yaml`:
@@ -202,13 +204,15 @@ or, equivalently, in `application.yaml`:
quarkus:
context:
propagation:
- allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+ headers:
+ enable:
+ optional: ${CONTEXT_PROPAGATION_HEADERS_ENABLE_OPTIONAL:}
```
The trailing `:` (empty default) lets the property gracefully resolve to an empty value when the ENV
-variable is absent — under our model that is equivalent to "not configured" and the internal blocklist
-applies in full. Setting `CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS=X-Channel-Request-Id` in the runtime
-environment turns the exemption on without touching the YAML.
+variable is absent — under our model that is equivalent to "not configured" and the restricted list
+applies in full. Setting `CONTEXT_PROPAGATION_HEADERS_ENABLE_OPTIONAL=X-Channel-Request-Id` in the runtime
+environment enables that header for propagation without touching the YAML.
The ENV variable name in the placeholder is just a contract between the application file and the runtime
environment — it can be any name, as long as both sides agree.
@@ -539,7 +543,4 @@ executorService.submit(contextPropagationCallable).get();
Sometimes, you may use `CompletableFuture` class and this way it would be convenient to use `ContextPropagationSupplier` delegator. This class takes delegate and context snapshot.
If you want to perform a task in a current context then you can perform the following code:
-```java
-ContextPropagationSupplier contextPropagationSupplier = new ContextPropagationSupplier(ContextManager.createContextSnapshot(), delegate);
-```
-
+`
\ No newline at end of file
diff --git a/core-context-propagation-quarkus/bom/context-propagation-bom-internal/pom.xml b/core-context-propagation-quarkus/bom/context-propagation-bom-internal/pom.xml
index b189b8ec4..9414af651 100644
--- a/core-context-propagation-quarkus/bom/context-propagation-bom-internal/pom.xml
+++ b/core-context-propagation-quarkus/bom/context-propagation-bom-internal/pom.xml
@@ -5,7 +5,7 @@
com.netcracker.cloud.quarkus
cloud-core-context-propagation-bom-aggregator
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../pom.xml
cloud-core-context-propagation-bom-internal
@@ -15,7 +15,7 @@
pom
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
3.5.3
diff --git a/core-context-propagation-quarkus/bom/context-propagation-bom/pom.xml b/core-context-propagation-quarkus/bom/context-propagation-bom/pom.xml
index 0e09c24ae..4b5fe98d0 100644
--- a/core-context-propagation-quarkus/bom/context-propagation-bom/pom.xml
+++ b/core-context-propagation-quarkus/bom/context-propagation-bom/pom.xml
@@ -4,7 +4,7 @@
com.netcracker.cloud.quarkus
cloud-core-context-propagation-bom
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
Cloud-Core Context Propagation BOM
pom
diff --git a/core-context-propagation-quarkus/bom/pom.xml b/core-context-propagation-quarkus/bom/pom.xml
index ba34f0fc2..9bc6d5665 100644
--- a/core-context-propagation-quarkus/bom/pom.xml
+++ b/core-context-propagation-quarkus/bom/pom.xml
@@ -5,7 +5,7 @@
com.netcracker.cloud.quarkus
cloud-core-context-propagation
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation-quarkus/build-parent/pom.xml b/core-context-propagation-quarkus/build-parent/pom.xml
index 92d45d688..324584003 100644
--- a/core-context-propagation-quarkus/build-parent/pom.xml
+++ b/core-context-propagation-quarkus/build-parent/pom.xml
@@ -5,7 +5,7 @@
com.netcracker.cloud.quarkus
cloud-core-context-propagation
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation-quarkus/context-propagation/deployment/pom.xml b/core-context-propagation-quarkus/context-propagation/deployment/pom.xml
index 0ca22b70a..2ec79c999 100644
--- a/core-context-propagation-quarkus/context-propagation/deployment/pom.xml
+++ b/core-context-propagation-quarkus/context-propagation/deployment/pom.xml
@@ -5,7 +5,7 @@
com.netcracker.cloud.quarkus
context-propagation-parent
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation-quarkus/context-propagation/pom.xml b/core-context-propagation-quarkus/context-propagation/pom.xml
index 9c7dd6913..de2bfa37d 100644
--- a/core-context-propagation-quarkus/context-propagation/pom.xml
+++ b/core-context-propagation-quarkus/context-propagation/pom.xml
@@ -5,7 +5,7 @@
com.netcracker.cloud.quarkus
cloud-core-context-propagation-build-parent
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../build-parent/pom.xml
diff --git a/core-context-propagation-quarkus/context-propagation/runtime/pom.xml b/core-context-propagation-quarkus/context-propagation/runtime/pom.xml
index 038f3d7ea..bd869d657 100644
--- a/core-context-propagation-quarkus/context-propagation/runtime/pom.xml
+++ b/core-context-propagation-quarkus/context-propagation/runtime/pom.xml
@@ -5,7 +5,7 @@
context-propagation-parent
com.netcracker.cloud.quarkus
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation-quarkus/context-propagation/runtime/src/test/java/com/netcracker/cloud/context/propagation/quarkus/runtime/filter/QuarkusPreAuthnContextProviderHandlerXChannelRequestIdTest.java b/core-context-propagation-quarkus/context-propagation/runtime/src/test/java/com/netcracker/cloud/context/propagation/quarkus/runtime/filter/QuarkusPreAuthnContextProviderHandlerXChannelRequestIdTest.java
index 6f37833d7..2e6655312 100644
--- a/core-context-propagation-quarkus/context-propagation/runtime/src/test/java/com/netcracker/cloud/context/propagation/quarkus/runtime/filter/QuarkusPreAuthnContextProviderHandlerXChannelRequestIdTest.java
+++ b/core-context-propagation-quarkus/context-propagation/runtime/src/test/java/com/netcracker/cloud/context/propagation/quarkus/runtime/filter/QuarkusPreAuthnContextProviderHandlerXChannelRequestIdTest.java
@@ -1,6 +1,7 @@
package com.netcracker.cloud.context.propagation.quarkus.runtime.filter;
import com.netcracker.cloud.context.propagation.core.ContextManager;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextProvider;
import com.netcracker.cloud.headerstracking.filters.context.ChannelRequestIdContext;
import io.vertx.core.MultiMap;
import io.vertx.core.http.HttpServerRequest;
@@ -32,7 +33,7 @@ void testDoFilterWithXChannelRequestIdHeader() {
HttpServerRequest httpServerRequest = mock(HttpServerRequest.class);
when(routingContext.request()).thenReturn(httpServerRequest);
- String xChannelRequestId = "X-Channel-Request-Id";
+ String xChannelRequestId = XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME;
String xChannelRequestIdValue = "channel-123";
MultiMap multiMap = new HeadersMultiMap();
diff --git a/core-context-propagation-quarkus/framework-contexts/deployment/pom.xml b/core-context-propagation-quarkus/framework-contexts/deployment/pom.xml
index be432c7ea..569a12a18 100644
--- a/core-context-propagation-quarkus/framework-contexts/deployment/pom.xml
+++ b/core-context-propagation-quarkus/framework-contexts/deployment/pom.xml
@@ -4,7 +4,7 @@
framework-contexts-parent
com.netcracker.cloud.quarkus
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation-quarkus/framework-contexts/deployment/src/main/java/com/netcracker/cloud/quarkus/framework/contexts/deployment/FrameworkContextsQuarkusProcessor.java b/core-context-propagation-quarkus/framework-contexts/deployment/src/main/java/com/netcracker/cloud/quarkus/framework/contexts/deployment/FrameworkContextsQuarkusProcessor.java
index c8dc372bd..c7dded0c9 100644
--- a/core-context-propagation-quarkus/framework-contexts/deployment/src/main/java/com/netcracker/cloud/quarkus/framework/contexts/deployment/FrameworkContextsQuarkusProcessor.java
+++ b/core-context-propagation-quarkus/framework-contexts/deployment/src/main/java/com/netcracker/cloud/quarkus/framework/contexts/deployment/FrameworkContextsQuarkusProcessor.java
@@ -2,6 +2,9 @@
import com.netcracker.cloud.framework.quarkus.contexts.allowedheaders.HeadersAllowedConfig;
import com.netcracker.cloud.framework.quarkus.contexts.allowedheaders.HeadersAllowedRecorder;
+import com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid.HeadersOptionalConfig;
+import com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid.HeadersOptionalRecorder;
+
import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
@@ -20,14 +23,22 @@ FeatureBuildItem feature() {
@BuildStep
UnremovableBeanBuildItem unremovableBeans() {
- return UnremovableBeanBuildItem.beanTypes(HeadersAllowedConfig.class);
+ return UnremovableBeanBuildItem.beanTypes(
+ HeadersAllowedConfig.class,
+ HeadersOptionalConfig.class);
}
@Record(ExecutionTime.RUNTIME_INIT)
@BuildStep
- ServiceStartBuildItem fillSystemProperty(HeadersAllowedRecorder headersAllowedRecorder) {
- headersAllowedRecorder.setAllowedHeadersToSystemProperty();
-
+ ServiceStartBuildItem fillAllowedHeadersSystemProperty(HeadersAllowedRecorder recorder) {
+ recorder.setAllowedHeadersToSystemProperty();
return new ServiceStartBuildItem("allowedHeadersRecord");
}
+
+ @Record(ExecutionTime.RUNTIME_INIT)
+ @BuildStep
+ ServiceStartBuildItem fillOptionalHeadersSystemProperty(HeadersOptionalRecorder recorder) {
+ recorder.setEnableOptionalToSystemProperty();
+ return new ServiceStartBuildItem("optionalHeadersRecord");
+ }
}
diff --git a/core-context-propagation-quarkus/framework-contexts/pom.xml b/core-context-propagation-quarkus/framework-contexts/pom.xml
index 929235c33..068f6a71b 100644
--- a/core-context-propagation-quarkus/framework-contexts/pom.xml
+++ b/core-context-propagation-quarkus/framework-contexts/pom.xml
@@ -5,7 +5,7 @@
com.netcracker.cloud.quarkus
cloud-core-context-propagation-build-parent
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../build-parent/pom.xml
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/pom.xml b/core-context-propagation-quarkus/framework-contexts/runtime/pom.xml
index 868b29e46..9e3c373cb 100644
--- a/core-context-propagation-quarkus/framework-contexts/runtime/pom.xml
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/pom.xml
@@ -4,7 +4,7 @@
framework-contexts-parent
com.netcracker.cloud.quarkus
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java
index 68e2a77b6..56a1973cf 100644
--- a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfig.java
@@ -5,7 +5,6 @@
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithName;
-import java.util.List;
import java.util.Optional;
@ConfigMapping(prefix = "quarkus")
@@ -17,31 +16,4 @@ public interface HeadersAllowedConfig {
*/
@WithName("headers.allowed")
Optional allowedHeaders();
-
- /**
- * Headers that should be allowed to propagate even though they appear in the framework's
- * internal blocklist. The blocklist itself is hard-coded and cannot be changed from
- * configuration.
- *
- * Semantics:
- *
- * - Property not set or empty: the internal blocklist is applied as-is. Any header
- * in the blocklist (for example {@code X-Channel-Request-Id}) is not propagated.
- * - Property contains a comma-separated list of header names: each listed name is
- * removed from the effective blocklist and is allowed to propagate. Names that
- * are not in the internal blocklist have no effect.
- *
- *
- * Example {@code application.yaml} with a container ENV indirection:
- *
- * quarkus:
- * context:
- * propagation:
- * allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
- *
- * The container then sets {@code CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS=X-Channel-Request-Id} when it needs
- * that header to be propagated.
- */
- @WithName("context.propagation.allow-blocked-headers")
- Optional> allowedHeadersFromBlocklist();
}
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java
index c0dabdb9e..81acb9ca4 100644
--- a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedRecorder.java
@@ -11,9 +11,5 @@ public void setAllowedHeadersToSystemProperty() {
allowedConfig.allowedHeaders()
.ifPresent(allowedHeaders -> System.setProperty("headers.allowed", allowedHeaders));
-
- allowedConfig.allowedHeadersFromBlocklist()
- .filter(list -> !list.isEmpty())
- .ifPresent(list -> System.setProperty("context.propagation.allow-blocked-headers", String.join(",", list)));
}
}
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfig.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfig.java
new file mode 100644
index 000000000..bb5411a22
--- /dev/null
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfig.java
@@ -0,0 +1,33 @@
+package com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid;
+
+import io.quarkus.runtime.annotations.ConfigPhase;
+import io.quarkus.runtime.annotations.ConfigRoot;
+import io.smallrye.config.ConfigMapping;
+import io.smallrye.config.WithName;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Configuration for headers that are restricted from propagation by default and may be
+ * optionally enabled via {@code quarkus.context.propagation.headers.enable.optional}.
+ *
+ * The framework owns a hard-coded list of restricted headers (currently {@code X-Channel-Request-Id})
+ * that are not propagated to outgoing requests by default. This configuration lets users opt in
+ * to propagating one or more of those restricted headers by listing them, comma-separated, in the
+ * {@code quarkus.context.propagation.headers.enable.optional} property.
+ *
+ */
+@ConfigMapping(prefix = "quarkus.context.propagation.headers")
+@ConfigRoot(phase = ConfigPhase.RUN_TIME)
+public interface HeadersOptionalConfig {
+
+ /**
+ * Comma-separated list of restricted headers to enable for propagation. Header names that
+ * are not part of the framework's restricted list are ignored.
+ *
+ * When the value is absent or empty, the restricted list applies in full.
+ */
+ @WithName("enable.optional")
+ Optional> enableOptional();
+}
diff --git a/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalRecorder.java b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalRecorder.java
new file mode 100644
index 000000000..bbb3d786c
--- /dev/null
+++ b/core-context-propagation-quarkus/framework-contexts/runtime/src/main/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalRecorder.java
@@ -0,0 +1,25 @@
+package com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid;
+
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+
+import io.quarkus.arc.Arc;
+import io.quarkus.runtime.annotations.Recorder;
+
+/**
+ * Bridges {@link HeadersOptionalConfig} to the JVM system property
+ * {@link HeaderPropagationConfiguration#ENABLE_OPTIONAL_PROPERTY} which the non-Quarkus
+ * framework reads to compute the effective restricted list.
+ */
+@Recorder
+public class HeadersOptionalRecorder {
+
+ public void setEnableOptionalToSystemProperty() {
+ HeadersOptionalConfig config = Arc.container().instance(HeadersOptionalConfig.class).get();
+
+ config.enableOptional()
+ .filter(list -> !list.isEmpty())
+ .ifPresent(list -> System.setProperty(
+ HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY,
+ String.join(",", list)));
+ }
+}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/pom.xml b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/pom.xml
index 15caa016e..01828114b 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/pom.xml
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/pom.xml
@@ -4,7 +4,7 @@
com.netcracker.cloud.quarkus
integration-tests
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
context-propagation-reactive-test
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowBlockedRecorderEffectTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowBlockedRecorderEffectTest.java
deleted file mode 100644
index 0d6f17fb1..000000000
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowBlockedRecorderEffectTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
-
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-import io.quarkus.test.junit.QuarkusTest;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@QuarkusTest
-class HeadersAllowBlockedRecorderEffectTest {
-
- @Test
- void shouldExposeAllowBlockedValueAsSystemProperty() {
- assertEquals("X-Channel-Request-Id",
- System.getProperty("context.propagation.allow-blocked-headers"),
- "Recorder must propagate the quarkus.context.propagation.allow-blocked-headers value " +
- "to the context.propagation.allow-blocked-headers system property.");
- }
-
- @Test
- void shouldRemoveExemptedHeaderFromInternalBlocklist() {
- // The blocked list is cached on first access; ensure we read the post-recorder state.
- HeaderPropagationConfiguration.resetCache();
-
- assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
- "The only entry of the internal blocklist (X-Channel-Request-Id) must be removed " +
- "by the exemption configured in application.properties.");
- assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "X-Channel-Request-Id must not be blocked when explicitly exempted.");
- }
-}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigNotSetTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigNotSetTest.java
deleted file mode 100644
index 61f016c4d..000000000
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigNotSetTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.quarkus.test.junit.QuarkusTestProfile;
-import io.quarkus.test.junit.TestProfile;
-import jakarta.inject.Inject;
-import org.junit.jupiter.api.Test;
-
-import java.util.Map;
-
-import static org.junit.jupiter.api.Assertions.assertFalse;
-
-@QuarkusTest
-@TestProfile(HeadersAllowedConfigNotSetTest.NotSetProfile.class)
-class HeadersAllowedConfigNotSetTest {
-
- @Inject
- HeadersAllowedConfig headersAllowedConfig;
-
- @Test
- void shouldReportAllowedFromBlocklistAsEmptyWhenNotConfigured() {
- assertFalse(headersAllowedConfig.allowedHeadersFromBlocklist().isPresent(),
- "quarkus.context.propagation.allow-blocked-headers must resolve to Optional.empty() " +
- "when no exemption value is configured");
- }
-
- public static class NotSetProfile implements QuarkusTestProfile {
-
- @Override
- public Map getConfigOverrides() {
- return Map.of("quarkus.context.propagation.allow-blocked-headers", "");
- }
- }
-}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java
index cf03260d5..34d672f7e 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersAllowedConfigTest.java
@@ -4,7 +4,6 @@
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
-import java.util.List;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -23,14 +22,4 @@ void shouldReadHeadersAllowedFromProperty() {
assertTrue(value.isPresent(), "quarkus.headers.allowed must be present");
assertEquals("test-quarkus.headers.allowed", value.get());
}
-
- @Test
- void shouldReadAllowedHeadersFromBlocklist() {
- Optional> value = headersAllowedConfig.allowedHeadersFromBlocklist();
-
- assertTrue(value.isPresent(),
- "quarkus.context.propagation.allow-blocked-headers must be present when configured");
- assertEquals(List.of("X-Channel-Request-Id"), value.get(),
- "SmallRye must parse the comma-separated value into a list");
- }
}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersEnableOptionalRecorderEffectTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersEnableOptionalRecorderEffectTest.java
new file mode 100644
index 000000000..66a3aeacc
--- /dev/null
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersEnableOptionalRecorderEffectTest.java
@@ -0,0 +1,49 @@
+package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
+
+import io.quarkus.test.junit.QuarkusTest;
+import org.junit.jupiter.api.Test;
+
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextObject.X_CHANNEL_REQUEST_ID;
+
+/**
+ * End-to-end integration scenario in a real running Quarkus application:
+ *
+ *
+ * - {@code application.properties} declares
+ * {@code quarkus.context.propagation.headers.enable.optional=X-Channel-Request-Id}.
+ * - At {@code RUNTIME_INIT}, {@code HeadersOptionalRecorder} reads the config from Arc
+ * and writes {@code context.propagation.headers.enable.optional=X-Channel-Request-Id} into the
+ * JVM system properties.
+ * - The non-Quarkus {@link HeaderPropagationConfiguration} reads the system property,
+ * drops {@code X-Channel-Request-Id} from the restricted list, and reports an empty
+ * effective restricted list.
+ *
+ *
+ */
+@QuarkusTest
+class HeadersEnableOptionalRecorderEffectTest {
+
+ @Test
+ void shouldExposeEnableOptionalValueAsSystemProperty() {
+ assertEquals(X_CHANNEL_REQUEST_ID,
+ System.getProperty("context.propagation.headers.enable.optional"),
+ "Recorder must propagate the quarkus.context.propagation.headers.enable.optional value " +
+ "to the context.propagation.headers.enable.optional system property.");
+ }
+
+ @Test
+ void shouldDropEnabledHeaderFromRestrictedList() {
+ HeaderPropagationConfiguration.resetCache();
+
+ assertTrue(HeaderPropagationConfiguration.restrictedHeaders().isEmpty(),
+ "Any entry of the restricted list must be dropped " +
+ "by the optional-enable configured in application.properties.");
+ assertFalse(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID),
+ "X-Channel-Request-Id must not be restricted when explicitly enabled.");
+ }
+}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigNotSetTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigNotSetTest.java
new file mode 100644
index 000000000..cd85d01b5
--- /dev/null
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigNotSetTest.java
@@ -0,0 +1,47 @@
+package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
+
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.junit.TestProfile;
+import jakarta.inject.Inject;
+import org.junit.jupiter.api.Test;
+
+import com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid.HeadersOptionalConfig;
+
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+/**
+ * Integration scenario: {@code quarkus.context.propagation.headers.enable.optional} is effectively
+ * not configured. Verifies that {@link HeadersOptionalConfig#enableOptional()} resolves to
+ * {@link java.util.Optional#empty()} — which is the signal the recorder uses to leave the
+ * system property untouched and let the restricted list apply in full.
+ *
+ * The module's {@code application.properties} sets the property to {@code X-Channel-Request-Id},
+ * so we use a {@link QuarkusTestProfile} that overrides it to an empty value. Under SmallRye Config
+ * semantics, an empty value for {@code Optional>} resolves to {@code Optional.empty()} —
+ * exactly the same observable state as "not configured".
+ */
+@QuarkusTest
+@TestProfile(HeadersOptionalConfigNotSetTest.NotSetProfile.class)
+class HeadersOptionalConfigNotSetTest {
+
+ @Inject
+ HeadersOptionalConfig headersOptionalConfig;
+
+ @Test
+ void shouldResolveToEmptyWhenNotConfigured() {
+ assertFalse(headersOptionalConfig.enableOptional().isPresent(),
+ "quarkus.context.propagation.headers.enable.optional must resolve to Optional.empty() " +
+ "when no value is configured");
+ }
+
+ public static class NotSetProfile implements QuarkusTestProfile {
+
+ @Override
+ public Map getConfigOverrides() {
+ return Map.of("quarkus.context.propagation.headers.enable.optional", "");
+ }
+ }
+}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigTest.java
new file mode 100644
index 000000000..cf33ae72e
--- /dev/null
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigTest.java
@@ -0,0 +1,31 @@
+package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
+
+import io.quarkus.test.junit.QuarkusTest;
+import jakarta.inject.Inject;
+import org.junit.jupiter.api.Test;
+
+import com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid.HeadersOptionalConfig;
+
+import java.util.List;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextObject.X_CHANNEL_REQUEST_ID;
+
+@QuarkusTest
+class HeadersOptionalConfigTest {
+
+ @Inject
+ HeadersOptionalConfig headersOptionalConfig;
+
+ @Test
+ void shouldReadEnableOptionalFromProperty() {
+ Optional> value = headersOptionalConfig.enableOptional();
+
+ assertTrue(value.isPresent(),
+ "quarkus.context.propagation.headers.enable.optional must be present when configured");
+ assertEquals(List.of(X_CHANNEL_REQUEST_ID), value.get(),
+ "SmallRye must parse the comma-separated value into a list");
+ }
+}
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties
index 544d085e0..463e3b318 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/resources/application.properties
@@ -5,5 +5,5 @@ quarkus.rest-client.my-client.url=http://localhost:${quarkus.http.test-port}
quarkus.headers.allowed=test-quarkus.headers.allowed
-quarkus.context.propagation.allow-blocked-headers=X-Channel-Request-Id
+quarkus.context.propagation.headers.enable.optional=X-Channel-Request-Id
headers.allowed=test-headers.allowed
diff --git a/core-context-propagation-quarkus/integration-tests/pom.xml b/core-context-propagation-quarkus/integration-tests/pom.xml
index 42bd7156a..69ed13318 100644
--- a/core-context-propagation-quarkus/integration-tests/pom.xml
+++ b/core-context-propagation-quarkus/integration-tests/pom.xml
@@ -4,7 +4,7 @@
com.netcracker.cloud.quarkus
cloud-core-context-propagation-build-parent
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../build-parent/pom.xml
integration-tests
diff --git a/core-context-propagation-quarkus/pom.xml b/core-context-propagation-quarkus/pom.xml
index 7972156b8..815d71d51 100644
--- a/core-context-propagation-quarkus/pom.xml
+++ b/core-context-propagation-quarkus/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.netcracker.cloud.quarkus
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
cloud-core-context-propagation
Cloud-Core Context Propagation
diff --git a/core-context-propagation-quarkus/report-aggregate/pom.xml b/core-context-propagation-quarkus/report-aggregate/pom.xml
index 6f474eab9..52c5da4fd 100644
--- a/core-context-propagation-quarkus/report-aggregate/pom.xml
+++ b/core-context-propagation-quarkus/report-aggregate/pom.xml
@@ -4,7 +4,7 @@
com.netcracker.cloud.quarkus
cloud-core-context-propagation-build-parent
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
../build-parent/pom.xml
pom
diff --git a/core-context-propagation/README.md b/core-context-propagation/README.md
index 2981f6fab..7a4b4e456 100644
--- a/core-context-propagation/README.md
+++ b/core-context-propagation/README.md
@@ -147,29 +147,30 @@ Propagates and allows to get `X-Channel-Request-Id` value. If an incoming reques
**Default behavior:** `X-Channel-Request-Id` is NOT propagated to outgoing requests.
-#### Internal blocklist
+#### Restricted contexts
-The framework owns a hard-coded internal blocklist of headers that are not propagated to outgoing
-requests. It currently contains:
+The framework owns a hard-coded list of restricted contexts — headers that are not propagated
+to outgoing requests by default. It currently contains:
- `X-Channel-Request-Id`
-The blocklist itself cannot be changed from configuration. The only externally visible knob is the
-`context.propagation.allow-blocked-headers` property, which lists header names that should be **exempted** from this
-blocklist (i.e. allowed to propagate).
+The list itself cannot be changed from configuration. The only externally visible knob is the
+`context.propagation.headers.enable.optional` property, which names headers from that list that
+should be enabled for propagation.
-#### `context.propagation.allow-blocked-headers` property
+#### `context.propagation.headers.enable.optional` property
-The property carries a comma-separated list of header names. Every name that matches an entry of
-the internal blocklist is removed from the effective blocklist. Names that are not in the internal blocklist have no effect.
+The property carries a comma-separated list of header names. Every name that matches a restricted
+context is dropped from the effective restricted list (and thus becomes eligible for propagation).
+Names that are not in the restricted list have no effect.
Examples:
| Property value | Effect |
|---|---|
-| not set / empty | Internal blocklist applies in full. `X-Channel-Request-Id` is not propagated. |
+| not set / empty | Restricted list applies in full. `X-Channel-Request-Id` is not propagated. |
| `X-Channel-Request-Id` | `X-Channel-Request-Id` is propagated to outgoing requests. |
-| `Some-Other-Header` | No effect — the header is not in the internal blocklist. |
+| `Some-Other-Header` | No effect — the header is not in the restricted list. |
| `X-Channel-Request-Id, Some-Other-Header` | `X-Channel-Request-Id` is propagated; the second entry is ignored. |
Comparison is case-insensitive. Whitespace around comma-separated entries is trimmed.
@@ -179,31 +180,33 @@ Comparison is case-insensitive. Whitespace around comma-separated entries is tri
**Spring (`application.properties` / `application.yml`):**
```properties
-context.propagation.allow-blocked-headers=X-Channel-Request-Id
+context.propagation.headers.enable.optional=X-Channel-Request-Id
```
```yaml
context:
propagation:
- allow-blocked-headers: X-Channel-Request-Id
+ headers:
+ enable:
+ optional: X-Channel-Request-Id
```
**Via JVM system property:**
```text
--Dcontext.propagation.allow-blocked-headers=X-Channel-Request-Id
+-Dcontext.propagation.headers.enable.optional=X-Channel-Request-Id
```
**Sourcing the value from an environment variable**
-Instead of hard-coding the list of exempted headers in `application.properties` / `application.yml`,
+Instead of hard-coding the list of enabled headers in `application.properties` / `application.yml`,
the value can be sourced from an environment variable using a standard `${ENV_VAR:default}` placeholder.
This way the file structure stays the same across environments and the actual list is controlled
externally — through an ENV variable that is set somewhere outside Spring (a container manifest,
a Helm chart, `systemd` unit, CI variable, local shell, etc.).
```properties
-context.propagation.allow-blocked-headers=${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+context.propagation.headers.enable.optional=${CONTEXT_PROPAGATION_HEADERS_ENABLE_OPTIONAL:}
```
or, equivalently, in `application.yml`:
@@ -211,13 +214,15 @@ or, equivalently, in `application.yml`:
```yaml
context:
propagation:
- allow-blocked-headers: ${CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS:}
+ headers:
+ enable:
+ optional: ${CONTEXT_PROPAGATION_HEADERS_ENABLE_OPTIONAL:}
```
The trailing `:` (empty default) lets the property gracefully resolve to an empty value when the ENV
-variable is absent — under our model that is equivalent to "not configured" and the internal blocklist
-applies in full. Setting `CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS=X-Channel-Request-Id` in the runtime
-environment turns the exemption on without touching the YAML.
+variable is absent — under our model that is equivalent to "not configured" and the restricted list
+applies in full. Setting `CONTEXT_PROPAGATION_HEADERS_ENABLE_OPTIONAL=X-Channel-Request-Id` in the runtime
+environment enables that header for propagation without touching the YAML.
The ENV variable name in the placeholder is just a contract between the application file and the runtime
environment — it can be any name, as long as both sides agree.
@@ -850,12 +855,4 @@ List of supported libraries:
`context-propagation-test-extensions` module provides Junit extension that can help running context tests from your IDE.
It addresses the problem that maven plugins execution can be skipped when running tests directly from IDE. This leads to issue
that jandex index isn't built and context defined in your module aren't loaded. `JandexContextLoaderExtension` Junit resolves
-this problem by building jandex index and loading contexts from it before tests are executed. You can add it to your tests using standard
-Junit annotation `@ExtendWith`:
-```
-@ExtendWith(JandexContextLoaderExtension.class)
-class SampleContextTest {
- ...
-}
-```
-
+this problem by building jandex index and loading contexts from it before tests are executed. You can add it t
\ No newline at end of file
diff --git a/core-context-propagation/api-tests/pom.xml b/core-context-propagation/api-tests/pom.xml
index 27c33b289..65e864a43 100644
--- a/core-context-propagation/api-tests/pom.xml
+++ b/core-context-propagation/api-tests/pom.xml
@@ -4,7 +4,7 @@
context-propagation
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/IncomingContextDataFactory.java b/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/IncomingContextDataFactory.java
index 20d6d3a25..600a7dec3 100644
--- a/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/IncomingContextDataFactory.java
+++ b/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/IncomingContextDataFactory.java
@@ -1,6 +1,7 @@
package com.netcracker.cloud.contexts;
import com.netcracker.cloud.context.propagation.core.contextdata.IncomingContextData;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextProvider;
import java.util.*;
@@ -100,7 +101,7 @@ private static Map xVersionData() {
private static Map xChannelRequestIdData() {
Map requestData = new HashMap<>();
- requestData.put("X-Channel-Request-Id", UUID.randomUUID().toString());
+ requestData.put(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME, UUID.randomUUID().toString());
return requestData;
}
}
diff --git a/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/xchannelrequestid/XChannelRequestIdContextObjectApiTest.java b/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/xchannelrequestid/XChannelRequestIdContextObjectApiTest.java
index 417aa3c8b..8aaa858b1 100644
--- a/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/xchannelrequestid/XChannelRequestIdContextObjectApiTest.java
+++ b/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/xchannelrequestid/XChannelRequestIdContextObjectApiTest.java
@@ -15,7 +15,6 @@
import static org.junit.jupiter.api.Assertions.*;
-
class XChannelRequestIdContextObjectApiTest {
@BeforeEach
@@ -33,7 +32,7 @@ void testDefaultXChannelRequestId() {
void testXChannelRequestIdFromIncomingContextData() {
IncomingContextData xChannelRequestIdIncomingContextData = IncomingContextDataFactory.getXChannelRequestIdIncomingContextData();
XChannelRequestIdContextObject xChannelRequestIdContextObject = new XChannelRequestIdContextObject(xChannelRequestIdIncomingContextData);
- String expectedValue = (String) xChannelRequestIdIncomingContextData.get("X-Channel-Request-Id");
+ String expectedValue = (String) xChannelRequestIdIncomingContextData.get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME);
assertEquals(expectedValue, xChannelRequestIdContextObject.getChannelRequestId());
}
@@ -52,7 +51,7 @@ void testGetXChannelRequestIdFromContextManager() {
RequestContextPropagation.initRequestContext(xChannelRequestIdIncomingContextData);
XChannelRequestIdContextObject xChannelRequestIdContextObject = ContextManager.get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME);
- assertEquals(xChannelRequestIdIncomingContextData.get("X-Channel-Request-Id"), xChannelRequestIdContextObject.getChannelRequestId());
+ assertEquals(xChannelRequestIdIncomingContextData.get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME), xChannelRequestIdContextObject.getChannelRequestId());
// No data, default placeholder "-"
RequestContextPropagation.initRequestContext(null);
diff --git a/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/xchannelrequestid/XChannelRequestIdProviderApiTest.java b/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/xchannelrequestid/XChannelRequestIdProviderApiTest.java
index 19e3efb9a..58b276bcc 100644
--- a/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/xchannelrequestid/XChannelRequestIdProviderApiTest.java
+++ b/core-context-propagation/api-tests/src/test/java/com/netcracker/cloud/contexts/xchannelrequestid/XChannelRequestIdProviderApiTest.java
@@ -15,12 +15,6 @@
class XChannelRequestIdProviderApiTest {
- @Test
- void checkXChannelRequestIdContextName() {
- assertEquals("X-Channel-Request-Id", XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME);
- assertEquals("X-Channel-Request-Id", new XChannelRequestIdContextProvider().contextName());
- }
-
@Test
void xChannelRequestIdProviderMustHaveDefaultConstructor() {
XChannelRequestIdContextProvider xChannelRequestIdContextProvider = new XChannelRequestIdContextProvider();
@@ -33,7 +27,7 @@ void xChannelRequestIdProvideMethodWithIncomingContextData() {
IncomingContextData xChannelRequestIdIncomingContextData = IncomingContextDataFactory.getXChannelRequestIdIncomingContextData();
XChannelRequestIdContextObject xChannelRequestIdContextObject = xChannelRequestIdContextProvider.provide(xChannelRequestIdIncomingContextData);
- assertEquals(xChannelRequestIdIncomingContextData.get("X-Channel-Request-Id"), xChannelRequestIdContextObject.getChannelRequestId());
+ assertEquals(xChannelRequestIdIncomingContextData.get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME), xChannelRequestIdContextObject.getChannelRequestId());
}
@Test
diff --git a/core-context-propagation/context-propagation-bom/pom.xml b/core-context-propagation/context-propagation-bom/pom.xml
index 421ebc3ba..115753bc2 100644
--- a/core-context-propagation/context-propagation-bom/pom.xml
+++ b/core-context-propagation/context-propagation-bom/pom.xml
@@ -5,7 +5,7 @@
com.netcracker.cloud
context-propagation-bom
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
pom
diff --git a/core-context-propagation/context-propagation-core/pom.xml b/core-context-propagation/context-propagation-core/pom.xml
index f0331b791..5b5db2512 100644
--- a/core-context-propagation/context-propagation-core/pom.xml
+++ b/core-context-propagation/context-propagation-core/pom.xml
@@ -5,7 +5,7 @@
context-propagation
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation/context-propagation-report-aggregate/pom.xml b/core-context-propagation/context-propagation-report-aggregate/pom.xml
index ebd44dcc9..8ee5e16a6 100644
--- a/core-context-propagation/context-propagation-report-aggregate/pom.xml
+++ b/core-context-propagation/context-propagation-report-aggregate/pom.xml
@@ -4,7 +4,7 @@
com.netcracker.cloud
context-propagation
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
pom
diff --git a/core-context-propagation/context-propagation-test-extensions/pom.xml b/core-context-propagation/context-propagation-test-extensions/pom.xml
index 49868d3c0..f0608ad23 100644
--- a/core-context-propagation/context-propagation-test-extensions/pom.xml
+++ b/core-context-propagation/context-propagation-test-extensions/pom.xml
@@ -5,7 +5,7 @@
context-propagation
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation/framework-contexts/pom.xml b/core-context-propagation/framework-contexts/pom.xml
index 23f609278..f2802639d 100644
--- a/core-context-propagation/framework-contexts/pom.xml
+++ b/core-context-propagation/framework-contexts/pom.xml
@@ -4,7 +4,7 @@
context-propagation
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
diff --git a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/AllowedHeadersContextObject.java b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/AllowedHeadersContextObject.java
index f991e8c05..10d65d869 100644
--- a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/AllowedHeadersContextObject.java
+++ b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/AllowedHeadersContextObject.java
@@ -8,6 +8,7 @@
import com.netcracker.cloud.context.propagation.core.contexts.SerializableContext;
import com.netcracker.cloud.context.propagation.core.contexts.SerializableDataContext;
import com.netcracker.cloud.context.propagation.core.contexts.common.RequestContextObject;
+
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -24,7 +25,7 @@ public AllowedHeadersContextObject(@Nullable IncomingContextData contextData, Li
if (contextData != null) {
for (String headerName : this.allowedHeaders) {
- if (!HeaderPropagationConfiguration.isBlacklisted(headerName) && contextData.get(headerName) != null) {
+ if (contextData.get(headerName) != null) {
headers.put(headerName, (String) contextData.get(headerName));
}
}
@@ -41,9 +42,7 @@ private static Map filterBlocked(Map headers) {
Map filteredHeaders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
if (headers != null) {
for (Map.Entry entry : headers.entrySet()) {
- if (!HeaderPropagationConfiguration.isBlacklisted(entry.getKey())) {
- filteredHeaders.put(entry.getKey(), entry.getValue());
- }
+ filteredHeaders.put(entry.getKey(), entry.getValue());
}
}
return filteredHeaders;
@@ -52,9 +51,7 @@ private static Map filterBlocked(Map headers) {
@Override
public void serialize(OutgoingContextData outgoingContextData) {
for (String headerName : headers.keySet()) {
- if (!HeaderPropagationConfiguration.isBlacklisted(headerName)) {
- outgoingContextData.set(headerName, headers.get(headerName));
- }
+ outgoingContextData.set(headerName, headers.get(headerName));
}
}
@@ -67,7 +64,7 @@ public Map getDefault() {
Map> headersFromContext = ((RequestContextObject) ContextManager.get("request")).getHttpHeaders();
Map result = new HashMap<>();
for (String headerName : headersFromContext.keySet()) {
- if (allowedHeaders.contains(headerName) && !HeaderPropagationConfiguration.isBlacklisted(headerName)) {
+ if (allowedHeaders.contains(headerName)) {
result.put(headerName, headersFromContext.get(headerName).get(0));
}
}
@@ -77,9 +74,7 @@ public Map getDefault() {
@Override
public void propagate(OutgoingContextData outgoingContextData) {
for (String headerName : headers.keySet()) {
- if (!HeaderPropagationConfiguration.isBlacklisted(headerName)) {
- outgoingContextData.set(headerName, headers.get(headerName));
- }
+ outgoingContextData.set(headerName, headers.get(headerName));
}
}
diff --git a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java
deleted file mode 100644
index 6e2291cb5..000000000
--- a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfiguration.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.netcracker.cloud.framework.contexts.allowedheaders;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.stream.Collectors;
-
-/**
- * Computes the effective set of headers that must not be propagated to outgoing requests.
- *
- * Model
- *
- * - The framework owns an internal blocklist ({@link #INTERNAL_BLOCKED_HEADERS}). It is
- * hard-coded and cannot be changed from configuration. By default it blocks
- * {@code X-Channel-Request-Id}.
- * - A user-facing system property {@value #ALLOW_BLOCKED_PROPERTY} carries a
- * comma-separated list of header names that should be exempted from the internal
- * blocklist (i.e. allowed to propagate). Names that are not in the internal
- * blocklist have no effect.
- *
- *
- * How the property is supplied
- * The Quarkus extension copies {@code quarkus.context.propagation.allow-blocked-headers} into this system property
- * at {@code RUNTIME_INIT}; the Spring configuration does the same for the Spring-style
- * {@code context.propagation.allow-blocked-headers} property. In both cases standard env-to-property mapping
- * applies, so a container ENV variable like {@code CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS=X-Channel-Request-Id}
- * propagates all the way through to this class.
- */
-public final class HeaderPropagationConfiguration {
-
- /** System property carrying exempted-from-blocklist header names, comma-separated. */
- public static final String ALLOW_BLOCKED_PROPERTY = "context.propagation.allow-blocked-headers";
-
- /**
- * Hard-coded internal blocklist of headers that the framework refuses to propagate
- * unless explicitly exempted via {@link #ALLOW_BLOCKED_PROPERTY}.
- */
- public static final List INTERNAL_BLOCKED_HEADERS = List.of("X-Channel-Request-Id");
-
- private static final AtomicReference cachedHeaders = new AtomicReference<>(null);
-
- private static final class CachedHeaders {
- final List list;
- final Set lowerSet;
-
- CachedHeaders(List list) {
- this.list = list;
- this.lowerSet = list.stream()
- .filter(h -> h != null && !h.isBlank())
- .map(h -> h.toLowerCase(Locale.ROOT))
- .collect(Collectors.toUnmodifiableSet());
- }
- }
-
- private HeaderPropagationConfiguration() {
- }
-
- private static CachedHeaders getOrInit() {
- CachedHeaders local = cachedHeaders.get();
- if (local == null) {
- synchronized (HeaderPropagationConfiguration.class) {
- local = cachedHeaders.get();
- if (local == null) {
- local = new CachedHeaders(computeEffectiveBlocklist());
- cachedHeaders.set(local);
- }
- }
- }
- return local;
- }
-
- public static List blockedHeaders() {
- return getOrInit().list;
- }
-
- public static void resetCache() {
- cachedHeaders.set(null);
- }
-
- public static boolean isBlacklisted(String headerName) {
- if (headerName == null || headerName.isBlank()) {
- return false;
- }
- return getOrInit().lowerSet.contains(headerName.toLowerCase(Locale.ROOT));
- }
-
- private static List computeEffectiveBlocklist() {
- Set exemptions = readExemptions();
- if (exemptions.isEmpty()) {
- return INTERNAL_BLOCKED_HEADERS;
- }
- return INTERNAL_BLOCKED_HEADERS.stream()
- .filter(h -> !exemptions.contains(h.toLowerCase(Locale.ROOT)))
- .toList();
- }
-
- private static Set readExemptions() {
- String raw = System.getProperty(ALLOW_BLOCKED_PROPERTY);
- if (raw == null || raw.isBlank()) {
- return Set.of();
- }
- return Arrays.stream(raw.split(","))
- .map(String::trim)
- .filter(s -> !s.isEmpty())
- .map(s -> s.toLowerCase(Locale.ROOT))
- .collect(Collectors.toUnmodifiableSet());
- }
-}
diff --git a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/HeaderPropagationConfiguration.java b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/HeaderPropagationConfiguration.java
new file mode 100644
index 000000000..00d29ed31
--- /dev/null
+++ b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/HeaderPropagationConfiguration.java
@@ -0,0 +1,112 @@
+package com.netcracker.cloud.framework.contexts.xchannelrequestid;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+/**
+ * Computes the effective set of restricted headers — i.e. headers that are NOT propagated to
+ * outgoing requests by default.
+ *
+ * Model
+ *
+ * - The framework owns a hard-coded list of restricted headers
+ * ({@link #RESTRICTED_HEADERS}). It cannot be changed from configuration. By default it
+ * restricts {@code X-Channel-Request-Id}.
+ * - A user-facing system property {@value #ENABLE_OPTIONAL_PROPERTY} carries a
+ * comma-separated list of restricted header names that should be enabled for propagation.
+ * Names that are not in the restricted list have no effect.
+ *
+ *
+ */
+public final class HeaderPropagationConfiguration {
+
+ /** System property carrying header names to enable for propagation, comma-separated. */
+ public static final String ENABLE_OPTIONAL_PROPERTY = "context.propagation.headers.enable.optional";
+
+ /**
+ * Hard-coded list of restricted headers — contexts that the framework refuses to propagate
+ * unless explicitly enabled via {@link #ENABLE_OPTIONAL_PROPERTY}.
+ */
+ public static final List RESTRICTED_HEADERS = List.of(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME);
+
+ private static final AtomicReference cachedHeaders = new AtomicReference<>(null);
+
+ private static final class CachedHeaders {
+ final List list;
+ final Set lowerSet;
+
+ CachedHeaders(List list) {
+ this.list = list;
+ this.lowerSet = list.stream()
+ .filter(h -> h != null && !h.isBlank())
+ .map(h -> h.toLowerCase(Locale.ROOT))
+ .collect(Collectors.toUnmodifiableSet());
+ }
+ }
+
+ private HeaderPropagationConfiguration() {
+ }
+
+ private static CachedHeaders getOrInit() {
+ CachedHeaders local = cachedHeaders.get();
+ if (local == null) {
+ synchronized (HeaderPropagationConfiguration.class) {
+ local = cachedHeaders.get();
+ if (local == null) {
+ local = new CachedHeaders(computeEffectiveRestricted());
+ cachedHeaders.set(local);
+ }
+ }
+ }
+ return local;
+ }
+
+ /**
+ * @return effective list of headers that are restricted from propagation right now
+ * (the hard-coded {@link #RESTRICTED_HEADERS} minus any enabled via
+ * {@link #ENABLE_OPTIONAL_PROPERTY}).
+ */
+ public static List restrictedHeaders() {
+ return getOrInit().list;
+ }
+
+ public static void resetCache() {
+ cachedHeaders.set(null);
+ }
+
+ /**
+ * @return {@code true} iff the given header is currently restricted from propagation.
+ */
+ public static boolean isRestricted(String headerName) {
+ if (headerName == null || headerName.isBlank()) {
+ return false;
+ }
+ return getOrInit().lowerSet.contains(headerName.toLowerCase(Locale.ROOT));
+ }
+
+ private static List computeEffectiveRestricted() {
+ Set enabled = readEnabledOptional();
+ if (enabled.isEmpty()) {
+ return RESTRICTED_HEADERS;
+ }
+ return RESTRICTED_HEADERS.stream()
+ .filter(h -> !enabled.contains(h.toLowerCase(Locale.ROOT)))
+ .toList();
+ }
+
+ private static Set readEnabledOptional() {
+ String raw = System.getProperty(ENABLE_OPTIONAL_PROPERTY);
+ if (raw == null || raw.isBlank()) {
+ return Set.of();
+ }
+ return Arrays.stream(raw.split(","))
+ .map(String::trim)
+ .filter(s -> !s.isEmpty())
+ .map(s -> s.toLowerCase(Locale.ROOT))
+ .collect(Collectors.toUnmodifiableSet());
+ }
+}
diff --git a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObject.java b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObject.java
index 9d2160195..f5bb5cd99 100644
--- a/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObject.java
+++ b/core-context-propagation/framework-contexts/src/main/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObject.java
@@ -5,7 +5,7 @@
import com.netcracker.cloud.context.propagation.core.contexts.ResponsePropagatableContext;
import com.netcracker.cloud.context.propagation.core.contexts.SerializableContext;
import com.netcracker.cloud.context.propagation.core.contexts.SerializableDataContext;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -17,7 +17,7 @@
*/
public class XChannelRequestIdContextObject implements SerializableContext,
ResponsePropagatableContext, SerializableDataContext {
- public static final String X_CHANNEL_REQUEST_ID = "X-Channel-Request-Id";
+ public static final String X_CHANNEL_REQUEST_ID = XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME;
private String channelRequestId;
@@ -35,7 +35,7 @@ public XChannelRequestIdContextObject(String channelRequestId) {
@Override
public void serialize(OutgoingContextData outgoingContextData) {
- if (!HeaderPropagationConfiguration.isBlacklisted(X_CHANNEL_REQUEST_ID)) {
+ if (!HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID)) {
outgoingContextData.set(X_CHANNEL_REQUEST_ID, channelRequestId);
}
}
@@ -51,7 +51,7 @@ public void propagate(OutgoingContextData outgoingContextData) {
@Override
public Map getSerializableContextData() {
- if (HeaderPropagationConfiguration.isBlacklisted(X_CHANNEL_REQUEST_ID)) {
+ if (HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID)) {
return Collections.emptyMap();
}
return Map.of(X_CHANNEL_REQUEST_ID, channelRequestId);
diff --git a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/AllowedHeadersPropertyTest.java b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/AllowedHeadersPropertyTest.java
index 51233e083..0d52376bd 100644
--- a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/AllowedHeadersPropertyTest.java
+++ b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/AllowedHeadersPropertyTest.java
@@ -5,6 +5,8 @@
import com.netcracker.cloud.framework.contexts.data.ContextDataRequest;
import com.netcracker.cloud.framework.contexts.data.ContextDataResponse;
import com.netcracker.cloud.framework.contexts.helper.AbstractContextTestWithProperties;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
diff --git a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
index de57edc09..d5fea098b 100644
--- a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
+++ b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/allowedheaders/HeaderPropagationConfigurationTest.java
@@ -5,80 +5,84 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+
+import static com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextObject.X_CHANNEL_REQUEST_ID;
+
class HeaderPropagationConfigurationTest {
@BeforeEach
void setup() {
- System.clearProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY);
+ System.clearProperty(HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY);
HeaderPropagationConfiguration.resetCache();
}
@AfterEach
void cleanup() {
- System.clearProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY);
+ System.clearProperty(HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY);
HeaderPropagationConfiguration.resetCache();
}
@Test
void shouldBlockXChannelRequestIdByDefault() {
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("x-channel-request-id"));
- Assertions.assertEquals(HeaderPropagationConfiguration.INTERNAL_BLOCKED_HEADERS,
- HeaderPropagationConfiguration.blockedHeaders());
+ Assertions.assertTrue(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID));
+ Assertions.assertTrue(HeaderPropagationConfiguration.isRestricted("x-channel-request-id"));
+ Assertions.assertEquals(HeaderPropagationConfiguration.RESTRICTED_HEADERS,
+ HeaderPropagationConfiguration.restrictedHeaders());
}
@Test
void shouldNotBlockXChannelRequestIdWhenExempted() {
- System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, "X-Channel-Request-Id");
+ System.setProperty(HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY, X_CHANNEL_REQUEST_ID);
HeaderPropagationConfiguration.resetCache();
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("x-channel-request-id"));
- Assertions.assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty());
+ Assertions.assertFalse(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isRestricted("x-channel-request-id"));
+ Assertions.assertTrue(HeaderPropagationConfiguration.restrictedHeaders().isEmpty());
}
@Test
void shouldApplyExemptionsCaseInsensitively() {
- System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, "x-channel-request-id");
+ System.setProperty(HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY, "x-channel-request-id");
HeaderPropagationConfiguration.resetCache();
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID));
}
@Test
void shouldIgnoreUnknownExemptionEntries() {
- // Names that are not in the internal blocklist must not change anything.
- System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, "Custom-Header, X-Request-Id");
+ // Names that are not in the restricted list must not change anything.
+ System.setProperty(HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY, "Custom-Header, X-Request-Id");
HeaderPropagationConfiguration.resetCache();
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "Internal blocklist must remain unchanged when no exemption matches it");
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("Custom-Header"));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Request-Id"));
+ Assertions.assertTrue(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID),
+ "Restricted list must remain unchanged when no entry matches it");
+ Assertions.assertFalse(HeaderPropagationConfiguration.isRestricted("Custom-Header"));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isRestricted("X-Request-Id"));
}
@Test
void shouldTreatEmptyExemptionPropertyAsNoExemption() {
- System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, "");
+ System.setProperty(HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY, "");
HeaderPropagationConfiguration.resetCache();
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
- Assertions.assertEquals(HeaderPropagationConfiguration.INTERNAL_BLOCKED_HEADERS,
- HeaderPropagationConfiguration.blockedHeaders());
+ Assertions.assertTrue(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID));
+ Assertions.assertEquals(HeaderPropagationConfiguration.RESTRICTED_HEADERS,
+ HeaderPropagationConfiguration.restrictedHeaders());
}
@Test
void shouldTreatBlankAndCommaOnlyExemptionPropertyAsNoExemption() {
- System.setProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY, " , ,, ");
+ System.setProperty(HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY, " , ,, ");
HeaderPropagationConfiguration.resetCache();
- Assertions.assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"));
+ Assertions.assertTrue(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID));
}
@Test
- void isBlacklistedShouldReturnFalseForNullAndBlank() {
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted(null));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted(""));
- Assertions.assertFalse(HeaderPropagationConfiguration.isBlacklisted(" "));
+ void isRestrictedShouldReturnFalseForNullAndBlank() {
+ Assertions.assertFalse(HeaderPropagationConfiguration.isRestricted(null));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isRestricted(""));
+ Assertions.assertFalse(HeaderPropagationConfiguration.isRestricted(" "));
}
}
diff --git a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/helper/AbstractContextTestWithProperties.java b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/helper/AbstractContextTestWithProperties.java
index be887345a..df5f66c83 100644
--- a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/helper/AbstractContextTestWithProperties.java
+++ b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/helper/AbstractContextTestWithProperties.java
@@ -3,7 +3,7 @@
import java.util.Map;
import com.netcracker.cloud.context.propagation.core.ContextManager;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
public abstract class AbstractContextTestWithProperties {
diff --git a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObjectPropagationTest.java b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObjectPropagationTest.java
index c26e5c2a3..21cd00a70 100644
--- a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObjectPropagationTest.java
+++ b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/framework/contexts/xchannelrequestid/XChannelRequestIdContextObjectPropagationTest.java
@@ -7,7 +7,6 @@
import com.netcracker.cloud.context.propagation.core.ContextManager;
import com.netcracker.cloud.context.propagation.core.RequestContextPropagation;
import com.netcracker.cloud.context.propagation.core.contextdata.IncomingContextData;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
import com.netcracker.cloud.framework.contexts.data.ContextDataRequest;
import com.netcracker.cloud.framework.contexts.data.ContextDataResponse;
import com.netcracker.cloud.framework.contexts.data.SimpleIncomingContextData;
@@ -20,10 +19,8 @@
import java.util.Map;
import static com.netcracker.cloud.framework.contexts.data.ContextDataRequest.CUSTOM_HEADER;
-import static com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME;
class XChannelRequestIdContextObjectPropagationTest extends AbstractContextTestWithProperties {
- public static final String X_CHANNEL_REQUEST_ID = "X-Channel-Request-Id";
static Map properties = Map.of("headers.allowed", CUSTOM_HEADER);
@@ -40,55 +37,55 @@ static void cleanup() {
@Test
void getDefaultValue() {
RequestContextPropagation.initRequestContext(new DefaultContextDataRequest()); // filter
- Assertions.assertNotNull(ContextManager.get(X_CHANNEL_REQUEST_ID));
- XChannelRequestIdContextObject xChannelRequestIdContextObject = ContextManager.get(X_CHANNEL_REQUEST_ID);
+ Assertions.assertNotNull(ContextManager.get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
+ XChannelRequestIdContextObject xChannelRequestIdContextObject = ContextManager.get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME);
Assertions.assertNotNull(xChannelRequestIdContextObject.getChannelRequestId());
}
@Test
void testXChannelRequestIdPropagation() {
RequestContextPropagation.initRequestContext(new ContextDataRequest()); // filter
- Assertions.assertNotNull(ContextManager.get(X_CHANNEL_REQUEST_ID));
- XChannelRequestIdContextObject xChannelRequestIdContextObject = ContextManager.get(X_CHANNEL_REQUEST_ID);
+ Assertions.assertNotNull(ContextManager.get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
+ XChannelRequestIdContextObject xChannelRequestIdContextObject = ContextManager.get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME);
Assertions.assertNotNull(xChannelRequestIdContextObject.getChannelRequestId());
- ContextManager.set(X_CHANNEL_REQUEST_ID, xChannelRequestIdContextObject);
+ ContextManager.set(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME, xChannelRequestIdContextObject);
ContextDataResponse responseContextData = new ContextDataResponse();
RequestContextPropagation.populateResponse(responseContextData);
- Assertions.assertNull(responseContextData.getResponseHeaders().get(X_CHANNEL_REQUEST_ID));
+ Assertions.assertNull(responseContextData.getResponseHeaders().get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
}
@Test
void testXChannelRequestIdPropagationWithResponsePropagatableData() {
RequestContextPropagation.initRequestContext(new ContextDataRequest()); // filter
- XChannelRequestIdContextObject xChannelRequestIdContextObject = ContextManager.get(X_CHANNEL_REQUEST_ID);
+ XChannelRequestIdContextObject xChannelRequestIdContextObject = ContextManager.get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME);
Assertions.assertNotNull(xChannelRequestIdContextObject.getChannelRequestId());
- ContextManager.set(X_CHANNEL_REQUEST_ID, xChannelRequestIdContextObject);
+ ContextManager.set(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME, xChannelRequestIdContextObject);
ContextDataResponse responseContextData = new ContextDataResponse();
RequestContextPropagation.setResponsePropagatableData(responseContextData);
- Assertions.assertEquals("-", responseContextData.getResponseHeaders().get(X_CHANNEL_REQUEST_ID));
+ Assertions.assertEquals("-", responseContextData.getResponseHeaders().get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
}
@Test
- void testXChannelRequestIdPropagationIsBlockedByInternalBlocklist() {
- System.clearProperty(HeaderPropagationConfiguration.ALLOW_BLOCKED_PROPERTY);
+ void testXChannelRequestIdPropagationIsBlockedByRestrictedList() {
+ System.clearProperty(HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY);
HeaderPropagationConfiguration.resetCache();
RequestContextPropagation.initRequestContext(new ContextDataRequest()); // filter
ContextDataResponse responseContextData = new ContextDataResponse();
RequestContextPropagation.setResponsePropagatableData(responseContextData);
- Assertions.assertEquals("-", responseContextData.getResponseHeaders().get(X_CHANNEL_REQUEST_ID));
+ Assertions.assertEquals("-", responseContextData.getResponseHeaders().get(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
Map> serializableContextData = ContextManager.getSerializableContextData();
- Assertions.assertTrue(serializableContextData.getOrDefault(X_CHANNEL_REQUEST_ID_CONTEXT_NAME, Collections.emptyMap()).isEmpty());
+ Assertions.assertTrue(serializableContextData.getOrDefault(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME, Collections.emptyMap()).isEmpty());
}
@Test
void testXChannelRequestSerializableDataFromCxtManager() {
- RequestContextPropagation.initRequestContext(new SimpleIncomingContextData(Map.of(X_CHANNEL_REQUEST_ID, "12345")));
+ RequestContextPropagation.initRequestContext(new SimpleIncomingContextData(Map.of(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME, "12345")));
Map> serializableContextData = ContextManager.getSerializableContextData();
- Assertions.assertTrue(serializableContextData.containsKey(X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
+ Assertions.assertTrue(serializableContextData.containsKey(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
}
@Test
diff --git a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/headerstracking/filters/context/AbstractContextTest.java b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/headerstracking/filters/context/AbstractContextTest.java
index 97a36748a..0e4f6bf25 100644
--- a/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/headerstracking/filters/context/AbstractContextTest.java
+++ b/core-context-propagation/framework-contexts/src/test/java/com/netcracker/cloud/headerstracking/filters/context/AbstractContextTest.java
@@ -3,8 +3,8 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
import com.netcracker.cloud.context.propagation.core.RequestContextPropagation;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
import com.netcracker.cloud.framework.contexts.data.ContextDataRequest;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
import com.netcracker.cloud.context.propagation.core.ContextManager;
public abstract class AbstractContextTest {
diff --git a/core-context-propagation/pom.xml b/core-context-propagation/pom.xml
index 2de7d1905..8f25373f1 100644
--- a/core-context-propagation/pom.xml
+++ b/core-context-propagation/pom.xml
@@ -4,7 +4,7 @@
com.netcracker.cloud
context-propagation
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
pom
diff --git a/core-context-propagation/sample-context-tests/pom.xml b/core-context-propagation/sample-context-tests/pom.xml
index dab7415f7..392a3c6e9 100644
--- a/core-context-propagation/sample-context-tests/pom.xml
+++ b/core-context-propagation/sample-context-tests/pom.xml
@@ -4,7 +4,7 @@
com.netcracker.cloud
sample-context-tests
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
diff --git a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationSpringCommonTest.java b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationSpringCommonTest.java
index 01bbb10e9..d94414a71 100644
--- a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationSpringCommonTest.java
+++ b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationSpringCommonTest.java
@@ -4,6 +4,8 @@
import org.junit.jupiter.api.Test;
import com.netcracker.cloud.context.propagation.spring.common.annotation.EnableSpringContextProvider;
import com.netcracker.cloud.context.propagation.spring.common.filter.SpringPostAuthnContextProviderFilter;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextProvider;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
@@ -30,13 +32,13 @@ class RequestPropagationSpringCommonTest {
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).addFilter(filter).build();
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
}
@Test
void testRequestPropagation() throws Exception {
mockMvc.perform(get("/spring/common/test/requestId"))
.andExpect(header().exists("X-Request-Id"))
- .andExpect(header().exists("X-Channel-Request-Id"));
+ .andExpect(header().exists(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
}
}
diff --git a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationTest.java b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationTest.java
index e62da4eba..7166c58be 100644
--- a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationTest.java
+++ b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationTest.java
@@ -7,7 +7,7 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import com.netcracker.cloud.context.propagation.spring.common.filter.SpringPostAuthnContextProviderFilter;
import com.netcracker.cloud.context.propagation.spring.common.filter.SpringPreAuthnContextProviderFilter;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -34,8 +34,6 @@
TestController.class, RequestPropagationTestConfig.class})
@TestPropertySource(properties = {
"headers.allowed=custom-header",
- // context.propagation.allow-blocked-headers deliberately not set — the internal blocklist applies and
- // X-Channel-Request-Id should not propagate to outgoing requests.
"cloud-core.context-propagation.url=/test_url/v111/test"
})
class RequestPropagationTest {
@@ -65,7 +63,7 @@ class RequestPropagationTest {
@BeforeEach
void setUp() {
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
mockMvc = MockMvcBuilders.webAppContextSetup(context).addFilters(preAuthnFilter, postAuthnFilter).build();
@@ -109,7 +107,7 @@ void testRequestPropagation() throws Exception {
@Test
void testXRequestIdNotAffectedByExemptionConfig() throws Exception {
- System.setProperty("context.propagation.allow-blocked-headers", X_REQUEST_ID_NAME);
+ System.setProperty("context.propagation.headers.enable.optional", X_REQUEST_ID_NAME);
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
diff --git a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdAllowedTest.java b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdAllowedTest.java
index 3c567f1fb..7129201bc 100644
--- a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdAllowedTest.java
+++ b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdAllowedTest.java
@@ -8,7 +8,8 @@
import com.netcracker.cloud.context.propagation.core.ContextManager;
import com.netcracker.cloud.context.propagation.spring.common.filter.SpringPostAuthnContextProviderFilter;
import com.netcracker.cloud.context.propagation.spring.common.filter.SpringPreAuthnContextProviderFilter;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -33,7 +34,7 @@
TestController.class, RequestPropagationTestConfig.class})
@TestPropertySource(properties = {
"headers.allowed=custom-header",
- "context.propagation.allow-blocked-headers=X-Channel-Request-Id",
+ "context.propagation.headers.enable.optional=X-Channel-Request-Id",
"cloud-core.context-propagation.url=/test_url/v111/test"
})
class RequestPropagationXChannelRequestIdAllowedTest {
@@ -64,7 +65,7 @@ class RequestPropagationXChannelRequestIdAllowedTest {
@BeforeAll
static void beforeAll() {
System.setProperty("headers.allowed", "custom-header");
- System.setProperty("context.propagation.allow-blocked-headers", "X-Channel-Request-Id");
+ System.setProperty("context.propagation.headers.enable.optional", XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME);
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
@@ -72,7 +73,7 @@ static void beforeAll() {
@AfterAll
static void afterAll() {
System.clearProperty("headers.allowed");
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
diff --git a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdResponseTest.java b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdResponseTest.java
index 19d649a2c..7de5dbbc0 100644
--- a/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdResponseTest.java
+++ b/core-context-propagation/sample-context-tests/src/test/java/com/netcracker/cloud/context/propagation/sample/requests/RequestPropagationXChannelRequestIdResponseTest.java
@@ -23,7 +23,7 @@
import com.netcracker.cloud.context.propagation.core.ContextManager;
import com.netcracker.cloud.context.propagation.spring.common.filter.SpringPostAuthnContextProviderFilter;
import com.netcracker.cloud.context.propagation.spring.common.filter.SpringPreAuthnContextProviderFilter;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
@SpringBootTest
@ContextConfiguration(classes = {
@@ -31,7 +31,6 @@
@TestPropertySource(properties = {
"headers.allowed=custom-header",
"cloud-core.context-propagation.url=/test_url/v111/test"
- // context.propagation.allow-blocked-headers is not set, internal blocklist applies → X-Channel-Request-Id blocked for outgoing requests
})
class RequestPropagationXChannelRequestIdResponseTest {
@@ -55,14 +54,14 @@ class RequestPropagationXChannelRequestIdResponseTest {
@BeforeAll
static void beforeAll() {
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
@AfterAll
static void afterAll() {
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
@@ -75,8 +74,6 @@ void setUp() {
@Test
void testXChannelRequestIdReturnedInResponseEvenWhenBlockedForOutgoing() throws Exception {
- // X-Channel-Request-Id blocked for outgoing requests
- // but should be sent in response to client
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/chain_request"))
.andExpect(request -> assertNull(
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/pom.xml b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/pom.xml
index c208c3358..2acc106de 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/pom.xml
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/pom.xml
@@ -3,7 +3,7 @@
spring-context-aggregator
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/main/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfiguration.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/main/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfiguration.java
index b06fc1b31..3e6f5a1b8 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/main/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfiguration.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/main/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfiguration.java
@@ -31,14 +31,14 @@ public SpringPreAuthnContextProviderFilter springPreAuthnContextProviderFilter()
@Value("${headers.allowed:}")
private String allowedHeaders;
- @Value("${context.propagation.allow-blocked-headers:}")
- private String allowedFromBlocklist;
+ @Value("${context.propagation.headers.enable.optional:}")
+ private String enableOptional;
@PostConstruct
public void init() {
System.setProperty("headers.allowed", allowedHeaders);
- if (environment.containsProperty("context.propagation.allow-blocked-headers")) {
- System.setProperty("context.propagation.allow-blocked-headers", allowedFromBlocklist);
+ if (environment.containsProperty("context.propagation.headers.enable.optional")) {
+ System.setProperty("context.propagation.headers.enable.optional", enableOptional);
}
}
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java
index 3f92991b4..2f876745f 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/HeaderPropagationStateReset.java
@@ -4,8 +4,14 @@
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+/**
+ * JUnit5 extension that wipes the global JVM state touched by
+ * {@code SpringContextProviderConfiguration#init()} so that adjacent test classes in the
+ * same JVM do not leak {@code headers.*} system properties or the cached restricted list
+ * into each other.
+ */
public class HeaderPropagationStateReset implements BeforeAllCallback, AfterAllCallback {
@Override
@@ -19,7 +25,7 @@ public void afterAll(ExtensionContext ctx) {
}
private static void reset() {
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty(HeaderPropagationConfiguration.ENABLE_OPTIONAL_PROPERTY);
System.clearProperty("headers.allowed");
HeaderPropagationConfiguration.resetCache();
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
index b5fe96476..1c4680d03 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationEmptyTest.java
@@ -1,7 +1,5 @@
package com.netcracker.cloud.context.propagation.spring.common.configuration;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.annotation.DirtiesContext;
@@ -9,25 +7,28 @@
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextObject.X_CHANNEL_REQUEST_ID;
@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
"headers.allowed=custom-header",
- "context.propagation.allow-blocked-headers="
+ "context.propagation.headers.enable.optional="
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationEmptyTest {
@Test
- void shouldSetEmptySystemPropertyAndStillApplyInternalBlocklist() {
- assertEquals("", System.getProperty("context.propagation.allow-blocked-headers"),
+ void shouldSetEmptySystemPropertyAndStillApplyRestrictedList() {
+ assertEquals("", System.getProperty("context.propagation.headers.enable.optional"),
"Spring init() must propagate explicit empty value to the system property");
HeaderPropagationConfiguration.resetCache();
- assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "Internal blocklist must still apply when the exemption property is blank");
+ assertTrue(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID),
+ "Restricted list must still apply when the enable.optional property is blank");
}
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
deleted file mode 100644
index 121acc73b..000000000
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationFromEnvVarTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.netcracker.cloud.context.propagation.spring.common.configuration;
-
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-import uk.org.webcompere.systemstubs.environment.EnvironmentVariables;
-import uk.org.webcompere.systemstubs.jupiter.SystemStub;
-import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@ExtendWith({HeaderPropagationStateReset.class, SystemStubsExtension.class, SpringExtension.class})
-@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
-@TestPropertySource(properties = {
- // context.propagation.allow-blocked-headers deliberately NOT declared here — it must come from the env var
- "headers.allowed=custom-header"
-})
-@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-class SpringContextProviderConfigurationFromEnvVarTest {
-
- @SystemStub
- static EnvironmentVariables envVars = new EnvironmentVariables("CONTEXT_PROPAGATION_ALLOW_BLOCKED_HEADERS", "X-Channel-Request-Id");
-
- @Test
- void shouldReadHeadersAllowBlockedFromEnvVar() {
- assertEquals("X-Channel-Request-Id", System.getProperty("context.propagation.allow-blocked-headers"),
- "Spring init() must propagate env-sourced value to the system property");
-
- HeaderPropagationConfiguration.resetCache();
- assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "Env-sourced exemption must take effect");
- assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
- "The only entry of the internal blocklist must be removed by the exemption");
- }
-}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
index a9da90895..e88a5d315 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationNotConfiguredTest.java
@@ -1,6 +1,5 @@
package com.netcracker.cloud.context.propagation.spring.common.configuration;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.annotation.DirtiesContext;
@@ -8,25 +7,28 @@
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextObject.X_CHANNEL_REQUEST_ID;
@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
- // context.propagation.allow-blocked-headers intentionally absent
+ // context.propagation.headers.enable.optional intentionally absent
"headers.allowed=custom-header"
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationNotConfiguredTest {
@Test
- void shouldNotTouchSystemPropertyAndKeepInternalBlocklist() {
- assertNull(System.getProperty("context.propagation.allow-blocked-headers"),
- "context.propagation.allow-blocked-headers must remain unset when no source configures it");
+ void shouldNotTouchSystemPropertyAndKeepRestrictedList() {
+ assertNull(System.getProperty("context.propagation.headers.enable.optional"),
+ "context.propagation.headers.enable.optional must remain unset when no source configures it");
HeaderPropagationConfiguration.resetCache();
- assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "Internal blocklist must apply when no exemption is configured");
+ assertTrue(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID),
+ "Restricted list must apply when no value is configured");
}
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownEntryTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownEntryTest.java
new file mode 100644
index 000000000..5392449a5
--- /dev/null
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownEntryTest.java
@@ -0,0 +1,41 @@
+package com.netcracker.cloud.context.propagation.spring.common.configuration;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextObject.X_CHANNEL_REQUEST_ID;
+
+/**
+ * Spring integration scenario: {@code context.propagation.headers.enable.optional} contains only
+ * header names that are not part of the framework's restricted list. The configuration has no
+ * effect — the restricted list applies unchanged.
+ */
+@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
+@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
+@TestPropertySource(properties = {
+ "headers.allowed=custom-header",
+ "context.propagation.headers.enable.optional=Custom-Header, X-Some-Other-Header"
+})
+@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
+class SpringContextProviderConfigurationUnknownEntryTest {
+
+ @Test
+ void shouldLeaveRestrictedListIntactWhenEntriesDontMatch() {
+ assertEquals("Custom-Header, X-Some-Other-Header",
+ System.getProperty("context.propagation.headers.enable.optional"));
+
+ HeaderPropagationConfiguration.resetCache();
+ assertTrue(HeaderPropagationConfiguration.isRestricted(X_CHANNEL_REQUEST_ID),
+ "Restricted list must remain intact when no entry matches it");
+ assertEquals(HeaderPropagationConfiguration.RESTRICTED_HEADERS,
+ HeaderPropagationConfiguration.restrictedHeaders());
+ }
+}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownExemptionTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownExemptionTest.java
deleted file mode 100644
index 1a8a766c1..000000000
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationUnknownExemptionTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.netcracker.cloud.context.propagation.spring.common.configuration;
-
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-@ExtendWith({HeaderPropagationStateReset.class, SpringExtension.class})
-@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
-@TestPropertySource(properties = {
- "headers.allowed=custom-header",
- "context.propagation.allow-blocked-headers=Custom-Header, X-Some-Other-Header"
-})
-@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-class SpringContextProviderConfigurationUnknownExemptionTest {
-
- @Test
- void shouldLeaveInternalBlocklistIntactWhenExemptionsDontMatch() {
- assertEquals("Custom-Header, X-Some-Other-Header",
- System.getProperty("context.propagation.allow-blocked-headers"));
-
- HeaderPropagationConfiguration.resetCache();
- assertTrue(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
- "Internal blocklist must remain intact when no exemption matches it");
- assertEquals(HeaderPropagationConfiguration.INTERNAL_BLOCKED_HEADERS,
- HeaderPropagationConfiguration.blockedHeaders());
- }
-}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
index b496265a1..7ca2d2a8a 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/configuration/SpringContextProviderConfigurationWithValueTest.java
@@ -1,6 +1,5 @@
package com.netcracker.cloud.context.propagation.spring.common.configuration;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.annotation.DirtiesContext;
@@ -8,6 +7,9 @@
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextProvider;
+
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -16,19 +18,19 @@
@ContextConfiguration(classes = SpringContextProviderConfiguration.class)
@TestPropertySource(properties = {
"headers.allowed=custom-header",
- "context.propagation.allow-blocked-headers=X-Channel-Request-Id"
+ "context.propagation.headers.enable.optional=X-Channel-Request-Id"
})
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
class SpringContextProviderConfigurationWithValueTest {
@Test
- void shouldExemptListedHeaderFromInternalBlocklist() {
- assertEquals("X-Channel-Request-Id", System.getProperty("context.propagation.allow-blocked-headers"));
+ void shouldExemptListedHeaderFromRestrictedList() {
+ assertEquals(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME, System.getProperty("context.propagation.headers.enable.optional"));
HeaderPropagationConfiguration.resetCache();
- assertFalse(HeaderPropagationConfiguration.isBlacklisted("X-Channel-Request-Id"),
+ assertFalse(HeaderPropagationConfiguration.isRestricted(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME),
"Exempted header must not be blocked");
- assertTrue(HeaderPropagationConfiguration.blockedHeaders().isEmpty(),
- "The only entry of the internal blocklist (X-Channel-Request-Id) must be removed");
+ assertTrue(HeaderPropagationConfiguration.restrictedHeaders().isEmpty(),
+ "Any entry of the restricted list must be removed");
}
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/filter/SpringContextProviderFilterTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/filter/SpringContextProviderFilterTest.java
index bafe4cdcf..1efa7ee02 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/filter/SpringContextProviderFilterTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-common/src/test/java/com/netcracker/cloud/context/propagation/spring/common/filter/SpringContextProviderFilterTest.java
@@ -28,7 +28,6 @@
class SpringContextProviderFilterTest {
public static final String X_REQUEST_ID_CONTEXT_NAME = "X-Request-Id";
- public static final String X_CHANNEL_REQUEST_ID_CONTEXT_NAME = "X-Channel-Request-Id";
@BeforeEach
void init() {
@@ -39,7 +38,7 @@ void init() {
void testDoFilterInternal() throws ServletException, IOException {
HttpServletRequest httpServletRequest = mock(HttpServletRequest.class);
when(httpServletRequest.getHeaderNames())
- .thenReturn(new EnumerationImpl<>(Arrays.asList(ACCEPT_LANGUAGE, X_REQUEST_ID_CONTEXT_NAME, X_CHANNEL_REQUEST_ID_CONTEXT_NAME).iterator()));
+ .thenReturn(new EnumerationImpl<>(Arrays.asList(ACCEPT_LANGUAGE, X_REQUEST_ID_CONTEXT_NAME, XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME).iterator()));
String acceptLanguageValue = "ru;en";
when(httpServletRequest.getHeaders(ACCEPT_LANGUAGE))
@@ -52,9 +51,9 @@ void testDoFilterInternal() throws ServletException, IOException {
.thenReturn(xRequestIdValue);
String xChannelRequestIdValue = "456";
- when(httpServletRequest.getHeaders(X_CHANNEL_REQUEST_ID_CONTEXT_NAME))
+ when(httpServletRequest.getHeaders(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME))
.thenReturn(new EnumerationImpl<>(Collections.singletonList(xChannelRequestIdValue).iterator()));
- when(httpServletRequest.getHeader(X_CHANNEL_REQUEST_ID_CONTEXT_NAME))
+ when(httpServletRequest.getHeader(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME))
.thenReturn(xChannelRequestIdValue);
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/pom.xml b/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/pom.xml
index 8d32f3923..0e3c4ec41 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/pom.xml
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/pom.xml
@@ -3,7 +3,7 @@
spring-context-aggregator
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/src/test/java/com/netcracker/cloud/context/propagation/spring/kafka/ContextPropagationTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/src/test/java/com/netcracker/cloud/context/propagation/spring/kafka/ContextPropagationTest.java
index 62a134218..f841708fd 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/src/test/java/com/netcracker/cloud/context/propagation/spring/kafka/ContextPropagationTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-kafka/src/test/java/com/netcracker/cloud/context/propagation/spring/kafka/ContextPropagationTest.java
@@ -9,7 +9,8 @@
import org.junit.jupiter.api.Timeout;
import com.netcracker.cloud.context.propagation.core.ContextManager;
import com.netcracker.cloud.context.propagation.spring.kafka.annotation.EnableKafkaContextPropagation;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextProvider;
import com.netcracker.cloud.headerstracking.filters.context.AcceptLanguageContext;
import com.netcracker.cloud.headerstracking.filters.context.AllowedHeadersContext;
import com.netcracker.cloud.headerstracking.filters.context.ChannelRequestIdContext;
@@ -50,7 +51,6 @@ public class ContextPropagationTest {
private static final String TEST_LANG = "ZULU";
private static final String CUSTOM_HEADER = "X-Custom-Header-1";
private static final String CUSTOM_HEADER_VALUE = "case-insensitive-test-value";
- private static final String X_CHANNEL_REQUEST_ID_NAME = "X-Channel-Request-Id";
private static final String X_CHANNEL_REQUEST_ID_VALUE = "456";
private static final AtomicReference>> consumed = new AtomicReference<>();
private static final CountingInterceptor interceptor = new CountingInterceptor();
@@ -61,7 +61,7 @@ public class ContextPropagationTest {
@BeforeAll
static void setup() {
System.setProperty("headers.allowed", CUSTOM_HEADER.toLowerCase());
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
HeaderPropagationConfiguration.resetCache();
}
@@ -73,7 +73,7 @@ void beforeEach() {
@AfterEach
void afterEach() {
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
HeaderPropagationConfiguration.resetCache();
}
@@ -93,7 +93,7 @@ void testContextPropagationBlocksXChannelRequestIdByDefault() throws Exception {
ContextManager.clearAll();
ConsumerRecord message = consumed.get().get(5, TimeUnit.SECONDS);
- assertNull(message.headers().lastHeader(X_CHANNEL_REQUEST_ID_NAME));
+ assertNull(message.headers().lastHeader(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
assertEquals(TEST_LANG, new String(message.headers().lastHeader(HttpHeaders.ACCEPT_LANGUAGE).value()));
assertEquals(CUSTOM_HEADER_VALUE, new String(message.headers().lastHeader(CUSTOM_HEADER).value()));
}
@@ -101,7 +101,7 @@ void testContextPropagationBlocksXChannelRequestIdByDefault() throws Exception {
@Test
@Timeout(30)
public void testContextPropagationAllowsXChannelRequestIdWhenExempted() throws Exception {
- System.setProperty("context.propagation.allow-blocked-headers", X_CHANNEL_REQUEST_ID_NAME);
+ System.setProperty("context.propagation.headers.enable.optional", XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME);
HeaderPropagationConfiguration.resetCache();
ChannelRequestIdContext.set(X_CHANNEL_REQUEST_ID_VALUE);
@@ -112,8 +112,8 @@ public void testContextPropagationAllowsXChannelRequestIdWhenExempted() throws E
ContextManager.clearAll();
ConsumerRecord message = consumed.get().get(5, TimeUnit.SECONDS);
- assertNotNull(message.headers().lastHeader(X_CHANNEL_REQUEST_ID_NAME));
- assertEquals(X_CHANNEL_REQUEST_ID_VALUE, new String(message.headers().lastHeader(X_CHANNEL_REQUEST_ID_NAME).value()));
+ assertNotNull(message.headers().lastHeader(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME));
+ assertEquals(X_CHANNEL_REQUEST_ID_VALUE, new String(message.headers().lastHeader(XChannelRequestIdContextProvider.X_CHANNEL_REQUEST_ID_CONTEXT_NAME).value()));
}
@Component
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/pom.xml b/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/pom.xml
index 1ad895b92..184b03ef0 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/pom.xml
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/pom.xml
@@ -3,7 +3,7 @@
spring-context-aggregator
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/src/test/java/com/netcracker/cloud/context/propagation/spring/rabbit/PropagationTest.java b/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/src/test/java/com/netcracker/cloud/context/propagation/spring/rabbit/PropagationTest.java
index 581b06fd8..1e8fc23fc 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/src/test/java/com/netcracker/cloud/context/propagation/spring/rabbit/PropagationTest.java
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-rabbit/src/test/java/com/netcracker/cloud/context/propagation/spring/rabbit/PropagationTest.java
@@ -2,7 +2,7 @@
import com.netcracker.cloud.context.propagation.core.ContextManager;
import com.netcracker.cloud.context.propagation.spring.rabbit.annotation.EnableRabbitContextPropagation;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
import com.netcracker.cloud.headerstracking.filters.context.AcceptLanguageContext;
import com.netcracker.cloud.headerstracking.filters.context.AllowedHeadersContext;
import com.netcracker.cloud.headerstracking.filters.context.ChannelRequestIdContext;
@@ -87,7 +87,7 @@ public static void setup() throws Exception {
channel.queueBind("orders", "orders", "invoice");
}
System.setProperty("headers.allowed", CUSTOM_HEADER.toLowerCase());
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
}
@AfterAll
@@ -103,7 +103,7 @@ void beforeEach() {
@AfterEach
void afterEach() {
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
HeaderPropagationConfiguration.resetCache();
}
@@ -126,8 +126,7 @@ public void testXChannelRequestIdBlockedByDefault() throws InterruptedException
@Test
@Timeout(value = 20, unit = TimeUnit.SECONDS)
public void testXChannelRequestIdAllowedWhenExempted() throws InterruptedException {
- // Exempt X-Channel-Request-Id from the internal blocklist — it must propagate.
- System.setProperty("context.propagation.allow-blocked-headers", X_CHANNEL_REQUEST_ID_NAME);
+ System.setProperty("context.propagation.headers.enable.optional", X_CHANNEL_REQUEST_ID_NAME);
HeaderPropagationConfiguration.resetCache();
AcceptLanguageContext.set("ZULU");
@@ -145,10 +144,8 @@ public void testXChannelRequestIdAllowedWhenExempted() throws InterruptedExcepti
@Test
@Timeout(value = 20, unit = TimeUnit.SECONDS)
- public void testUnknownExemptionDoesNotAffectInternalBlocklist() throws InterruptedException {
- // Listing a header that is NOT in the internal blocklist has no effect — the
- // internal blocklist (containing X-Channel-Request-Id) still applies.
- System.setProperty("context.propagation.allow-blocked-headers", ANOTHER_HEADER);
+ public void testUnknownExemptionDoesNotAffectRestrictedList() throws InterruptedException {
+ System.setProperty("context.propagation.headers.enable.optional", ANOTHER_HEADER);
HeaderPropagationConfiguration.resetCache();
AcceptLanguageContext.set("ZULU");
@@ -164,7 +161,7 @@ public void testUnknownExemptionDoesNotAffectInternalBlocklist() throws Interrup
}
assertNull(getHeaderIgnoreCase(receivedHeaders.get(), X_CHANNEL_REQUEST_ID_NAME),
- "Internal blocklist must remain intact when no exemption matches it");
+ "Restricted list must remain intact when no entry matches it");
assertEquals(CUSTOM_HEADER_VALUE, getHeaderIgnoreCase(receivedHeaders.get(), CUSTOM_HEADER));
assertEquals(ANOTHER_HEADER_VALUE, getHeaderIgnoreCase(receivedHeaders.get(), ANOTHER_HEADER));
}
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-resttemplate/pom.xml b/core-context-propagation/spring-context-aggregator/context-propagation-spring-resttemplate/pom.xml
index 4a77740b3..a5ec3b8d2 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-resttemplate/pom.xml
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-resttemplate/pom.xml
@@ -3,7 +3,7 @@
spring-context-aggregator
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/core-context-propagation/spring-context-aggregator/context-propagation-spring-webclient/pom.xml b/core-context-propagation/spring-context-aggregator/context-propagation-spring-webclient/pom.xml
index e8c0c61fa..c73575f85 100644
--- a/core-context-propagation/spring-context-aggregator/context-propagation-spring-webclient/pom.xml
+++ b/core-context-propagation/spring-context-aggregator/context-propagation-spring-webclient/pom.xml
@@ -3,7 +3,7 @@
spring-context-aggregator
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/core-context-propagation/spring-context-aggregator/pom.xml b/core-context-propagation/spring-context-aggregator/pom.xml
index 1aa6fe02b..6302ba383 100644
--- a/core-context-propagation/spring-context-aggregator/pom.xml
+++ b/core-context-propagation/spring-context-aggregator/pom.xml
@@ -3,7 +3,7 @@
context-propagation
com.netcracker.cloud
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
../pom.xml
4.0.0
diff --git a/core-microservice-dependencies/cloud-core-java-bom/pom.xml b/core-microservice-dependencies/cloud-core-java-bom/pom.xml
index 83561ccaa..d9d8bc048 100644
--- a/core-microservice-dependencies/cloud-core-java-bom/pom.xml
+++ b/core-microservice-dependencies/cloud-core-java-bom/pom.xml
@@ -25,7 +25,7 @@
7.2.0-SNAPSHOT
9.1.0-SNAPSHOT
7.1.0-SNAPSHOT
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
12.2.0-SNAPSHOT
4.2.0-SNAPSHOT
diff --git a/core-quarkus-extensions/cloud-core-quarkus-bom/cloud-core-quarkus-bom-internal/pom.xml b/core-quarkus-extensions/cloud-core-quarkus-bom/cloud-core-quarkus-bom-internal/pom.xml
index 8dba44196..8f486b647 100644
--- a/core-quarkus-extensions/cloud-core-quarkus-bom/cloud-core-quarkus-bom-internal/pom.xml
+++ b/core-quarkus-extensions/cloud-core-quarkus-bom/cloud-core-quarkus-bom-internal/pom.xml
@@ -13,7 +13,7 @@
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
9.1.0-SNAPSHOT
3.1.0-SNAPSHOT
diff --git a/core-quarkus-extensions/cloud-core-quarkus-bom/cloud-core-quarkus-bom-parent/pom.xml b/core-quarkus-extensions/cloud-core-quarkus-bom/cloud-core-quarkus-bom-parent/pom.xml
index c2cf72236..57ed35af9 100644
--- a/core-quarkus-extensions/cloud-core-quarkus-bom/cloud-core-quarkus-bom-parent/pom.xml
+++ b/core-quarkus-extensions/cloud-core-quarkus-bom/cloud-core-quarkus-bom-parent/pom.xml
@@ -12,6 +12,6 @@
pom
- 9.1.0-SNAPSHOT
+ 9.1.1-SNAPSHOT
diff --git a/core-rest-libraries/rest-third-party/pom.xml b/core-rest-libraries/rest-third-party/pom.xml
index a4cac0399..b22dc5952 100644
--- a/core-rest-libraries/rest-third-party/pom.xml
+++ b/core-rest-libraries/rest-third-party/pom.xml
@@ -14,7 +14,7 @@
7.1.0-SNAPSHOT
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
4.2.0-SNAPSHOT
2.0.9
diff --git a/dbaas-client/dbaas-client-bom-parent/dbaas-client-bom-internal/pom.xml b/dbaas-client/dbaas-client-bom-parent/dbaas-client-bom-internal/pom.xml
index 5bb896700..ed559650e 100644
--- a/dbaas-client/dbaas-client-bom-parent/dbaas-client-bom-internal/pom.xml
+++ b/dbaas-client/dbaas-client-bom-parent/dbaas-client-bom-internal/pom.xml
@@ -26,7 +26,7 @@
7.2.0-SNAPSHOT
7.1.0-SNAPSHOT
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
3.1.0-SNAPSHOT
diff --git a/maas-client/kafka-context-propagation/src/test/java/com/netcracker/cloud/maas/client/context/kafka/KafkaContextPropagationTest.java b/maas-client/kafka-context-propagation/src/test/java/com/netcracker/cloud/maas/client/context/kafka/KafkaContextPropagationTest.java
index a5ee8744c..caed936e2 100644
--- a/maas-client/kafka-context-propagation/src/test/java/com/netcracker/cloud/maas/client/context/kafka/KafkaContextPropagationTest.java
+++ b/maas-client/kafka-context-propagation/src/test/java/com/netcracker/cloud/maas/client/context/kafka/KafkaContextPropagationTest.java
@@ -6,7 +6,7 @@
import com.netcracker.cloud.framework.contexts.xversion.XVersionProvider;
import com.netcracker.cloud.headerstracking.filters.context.AcceptLanguageContext;
import com.netcracker.cloud.maas.client.context.kafka.KafkaContextPropagation.HeadersAdapter;
-import com.netcracker.cloud.framework.contexts.allowedheaders.HeaderPropagationConfiguration;
+import com.netcracker.cloud.framework.contexts.xchannelrequestid.HeaderPropagationConfiguration;
import com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextObject;
import com.netcracker.cloud.framework.contexts.xchannelrequestid.XChannelRequestIdContextProvider;
@@ -104,7 +104,7 @@ void testDumpDoesNotContainXChannelRequestIdByDefault() {
@Test
void testDumpContainsXChannelRequestIdWhenExempted() {
- System.setProperty("context.propagation.allow-blocked-headers", X_CHANNEL_REQUEST_ID);
+ System.setProperty("context.propagation.headers.enable.optional", X_CHANNEL_REQUEST_ID);
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
@@ -117,7 +117,7 @@ void testDumpContainsXChannelRequestIdWhenExempted() {
assertEquals("ch-456", dumped.get(X_CHANNEL_REQUEST_ID));
} finally {
- System.clearProperty("context.propagation.allow-blocked-headers");
+ System.clearProperty("context.propagation.headers.enable.optional");
HeaderPropagationConfiguration.resetCache();
ContextManager.reinitialize();
}
diff --git a/maas-client/pom.xml b/maas-client/pom.xml
index 7fd992438..c4dcd3527 100644
--- a/maas-client/pom.xml
+++ b/maas-client/pom.xml
@@ -19,7 +19,7 @@
21
21
UTF-8
- 8.2.0-SNAPSHOT
+ 8.2.1-SNAPSHOT
2.1.0-SNAPSHOT
4.2.0
From aef8aabfd1b36281d039cb1f01c62c8d6cd31337 Mon Sep 17 00:00:00 2001
From: Ksiona
Date: Tue, 19 May 2026 22:33:28 +0400
Subject: [PATCH 9/9] chore: fix review requested + version bump
---
.../HeadersEnableOptionalRecorderEffectTest.java | 2 +-
.../HeadersOptionalConfigNotSetTest.java | 3 +--
.../HeadersOptionalConfigTest.java | 3 +--
3 files changed, 3 insertions(+), 5 deletions(-)
rename core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/{allowedheaders => xchannelrequestid}/HeadersEnableOptionalRecorderEffectTest.java (96%)
rename core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/{allowedheaders => xchannelrequestid}/HeadersOptionalConfigNotSetTest.java (91%)
rename core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/{allowedheaders => xchannelrequestid}/HeadersOptionalConfigTest.java (84%)
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersEnableOptionalRecorderEffectTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersEnableOptionalRecorderEffectTest.java
similarity index 96%
rename from core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersEnableOptionalRecorderEffectTest.java
rename to core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersEnableOptionalRecorderEffectTest.java
index 66a3aeacc..06b3f93c5 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersEnableOptionalRecorderEffectTest.java
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersEnableOptionalRecorderEffectTest.java
@@ -1,4 +1,4 @@
-package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
+package com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigNotSetTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfigNotSetTest.java
similarity index 91%
rename from core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigNotSetTest.java
rename to core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfigNotSetTest.java
index cd85d01b5..e81384031 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigNotSetTest.java
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfigNotSetTest.java
@@ -1,4 +1,4 @@
-package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
+package com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.QuarkusTestProfile;
@@ -6,7 +6,6 @@
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
-import com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid.HeadersOptionalConfig;
import java.util.Map;
diff --git a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigTest.java b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfigTest.java
similarity index 84%
rename from core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigTest.java
rename to core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfigTest.java
index cf33ae72e..b4cd5358d 100644
--- a/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/allowedheaders/HeadersOptionalConfigTest.java
+++ b/core-context-propagation-quarkus/integration-tests/context-propagation-reactive-test/src/test/java/com/netcracker/cloud/framework/quarkus/contexts/xchannelrequestid/HeadersOptionalConfigTest.java
@@ -1,10 +1,9 @@
-package com.netcracker.cloud.framework.quarkus.contexts.allowedheaders;
+package com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
-import com.netcracker.cloud.framework.quarkus.contexts.xchannelrequestid.HeadersOptionalConfig;
import java.util.List;
import java.util.Optional;