Fix the bug that the Zuul adapter does not exit the entry with parameters (#1148)
This commit is contained in:
parent
ff5c010a51
commit
73188b46b7
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 1999-2019 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.alibaba.csp.sentinel.adapter.gateway.zuul.filters;
|
||||
|
||||
import com.alibaba.csp.sentinel.Entry;
|
||||
|
||||
/**
|
||||
* @author wavesZh
|
||||
*/
|
||||
class EntryHolder {
|
||||
|
||||
final private Entry entry;
|
||||
|
||||
final private Object[] params;
|
||||
|
||||
public EntryHolder(Entry entry, Object[] params) {
|
||||
this.entry = entry;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public Entry getEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
public Object[] getParams() {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ package com.alibaba.csp.sentinel.adapter.gateway.zuul.filters;
|
|||
|
||||
import java.util.Deque;
|
||||
|
||||
import com.alibaba.csp.sentinel.AsyncEntry;
|
||||
import com.alibaba.csp.sentinel.Entry;
|
||||
import com.alibaba.csp.sentinel.Tracer;
|
||||
import com.alibaba.csp.sentinel.adapter.gateway.zuul.constants.ZuulConstant;
|
||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||
|
|
@ -34,11 +34,11 @@ final class SentinelEntryUtils {
|
|||
static void tryExitFromCurrentContext() {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
if (ctx.containsKey(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY)) {
|
||||
Deque<AsyncEntry> asyncEntries = (Deque<AsyncEntry>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||
AsyncEntry entry;
|
||||
while (!asyncEntries.isEmpty()) {
|
||||
entry = asyncEntries.pop();
|
||||
entry.exit();
|
||||
Deque<EntryHolder> holders = (Deque<EntryHolder>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||
EntryHolder holder;
|
||||
while (!holders.isEmpty()) {
|
||||
holder = holders.pop();
|
||||
exit(holder);
|
||||
}
|
||||
ctx.remove(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||
}
|
||||
|
|
@ -50,17 +50,22 @@ final class SentinelEntryUtils {
|
|||
static void tryTraceExceptionThenExitFromCurrentContext(Throwable t) {
|
||||
RequestContext ctx = RequestContext.getCurrentContext();
|
||||
if (ctx.containsKey(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY)) {
|
||||
Deque<AsyncEntry> asyncEntries = (Deque<AsyncEntry>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||
AsyncEntry entry;
|
||||
while (!asyncEntries.isEmpty()) {
|
||||
entry = asyncEntries.pop();
|
||||
Tracer.traceEntry(t, entry);
|
||||
entry.exit();
|
||||
Deque<EntryHolder> holders = (Deque<EntryHolder>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||
EntryHolder holder;
|
||||
while (!holders.isEmpty()) {
|
||||
holder = holders.pop();
|
||||
Tracer.traceEntry(t, holder.getEntry());
|
||||
exit(holder);
|
||||
}
|
||||
ctx.remove(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||
}
|
||||
ContextUtil.exit();
|
||||
}
|
||||
|
||||
static void exit(EntryHolder holder) {
|
||||
Entry entry = holder.getEntry();
|
||||
entry.exit(1, holder.getParams());
|
||||
}
|
||||
|
||||
private SentinelEntryUtils() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
|||
}
|
||||
|
||||
private void doSentinelEntry(String resourceName, final int resType, RequestContext requestContext,
|
||||
Deque<AsyncEntry> asyncEntries) throws BlockException {
|
||||
Deque<EntryHolder> holders) throws BlockException {
|
||||
Object[] params = paramParser.parseParameterFor(resourceName, requestContext,
|
||||
new Predicate<GatewayFlowRule>() {
|
||||
@Override
|
||||
|
|
@ -99,7 +99,8 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
|||
});
|
||||
AsyncEntry entry = SphU.asyncEntry(resourceName, ResourceTypeConstants.COMMON_API_GATEWAY,
|
||||
EntryType.IN, params);
|
||||
asyncEntries.push(entry);
|
||||
EntryHolder holder = new EntryHolder(entry, params);
|
||||
holders.push(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -108,12 +109,12 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
|||
String origin = parseOrigin(ctx.getRequest());
|
||||
String routeId = (String)ctx.get(ZuulConstant.PROXY_ID_KEY);
|
||||
|
||||
Deque<AsyncEntry> asyncEntries = new ArrayDeque<>();
|
||||
Deque<EntryHolder> holders = new ArrayDeque<>();
|
||||
String fallBackRoute = routeId;
|
||||
try {
|
||||
if (StringUtil.isNotBlank(routeId)) {
|
||||
ContextUtil.enter(GATEWAY_CONTEXT_ROUTE_PREFIX + routeId, origin);
|
||||
doSentinelEntry(routeId, RESOURCE_MODE_ROUTE_ID, ctx, asyncEntries);
|
||||
doSentinelEntry(routeId, RESOURCE_MODE_ROUTE_ID, ctx, holders);
|
||||
}
|
||||
|
||||
Set<String> matchingApis = pickMatchingApiDefinitions(ctx);
|
||||
|
|
@ -122,7 +123,7 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
|||
}
|
||||
for (String apiName : matchingApis) {
|
||||
fallBackRoute = apiName;
|
||||
doSentinelEntry(apiName, RESOURCE_MODE_CUSTOM_API_NAME, ctx, asyncEntries);
|
||||
doSentinelEntry(apiName, RESOURCE_MODE_CUSTOM_API_NAME, ctx, holders);
|
||||
}
|
||||
} catch (BlockException ex) {
|
||||
ZuulBlockFallbackProvider zuulBlockFallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(
|
||||
|
|
@ -140,8 +141,8 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
|||
} finally {
|
||||
// We don't exit the entry here. We need to exit the entries in post filter to record Rt correctly.
|
||||
// So here the entries will be carried in the request context.
|
||||
if (!asyncEntries.isEmpty()) {
|
||||
ctx.put(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY, asyncEntries);
|
||||
if (!holders.isEmpty()) {
|
||||
ctx.put(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY, holders);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue