@@ -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); | |||||
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); | 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); | |||||
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); | 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); | |||||
asyncEntries.push(entry); | |||||
EntryType.IN, params); | |||||
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()) { | |||||
ctx.put(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY, asyncEntries); | |||||
if (!holders.isEmpty()) { | |||||
ctx.put(ZuulConstant.ZUUL_CTX_SENTINEL_ENTRIES_KEY, holders); | |||||
} | } | ||||
} | } | ||||
return null; | return null; | ||||