下面列出了org.springframework.util.concurrent.CompletableToListenableFutureAdapter#org.apache.servicecomb.core.Invocation 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx httpServletRequestEx) {
if (isInvocationNeedValidate(invocation.getMicroserviceName(), invocation.getOperationName())) {
String token = httpServletRequestEx.getHeader(AUTHORIZATION);
if (StringUtils.isNotEmpty(token)) {
String userName = template
.getForObject("cse://" + USER_SERVICE_NAME + "/validate?token={token}", String.class, token);
if (StringUtils.isNotEmpty(userName)) {
//Add header
invocation.getContext().put(EDGE_AUTHENTICATION_NAME, userName);
} else {
return Response
.failResp(new InvocationException(Status.UNAUTHORIZED, "authentication failed, invalid token"));
}
} else {
return Response.failResp(
new InvocationException(Status.UNAUTHORIZED, "authentication failed, missing AUTHORIZATION header"));
}
}
return null;
}
/**
* pass through headers
*
* @param invocation
* @param httpServletRequestEx
* @return
*/
@Override
public Response afterReceiveRequest(Invocation invocation,
HttpServletRequestEx httpServletRequestEx) {
if (!isHaveHeadersRule()) {
return null;
}
if (!RouterRuleCache.isServerContainRule(invocation.getMicroserviceName())) {
return null;
}
if (loadHeaders()) {
Map<String, String> headerMap = getHeaderMap(httpServletRequestEx);
try {
invocation.addContext(ROUTER_HEADER, JsonUtils.OBJ_MAPPER.writeValueAsString(headerMap));
} catch (JsonProcessingException e) {
LOGGER.error("canary context serialization failed");
}
}
return null;
}
public ServiceCombServer chooseServer(Invocation invocation) {
List<ServiceCombServer> servers = invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
int serversCount = servers.size();
for (ServerListFilterExt filterExt : filters) {
if(!filterExt.enabled()) {
continue;
}
servers = filterExt.getFilteredListOfServers(servers, invocation);
if (servers.isEmpty() && serversCount > 0) {
LOGGER.warn("There are not servers exist after filtered by {}.", filterExt.getClass());
break;
}
}
ServiceCombServer server = rule.choose(servers, invocation);
if (null == server) {
return null;
}
ServiceCombServerStats serverStats = ServiceCombLoadBalancerStats.INSTANCE.getServiceCombServerStats(server);
if (serverStats.isIsolated()) {
LOGGER.info("The Service {}'s instance {} has been isolated for a while, give a single test opportunity.",
invocation.getMicroserviceName(),
server.getInstance().getInstanceId());
}
return server;
}
@Test
public void testConstructProvider() {
Invocation invocation = Mockito.mock(Invocation.class);
Mockito.when(invocation.getOperationMeta()).thenReturn(Mockito.mock(OperationMeta.class));
Mockito.when(invocation.getOperationMeta().getMicroserviceQualifiedName()).thenReturn("test1");
HystrixCommandProperties.Setter setter = HystrixCommandProperties.Setter()
.withRequestCacheEnabled(true)
.withRequestLogEnabled(false);
BizkeeperCommand bizkeeperCommand = new ProviderBizkeeperCommand("groupname", invocation,
HystrixObservableCommand.Setter
.withGroupKey(CommandKey.toHystrixCommandGroupKey("groupname", invocation))
.andCommandKey(CommandKey.toHystrixCommandKey("groupname", invocation))
.andCommandPropertiesDefaults(setter));
Observable<Response> response = bizkeeperCommand.construct();
Assert.assertNotNull(response);
}
@Override
public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx requestEx) {
EncryptContext encryptContext = (EncryptContext) invocation.getHandlerContext().get(EdgeConst.ENCRYPT_CONTEXT);
if (encryptContext == null) {
return null;
}
Hcr hcr = encryptContext.getHcr();
// signature for query and form
List<String> names = Collections.list(requestEx.getParameterNames());
names.sort(Comparator.naturalOrder());
Hasher hasher = Hashing.sha256().newHasher();
hasher.putString(hcr.getSignatureKey(), StandardCharsets.UTF_8);
for (String name : names) {
hasher.putString(name, StandardCharsets.UTF_8);
hasher.putString(requestEx.getParameter(name), StandardCharsets.UTF_8);
}
LOGGER.info("afterReceiveRequest signature: {}", hasher.hash().toString());
return null;
}
@Test
public void testLoadBalancerFullOperationWithoutException() {
List<ServiceCombServer> newServers = new ArrayList<>();
ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
Invocation invocation = Mockito.mock(Invocation.class);
MicroserviceInstance microserviceInstance = Mockito.mock(MicroserviceInstance.class);
newServers.add(server);
when(invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST)).thenReturn(newServers);
when(server.getInstance()).thenReturn(microserviceInstance);
when(microserviceInstance.getInstanceId()).thenReturn("123456");
LoadBalancer loadBalancer = new LoadBalancer(rule, "test");
loadBalancer.chooseServer(invocation);
when(rule.choose(newServers, invocation)).thenReturn(server);
Assert.assertEquals(server, loadBalancer.chooseServer(invocation));
Assert.assertNotNull(loadBalancer.getLoadBalancerStats());
Assert.assertEquals("test", loadBalancer.getMicroServiceName());
}
@Test
public void testGetCommandPropertiesCacheKey() {
assertNotNull(HystrixPropertiesStrategyExt.getInstance());
HystrixPropertiesStrategyExt hps = HystrixPropertiesStrategyExt.getInstance();
HystrixCommandKey commandKey = Mockito.mock(HystrixCommandKey.class);
Invocation invocation = Mockito.mock(Invocation.class);
Mockito.when(invocation.getOperationMeta()).thenReturn(Mockito.mock(OperationMeta.class));
Mockito.when(invocation.getOperationMeta().getMicroserviceName()).thenReturn("testqualify");
HystrixCommandProperties.Setter setter = HystrixCommandProperties.Setter()
.withRequestCacheEnabled(true)
.withRequestLogEnabled(false)
.withFallbackIsolationSemaphoreMaxConcurrentRequests(
Configuration.INSTANCE.getFallbackMaxConcurrentRequests("groupname",
"testing",
invocation.getOperationMeta().getMicroserviceQualifiedName()));
String str1 = hps.getCommandPropertiesCacheKey(commandKey, setter);
Assert.assertNull(str1);
}
@Before
public void initStrBuilder() {
accessLogEvent = new ServerAccessLogEvent();
routingContext = Mockito.mock(RoutingContext.class);
finishEvent = Mockito.mock(InvocationFinishEvent.class);
serverRequest = Mockito.mock(HttpServerRequest.class);
socketAddress = Mockito.mock(SocketAddress.class);
invocation = Mockito.mock(Invocation.class);
restClientRequest = Mockito.mock(RestClientRequestImpl.class);
clientRequest = Mockito.mock(HttpClientRequest.class);
connection = Mockito.mock(HttpConnection.class);
Map<String, Object> handlerMap = new HashMap<>();
handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
when(finishEvent.getInvocation()).thenReturn(invocation);
when(invocation.getHandlerContext()).thenReturn(handlerMap);
accessLogEvent.setRoutingContext(routingContext);
strBuilder = new StringBuilder();
}
@Override
public Response afterReceiveResponse(Invocation invocation, HttpServletResponseEx responseEx) {
Response response = extractResponse(invocation, responseEx);
for (String headerName : responseEx.getHeaderNames()) {
if (headerName.equals(":status")) {
continue;
}
Collection<String> headerValues = responseEx.getHeaders(headerName);
for (String headerValue : headerValues) {
response.getHeaders().addHeader(headerName, headerValue);
}
}
return response;
}
@Test
public void testBenchmarkRobin() {
// less than 0.001ms
RoundRobinRuleExt rule = new RoundRobinRuleExt();
LoadBalancer loadBalancer = new LoadBalancer(rule, "testService");
List<ServiceCombServer> servers = new ArrayList<>();
Invocation invocation = Mockito.mock(Invocation.class);
for (int i = 0; i < 100; i++) {
ServiceCombServer server = Mockito.mock(ServiceCombServer.class);
Mockito.when(server.toString()).thenReturn("server " + i);
servers.add(server);
loadBalancer.getLoadBalancerStats().noteResponseTime(server, 2);
}
long begin = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
rule.choose(servers, invocation);
}
long taken = System.currentTimeMillis() - begin;
System.out.println("taken " + taken);
Assert.assertEquals("actual token " + taken, taken < 10 * 5, true); // 5 * times make slow machine happy
}
@Override
public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx requestEx) {
EncryptContext encryptContext = (EncryptContext) invocation.getHandlerContext().get(EdgeConst.ENCRYPT_CONTEXT);
if (encryptContext == null) {
return null;
}
Hcr hcr = encryptContext.getHcr();
String encodedBody = requestEx.getParameter("body");
if (encodedBody == null) {
return null;
}
encodedBody = encodedBody.substring(hcr.getBodyKey().length());
try {
Map<String, String[]> decodedBody = RestObjectMapperFactory.getRestObjectMapper()
.readValue(encodedBody, bodyType);
requestEx.getParameterMap().putAll(decodedBody);
} catch (Throwable e) {
// should be a meaning exception response
return Response.producerFailResp(e);
}
return null;
}
@Override
public void injectFault(Invocation invocation, FaultParam faultParam, AsyncResponse asynResponse) {
if (!shouldDelay(invocation, faultParam, asynResponse)) {
asynResponse.success(SUCCESS_RESPONSE);
return;
}
LOGGER.debug("Fault injection: delay is added for the request by fault inject handler");
long delay = FaultInjectionUtil.getFaultInjectionConfig(invocation,
"delay.fixedDelay");
if (delay == FaultInjectionConst.FAULT_INJECTION_DEFAULT_VALUE) {
LOGGER.debug("Fault injection: delay is not configured");
asynResponse.success(SUCCESS_RESPONSE);
return;
}
executeDelay(faultParam, asynResponse, delay);
}
@SuppressWarnings({"try", "unused"})
@Override
public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
Span span = tracingDelegate.createSpan(invocation);
try (SpanInScope scope = tracer.tracer().withSpanInScope(span)) {
LOGGER.debug("{}: Generated tracing span for {}",
tracingDelegate.name(),
invocation.getOperationName());
invocation.next(onResponse(invocation, asyncResp, span));
} catch (Exception e) {
LOGGER.debug("{}: Failed invocation on {}",
tracingDelegate.name(),
invocation.getOperationName(),
e);
tracingDelegate.onResponse(span, null, e);
throw e;
}
}
@Before
public void initStrBuilder() {
accessLogEvent = new ServerAccessLogEvent();
routingContext = Mockito.mock(RoutingContext.class);
finishEvent = Mockito.mock(InvocationFinishEvent.class);
serverRequest = Mockito.mock(HttpServerRequest.class);
socketAddress = Mockito.mock(SocketAddress.class);
invocation = Mockito.mock(Invocation.class);
restClientRequest = Mockito.mock(RestClientRequestImpl.class);
clientRequest = Mockito.mock(HttpClientRequest.class);
connection = Mockito.mock(HttpConnection.class);
Map<String, Object> handlerMap = new HashMap<>();
handlerMap.put(RestConst.INVOCATION_HANDLER_REQUESTCLIENT, restClientRequest);
when(finishEvent.getInvocation()).thenReturn(invocation);
when(invocation.getHandlerContext()).thenReturn(handlerMap);
accessLogEvent.setRoutingContext(routingContext);
strBuilder = new StringBuilder();
}
@Before
public void setUp() throws Exception {
ServiceManager.INSTANCE.boot();
invocationInterceptor = new ProducerOperationHandlerInterceptor();
PowerMockito.mock(Invocation.class);
when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
when(endpoint.getAddress()).thenReturn("0.0.0.0:7777");
when(invocation.getEndpoint()).thenReturn(endpoint);
when(invocation.getMicroserviceQualifiedName()).thenReturn("productorTest");
when(operationMeta.getOperationPath()).thenReturn("/bmi");
when(invocation.getOperationMeta()).thenReturn(operationMeta);
when(invocation.getStatus()).thenReturn(statusType);
when(statusType.getStatusCode()).thenReturn(200);
when(method.getName()).thenReturn("producer");
when(invocation.getInvocationType()).thenReturn(InvocationType.PRODUCER);
Config.Agent.SERVICE_NAME = "serviceComnTestCases-APP";
allArguments = new Object[] {invocation};
argumentsType = new Class[] {};
swaggerArguments = new Class[] {};
}
@Override
public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception {
if (invocation.getHandlerIndex() > 0) {
// handlerIndex > 0, which means this handler is executed in handler chain.
// As this flow control logic has been executed in advance, this time it should be ignored.
invocation.next(asyncResp);
return;
}
// The real executing position of this handler is no longer in handler chain, but in AbstractRestInvocation.
// Therefore, the Invocation#next() method should not be called below.
if (!Config.INSTANCE.isProviderEnabled()) {
return;
}
String microserviceName = invocation.getContext(Const.SRC_MICROSERVICE);
QpsController qpsController =
StringUtils.isEmpty(microserviceName)
? qpsControllerMgr.getGlobalQpsController()
: qpsControllerMgr.getOrCreate(microserviceName, invocation);
isLimitNewRequest(qpsController, asyncResp);
}
private void initConsumerRequestCodec(Invocation invocation, Message requestMessage, ProtoMapper mapper) {
if (ProtoUtils.isWrapArguments(requestMessage)) {
requestRootSerializer = new RequestRootSerializer(
mapper.createRootSerializer(requestMessage, Object.class), true, false);
} else {
if (invocation.getOperationMeta().getSwaggerOperation().getParameters().isEmpty()) {
requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage, Object.class),
false, false);
} else if (invocation.getOperationMeta().getSwaggerOperation().getParameters().size() == 1) {
requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage,
Object.class), false, true);
} else {
throw new IllegalStateException(
"unexpected operation definition " + invocation.getOperationMeta().getMicroserviceQualifiedName());
}
}
}
public Response doInvoke(Invocation invocation, SwaggerProducerOperation producerOperation) {
Response response;
try {
invocation.onBusinessMethodStart();
Object[] args = invocation.toProducerArguments();
for (ProducerInvokeExtension producerInvokeExtension : producerOperation.getProducerInvokeExtenstionList()) {
producerInvokeExtension.beforeMethodInvoke(invocation, producerOperation, args);
}
Object result = producerOperation.getProducerMethod().invoke(producerOperation.getProducerInstance(), args);
response = producerOperation.getResponseMapper().mapResponse(invocation.getStatus(), result);
invocation.onBusinessMethodFinish();
invocation.onBusinessFinish();
} catch (Throwable e) {
if (shouldPrintErrorLog(e)) {
invocation.getTraceIdLogger().error(LOGGER, "unexpected error {},",
invocation.getInvocationQualifiedName(), e);
}
invocation.onBusinessMethodFinish();
invocation.onBusinessFinish();
response = processException(invocation, e);
}
return response;
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
Invocation invocation = (Invocation) allArguments[0];
AbstractSpan span = ContextManager.activeSpan();
int statusCode = invocation.getStatus().getStatusCode();
if (statusCode >= 400) {
span.errorOccurred();
Tags.STATUS_CODE.set(span, Integer.toString(statusCode));
}
ContextManager.stopSpan();
return ret;
}
private Settings createSettings(Invocation invocation) {
Settings settings = new Settings();
settings.errorThresholdPercentage = Configuration.INSTANCE
.getErrorThresholdPercentage(invocation.getMicroserviceName());
settings.singleTestTime = Configuration.INSTANCE.getSingleTestTime(invocation.getMicroserviceName());
settings.enableRequestThreshold = Configuration.INSTANCE
.getEnableRequestThreshold(invocation.getMicroserviceName());
settings.continuousFailureThreshold = Configuration.INSTANCE
.getContinuousFailureThreshold(invocation.getMicroserviceName());
settings.minIsolationTime = Configuration.INSTANCE
.getMinIsolationTime(invocation.getMicroserviceName());
return settings;
}
@Override
@SuppressWarnings("unchecked")
public void beforeSendRequest(Invocation invocation, HttpServletRequestEx requestEx) {
RestClientRequestImpl restClientRequest = (RestClientRequestImpl) invocation.getHandlerContext()
.get(RestConst.INVOCATION_HANDLER_REQUESTCLIENT);
OperationMeta operationMeta = invocation.getOperationMeta();
RestOperationMeta swaggerRestOperation = operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
try {
RestCodec.argsToRest(invocation.getSwaggerArguments(), swaggerRestOperation,
restClientRequest);
requestEx.setBodyBuffer(restClientRequest.getBodyBuffer());
} catch (Throwable e) {
throw ExceptionFactory.convertConsumerException(e);
}
}
@Override
public CompletableFuture<Void> beforeSendResponseAsync(Invocation invocation, HttpServletResponseEx responseEx) {
Response response = (Response) responseEx.getAttribute(RestConst.INVOCATION_HANDLER_RESPONSE);
ProduceProcessor produceProcessor =
(ProduceProcessor) responseEx.getAttribute(RestConst.INVOCATION_HANDLER_PROCESSOR);
Object body = response.getResult();
if (response.isFailed()) {
body = ((InvocationException) body).getErrorData();
}
if (null != invocation && isDownloadFileResponseType(invocation, response)) {
return responseEx.sendPart(PartUtils.getSinglePart(null, body));
}
responseEx.setContentType(produceProcessor.getName() + "; charset=utf-8");
CompletableFuture<Void> future = new CompletableFuture<>();
try (BufferOutputStream output = new BufferOutputStream(Unpooled.compositeBuffer())) {
produceProcessor.encodeResponse(output, body);
responseEx.setBodyBuffer(output.getBuffer());
future.complete(null);
} catch (Throwable e) {
future.completeExceptionally(ExceptionFactory.convertProducerException(e));
}
return future;
}
@Before
public void setUp() throws Exception {
ConfigUtil.installDynamicConfig();
invocation = Mockito.mock(Invocation.class);
asyncResp = Mockito.mock(AsyncResponse.class);
Mockito.when(invocation.getContext(Const.AUTH_TOKEN)).thenReturn("testtoken");
}
@SuppressWarnings({"try", "unused"})
@Override
public CompletableFuture<Response> onFilter(Invocation invocation, FilterNode nextNode) {
ZipkinTracingDelegate tracing = collectTracing(invocation);
Span span = tracing.createSpan(invocation);
try (SpanInScope scope = tracing.tracer().tracer().withSpanInScope(span)) {
return nextNode.onFilter(invocation)
.whenComplete((response, exception) -> tracing.onResponse(span, response, Exceptions.unwrap(exception)));
}
}
@Override
protected BizkeeperCommand createBizkeeperCommand(Invocation invocation) {
HystrixCommandProperties.Setter setter = HystrixCommandProperties.Setter()
.withRequestCacheEnabled(false)
.withRequestLogEnabled(false);
setCommonProperties(invocation, setter);
BizkeeperCommand command = new ProviderBizkeeperCommand(groupname, invocation,
HystrixObservableCommand.Setter
.withGroupKey(CommandKey.toHystrixCommandGroupKey(groupname, invocation))
.andCommandKey(CommandKey.toHystrixCommandKey(groupname, invocation))
.andCommandPropertiesDefaults(setter));
return command;
}
@Override
public ServiceCombServer choose(List<ServiceCombServer> servers, Invocation invocation) {
if (servers.isEmpty()) {
return null;
}
int index = Math.abs(counter.getAndIncrement()) % servers.size();
return servers.get(index);
}
private Invocation mockInvocation(String operation, InvocationType invocationType) {
OperationMeta operationMeta;
boolean isConsumer;
Invocation invocation = Mockito.mock(Invocation.class);
InvocationRuntimeType invocationRuntimeType;
if (InvocationType.CONSUMER == invocationType) {
operationMeta = consumerSchemaMeta.getOperations().get(operation);
isConsumer = true;
Mockito.when(invocation.getSchemaMeta()).thenReturn(consumerSchemaMeta);
invocationRuntimeType = operationMeta.buildBaseConsumerRuntimeType();
} else {
operationMeta = providerSchemaMeta.getOperations().get(operation);
isConsumer = false;
Mockito.when(invocation.getSchemaMeta()).thenReturn(providerSchemaMeta);
invocationRuntimeType = operationMeta.buildBaseProviderRuntimeType();
}
MicroserviceMeta microserviceMeta = operationMeta.getMicroserviceMeta();
Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);
Mockito.when(invocation.getInvocationRuntimeType())
.thenReturn(invocationRuntimeType);
Mockito.when(invocation.findResponseType(200))
.thenReturn(invocationRuntimeType.findResponseType(200));
Mockito.when(invocation.getInvocationType()).thenReturn(invocationType);
Mockito.when(invocation.getMicroserviceMeta()).thenReturn(microserviceMeta);
Mockito.when(invocation.isConsumer()).thenReturn(isConsumer);
return invocation;
}
@Override
public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx requestEx) {
// String signature = SignatureUtils.genSignature(requestEx);
// String clientSignature = requestEx.getHeader("signature");
// LOGGER.debug("check request signature, client: {}, server: {}.", clientSignature, signature);
// if (!signature.equals(clientSignature)) {
// LOGGER.error("check request signature failed: {}", invocation.getInvocationQualifiedName());
// return Response
// .create(Status.UNAUTHORIZED, "check request signature failed: " + invocation.getInvocationQualifiedName());
// }
return null;
}
@Test
public void testGlobalQpsControl(final @Injectable Invocation invocation,
final @Injectable AsyncResponse asyncResp) throws Exception {
new Expectations() {
{
invocation.getHandlerIndex();
result = 0;
invocation.getContext(Const.SRC_MICROSERVICE);
result = "test";
invocation.getOperationMeta();
result = QpsControllerManagerTest.getMockOperationMeta("pojo", "server", "opr");
invocation.getSchemaId();
result = "server";
asyncResp.producerFail((Throwable) any);
result = new RuntimeException("test error");
}
};
ProviderQpsFlowControlHandler gHandler = new ProviderQpsFlowControlHandler();
gHandler.handle(invocation, asyncResp);
ArchaiusUtils.setProperty(Config.PROVIDER_LIMIT_KEY_GLOBAL, 3);
expectedException.expect(RuntimeException.class);
expectedException.expectMessage("test error");
gHandler.handle(invocation, asyncResp);
gHandler.handle(invocation, asyncResp);
}
@Before
public void setUp() {
ArchaiusUtils.resetConfig();
handler = new FaultInjectionHandler();
invocation = Mockito.mock(Invocation.class);
asyncResp = Mockito.mock(AsyncResponse.class);
operationMeta = Mockito.mock(OperationMeta.class);
transport = Mockito.mock(Transport.class);
MockitoAnnotations.initMocks(this);
}