All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tencent.polaris.circuitbreak.client.api.DefaultInvokeHandler Maven / Gradle / Ivy

/*
 * Tencent is pleased to support the open source community by making Polaris available.
 *
 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
 *
 * Licensed under the BSD 3-Clause License (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://opensource.org/licenses/BSD-3-Clause
 *
 * 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.tencent.polaris.circuitbreak.client.api;

import com.tencent.polaris.api.plugin.circuitbreaker.ResourceStat;
import com.tencent.polaris.api.plugin.circuitbreaker.entity.MethodResource;
import com.tencent.polaris.api.plugin.circuitbreaker.entity.Resource;
import com.tencent.polaris.api.plugin.circuitbreaker.entity.ServiceResource;
import com.tencent.polaris.api.pojo.RetStatus;
import com.tencent.polaris.api.utils.StringUtils;
import com.tencent.polaris.circuitbreak.api.CircuitBreakAPI;
import com.tencent.polaris.circuitbreak.api.InvokeHandler;
import com.tencent.polaris.circuitbreak.api.pojo.CheckResult;
import com.tencent.polaris.circuitbreak.api.pojo.InvokeContext;
import com.tencent.polaris.circuitbreak.api.pojo.ResultToErrorCode;
import com.tencent.polaris.circuitbreak.client.exception.CallAbortedException;

public class DefaultInvokeHandler implements InvokeHandler {

	private final CircuitBreakAPI circuitBreakAPI;

	private final InvokeContext.RequestContext requestContext;

	public DefaultInvokeHandler(InvokeContext.RequestContext requestContext, CircuitBreakAPI circuitBreakAPI) {
		this.requestContext = requestContext;
		this.circuitBreakAPI = circuitBreakAPI;
	}

	@Override
	public void acquirePermission() {
		CheckResult check = commonCheck(requestContext);
		if (check != null){
			throw new CallAbortedException(check.getRuleName(), check.getFallbackInfo());
		}
	}

	@Override
	public void onSuccess(InvokeContext.ResponseContext responseContext) {
		long delay = responseContext.getDurationUnit().toMillis(responseContext.getDuration());
		ResultToErrorCode resultToErrorCode = requestContext.getResultToErrorCode();
		int code = 0;
		RetStatus retStatus = RetStatus.RetUnknown;
		if (null != resultToErrorCode) {
			code = resultToErrorCode.onSuccess(responseContext.getResult());
		}
		commonReport(requestContext, delay, code, retStatus);
	}

	@Override
	public void onError(InvokeContext.ResponseContext responseContext) {
		long delay = responseContext.getDurationUnit().toMillis(responseContext.getDuration());
		ResultToErrorCode resultToErrorCode = requestContext.getResultToErrorCode();
		int code = -1;
		RetStatus retStatus = RetStatus.RetUnknown;
		if (null != resultToErrorCode) {
			code = resultToErrorCode.onError(responseContext.getError());
		}
		if (responseContext.getError() instanceof CallAbortedException) {
			retStatus = RetStatus.RetReject;
		}
		commonReport(requestContext, delay, code, retStatus);
	}

	private CheckResult commonCheck(InvokeContext.RequestContext requestContext) {
		// check service
		Resource svcResource = new ServiceResource(requestContext.getService(),
				requestContext.getSourceService());
		CheckResult check = circuitBreakAPI.check(svcResource);
		if (!check.isPass()) {
			return check;
		}
		// check method
		if (StringUtils.isNotBlank(requestContext.getMethod())) {
			Resource methodResource = new MethodResource(requestContext.getService(),
					requestContext.getMethod(), requestContext.getSourceService());
			check = circuitBreakAPI.check(methodResource);
			if (!check.isPass()) {
				return check;
			}
		}
		return null;
	}

	private void commonReport(InvokeContext.RequestContext requestContext, long delayMills, int code, RetStatus retStatus) {
		// report service
		Resource svcResource = new ServiceResource(requestContext.getService(),
				requestContext.getSourceService());
		ResourceStat resourceStat = new ResourceStat(svcResource, code, delayMills, retStatus);
		circuitBreakAPI.report(resourceStat);
		// report method
		if (StringUtils.isNotBlank(requestContext.getMethod())) {
			Resource methodResource = new MethodResource(requestContext.getService(),
					requestContext.getMethod(), requestContext.getSourceService());
			resourceStat = new ResourceStat(methodResource, code, delayMills, retStatus);
			circuitBreakAPI.report(resourceStat);
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy