diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/instance/Endpoint.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/instance/Endpoint.java index 14219b68..100b1ec5 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/instance/Endpoint.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/instance/Endpoint.java @@ -24,6 +24,7 @@ import com.jd.live.agent.governance.rule.tag.TagCondition; import java.util.List; +import java.util.Set; /** * Represents an endpoint in a distributed system, providing methods to access its properties and match against tag conditions. @@ -204,6 +205,16 @@ default String getGroup() { return getLabel(Constants.LABEL_SERVICE_GROUP, PolicyId.DEFAULT_GROUP); } + /** + * Checks if the live space ID is null or empty. + * + * @return true if the live space ID is null or empty, false otherwise + */ + default boolean isLiveless() { + String spaceId = getLiveSpaceId(); + return spaceId == null || spaceId.isEmpty(); + } + /** * Determines if the live space ID matches the specified live space ID. * @@ -224,6 +235,20 @@ default boolean isUnit(String unit) { return unit != null && unit.equals(getUnit()); } + /** + * Determines if the unit matches the specified units. + * + * @param units The units to match. + * @return true if the unit matches, false otherwise. + */ + default boolean isUnit(Set units) { + if (units == null || units.isEmpty()) { + return false; + } + String unit = getUnit(); + return unit != null && units.contains(unit); + } + /** * Determines if the live space and unit match the specified live space ID and unit. * @@ -235,6 +260,17 @@ default boolean isUnit(String liveSpaceId, String unit) { return isLiveSpace(liveSpaceId) && isUnit(unit); } + /** + * Determines if the live space and unit match the specified live space ID and units. + * + * @param liveSpaceId The live space ID to match. + * @param units The units to match. + * @return true if both the live space ID and unit match, false otherwise. + */ + default boolean isUnit(String liveSpaceId, Set units) { + return isLiveSpace(liveSpaceId) && isUnit(units); + } + /** * Determines if the cell matches the specified cell. * @@ -305,8 +341,9 @@ default boolean isCloud(String cloud) { */ default boolean isGroup(String group) { String label = getGroup(); - if (group == null) { - return PolicyId.DEFAULT_GROUP.equals(label); + // default group + if (group == null || group.isEmpty() || PolicyId.DEFAULT_GROUP.equals(group)) { + return label == null || label.isEmpty() || PolicyId.DEFAULT_GROUP.equals(label); } else { return group.equals(label); } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/CellAction.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/CellAction.java index 463ffeda..21150f7a 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/CellAction.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/CellAction.java @@ -34,6 +34,10 @@ public class CellAction { */ private final String message; + public CellAction(CellActionType type) { + this(type, null); + } + /** * Creates a new CellAction with the specified type and message. * diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/RouteTarget.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/RouteTarget.java index 1f793c5e..6c6269b8 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/RouteTarget.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/RouteTarget.java @@ -147,6 +147,42 @@ public void choose(Function, List> } } + /** + * Filters the list of endpoints based on the provided predicate. + * + * @param predicate The predicate to use for filtering. + * @return The filtered list of endpoints. + */ + public List filtrate(Predicate predicate) { + filter(endpoints, predicate, -1, true); + return endpoints; + } + + /** + * Filters the list of endpoints based on the provided predicate and maximum size. + * + * @param predicate The predicate to use for filtering. + * @param maxSize The maximum size of the list to return. + * @return The filtered list of endpoints. + */ + public List filtrate(Predicate predicate, int maxSize) { + filter(endpoints, predicate, maxSize, true); + return endpoints; + } + + /** + * Filters the list of endpoints based on the provided predicate and maximum size. + * + * @param predicate The predicate to use for filtering. + * @param maxSize The maximum size of the list to return. + * @param nullable Whether a null list is acceptable. + * @return The filtered list of endpoints. + */ + public List filtrate(Predicate predicate, int maxSize, boolean nullable) { + filter(endpoints, predicate, maxSize, nullable); + return endpoints; + } + /** * Filters the list of endpoints based on the provided predicate. * @@ -154,7 +190,7 @@ public void choose(Function, List> * @return The count of endpoints that matched the predicate. */ public int filter(Predicate predicate) { - return filter(predicate, -1, false); + return filter(endpoints, predicate, -1, true); } /** @@ -165,7 +201,7 @@ public int filter(Predicate predicate) { * @return The count of endpoints that matched the predicate. */ public int filter(Predicate predicate, int maxSize) { - return filter(predicate, maxSize, false); + return filter(endpoints, predicate, maxSize, true); } /** @@ -180,6 +216,16 @@ public int filter(Predicate predicate, int maxSize, boolean nullable) return filter(endpoints, predicate, maxSize, nullable); } + /** + * Creates a new list containing elements from the original list that match the given predicate. + * + * @param predicate The predicate to use for filtering. If null, the method returns the original list. + * @return A new list containing the filtered endpoints. If the input list or predicate is null, returns the original list. + */ + public List tryCopy(Predicate predicate) { + return tryCopy(endpoints, predicate, 0); + } + /** * Creates a new list containing elements from the original list that match the given predicate, * up to a specified maximum size. @@ -243,7 +289,11 @@ public static int filter(List endpoints, Predicate 0 || nullable) && writeIndex < size) { - endpoints.subList(writeIndex, size).clear(); + if (writeIndex == 0) { + endpoints.clear(); + } else { + endpoints.subList(writeIndex, size).clear(); + } } return writeIndex; } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/inbound/CellFilter.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/inbound/CellFilter.java index 22eb8df4..22b442f9 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/inbound/CellFilter.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/inbound/CellFilter.java @@ -65,15 +65,19 @@ public void filter(InboundInvocation invocation, I } protected CellAction cellAction(InboundInvocation invocation) { - LiveMetadata liveMetadata = invocation.getLiveMetadata(); - Unit localUnit = liveMetadata.getLocalUnit(); - Cell localCell = liveMetadata.getLocalCell(); - String variable = liveMetadata.getVariable(); - UnitRule unitRule = liveMetadata.getRule(); - if (unitRule == null) { - return new CellAction(CellActionType.FORWARD, null); + LiveMetadata metadata = invocation.getLiveMetadata(); + if (metadata.getLocalSpace() == null) { + // liveless + return new CellAction(CellActionType.FORWARD); } - UnitRoute unitRoute = localUnit == null ? null : unitRule.getUnitRoute(localUnit.getCode()); + UnitRule rule = metadata.getRule(); + if (rule == null) { + return new CellAction(CellActionType.FORWARD); + } + Unit localUnit = metadata.getLocalUnit(); + Cell localCell = metadata.getLocalCell(); + String variable = metadata.getVariable(); + UnitRoute unitRoute = localUnit == null ? null : rule.getUnitRoute(localUnit.getCode()); CellRoute cellRoute = null; if (unitRoute != null) { cellRoute = unitRoute.getCellRouteByVariable(variable); @@ -85,7 +89,7 @@ protected CellAction cellAction(InboundInvocation } if (invocation.isAccessible(localCell) && (cellRoute == null || !cellRoute.isEmpty() && invocation.isAccessible(cellRoute.getAccessMode()))) { - return new CellAction(CellActionType.FORWARD, null); + return new CellAction(CellActionType.FORWARD); } return new CellAction(CellActionType.FAILOVER, invocation.getError(FAILOVER_CELL_NOT_ACCESSIBLE)); } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/inbound/UnitFilter.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/inbound/UnitFilter.java index 027df058..c760a5ad 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/inbound/UnitFilter.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/inbound/UnitFilter.java @@ -78,12 +78,15 @@ private UnitAction unitAction(InboundInvocation in UnitAction action = validateSpace(invocation); if (action != null) { return action; + } else if (metadata.getLocalSpace() == null) { + // liveless + return onLiveless(invocation); } else if (rule == null) { return onMissingRule(invocation); - } else if (unitPolicy == UnitPolicy.NONE) { - return onNone(invocation); } else if (metadata.getLocalUnit() == null) { return onMissingLocalUnit(invocation); + } else if (unitPolicy == UnitPolicy.NONE) { + return onNone(invocation); } else if (unitPolicy == UnitPolicy.CENTER) { return onCenter(invocation); } else if (unitPolicy == UnitPolicy.PREFER_LOCAL_UNIT) { @@ -113,6 +116,16 @@ private UnitAction validateSpace(InboundInvocation return null; } + /** + * Handles the case when no other options are enabled. + * + * @param invocation the inbound invocation + * @return a UnitAction indicating the action to take + */ + private UnitAction onLiveless(InboundInvocation invocation) { + return new UnitAction(UnitActionType.FORWARD); + } + /** * Handles the case when the local unit is missing. * @@ -190,7 +203,7 @@ private UnitAction onPreferLocal(InboundInvocation private UnitAction onCenter(InboundInvocation invocation) { Unit local = invocation.getLiveMetadata().getLocalUnit(); if (local.getType() == UnitType.CENTER) { - return invocation.isAccessible(local) ? new UnitAction(UnitActionType.FORWARD, null) : + return invocation.isAccessible(local) ? new UnitAction(UnitActionType.FORWARD) : new UnitAction(UnitActionType.REJECT, invocation.getError(FAILOVER_UNIT_NOT_ACCESSIBLE)); } else { return new UnitAction(UnitActionType.FAILOVER_CENTER, invocation.getError(REJECT_UNIT_NOT_CENTER)); @@ -205,7 +218,7 @@ private UnitAction onCenter(InboundInvocation invo */ private UnitAction onNone(InboundInvocation invocation) { Unit local = invocation.getLiveMetadata().getLocalUnit(); - return invocation.isAccessible(local) ? new UnitAction(UnitActionType.FORWARD, null) : + return invocation.isAccessible(local) ? new UnitAction(UnitActionType.FORWARD) : new UnitAction(UnitActionType.FAILOVER, invocation.getError(FAILOVER_UNIT_NOT_ACCESSIBLE)); } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/GroupFilter.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/GroupFilter.java index 715fc2a3..9aa292d0 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/GroupFilter.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/GroupFilter.java @@ -41,9 +41,11 @@ public void filter(OutboundInvocation invocation, String group = serviceMetadata.getServiceGroup(); RouteTarget target = invocation.getRouteTarget(); if (group != null && !group.isEmpty()) { - target.filter(endpoint -> endpoint.isGroup(group), -1, true); + // target group + target.filter(endpoint -> endpoint.isGroup(group)); } else if (serviceConfig != null && !serviceConfig.isServiceGroupOpen()) { - target.filter(endpoint -> endpoint.isGroup(null), -1, true); + // default group + target.filter(endpoint -> endpoint.isGroup(null)); } chain.filter(invocation); } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/TagRouteFilter.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/TagRouteFilter.java index 1aaf140a..9fc54e36 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/TagRouteFilter.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/TagRouteFilter.java @@ -73,11 +73,12 @@ public void filter(OutboundInvocation invocation, * @return true if a match is found and the filter is applied, false otherwise. */ private boolean match(OutboundInvocation invocation, RoutePolicy policy) { + RouteTarget target = invocation.getRouteTarget(); for (TagRule rule : policy.getTagRules()) { if (rule.match(invocation)) { TagDestination destination = RandomWeight.choose(rule.getDestinations(), TagDestination::getWeight); if (destination != null) { - invocation.getRouteTarget().filter(destination::match); + target.filter(destination::match); } return true; } diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/UnitFilter.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/UnitFilter.java index 16c956bc..60a17ec7 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/UnitFilter.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/filter/route/UnitFilter.java @@ -20,7 +20,6 @@ import com.jd.live.agent.core.inject.annotation.Injectable; import com.jd.live.agent.governance.config.GovernanceConfig; import com.jd.live.agent.governance.config.ServiceConfig; -import com.jd.live.agent.governance.instance.Endpoint; import com.jd.live.agent.governance.instance.EndpointGroup; import com.jd.live.agent.governance.instance.UnitGroup; import com.jd.live.agent.governance.invoke.OutboundInvocation; @@ -45,7 +44,6 @@ import java.util.concurrent.ThreadLocalRandom; import java.util.function.Predicate; -import static com.jd.live.agent.core.util.StringUtils.isEmpty; import static com.jd.live.agent.governance.invoke.Invocation.*; /** @@ -106,11 +104,23 @@ private RouteTarget route(OutboundInvocation invo * @return The route target indicating the action to be taken (forward, reject, etc.). */ private RouteTarget routeNone(OutboundInvocation invocation) { - RouteTarget target = invocation.getRouteTarget(); - target.filter(e -> isEmpty(e.getLiveSpaceId()), 0, true); - List endpoints = target.getEndpoints(); - UnitRule rule = invocation.getLiveMetadata().getRule(); + LiveMetadata metadata = invocation.getLiveMetadata(); + String targetSpaceId = metadata.getTargetSpaceId(); + UnitRule rule = metadata.getRule(); List routes = rule == null ? null : rule.getUnitRoutes(); + Set units = getAvailableUnits(invocation, routes); + return RouteTarget.forward(invocation.getRouteTarget().filtrate(e -> e.isUnit(targetSpaceId, units) || e.isLiveless())); + + } + + /** + * Gets the available units for the given outbound invocation based on the provided routes. + * + * @param invocation the outbound invocation + * @param routes the list of unit routes + * @return a set of available unit codes, or null if no routes are provided or all units are inaccessible + */ + private Set getAvailableUnits(OutboundInvocation invocation, List routes) { if (routes != null && !routes.isEmpty()) { Set availableUnits = new HashSet<>(routes.size()); for (UnitRoute route : routes) { @@ -118,18 +128,9 @@ private RouteTarget routeNone(OutboundInvocation invocation) { availableUnits.add(route.getCode()); } } - if (availableUnits.isEmpty()) { - return RouteTarget.reject(invocation.getError(REJECT_UNIT_NOT_ACCESSIBLE)); - } else if (routes.size() == 1) { - return RouteTarget.forward(endpoints, routes.get(0)); - } else if (routes.size() != availableUnits.size()) { - RouteTarget.filter(endpoints, e -> availableUnits.contains(e.getUnit())); - if (availableUnits.size() == 1) { - return RouteTarget.forward(endpoints, rule.getUnitRoute(availableUnits.iterator().next())); - } - } + return availableUnits; } - return RouteTarget.forward(endpoints); + return null; } /** @@ -152,8 +153,7 @@ private RouteTarget routeCenter(OutboundInvocation invocation) { } String targetSpaceId = metadata.getTargetSpaceId(); RouteTarget target = invocation.getRouteTarget(); - target.filter(e -> e.isLiveSpace(targetSpaceId), 0, true); - return RouteTarget.forward(target.getEndpoints(), route); + return RouteTarget.forward(target.filtrate(e -> e.isLiveSpace(targetSpaceId)), route); } /** @@ -174,8 +174,7 @@ private RouteTarget routeUnit(OutboundInvocation invocation) { } String targetSpaceId = invocation.getLiveMetadata().getTargetSpaceId(); RouteTarget target = invocation.getRouteTarget(); - target.filter(e -> e.isLiveSpace(targetSpaceId), 0, true); - return RouteTarget.forward(target.getEndpoints(), route); + return RouteTarget.forward(target.filtrate(e -> e.isLiveSpace(targetSpaceId)), route); } /** @@ -186,9 +185,7 @@ private RouteTarget routeUnit(OutboundInvocation invocation) { */ private RouteTarget routeLocal(OutboundInvocation invocation) { String targetSpaceId = invocation.getLiveMetadata().getTargetSpaceId(); - RouteTarget routeTarget = invocation.getRouteTarget(); - routeTarget.filter(e -> e.isLiveSpace(targetSpaceId), 0, true); - EndpointGroup group = new EndpointGroup(routeTarget.getEndpoints()); + EndpointGroup group = new EndpointGroup(invocation.getRouteTarget().filtrate(e -> e.isLiveSpace(targetSpaceId))); Election election = getPreferUnits(invocation, group); List candidates = election.getCandidates(); if (election.isEmpty()) { diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/metadata/parser/LiveMetadataParser.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/metadata/parser/LiveMetadataParser.java index 43f67447..5a71af55 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/metadata/parser/LiveMetadataParser.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/metadata/parser/LiveMetadataParser.java @@ -380,7 +380,13 @@ public OutboundLiveMetadataParser(ServiceRequest request, @Override protected String parseLiveSpaceId() { String result = super.parseLiveSpaceId(); - return result != null && !result.isEmpty() ? result : application.getLocation().getLiveSpaceId(); + if (result == null || result.isEmpty()) { + result = application.getLocation().getLiveSpaceId(); + if (result != null && !result.isEmpty()) { + RequestContext.getOrCreate().setCargo(Constants.LABEL_LIVE_SPACE_ID, result); + } + } + return result; } @Override @@ -392,7 +398,10 @@ protected String parseRuleId(String spaceId) { } else if (spaceId != null) { Location location = application.getLocation(); if (spaceId.equals(location.getLiveSpaceId())) { - return location.getUnitRuleId(); + result = location.getUnitRuleId(); + if (result != null && !result.isEmpty()) { + RequestContext.getOrCreate().setCargo(Constants.LABEL_RULE_ID, result); + } } } return null; diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/response/AbstractHttpResponse.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/response/AbstractHttpResponse.java index 444e0243..c24ac739 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/response/AbstractHttpResponse.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/response/AbstractHttpResponse.java @@ -15,10 +15,9 @@ */ package com.jd.live.agent.governance.response; -import com.jd.live.agent.core.util.cache.LazyObject; +import com.jd.live.agent.core.util.cache.UnsafeLazyObject; import com.jd.live.agent.governance.exception.ErrorPredicate; import com.jd.live.agent.governance.exception.ServiceError; -import com.jd.live.agent.governance.request.Cookie; import java.net.URI; import java.util.List; @@ -44,17 +43,12 @@ public abstract class AbstractHttpResponse extends AbstractServiceResponse /** * Lazily evaluated, parsed cookies from the HTTP request. */ - protected LazyObject>> cookies; - - /** - * Lazily evaluated, parsed query parameters from the HTTP request URL. - */ - protected LazyObject>> queries; + protected UnsafeLazyObject>> cookies; /** * Lazily evaluated HTTP headers from the request. */ - protected LazyObject>> headers; + protected UnsafeLazyObject>> headers; /** * The URI of the HTTP request. @@ -64,17 +58,17 @@ public abstract class AbstractHttpResponse extends AbstractServiceResponse /** * Lazily evaluated port number of the request URI. */ - protected LazyObject port; + protected UnsafeLazyObject port; /** * Lazily evaluated host of the request URI. */ - protected LazyObject host; + protected UnsafeLazyObject host; /** * Lazily evaluated scheme of the request URI. */ - protected LazyObject schema; + protected UnsafeLazyObject schema; /** * Constructs an instance of {@code AbstractHttpResponse} with the original response object. @@ -104,9 +98,9 @@ public AbstractHttpResponse(ServiceError error, ErrorPredicate predicate) { */ public AbstractHttpResponse(T response, ServiceError error, ErrorPredicate predicate) { super(response, error, predicate); - port = new LazyObject<>(this::parsePort); - host = new LazyObject<>(this::parseHost); - schema = new LazyObject<>(this::parseScheme); + port = new UnsafeLazyObject<>(this::parsePort); + host = new UnsafeLazyObject<>(this::parseHost); + schema = new UnsafeLazyObject<>(this::parseScheme); } @Override @@ -144,32 +138,22 @@ public Map> getHeaders() { @Override public String getHeader(String key) { if (key == null) return null; - List values = headers.get().get(key); - return values == null || values.isEmpty() ? null : values.get(0); - } - - @Override - public String getQuery(String key) { - if (key == null) return null; - List values = queries.get().get(key); + Map> headers = getHeaders(); + List values = headers == null ? null : headers.get(key); return values == null || values.isEmpty() ? null : values.get(0); } @Override - public Map> getQueries() { - return queries.get(); - } - - @Override - public Map> getCookies() { - return cookies.get(); + public Map> getCookies() { + return cookies == null ? null : cookies.get(); } @Override public String getCookie(String key) { if (key == null) return null; - List values = cookies.get().get(key); - return values == null || values.isEmpty() ? null : values.get(0).getValue(); + Map> cookies = getCookies(); + List values = cookies == null ? null : cookies.get(key); + return values == null || values.isEmpty() ? null : values.get(0); } /** diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/response/HttpResponse.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/response/HttpResponse.java index 46e739b6..48f44746 100644 --- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/response/HttpResponse.java +++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/response/HttpResponse.java @@ -17,7 +17,6 @@ import com.jd.live.agent.governance.exception.ErrorPolicy; import com.jd.live.agent.governance.policy.service.exception.CodePolicy; -import com.jd.live.agent.governance.request.Cookie; import java.net.URI; import java.util.List; @@ -97,27 +96,12 @@ default String getHeader(String key) { return headers == null || headers.isEmpty() ? null : headers.get(0); } - /** - * Returns all query parameters of the request as a map. - * - * @return A map of query parameter names to their respective list of values. - */ - Map> getQueries(); - - /** - * 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 all cookies of the request as a map. * * @return A map of cookie names to their respective list of cookies. */ - Map> getCookies(); + Map> getCookies(); /** * Returns the value of a specific cookie. diff --git a/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/BlockingClusterResponse.java b/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/BlockingClusterResponse.java index 5fc81f67..bc486b0f 100644 --- a/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/BlockingClusterResponse.java +++ b/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/BlockingClusterResponse.java @@ -19,7 +19,8 @@ import com.jd.live.agent.bootstrap.logger.LoggerFactory; import com.jd.live.agent.core.util.Close; import com.jd.live.agent.core.util.IOUtils; -import com.jd.live.agent.core.util.cache.LazyObject; +import com.jd.live.agent.core.util.cache.UnsafeLazyObject; +import com.jd.live.agent.core.util.http.HttpUtils; import com.jd.live.agent.governance.exception.ErrorPredicate; import com.jd.live.agent.governance.exception.ServiceError; import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; @@ -47,7 +48,8 @@ public class BlockingClusterResponse extends AbstractHttpOutboundResponse(response.getHeaders()); + this.headers = new UnsafeLazyObject<>(response::getHeaders); + this.cookies = new UnsafeLazyObject<>(() -> HttpUtils.parseCookie(HttpHeaders.writableHttpHeaders(response.getHeaders()).get(HttpHeaders.COOKIE))); } public BlockingClusterResponse(ServiceError error, ErrorPredicate predicate) { diff --git a/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/FeignClusterResponse.java b/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/FeignClusterResponse.java index 48aaf825..7d3148b2 100644 --- a/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/FeignClusterResponse.java +++ b/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/FeignClusterResponse.java @@ -19,11 +19,13 @@ import com.jd.live.agent.bootstrap.logger.LoggerFactory; import com.jd.live.agent.core.util.Close; import com.jd.live.agent.core.util.IOUtils; -import com.jd.live.agent.core.util.cache.LazyObject; -import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; +import com.jd.live.agent.core.util.cache.UnsafeLazyObject; +import com.jd.live.agent.core.util.http.HttpUtils; import com.jd.live.agent.governance.exception.ErrorPredicate; import com.jd.live.agent.governance.exception.ServiceError; +import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; import feign.Response; +import org.springframework.http.HttpHeaders; import java.io.InputStream; import java.util.ArrayList; @@ -44,28 +46,14 @@ public class FeignClusterResponse extends AbstractHttpOutboundResponse public FeignClusterResponse(Response response) { super(response); - headers = new LazyObject<>(() -> parserHeader(response)); + this.headers = new UnsafeLazyObject<>(() -> parserHeader(response)); + this.cookies = new UnsafeLazyObject<>(() -> HttpUtils.parseCookie(response.headers().get(HttpHeaders.COOKIE))); } public FeignClusterResponse(ServiceError error, ErrorPredicate predicate) { super(error, predicate); } - private Map> parserHeader(Response response) { - if (response == null || response.headers() == null) { - return null; - } - Map> headers = new HashMap<>(); - response.headers().forEach((k, v) -> { - if (v instanceof List) { - headers.put(k, (List) v); - } else { - headers.put(k, new ArrayList<>(v)); - } - }); - return headers; - } - @Override public String getCode() { return response == null ? null : String.valueOf(response.status()); @@ -99,4 +87,19 @@ public Object getResult() { return body; } + private Map> parserHeader(Response response) { + if (response == null || response.headers() == null) { + return null; + } + Map> headers = new HashMap<>(); + response.headers().forEach((k, v) -> { + if (v instanceof List) { + headers.put(k, (List) v); + } else { + headers.put(k, new ArrayList<>(v)); + } + }); + return headers; + } + } diff --git a/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/ReactiveClusterResponse.java b/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/ReactiveClusterResponse.java index 09371cac..c01746f2 100644 --- a/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/ReactiveClusterResponse.java +++ b/joylive-plugin/joylive-router/joylive-router-springcloud3/src/main/java/com/jd/live/agent/plugin/router/springcloud/v3/response/ReactiveClusterResponse.java @@ -15,9 +15,12 @@ */ package com.jd.live.agent.plugin.router.springcloud.v3.response; +import com.jd.live.agent.core.util.cache.UnsafeLazyObject; +import com.jd.live.agent.core.util.http.HttpUtils; import com.jd.live.agent.governance.exception.ErrorPredicate; import com.jd.live.agent.governance.exception.ServiceError; import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; +import org.springframework.http.ResponseCookie; import org.springframework.web.reactive.function.client.ClientResponse; /** @@ -31,6 +34,8 @@ public class ReactiveClusterResponse extends AbstractHttpOutboundResponse(() -> response.headers().asHttpHeaders()); + this.cookies = new UnsafeLazyObject<>(() -> HttpUtils.parseCookie(response.cookies(), ResponseCookie::getValue)); } public ReactiveClusterResponse(ServiceError error, ErrorPredicate predicate) { diff --git a/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/BlockingClusterResponse.java b/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/BlockingClusterResponse.java index 66773023..c2571208 100644 --- a/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/BlockingClusterResponse.java +++ b/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/BlockingClusterResponse.java @@ -19,7 +19,8 @@ import com.jd.live.agent.bootstrap.logger.LoggerFactory; import com.jd.live.agent.core.util.Close; import com.jd.live.agent.core.util.IOUtils; -import com.jd.live.agent.core.util.cache.LazyObject; +import com.jd.live.agent.core.util.cache.UnsafeLazyObject; +import com.jd.live.agent.core.util.http.HttpUtils; import com.jd.live.agent.governance.exception.ErrorPredicate; import com.jd.live.agent.governance.exception.ServiceError; import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; @@ -47,7 +48,8 @@ public class BlockingClusterResponse extends AbstractHttpOutboundResponse(this.response.getHeaders()); + this.headers = new UnsafeLazyObject<>(response::getHeaders); + this.cookies = new UnsafeLazyObject<>(() -> HttpUtils.parseCookie(HttpHeaders.writableHttpHeaders(response.getHeaders()).get(HttpHeaders.COOKIE))); } public BlockingClusterResponse(ServiceError error, ErrorPredicate predicate) { diff --git a/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/FeignClusterResponse.java b/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/FeignClusterResponse.java index aa2a1cb3..87299a5d 100644 --- a/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/FeignClusterResponse.java +++ b/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/FeignClusterResponse.java @@ -19,11 +19,13 @@ import com.jd.live.agent.bootstrap.logger.LoggerFactory; import com.jd.live.agent.core.util.Close; import com.jd.live.agent.core.util.IOUtils; -import com.jd.live.agent.core.util.cache.LazyObject; -import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; +import com.jd.live.agent.core.util.cache.UnsafeLazyObject; +import com.jd.live.agent.core.util.http.HttpUtils; import com.jd.live.agent.governance.exception.ErrorPredicate; import com.jd.live.agent.governance.exception.ServiceError; +import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; import feign.Response; +import org.springframework.http.HttpHeaders; import java.io.InputStream; import java.util.ArrayList; @@ -44,7 +46,8 @@ public class FeignClusterResponse extends AbstractHttpOutboundResponse public FeignClusterResponse(Response response) { super(response); - headers = new LazyObject<>(() -> parserHeader(response)); + this.headers = new UnsafeLazyObject<>(() -> parserHeader(response)); + this.cookies = new UnsafeLazyObject<>(() -> HttpUtils.parseCookie(response.headers().get(HttpHeaders.COOKIE))); } public FeignClusterResponse(ServiceError error, ErrorPredicate predicate) { diff --git a/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/ReactiveClusterResponse.java b/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/ReactiveClusterResponse.java index 67fb1635..b696120b 100644 --- a/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/ReactiveClusterResponse.java +++ b/joylive-plugin/joylive-router/joylive-router-springcloud4/src/main/java/com/jd/live/agent/plugin/router/springcloud/v4/response/ReactiveClusterResponse.java @@ -15,10 +15,13 @@ */ package com.jd.live.agent.plugin.router.springcloud.v4.response; +import com.jd.live.agent.core.util.cache.UnsafeLazyObject; +import com.jd.live.agent.core.util.http.HttpUtils; import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; import com.jd.live.agent.governance.exception.ErrorPredicate; import com.jd.live.agent.governance.exception.ServiceError; import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseCookie; import org.springframework.web.reactive.function.client.ClientResponse; /** @@ -32,6 +35,8 @@ public class ReactiveClusterResponse extends AbstractHttpOutboundResponse(() -> response.headers().asHttpHeaders()); + this.cookies = new UnsafeLazyObject<>(() -> HttpUtils.parseCookie(response.cookies(), ResponseCookie::getValue)); } public ReactiveClusterResponse(ServiceError error, ErrorPredicate predicate) { diff --git a/joylive-plugin/joylive-router/joylive-router-springgateway3/src/main/java/com/jd/live/agent/plugin/router/springgateway/v3/response/GatewayClusterResponse.java b/joylive-plugin/joylive-router/joylive-router-springgateway3/src/main/java/com/jd/live/agent/plugin/router/springgateway/v3/response/GatewayClusterResponse.java index 5110c87d..e7b949fa 100644 --- a/joylive-plugin/joylive-router/joylive-router-springgateway3/src/main/java/com/jd/live/agent/plugin/router/springgateway/v3/response/GatewayClusterResponse.java +++ b/joylive-plugin/joylive-router/joylive-router-springgateway3/src/main/java/com/jd/live/agent/plugin/router/springgateway/v3/response/GatewayClusterResponse.java @@ -15,10 +15,12 @@ */ package com.jd.live.agent.plugin.router.springgateway.v3.response; -import com.jd.live.agent.core.util.cache.LazyObject; +import com.jd.live.agent.core.util.cache.UnsafeLazyObject; +import com.jd.live.agent.core.util.http.HttpUtils; import com.jd.live.agent.governance.exception.ErrorPredicate; import com.jd.live.agent.governance.exception.ServiceError; import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; +import org.springframework.http.ResponseCookie; import org.springframework.http.server.reactive.ServerHttpResponse; import java.util.function.Supplier; @@ -30,7 +32,7 @@ */ public class GatewayClusterResponse extends AbstractHttpOutboundResponse { - private final LazyObject body; + private final UnsafeLazyObject body; public GatewayClusterResponse(ServerHttpResponse response) { this(response, null); @@ -38,7 +40,9 @@ public GatewayClusterResponse(ServerHttpResponse response) { public GatewayClusterResponse(ServerHttpResponse response, Supplier supplier) { super(response); - this.body = new LazyObject<>(supplier); + this.headers = new UnsafeLazyObject<>(response::getHeaders); + this.cookies = new UnsafeLazyObject<>(() -> HttpUtils.parseCookie(response.getCookies(), ResponseCookie::getValue)); + this.body = new UnsafeLazyObject<>(supplier); } public GatewayClusterResponse(ServiceError error, ErrorPredicate predicate) { diff --git a/joylive-plugin/joylive-router/joylive-router-springgateway4/src/main/java/com/jd/live/agent/plugin/router/springgateway/v4/response/GatewayClusterResponse.java b/joylive-plugin/joylive-router/joylive-router-springgateway4/src/main/java/com/jd/live/agent/plugin/router/springgateway/v4/response/GatewayClusterResponse.java index 555664bf..10e248a5 100644 --- a/joylive-plugin/joylive-router/joylive-router-springgateway4/src/main/java/com/jd/live/agent/plugin/router/springgateway/v4/response/GatewayClusterResponse.java +++ b/joylive-plugin/joylive-router/joylive-router-springgateway4/src/main/java/com/jd/live/agent/plugin/router/springgateway/v4/response/GatewayClusterResponse.java @@ -15,11 +15,13 @@ */ package com.jd.live.agent.plugin.router.springgateway.v4.response; -import com.jd.live.agent.core.util.cache.LazyObject; +import com.jd.live.agent.core.util.cache.UnsafeLazyObject; +import com.jd.live.agent.core.util.http.HttpUtils; import com.jd.live.agent.governance.exception.ErrorPredicate; import com.jd.live.agent.governance.exception.ServiceError; import com.jd.live.agent.governance.response.AbstractHttpResponse.AbstractHttpOutboundResponse; import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseCookie; import org.springframework.http.server.reactive.ServerHttpResponse; import java.util.function.Supplier; @@ -31,7 +33,7 @@ */ public class GatewayClusterResponse extends AbstractHttpOutboundResponse { - private final LazyObject body; + private final UnsafeLazyObject body; public GatewayClusterResponse(ServerHttpResponse response) { this(response, null); @@ -39,7 +41,9 @@ public GatewayClusterResponse(ServerHttpResponse response) { public GatewayClusterResponse(ServerHttpResponse response, Supplier supplier) { super(response); - this.body = new LazyObject<>(supplier); + this.headers = new UnsafeLazyObject<>(response::getHeaders); + this.cookies = new UnsafeLazyObject<>(() -> HttpUtils.parseCookie(response.getCookies(), ResponseCookie::getValue)); + this.body = new UnsafeLazyObject<>(supplier); } public GatewayClusterResponse(ServiceError error, ErrorPredicate predicate) {