Skip to content

Commit 99f5e95

Browse files
authored
Scripting: body access decoded and array jsonpath in exchange expressions (#2236)
* fix: decodierung of body content for if, call, setHeader. Make jsonpath accept arrays as input. * fix: decodierung of body content for if, call, setHeader. Make jsonpath accept arrays as input. * fix: CallInterceptor Keep transfer- and content-encoding * refactor: CallInterceptor copy just bytes and let setBodyContent handle transfer encoding * refactor: minor * refactor: minor * refactor: minor * refactor: minor
1 parent b014256 commit 99f5e95

24 files changed

Lines changed: 120 additions & 69 deletions

core/src/main/java/com/predic8/membrane/core/interceptor/apikey/extractors/ApiKeyExpressionExtractor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import static com.predic8.membrane.core.interceptor.Interceptor.Flow.REQUEST;
2727
import static com.predic8.membrane.core.lang.ExchangeExpression.Language.SPEL;
28+
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;
2829
import static com.predic8.membrane.core.security.ApiKeySecurityScheme.In.EXPRESSION;
2930

3031
/**
@@ -53,7 +54,7 @@ public class ApiKeyExpressionExtractor implements ApiKeyExtractor, Polyglot {
5354

5455
@Override
5556
public void init(Router router) {
56-
exchangeExpression = ExchangeExpression.newInstance(router, language, expression);
57+
exchangeExpression = expression(router, language, expression);
5758
}
5859

5960
@Override

core/src/main/java/com/predic8/membrane/core/interceptor/balancer/PolyglotSessionIdExtractor.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import com.predic8.membrane.core.lang.ExchangeExpression;
2525
import com.predic8.membrane.core.lang.ExchangeExpression.Language;
2626

27+
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;
28+
2729
@MCElement(name = "sessionIdExtractor")
2830
public class PolyglotSessionIdExtractor extends AbstractXmlElement implements SessionIdExtractor, Polyglot {
2931

@@ -33,7 +35,7 @@ public class PolyglotSessionIdExtractor extends AbstractXmlElement implements Se
3335

3436
public void init(Router router) {
3537
if (sessionSource != null && !sessionSource.isEmpty()) {
36-
exchangeExpression = ExchangeExpression.newInstance(router, language, sessionSource);
38+
exchangeExpression = expression(router, language, sessionSource);
3739
}
3840
}
3941

core/src/main/java/com/predic8/membrane/core/interceptor/flow/CallInterceptor.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public class CallInterceptor extends AbstractExchangeExpressionInterceptor {
5353
* and are not added to the current message.
5454
*/
5555
private static final List<String> REMOVE_HEADERS = List.of(
56-
SERVER, TRANSFER_ENCODING, CONTENT_ENCODING
56+
SERVER, CONTENT_ENCODING, TRANSFER_ENCODING
5757
);
5858

5959
private String method = GET;
@@ -87,7 +87,11 @@ private Outcome handleInternal(Exchange exc) {
8787
}
8888

8989
try {
90-
exc.getRequest().setBodyContent(newExc.getResponse().getBody().getContent());
90+
/**
91+
* The content is copied from the response with decoding. The response headers transfer-encoding
92+
* and content-encoding are removed by the setBodyContent method.
93+
*/
94+
exc.getRequest().setBodyContent(newExc.getResponse().getBodyAsStreamDecoded().readAllBytes());
9195
copyHeadersFromResponseToRequest(newExc, exc);
9296
return CONTINUE;
9397
} catch (Exception e) {

core/src/main/java/com/predic8/membrane/core/interceptor/flow/ForInterceptor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import static com.predic8.membrane.core.interceptor.Outcome.ABORT;
3030
import static com.predic8.membrane.core.interceptor.Outcome.CONTINUE;
3131
import static com.predic8.membrane.core.lang.ExchangeExpression.Language.SPEL;
32+
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;
3233

3334
/**
3435
* @description Iterates over a collection extracted from the <code>Exchange</code> and applies
@@ -56,7 +57,7 @@ public class ForInterceptor extends AbstractFlowWithChildrenInterceptor {
5657
public void init() {
5758
super.init();
5859
try {
59-
exchangeExpression = ExchangeExpression.newInstance(router, language, in);
60+
exchangeExpression = expression(router, language, in);
6061
} catch (ConfigurationException ce) {
6162
throw new ConfigurationException(ce.getMessage() + """
6263

core/src/main/java/com/predic8/membrane/core/interceptor/flow/IfInterceptor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import static com.predic8.membrane.core.interceptor.Outcome.ABORT;
2727
import static com.predic8.membrane.core.interceptor.Outcome.*;
2828
import static com.predic8.membrane.core.lang.ExchangeExpression.Language.*;
29+
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;
2930

3031
/**
3132
* @description <p>
@@ -52,7 +53,7 @@ public IfInterceptor() {
5253
@Override
5354
public void init() {
5455
super.init();
55-
exchangeExpression = ExchangeExpression.newInstance(router, language, test);
56+
exchangeExpression = expression(router, language, test);
5657
}
5758

5859
@Override

core/src/main/java/com/predic8/membrane/core/interceptor/flow/choice/Case.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.slf4j.LoggerFactory;
2626

2727
import static com.predic8.membrane.core.lang.ExchangeExpression.Language.SPEL;
28+
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;
2829

2930
@MCElement(name = "case", topLevel = false)
3031
public class Case extends InterceptorContainer {
@@ -36,7 +37,7 @@ public class Case extends InterceptorContainer {
3637
private ExchangeExpression exchangeExpression;
3738

3839
public void init(Router router) {
39-
exchangeExpression = ExchangeExpression.newInstance(router, language, test);
40+
exchangeExpression = expression(router, language, test);
4041
}
4142

4243
boolean evaluate(Exchange exc, Flow flow) {

core/src/main/java/com/predic8/membrane/core/interceptor/idempotency/IdempotencyInterceptor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import static com.predic8.membrane.core.interceptor.Outcome.ABORT;
3333
import static com.predic8.membrane.core.interceptor.Outcome.CONTINUE;
3434
import static com.predic8.membrane.core.lang.ExchangeExpression.Language.SPEL;
35+
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;
3536

3637
/**
3738
* @description <p>Prevents duplicate request processing based on a dynamic idempotency key.</p>
@@ -54,7 +55,7 @@ public class IdempotencyInterceptor extends AbstractInterceptor {
5455
@Override
5556
public void init() {
5657
super.init();
57-
exchangeExpression = ExchangeExpression.newInstance(router, language, key);
58+
exchangeExpression = expression(router, language, key);
5859
processedKeys = CacheBuilder.newBuilder()
5960
.maximumSize(10000)
6061
.expireAfterWrite(expiration, TimeUnit.SECONDS)

core/src/main/java/com/predic8/membrane/core/interceptor/ratelimit/RateLimitInterceptor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import static com.predic8.membrane.core.interceptor.Interceptor.Flow.REQUEST;
3131
import static com.predic8.membrane.core.interceptor.Interceptor.Flow.Set.*;
3232
import static com.predic8.membrane.core.interceptor.Outcome.*;
33+
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;
3334
import static com.predic8.membrane.core.util.HttpUtil.*;
3435
import static java.lang.String.*;
3536

@@ -93,7 +94,7 @@ protected ExchangeExpression getExchangeExpression() {
9394
// If there is no expression use the client IP
9495
if (expression.isEmpty())
9596
return null;
96-
return ExchangeExpression.newInstance(router, language, expression);
97+
return expression(router, language, expression);
9798
}
9899

99100
@Override

core/src/main/java/com/predic8/membrane/core/lang/ExchangeExpression.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ enum Language {GROOVY, SPEL, XPATH, JSONPATH}
4848
*/
4949
<T> T evaluate(Exchange exchange, Interceptor.Flow flow, Class<T> type) throws ExchangeExpressionException;
5050

51-
static ExchangeExpression newInstance(Router router, Language language, String expression) {
51+
static ExchangeExpression expression(Router router, Language language, String expression) {
5252
return switch (language) {
5353
case GROOVY -> new GroovyExchangeExpression(router, expression);
5454
case SPEL -> new SpELExchangeExpression(expression,null);

core/src/main/java/com/predic8/membrane/core/lang/spel/spelable/SpELBody.java renamed to core/src/main/java/com/predic8/membrane/core/lang/LazyBody.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,33 @@
1111
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
See the License for the specific language governing permissions and
1313
limitations under the License. */
14-
package com.predic8.membrane.core.lang.spel.spelable;
14+
package com.predic8.membrane.core.lang;
1515

1616
import com.predic8.membrane.core.http.*;
1717

18-
public class SpELBody {
18+
/**
19+
* Enables the use of ${body} in scripting environments without reading the body from InputStream when it is not needed.
20+
*/
21+
public class LazyBody {
1922

2023
/**
2124
* Store message instead of body to be able to extract even zipped bodies
2225
*/
2326
final Message message;
2427

25-
public SpELBody(Message msg) {
28+
public LazyBody(Message msg) {
2629
message = msg;
2730
}
2831

2932
public Message getMessage() {
3033
return message;
3134
}
35+
36+
/**
37+
* This method is called in an expression like "Body ${body}".
38+
*/
39+
@Override
40+
public String toString() {
41+
return message.getBodyAsStringDecoded();
42+
}
3243
}

0 commit comments

Comments
 (0)