Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import static com.predic8.membrane.core.interceptor.Interceptor.Flow.REQUEST;
import static com.predic8.membrane.core.lang.ExchangeExpression.Language.SPEL;
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;
import static com.predic8.membrane.core.security.ApiKeySecurityScheme.In.EXPRESSION;

/**
Expand Down Expand Up @@ -53,7 +54,7 @@ public class ApiKeyExpressionExtractor implements ApiKeyExtractor, Polyglot {

@Override
public void init(Router router) {
exchangeExpression = ExchangeExpression.newInstance(router, language, expression);
exchangeExpression = expression(router, language, expression);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import com.predic8.membrane.core.lang.ExchangeExpression;
import com.predic8.membrane.core.lang.ExchangeExpression.Language;

import static com.predic8.membrane.core.lang.ExchangeExpression.expression;

@MCElement(name = "sessionIdExtractor")
public class PolyglotSessionIdExtractor extends AbstractXmlElement implements SessionIdExtractor, Polyglot {

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

public void init(Router router) {
if (sessionSource != null && !sessionSource.isEmpty()) {
exchangeExpression = ExchangeExpression.newInstance(router, language, sessionSource);
exchangeExpression = expression(router, language, sessionSource);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public class CallInterceptor extends AbstractExchangeExpressionInterceptor {
* and are not added to the current message.
*/
private static final List<String> REMOVE_HEADERS = List.of(
SERVER, TRANSFER_ENCODING, CONTENT_ENCODING
SERVER, CONTENT_ENCODING, TRANSFER_ENCODING
);

private String method = GET;
Expand Down Expand Up @@ -87,7 +87,11 @@ private Outcome handleInternal(Exchange exc) {
}

try {
exc.getRequest().setBodyContent(newExc.getResponse().getBody().getContent());
/**
* The content is copied from the response with decoding. The response headers transfer-encoding
* and content-encoding are removed by the setBodyContent method.
*/
exc.getRequest().setBodyContent(newExc.getResponse().getBodyAsStreamDecoded().readAllBytes());
copyHeadersFromResponseToRequest(newExc, exc);
return CONTINUE;
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import static com.predic8.membrane.core.interceptor.Outcome.ABORT;
import static com.predic8.membrane.core.interceptor.Outcome.CONTINUE;
import static com.predic8.membrane.core.lang.ExchangeExpression.Language.SPEL;
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;

/**
* @description Iterates over a collection extracted from the <code>Exchange</code> and applies
Expand Down Expand Up @@ -56,7 +57,7 @@ public class ForInterceptor extends AbstractFlowWithChildrenInterceptor {
public void init() {
super.init();
try {
exchangeExpression = ExchangeExpression.newInstance(router, language, in);
exchangeExpression = expression(router, language, in);
} catch (ConfigurationException ce) {
throw new ConfigurationException(ce.getMessage() + """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import static com.predic8.membrane.core.interceptor.Outcome.ABORT;
import static com.predic8.membrane.core.interceptor.Outcome.*;
import static com.predic8.membrane.core.lang.ExchangeExpression.Language.*;
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;

/**
* @description <p>
Expand All @@ -52,7 +53,7 @@ public IfInterceptor() {
@Override
public void init() {
super.init();
exchangeExpression = ExchangeExpression.newInstance(router, language, test);
exchangeExpression = expression(router, language, test);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.slf4j.LoggerFactory;

import static com.predic8.membrane.core.lang.ExchangeExpression.Language.SPEL;
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;

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

public void init(Router router) {
exchangeExpression = ExchangeExpression.newInstance(router, language, test);
exchangeExpression = expression(router, language, test);
}

boolean evaluate(Exchange exc, Flow flow) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import static com.predic8.membrane.core.interceptor.Outcome.ABORT;
import static com.predic8.membrane.core.interceptor.Outcome.CONTINUE;
import static com.predic8.membrane.core.lang.ExchangeExpression.Language.SPEL;
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;

/**
* @description <p>Prevents duplicate request processing based on a dynamic idempotency key.</p>
Expand All @@ -54,7 +55,7 @@ public class IdempotencyInterceptor extends AbstractInterceptor {
@Override
public void init() {
super.init();
exchangeExpression = ExchangeExpression.newInstance(router, language, key);
exchangeExpression = expression(router, language, key);
processedKeys = CacheBuilder.newBuilder()
.maximumSize(10000)
.expireAfterWrite(expiration, TimeUnit.SECONDS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import static com.predic8.membrane.core.interceptor.Interceptor.Flow.REQUEST;
import static com.predic8.membrane.core.interceptor.Interceptor.Flow.Set.*;
import static com.predic8.membrane.core.interceptor.Outcome.*;
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;
import static com.predic8.membrane.core.util.HttpUtil.*;
import static java.lang.String.*;

Expand Down Expand Up @@ -93,7 +94,7 @@ protected ExchangeExpression getExchangeExpression() {
// If there is no expression use the client IP
if (expression.isEmpty())
return null;
return ExchangeExpression.newInstance(router, language, expression);
return expression(router, language, expression);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ enum Language {GROOVY, SPEL, XPATH, JSONPATH}
*/
<T> T evaluate(Exchange exchange, Interceptor.Flow flow, Class<T> type) throws ExchangeExpressionException;

static ExchangeExpression newInstance(Router router, Language language, String expression) {
static ExchangeExpression expression(Router router, Language language, String expression) {
return switch (language) {
case GROOVY -> new GroovyExchangeExpression(router, expression);
case SPEL -> new SpELExchangeExpression(expression,null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,33 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
package com.predic8.membrane.core.lang.spel.spelable;
package com.predic8.membrane.core.lang;

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

public class SpELBody {
/**
* Enables the use of ${body} in scripting environments without reading the body from InputStream when it is not needed.
*/
public class LazyBody {

/**
* Store message instead of body to be able to extract even zipped bodies
*/
final Message message;

public SpELBody(Message msg) {
public LazyBody(Message msg) {
message = msg;
}

public Message getMessage() {
return message;
}

/**
* This method is called in an expression like "Body ${body}".
*/
@Override
public String toString() {
return message.getBodyAsStringDecoded();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,28 +71,26 @@ public static HashMap<String, Object> createParameterBindings(Router router, Exc

if (msg != null) {
params.put("message", msg);
params.put("body", new LazyBody(msg));
params.put("header", msg.getHeader());
params.put("headers", msg.getHeader());
if (includeJsonObject) {
try {
log.info("Parsing body as JSON for scripting plugins");
params.put("json",om.readValue(readInputStream(msg.getBodyAsStream()),Map.class));
params.put("json", om.readValue(readInputStream(msg.getBodyAsStreamDecoded()), Map.class));
} catch (Exception e) {
log.warn("Can't parse body as JSON", e);
}
}
}

/**
properties does not work in Groovy based Template Interceptor!

Reason: properties is a special built-in property in Groovy. Every Groovy object has a properties property
that returns a Map of all the object's properties.

But it can be accessed in Groovy Interceptor

Decision: Keep it but change examples to use property, even for spel, ..
*/
/*
properties does not work in Groovy based Template Interceptor!
Reason: properties is a special built-in property in Groovy. Every Groovy object has a properties property
that returns a Map of all the object's properties.
But it can be accessed in Groovy Interceptor
Decision: Keep it but change examples to use property, even for spel, ..
*/
params.put("properties", exc.getProperties());

// Also expose properties unter props and property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.regex.*;

import static com.predic8.membrane.core.lang.ExchangeExpression.Language.*;
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;

public class TemplateExchangeExpression extends AbstractExchangeExpression {

Expand Down Expand Up @@ -95,7 +96,7 @@ protected static List<Token> parseTokens(Router router, Language language, Strin
}
String expr = m.group(3);
if (expr != null) {
tokens.add(new Expression(ExchangeExpression.newInstance(router, language, expr)));
tokens.add(new Expression(expression(router, language, expr)));
}
}
log.debug("Tokens: {}", tokens);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,6 @@ private boolean convertToBoolean(Object o) {
}

private Object execute(Exchange exchange, Flow flow) throws IOException {
return JsonPath.read(om.readValue(exchange.getMessage(flow).getBodyAsStream(), Map.class), expression);
return JsonPath.read(om.readValue(exchange.getMessage(flow).getBodyAsStreamDecoded(), Object.class), expression);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.predic8.membrane.core.exchange.*;
import com.predic8.membrane.core.http.*;
import com.predic8.membrane.core.interceptor.Interceptor.*;
import com.predic8.membrane.core.lang.*;
import com.predic8.membrane.core.lang.spel.functions.*;
import com.predic8.membrane.core.lang.spel.spelable.*;
import com.predic8.membrane.core.lang.spel.typeconverters.*;
Expand All @@ -39,7 +40,7 @@ public class SpELExchangeEvaluationContext extends StandardEvaluationContext {

private final Exchange exchange;
private final Message message;
private final SpELBody body; // Is used by SpEL in scripts
private final LazyBody body; // Is used by SpEL in scripts

// Avoid the common plural error
private final SpELLablePropertyAware headers;
Expand Down Expand Up @@ -70,7 +71,7 @@ public SpELExchangeEvaluationContext(Exchange exchange, Flow flow) {
this.exchange = exchange;
this.flow = flow;
this.message = exchange.getMessage(flow);
this.body = new SpELBody(message);
this.body = new LazyBody(message);

pathParam = new SpELPathParameters(exchange);
properties = new SpELProperties(exchange.getProperties());
Expand Down Expand Up @@ -174,7 +175,7 @@ public Message getMessage() {
return message;
}

public SpELBody getBody() { return body; }
public LazyBody getBody() { return body; }

public String getPath() {
return path;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
limitations under the License. */
package com.predic8.membrane.core.lang.spel.typeconverters;

import com.predic8.membrane.core.lang.spel.spelable.*;
import com.predic8.membrane.core.lang.*;
import com.predic8.membrane.core.util.*;
import org.slf4j.*;
import org.springframework.core.convert.converter.*;

public class SpELBodyToStringTypeConverter implements Converter<SpELBody, String> {
public class SpELBodyToStringTypeConverter implements Converter<LazyBody, String> {

private static final Logger log = LoggerFactory.getLogger(SpELBodyToStringTypeConverter.class.getName());

@Override
public String convert(SpELBody body) {
public String convert(LazyBody body) {
try {
return new String(MessageUtil.getContent(body.getMessage()));
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import java.util.*;

import static com.predic8.membrane.core.lang.ExchangeExpression.Language.SPEL;
import static com.predic8.membrane.core.lang.ExchangeExpression.expression;

/**
* @description The api proxy extends the serviceProxy with API related functions like OpenAPI support and path parameters.
Expand Down Expand Up @@ -82,7 +83,7 @@ public void setSpecs(List<OpenAPISpec> specs) {
public void init() {
super.init();
if (test != null && !test.isEmpty()) {
exchangeExpression = ExchangeExpression.newInstance(router, language, test);
exchangeExpression = expression(router, language, test);
}
key = new APIProxyKey(key, exchangeExpression, !specs.isEmpty());
initOpenAPI();
Expand Down
32 changes: 16 additions & 16 deletions core/src/main/java/com/predic8/membrane/core/util/MessageUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,36 +36,36 @@ public class MessageUtil {
saxParserFactory.setValidating(false);
}

public static InputStream getContentAsStream(Message res) throws IOException {
if (res.isGzip()) {
return new GZIPInputStream(res.getBodyAsStream());
public static InputStream getContentAsStream(Message msg) throws IOException {
if (msg.isGzip()) {
return new GZIPInputStream(msg.getBodyAsStream());
}
if (res.isDeflate()) {
return new ByteArrayInputStream(getDecompressedData(res.getBody().getContent()));
if (msg.isDeflate()) {
return new ByteArrayInputStream(getDecompressedData(msg.getBody().getContent()));
}
if (res.isBrotli()) {
return new BrotliInputStream(res.getBodyAsStream());
if (msg.isBrotli()) {
return new BrotliInputStream(msg.getBodyAsStream());
}
return res.getBodyAsStream();
return msg.getBodyAsStream();
}

public static byte[] getContent(Message res) throws Exception {
if (res.isGzip()) {
try (InputStream lInputStream = res.getBodyAsStream();
public static byte[] getContent(Message msg) throws Exception {
if (msg.isGzip()) {
try (InputStream lInputStream = msg.getBodyAsStream();
GZIPInputStream lGZIPInputStream = new GZIPInputStream(lInputStream)) {
return lGZIPInputStream.readAllBytes();
}
}
if (res.isDeflate()) {
return getDecompressedData(res.getBody().getContent());
if (msg.isDeflate()) {
return getDecompressedData(msg.getBody().getContent());
}
if (res.isBrotli()) {
try (InputStream lInputStream = res.getBodyAsStream();
if (msg.isBrotli()) {
try (InputStream lInputStream = msg.getBodyAsStream();
BrotliInputStream lBrotliInputStream = new BrotliInputStream(lInputStream)) {
return lBrotliInputStream.readAllBytes();
}
}
return res.getBody().getContent();
return msg.getBody().getContent();
}

public static Source getSOAPBody(InputStream stream) {
Expand Down
Loading