diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/interceptor/AbstractInterceptor.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/interceptor/AbstractInterceptor.java
index 11a701fc..4664a2dc 100644
--- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/interceptor/AbstractInterceptor.java
+++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/interceptor/AbstractInterceptor.java
@@ -24,12 +24,20 @@
import com.jd.live.agent.governance.invoke.OutboundInvocation;
import com.jd.live.agent.governance.invoke.OutboundInvocation.HttpOutboundInvocation;
import com.jd.live.agent.governance.invoke.filter.*;
+import com.jd.live.agent.governance.invoke.retry.Retrier;
+import com.jd.live.agent.governance.invoke.retry.RetrierFactory;
+import com.jd.live.agent.governance.policy.service.ServicePolicy;
+import com.jd.live.agent.governance.policy.service.retry.RetryPolicy;
import com.jd.live.agent.governance.request.HttpRequest.HttpInboundRequest;
import com.jd.live.agent.governance.request.HttpRequest.HttpOutboundRequest;
import com.jd.live.agent.governance.request.ServiceRequest.InboundRequest;
import com.jd.live.agent.governance.request.ServiceRequest.OutboundRequest;
+import com.jd.live.agent.governance.response.Response;
+import java.lang.reflect.Method;
import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
/**
* AbstractInterceptor is the base class for all interceptors within the framework.
@@ -117,15 +125,18 @@ public static abstract class AbstractOutboundInterceptor retrierFactories;
+
/**
* Constructs a new AbstractOutboundInterceptor with the given InvocationContext and outbound filters.
*
- * @param context the InvocationContext for the current invocation
- * @param filters a list of OutboundFilter instances to be applied to the outbound request
+ * @param context the InvocationContext for the current invocation
+ * @param filters a list of OutboundFilter instances to be applied to the outbound request
*/
- public AbstractOutboundInterceptor(InvocationContext context, List filters) {
+ public AbstractOutboundInterceptor(InvocationContext context, List filters, Map retrierFactories) {
super(context);
this.outboundFilters = filters == null ? new OutboundFilter[0] : filters.toArray(new OutboundFilter[0]);
+ this.retrierFactories = retrierFactories;
}
/**
@@ -157,6 +168,30 @@ protected O process(R request) {
*/
protected abstract void process(O invocation);
+ /**
+ * Create a retry supplier
+ *
+ * @param target The object on which the method is called.
+ * @param method The method being called.
+ * @param allArguments All parameters of the method.
+ * @param result The result of the method call.
+ * @return Returns a supplier for retry logic.
+ */
+ protected abstract Supplier createRetrySupplier(Object target, Method method, Object[] allArguments, Object result);
+
+ protected Response tryRetry(O invocation, Response response, Supplier retrySupplier) {
+ ServicePolicy servicePolicy = invocation == null ? null : invocation.getServiceMetadata().getServicePolicy();
+ RetryPolicy retryPolicy = servicePolicy == null ? null : servicePolicy.getRetryPolicy();
+ if (retryPolicy != null && retrierFactories != null) {
+ RetrierFactory retrierFactory = retrierFactories.get(retryPolicy.getType());
+ Retrier retrier = retrierFactory == null ? null : retrierFactory.get(retryPolicy);
+ if (retrier != null && retrier.isRetryable(response)) {
+ return retrier.execute(retrySupplier);
+ }
+ }
+ return null;
+ }
+
}
/**
@@ -176,8 +211,8 @@ public static abstract class AbstractRouteInterceptor filters) {
super(context);
@@ -199,8 +234,8 @@ protected O routing(R request) {
/**
* Initiates the routing process for the outbound request by creating an OutboundInvocation and providing a list of candidate endpoints.
*
- * @param request the outbound request to be routed
- * @param instances a list of Endpoint instances to be considered during routing
+ * @param request the outbound request to be routed
+ * @param instances a list of Endpoint instances to be considered during routing
* @return the resulting OutboundInvocation after initiating the routing process
*/
protected O routing(R request, List extends Endpoint> instances) {
@@ -230,8 +265,8 @@ protected O routing(R request, List extends Endpoint> instances) {
* Creates a new OutboundInvocation for the given outbound request and initializes it with a list of Endpoint instances.
* This method can be overridden by concrete subclasses if additional initialization is required.
*
- * @param request the outbound request for which to create an OutboundInvocation
- * @param instances a list of Endpoint instances to be associated with the OutboundInvocation
+ * @param request the outbound request for which to create an OutboundInvocation
+ * @param instances a list of Endpoint instances to be associated with the OutboundInvocation
* @return a new OutboundInvocation instance with the specified Endpoint instances
*/
protected O createOutlet(R request, List extends Endpoint> instances) {
@@ -252,8 +287,8 @@ public static abstract class AbstractHttpInboundInterceptor filters) {
super(context, filters);
@@ -283,11 +318,11 @@ public static abstract class AbstractHttpOutboundInterceptor filters) {
- super(context, filters);
+ public AbstractHttpOutboundInterceptor(InvocationContext context, List filters, Map retrierFactories) {
+ super(context, filters, retrierFactories);
}
@Override
@@ -368,9 +403,9 @@ public static abstract class AbstractGatewayInterceptor inboundFilters, List routeFilters) {
super(context);
diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/retry/Retrier.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/retry/Retrier.java
index c59413b3..09593407 100644
--- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/retry/Retrier.java
+++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/invoke/retry/Retrier.java
@@ -16,6 +16,7 @@
package com.jd.live.agent.governance.invoke.retry;
import com.jd.live.agent.governance.policy.service.retry.RetryPolicy;
+import com.jd.live.agent.governance.response.Response;
import java.util.function.Supplier;
@@ -26,6 +27,14 @@
*/
public interface Retrier {
+ /**
+ * Determine whether to retry
+ *
+ * @param response Response
+ * @return true: retry, false: no need to retry
+ */
+ boolean isRetryable(Response response);
+
/**
* Execute retry logic
*
@@ -33,7 +42,7 @@ public interface Retrier {
* @param Response type
* @return Response
*/
- T execute(Supplier supplier);
+ T execute(Supplier supplier);
/**
* Get failover policy
diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/policy/PolicyId.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/policy/PolicyId.java
index fb57ffe2..974c3534 100644
--- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/policy/PolicyId.java
+++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/policy/PolicyId.java
@@ -120,7 +120,9 @@ protected Map supplementTag() {
/**
* Supplements the existing tag map with additional key-value pairs.
*
- * This method takes a variable number of string arguments representing key-value pairs of tags to be added to the current tag map. It creates a new map containing all the entries of the original tag map, if it exists, and then adds the new key-value pairs to it.
+ * This method takes a variable number of string arguments representing key-value pairs of tags to be added to the current tag map.
+ * It creates a new map containing all the entries of the original tag map, if it exists,
+ * and then adds the new key-value pairs to it.
*
* If the number of key-value pairs provided is not an even number, the last provided value will be ignored.
*
diff --git a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/policy/service/retry/RetryPolicy.java b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/policy/service/retry/RetryPolicy.java
index a246c1d6..54a0f410 100644
--- a/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/policy/service/retry/RetryPolicy.java
+++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/policy/service/retry/RetryPolicy.java
@@ -49,6 +49,11 @@ public class RetryPolicy extends PolicyId implements PolicyInheritWithId retryableStatusCodes = new HashSet<>(Arrays.asList(500, 502, 503));
+ private Set retryableStatusCodes = new HashSet<>(Arrays.asList("500", "502", "503"));
/**
* A collection of retryable exception class names.
@@ -82,6 +87,9 @@ public void supplement(RetryPolicy source) {
if (source == null) {
return;
}
+ if (type == null) {
+ type = source.type;
+ }
if (retry == null) {
retry = source.retry;
}
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 eb15de2f..b969f52b 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
@@ -148,7 +148,6 @@ interface HttpInboundRequest extends HttpRequest, InboundRequest {
* This interface represents HTTP requests that are sent by a service.
*
*
- * @author Zhiguo.Chen
* @since 1.0.0
*/
interface HttpOutboundRequest extends HttpRequest, OutboundRequest {
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
new file mode 100644
index 00000000..ad6a906f
--- /dev/null
+++ b/joylive-core/joylive-governance-api/src/main/java/com/jd/live/agent/governance/response/AbstractHttpResponse.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright © ${year} ${owner} (${email})
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.jd.live.agent.governance.response;
+
+import com.jd.live.agent.core.util.cache.LazyObject;
+import com.jd.live.agent.governance.request.Cookie;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * AbstractHttpResponse
+ *
+ * @since 1.0.0
+ */
+public abstract class AbstractHttpResponse extends AbstractServiceResponse implements HttpResponse {
+
+ /**
+ * Key for the "Host" header in HTTP requests.
+ */
+ protected static final String HEAD_HOST_KEY = "Host";
+
+ /**
+ * Key for the "serviceGroup" header in HTTP requests.
+ */
+ protected static final String HEAD_GROUP_KEY = "serviceGroup";
+
+ /**
+ * Lazily evaluated, parsed cookies from the HTTP request.
+ */
+ protected LazyObject