diff --git a/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/util/type/ValuePath.java b/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/util/type/ValuePath.java index 379b59c2..17406a5d 100644 --- a/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/util/type/ValuePath.java +++ b/joylive-core/joylive-core-api/src/main/java/com/jd/live/agent/core/util/type/ValuePath.java @@ -21,6 +21,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; import static com.jd.live.agent.core.util.type.TypeScanner.UNTIL_OBJECT; @@ -31,6 +32,8 @@ */ public class ValuePath implements ObjectGetter { + private static final Map VALUE_PATHS = new ConcurrentHashMap<>(); + @Getter protected final String path; @@ -59,6 +62,16 @@ public ValuePath(String path, Predicate predicate) { this.paths = parse(path); } + /** + * Creates a new ValuePath instance with the specified path. + * + * @param path the path to the value + * @return a new ValuePath instance + */ + public static ValuePath of(String path) { + return VALUE_PATHS.computeIfAbsent(path, ValuePath::new); + } + @SuppressWarnings("unchecked") @Override public Object get(Object target) { diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/AbstractTagMatcher.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/AbstractTagMatcher.java index b63e31d6..3171082f 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/AbstractTagMatcher.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/AbstractTagMatcher.java @@ -15,7 +15,7 @@ */ package com.jd.live.agent.governance.invoke.matcher; -import com.jd.live.agent.governance.request.Request; +import com.jd.live.agent.governance.request.ServiceRequest; import com.jd.live.agent.governance.rule.tag.TagCondition; import java.util.List; @@ -33,7 +33,7 @@ public abstract class AbstractTagMatcher implements TagMatcher { * @return true if the condition matches the request, false otherwise. */ @Override - public boolean match(TagCondition condition, Request request) { + public boolean match(TagCondition condition, ServiceRequest request) { return condition.match(getValues(condition, request)); } @@ -44,5 +44,5 @@ public boolean match(TagCondition condition, Request request) { * @param request The request. * @return The value list to be matched. */ - protected abstract List getValues(TagCondition condition, Request request); + protected abstract List getValues(TagCondition condition, ServiceRequest request); } \ No newline at end of file diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/TagMatcher.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/TagMatcher.java index 4dc6d59a..d62fcbc4 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/TagMatcher.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/TagMatcher.java @@ -16,7 +16,7 @@ package com.jd.live.agent.governance.invoke.matcher; import com.jd.live.agent.core.extension.annotation.Extensible; -import com.jd.live.agent.governance.request.Request; +import com.jd.live.agent.governance.request.ServiceRequest; import com.jd.live.agent.governance.rule.tag.TagCondition; /** @@ -37,6 +37,6 @@ public interface TagMatcher { * @param request The {@code Request} object containing the data to be evaluated against the condition. * @return {@code true} if the request meets the tag condition; {@code false} otherwise. */ - boolean match(TagCondition condition, Request request); + boolean match(TagCondition condition, ServiceRequest request); } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/cookie/CookieTagMatcher.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/cookie/CookieTagMatcher.java index 8df3e169..17533b71 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/cookie/CookieTagMatcher.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/cookie/CookieTagMatcher.java @@ -17,8 +17,7 @@ import com.jd.live.agent.core.extension.annotation.Extension; import com.jd.live.agent.governance.invoke.matcher.AbstractTagMatcher; -import com.jd.live.agent.governance.request.HttpRequest; -import com.jd.live.agent.governance.request.Request; +import com.jd.live.agent.governance.request.ServiceRequest; import com.jd.live.agent.governance.rule.tag.TagCondition; import java.util.List; @@ -33,7 +32,7 @@ public class CookieTagMatcher extends AbstractTagMatcher { @Override - protected List getValues(TagCondition condition, Request request) { - return request instanceof HttpRequest ? ((HttpRequest) request).getCookies(condition.getKey()) : null; + protected List getValues(TagCondition condition, ServiceRequest request) { + return request.getCookies(condition.getKey()); } } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/header/HeaderTagMatcher.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/header/HeaderTagMatcher.java index 41d2ca45..ed69cfff 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/header/HeaderTagMatcher.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/header/HeaderTagMatcher.java @@ -16,12 +16,9 @@ package com.jd.live.agent.governance.invoke.matcher.header; import com.jd.live.agent.core.extension.annotation.Extension; -import com.jd.live.agent.core.util.tag.Label; import com.jd.live.agent.governance.invoke.matcher.AbstractTagMatcher; import com.jd.live.agent.governance.invoke.matcher.TagMatcher; -import com.jd.live.agent.governance.request.HttpRequest; -import com.jd.live.agent.governance.request.Request; -import com.jd.live.agent.governance.request.RpcRequest; +import com.jd.live.agent.governance.request.ServiceRequest; import com.jd.live.agent.governance.rule.tag.TagCondition; import java.util.List; @@ -36,16 +33,7 @@ public class HeaderTagMatcher extends AbstractTagMatcher { @Override - protected List getValues(TagCondition condition, Request request) { - List values = null; - if (request instanceof HttpRequest) { - values = ((HttpRequest) request).getHeaders(condition.getKey()); - } else if (request instanceof RpcRequest) { - Object value = ((RpcRequest) request).getAttachment(condition.getKey()); - if (value instanceof String) { - values = Label.parseValue((String) value); - } - } - return values; + protected List getValues(TagCondition condition, ServiceRequest request) { + return request.getHeaders(condition.getKey()); } } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/query/QueryTagMatcher.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/query/QueryTagMatcher.java index 2d68ea48..a5185a9a 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/query/QueryTagMatcher.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/query/QueryTagMatcher.java @@ -18,8 +18,7 @@ import com.jd.live.agent.core.extension.annotation.Extension; import com.jd.live.agent.governance.invoke.matcher.AbstractTagMatcher; import com.jd.live.agent.governance.invoke.matcher.TagMatcher; -import com.jd.live.agent.governance.request.HttpRequest; -import com.jd.live.agent.governance.request.Request; +import com.jd.live.agent.governance.request.ServiceRequest; import com.jd.live.agent.governance.rule.tag.TagCondition; import java.util.List; @@ -34,7 +33,7 @@ public class QueryTagMatcher extends AbstractTagMatcher { @Override - protected List getValues(TagCondition condition, Request request) { - return request instanceof HttpRequest ? ((HttpRequest) request).getQueries(condition.getKey()) : null; + protected List getValues(TagCondition condition, ServiceRequest request) { + return request.getQueries(condition.getKey()); } } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/ClientIpTagProvider.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/ClientIpTagProvider.java index 9ed3b839..2235c9ca 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/ClientIpTagProvider.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/ClientIpTagProvider.java @@ -16,17 +16,20 @@ package com.jd.live.agent.governance.invoke.matcher.system; import com.jd.live.agent.core.extension.annotation.Extension; -import com.jd.live.agent.governance.request.Request; +import com.jd.live.agent.governance.request.ServiceRequest; import com.jd.live.agent.governance.request.ServiceRequest.InboundRequest; import java.util.Collections; import java.util.List; +/** + * A system tag provider that provides the client IP address as a tag value. + */ @Extension(value = "clientIp") public class ClientIpTagProvider implements SystemTagProvider { @Override - public List getValues(Request request, String key) { + public List getValues(ServiceRequest request) { return request instanceof InboundRequest ? Collections.singletonList(((InboundRequest) request).getClientIp()) : null; } } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/ConsumerTagProvider.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/ConsumerTagProvider.java index febcd87d..18abcfba 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/ConsumerTagProvider.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/ConsumerTagProvider.java @@ -19,15 +19,18 @@ import com.jd.live.agent.core.extension.annotation.Extension; import com.jd.live.agent.governance.context.RequestContext; import com.jd.live.agent.governance.context.bag.Cargo; -import com.jd.live.agent.governance.request.Request; +import com.jd.live.agent.governance.request.ServiceRequest; import java.util.List; +/** + * A system tag provider that provides the consumer information as tag values. + */ @Extension(value = "consumer") public class ConsumerTagProvider implements SystemTagProvider { @Override - public List getValues(Request request, String key) { + public List getValues(ServiceRequest request) { Cargo cargo = RequestContext.getCargo(Constants.LABEL_SERVICE_CONSUMER); return cargo == null ? null : cargo.getValues(); } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/SystemTagMatcher.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/SystemTagMatcher.java index d4903d97..7fd3262d 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/SystemTagMatcher.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/SystemTagMatcher.java @@ -19,12 +19,15 @@ import com.jd.live.agent.core.inject.annotation.Inject; import com.jd.live.agent.core.inject.annotation.Injectable; import com.jd.live.agent.governance.invoke.matcher.AbstractTagMatcher; -import com.jd.live.agent.governance.request.Request; +import com.jd.live.agent.governance.request.ServiceRequest; import com.jd.live.agent.governance.rule.tag.TagCondition; import java.util.List; import java.util.Map; +/** + * A system tag matcher that matches tags based on system-defined criteria. + */ @Injectable @Extension(value = "system") public class SystemTagMatcher extends AbstractTagMatcher { @@ -33,8 +36,8 @@ public class SystemTagMatcher extends AbstractTagMatcher { private Map providers; @Override - protected List getValues(TagCondition condition, Request request) { + protected List getValues(TagCondition condition, ServiceRequest request) { SystemTagProvider provider = providers.get(condition.getKey()); - return provider == null ? null : provider.getValues(request, condition.getKey()); + return provider == null ? null : provider.getValues(request); } } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/SystemTagProvider.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/SystemTagProvider.java index 16ff61d9..d131b279 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/SystemTagProvider.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/matcher/system/SystemTagProvider.java @@ -16,7 +16,7 @@ package com.jd.live.agent.governance.invoke.matcher.system; import com.jd.live.agent.core.extension.annotation.Extensible; -import com.jd.live.agent.governance.request.Request; +import com.jd.live.agent.governance.request.ServiceRequest; import java.util.List; @@ -30,8 +30,7 @@ public interface SystemTagProvider { * Retrieves values associated with the given key from the request. * * @param request The request object. - * @param key The key for which values are to be retrieved. * @return A list of values associated with the key. */ - List getValues(Request request, String key); + List getValues(ServiceRequest request); } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/HttpRequest.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/HttpRequest.java index b1908588..c2612eec 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/HttpRequest.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/HttpRequest.java @@ -80,23 +80,13 @@ public interface HttpRequest extends ServiceRequest { */ Map> getHeaders(); - /** - * Returns the values of a specific header. - * - * @param key The name of the header. - * @return A list of values for the specified header, or null if the header does not exist. - */ + @Override default List getHeaders(String key) { Map> result = getHeaders(); return result == null || key == null ? null : result.get(key); } - /** - * Returns the first value of a specific header. - * - * @param key The name of the header. - * @return The first value of the specified header, or null if the header does not exist or has no values. - */ + @Override default String getHeader(String key) { List headers = getHeaders(key); return headers == null || headers.isEmpty() ? null : headers.get(0); @@ -109,23 +99,13 @@ default String getHeader(String key) { */ Map> getQueries(); - /** - * Returns the values of a specific query. - * - * @param key The name of the query. - * @return A list of values for the specified query, or null if the query does not exist. - */ + @Override default List getQueries(String key) { Map> result = getQueries(); return result == null || key == null ? null : result.get(key); } - /** - * Returns the value of a specific query parameter. - * - * @param key The name of the query parameter. - * @return The value of the specified query parameter, or null if it does not exist. - */ + @Override default String getQuery(String key) { List queries = getQueries(key); return queries == null || queries.isEmpty() ? null : queries.get(0); @@ -138,29 +118,18 @@ default String getQuery(String key) { */ Map> getCookies(); - /** - * Returns the values of a specific cookie. - * - * @param key The name of the header. - * @return A list of values for the specified cookie, or null if the cookie does not exist. - */ + @Override default List getCookies(String key) { Map> result = getCookies(); return result == null || key == null ? null : result.get(key); } - /** - * Returns the value of a specific cookie. - * - * @param key The name of the cookie. - * @return The value of the specified cookie, or null if it does not exist. - */ + @Override default String getCookie(String key) { List cookies = getCookies(key); return cookies == null || cookies.isEmpty() ? null : cookies.get(0); } - /** * Defines an interface for inbound HTTP requests. *

diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/RpcRequest.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/RpcRequest.java index 6997362e..5fa02ddd 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/RpcRequest.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/RpcRequest.java @@ -15,6 +15,16 @@ */ package com.jd.live.agent.governance.request; +import com.jd.live.agent.core.util.tag.Label; +import com.jd.live.agent.core.util.type.ValuePath; +import com.jd.live.agent.governance.context.RequestContext; +import com.jd.live.agent.governance.context.bag.Cargo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * Defines an interface for RPC (Remote Procedure Call) requests, extending the {@link ServiceRequest} interface. *

@@ -26,13 +36,6 @@ */ public interface RpcRequest extends ServiceRequest { - /** - * Retrieves the arguments passed with the RPC request. - * - * @return An array of {@link Object} containing the arguments. - */ - Object[] getArguments(); - /** * Retrieves a specific argument from the RPC request based on its index. * @@ -44,11 +47,71 @@ default Object getArgument(int index) { return arguments == null || index < 0 || index >= arguments.length ? null : arguments[index]; } + @Override + default List getQueries(String key) { + List result = new ArrayList<>(); + String query = getQuery(key); + if (query == null) { + return result; + } else { + result.add(query); + return result; + } + } + + @Override + default String getQuery(String key) { + if (key == null || key.isEmpty()) { + return null; + } + Object[] arguments = getArguments(); + if (arguments == null || arguments.length == 0) { + return null; + } + Map params = new HashMap<>(arguments.length); + for (int i = 0; i < arguments.length; i++) { + params.put("arg" + i, arguments[i]); + } + + Object value = ValuePath.of(key).get(params); + return value == null ? null : value.toString(); + } + + @Override + default List getHeaders(String key) { + String header = getHeader(key); + if (header == null) { + return null; + } else { + return Label.parseValue(header); + } + } + @Override default String getHeader(String key) { - return (String) getAttachment(key); + Object attachment = getAttachment(key); + return attachment == null ? null : attachment.toString(); } + @Override + default List getCookies(String key) { + Cargo cargo = RequestContext.getCargo(key); + return cargo == null ? null : cargo.getValues(); + } + + @Override + default String getCookie(String key) { + Cargo cargo = RequestContext.getCargo(key); + return cargo == null ? null : cargo.getFirstValue(); + } + + /** + * Retrieves the arguments passed with the RPC request. + * + * @return An array of {@link Object} containing the arguments. + */ + Object[] getArguments(); + /** * Retrieves an attachment by its key. * diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/ServiceRequest.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/ServiceRequest.java index a3f097f8..86eb6475 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/ServiceRequest.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/request/ServiceRequest.java @@ -20,6 +20,7 @@ import com.jd.live.agent.governance.policy.live.FaultType; import com.jd.live.agent.governance.policy.service.circuitbreak.DegradeConfig; +import java.util.List; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.function.Function; @@ -63,6 +64,14 @@ public interface ServiceRequest extends Request { */ String getPath(); + /** + * Returns the values of a specific header. + * + * @param key The name of the header. + * @return A list of values for the specified header, or null if the header does not exist. + */ + List getHeaders(String key); + /** * Returns the values of a specific header. * @@ -71,6 +80,38 @@ public interface ServiceRequest extends Request { */ String getHeader(String key); + /** + * Returns the value of a specific query parameter. + * + * @param key The name of the query parameter. + * @return The value of the specified query parameter, or null if it does not exist. + */ + String getQuery(String key); + + /** + * Returns the values of a specific query. + * + * @param key The name of the query. + * @return A list of values for the specified query, or null if the query does not exist. + */ + List getQueries(String key); + + /** + * Returns the values of a specific cookie. + * + * @param key The name of the header. + * @return A list of values for the specified cookie, or null if the cookie does not exist. + */ + List getCookies(String key); + + /** + * Returns the value of a specific cookie. + * + * @param key The name of the cookie. + * @return The value of the specified cookie, or null if it does not exist. + */ + String getCookie(String key); + /** * Returns the start time. * diff --git a/joylive-core/joylive-governance-api/src/main/resources/META-INF/services/com.jd.live.agent.governance.invoke.matcher.TagMatcher b/joylive-core/joylive-governance-api/src/main/resources/META-INF/services/com.jd.live.agent.governance.invoke.matcher.TagMatcher index 670ceb2c..612ce1c7 100644 --- a/joylive-core/joylive-governance-api/src/main/resources/META-INF/services/com.jd.live.agent.governance.invoke.matcher.TagMatcher +++ b/joylive-core/joylive-governance-api/src/main/resources/META-INF/services/com.jd.live.agent.governance.invoke.matcher.TagMatcher @@ -1,3 +1,4 @@ com.jd.live.agent.governance.invoke.matcher.header.HeaderTagMatcher com.jd.live.agent.governance.invoke.matcher.cookie.CookieTagMatcher -com.jd.live.agent.governance.invoke.matcher.query.QueryTagMatcher \ No newline at end of file +com.jd.live.agent.governance.invoke.matcher.query.QueryTagMatcher +com.jd.live.agent.governance.invoke.matcher.system.SystemTagMatcher \ No newline at end of file