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 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.Tracer;
|
||||||
import com.alibaba.csp.sentinel.adapter.gateway.zuul.constants.ZuulConstant;
|
import com.alibaba.csp.sentinel.adapter.gateway.zuul.constants.ZuulConstant;
|
||||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||||
|
|
@ -34,11 +34,11 @@ final class SentinelEntryUtils {
|
||||||
static void tryExitFromCurrentContext() {
|
static void tryExitFromCurrentContext() {
|
||||||
RequestContext ctx = RequestContext.getCurrentContext();
|
RequestContext ctx = RequestContext.getCurrentContext();
|
||||||
if (ctx.containsKey(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY)) {
|
if (ctx.containsKey(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY)) {
|
||||||
Deque<AsyncEntry> asyncEntries = (Deque<AsyncEntry>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
Deque<EntryHolder> holders = (Deque<EntryHolder>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||||
AsyncEntry entry;
|
EntryHolder holder;
|
||||||
while (!asyncEntries.isEmpty()) {
|
while (!holders.isEmpty()) {
|
||||||
entry = asyncEntries.pop();
|
holder = holders.pop();
|
||||||
entry.exit();
|
exit(holder);
|
||||||
}
|
}
|
||||||
ctx.remove(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
ctx.remove(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||||
}
|
}
|
||||||
|
|
@ -50,17 +50,22 @@ final class SentinelEntryUtils {
|
||||||
static void tryTraceExceptionThenExitFromCurrentContext(Throwable t) {
|
static void tryTraceExceptionThenExitFromCurrentContext(Throwable t) {
|
||||||
RequestContext ctx = RequestContext.getCurrentContext();
|
RequestContext ctx = RequestContext.getCurrentContext();
|
||||||
if (ctx.containsKey(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY)) {
|
if (ctx.containsKey(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY)) {
|
||||||
Deque<AsyncEntry> asyncEntries = (Deque<AsyncEntry>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
Deque<EntryHolder> holders = (Deque<EntryHolder>) ctx.get(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||||
AsyncEntry entry;
|
EntryHolder holder;
|
||||||
while (!asyncEntries.isEmpty()) {
|
while (!holders.isEmpty()) {
|
||||||
entry = asyncEntries.pop();
|
holder = holders.pop();
|
||||||
Tracer.traceEntry(t, entry);
|
Tracer.traceEntry(t, holder.getEntry());
|
||||||
entry.exit();
|
exit(holder);
|
||||||
}
|
}
|
||||||
ctx.remove(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
ctx.remove(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY);
|
||||||
}
|
}
|
||||||
ContextUtil.exit();
|
ContextUtil.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void exit(EntryHolder holder) {
|
||||||
|
Entry entry = holder.getEntry();
|
||||||
|
entry.exit(1, holder.getParams());
|
||||||
|
}
|
||||||
|
|
||||||
private SentinelEntryUtils() {}
|
private SentinelEntryUtils() {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doSentinelEntry(String resourceName, final int resType, RequestContext requestContext,
|
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,
|
Object[] params = paramParser.parseParameterFor(resourceName, requestContext,
|
||||||
new Predicate<GatewayFlowRule>() {
|
new Predicate<GatewayFlowRule>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -98,8 +98,9 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
AsyncEntry entry = SphU.asyncEntry(resourceName, ResourceTypeConstants.COMMON_API_GATEWAY,
|
AsyncEntry entry = SphU.asyncEntry(resourceName, ResourceTypeConstants.COMMON_API_GATEWAY,
|
||||||
EntryType.IN, params);
|
EntryType.IN, params);
|
||||||
asyncEntries.push(entry);
|
EntryHolder holder = new EntryHolder(entry, params);
|
||||||
|
holders.push(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -108,12 +109,12 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
||||||
String origin = parseOrigin(ctx.getRequest());
|
String origin = parseOrigin(ctx.getRequest());
|
||||||
String routeId = (String)ctx.get(ZuulConstant.PROXY_ID_KEY);
|
String routeId = (String)ctx.get(ZuulConstant.PROXY_ID_KEY);
|
||||||
|
|
||||||
Deque<AsyncEntry> asyncEntries = new ArrayDeque<>();
|
Deque<EntryHolder> holders = new ArrayDeque<>();
|
||||||
String fallBackRoute = routeId;
|
String fallBackRoute = routeId;
|
||||||
try {
|
try {
|
||||||
if (StringUtil.isNotBlank(routeId)) {
|
if (StringUtil.isNotBlank(routeId)) {
|
||||||
ContextUtil.enter(GATEWAY_CONTEXT_ROUTE_PREFIX + routeId, origin);
|
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);
|
Set<String> matchingApis = pickMatchingApiDefinitions(ctx);
|
||||||
|
|
@ -122,7 +123,7 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
||||||
}
|
}
|
||||||
for (String apiName : matchingApis) {
|
for (String apiName : matchingApis) {
|
||||||
fallBackRoute = apiName;
|
fallBackRoute = apiName;
|
||||||
doSentinelEntry(apiName, RESOURCE_MODE_CUSTOM_API_NAME, ctx, asyncEntries);
|
doSentinelEntry(apiName, RESOURCE_MODE_CUSTOM_API_NAME, ctx, holders);
|
||||||
}
|
}
|
||||||
} catch (BlockException ex) {
|
} catch (BlockException ex) {
|
||||||
ZuulBlockFallbackProvider zuulBlockFallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(
|
ZuulBlockFallbackProvider zuulBlockFallbackProvider = ZuulBlockFallbackManager.getFallbackProvider(
|
||||||
|
|
@ -140,8 +141,8 @@ public class SentinelZuulPreFilter extends ZuulFilter {
|
||||||
} finally {
|
} finally {
|
||||||
// We don't exit the entry here. We need to exit the entries in post filter to record Rt correctly.
|
// 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.
|
// So here the entries will be carried in the request context.
|
||||||
if (!asyncEntries.isEmpty()) {
|
if (!holders.isEmpty()) {
|
||||||
ctx.put(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY, asyncEntries);
|
ctx.put(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY, holders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue