net.hasor.rsf.address.AddressCacheResult Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2008-2009 the original author or authors.
*
* 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
*
* http://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 net.hasor.rsf.address;
import net.hasor.rsf.InterAddress;
import net.hasor.rsf.address.route.rule.ArgsKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.Map.Entry;
/**
* 路由计算结果缓存
* 接口级 方法级 参数级
* @version : 2015年3月29日
* @author 赵永春 ([email protected])
*/
class AddressCacheResult {
protected static Logger logger = LoggerFactory.getLogger(AddressCacheResult.class);
private volatile CacheResult cacheResultRef;
private final AddressPool addressPool;
//
public AddressCacheResult(AddressPool addressPool) {
this.addressPool = Objects.requireNonNull(addressPool);
}
//
/**从全部地址中计算执行动态计算并缓存计算结果.*/
public List getAddressList(String serviceID, String methodName, Object[] args) {
if (this.cacheResultRef == null) {
logger.warn("getAddressList fail. resultRef is null.");
return null;
}
List result = null;
CacheResult resultRef = this.cacheResultRef;
//
//1.获取参数级地址列表
ArgsKey argsKeyBuilder = addressPool.getArgsKey();
if (argsKeyBuilder != null) {
Map>> methodList = resultRef.argsLevel.get(serviceID);
if (methodList != null) {
Map> cacheList = methodList.get(methodName);
if (cacheList != null) {
String key = argsKeyBuilder.eval(serviceID, methodName, args);
if (key != null) {
result = cacheList.get(key);
}
}
}
}
//
//2.获取方法级地址列表
if (result == null) {
Map> cacheList = resultRef.methodLevel.get(serviceID);
if (cacheList != null) {
result = cacheList.get(methodName);
}
}
//
//3.获取服务级别地址列表
if (result == null) {
result = resultRef.serviceLevel.get(serviceID);
}
return result;
}
/**重置缓存结果*/
public void reset() {
this.logger.info("reset addressCache.");
Map> allAddress = this.addressPool.allServiceAddressToSnapshot();
Set allServiceIDs = this.addressPool.getBucketNames();
CacheResult cacheResultRef = new CacheResult();
//
for (String serviceID : allServiceIDs) {
/*计算使用的地址列表(所有可用的/本单元的/本地网络的)*/
List all = allAddress.get(serviceID);
List unit = allAddress.get(serviceID + "_UNIT");
List allStrList = convertToStr(all);
RuleRef refRule = this.addressPool.getRefRule(serviceID);
//
//1.计算缓存的服务接口级,地址列表
List serviceLevelResult = null;
if (!refRule.getServiceLevel().isEnable()) {
logger.debug("eval routeScript [ServiceLevel], service {} route undefined.", serviceID);
} else {
List serviceLevelResultStr = evalServiceLevel(serviceID, refRule, allStrList);
if (serviceLevelResultStr != null && !serviceLevelResultStr.isEmpty()) {
serviceLevelResult = convertToAddress(all, serviceLevelResultStr);
}
}
if (serviceLevelResult == null || serviceLevelResult.isEmpty()) {
serviceLevelResult = unit;/*如果计算结果为空,就使用单元化的地址 -> 如果单元化策略没有配置则单元化地址就是全量地址。*/
}
cacheResultRef.serviceLevel.put(serviceID, serviceLevelResult);
//
//2.计算缓存的服务方法级,地址列表
if (!refRule.getMethodLevel().isEnable()) {
logger.debug("eval routeScript [MethodLevel], service {} route undefined.", serviceID);
} else {
Map> methodLevelResultStr = evalMethodLevel(serviceID, refRule, allStrList);
if (methodLevelResultStr != null && !methodLevelResultStr.isEmpty()) {
Map> methodLevelResult = convertToAddressMethod(all, methodLevelResultStr);
cacheResultRef.methodLevel.put(serviceID, methodLevelResult);/*保存计算结果*/
}
}
//
//3.计算缓存的服务参数级,地址列表
if (!refRule.getArgsLevel().isEnable()) {
logger.debug("eval routeScript [ArgsLevel], service {} route undefined.", serviceID);
} else if (addressPool.getArgsKey() == null) {
logger.error("argsKeyBuilder is null , evalArgsLevel failed.");
} else {
Map>> argsLevelResultStr = evalArgsLevel(serviceID, refRule, allStrList);
if (argsLevelResultStr != null && !argsLevelResultStr.isEmpty()) {
Map>> argsLevelResult = convertToAddressArgs(all, argsLevelResultStr);
cacheResultRef.argsLevel.put(serviceID, argsLevelResult);/*保存计算结果*/
}
}
//
}
logger.debug("switch cacheResultRef.");
this.cacheResultRef = cacheResultRef;
}
//
//
//
private static Map>> convertToAddressArgs(List all, Map>> argsLevelResult) {
Map>> result = new HashMap<>();
for (Entry>> ent : argsLevelResult.entrySet()) {
String key = ent.getKey();
Map> val = convertToAddressMethod(all, ent.getValue());
if (val != null && !val.isEmpty()) {
result.put(key, val);
}
}
return result;
}
private static Map> convertToAddressMethod(List all, Map> methodLevelResult) {
Map> result = new HashMap<>();
for (Entry> ent : methodLevelResult.entrySet()) {
String key = ent.getKey();
List val = convertToAddress(all, ent.getValue());
if (val != null && !val.isEmpty()) {
result.put(key, val);
}
}
return result;
}
private static List convertToAddress(List all, List serviceLevelResult) {
List result = new ArrayList<>(serviceLevelResult.size());
for (String evalResult : serviceLevelResult) {
for (InterAddress address : all) {
try {
if (address.equalsHost(evalResult)) {
result.add(address);
}
} catch (Exception e) {
logger.info(e.getMessage(), e);
}
}
}
return result;
}
private static List convertToStr(List all) {
List result = new ArrayList<>();
for (InterAddress address : all) {
try {
result.add(address.getHostPort());
} catch (Exception e) {
logger.info(e.getMessage(), e);
}
}
return result;
}
/** 脚本说明:
* 入参:
* serviceID (String)
* allAddress (List<String>)
* 返回值
* List<String>
*
* 样例:
* def List<String> evalAddress(String serviceID,List<String> allAddress) {
* //
* //[RSF]sorg.mytest.FooFacse-1.0.0 ,组别:RSF,接口:sorg.mytest.FooFacse,版本:1.0.0
* if ( serviceID == "[RSF]sorg.mytest.FooFacse-1.0.0" ) {
* return [
* "192.168.1.2:8000",
* "192.168.1.2:8001",
* "192.168.1.3:8000"
* ]
* }
* return null
* }
* */
private List evalServiceLevel(String serviceID, RuleRef refRule, List all) {
InnerRuleEngine serviceLevel = refRule.getServiceLevel();
if (serviceLevel == null) {
return null;
}
try {
Object result = serviceLevel.runRule(serviceID, all);
return (List) result;
} catch (Throwable e) {
logger.error("evalServiceLevel error ,message = " + e.getMessage(), e);
return null;
}
}
//
/** 脚本说明:
* 入参:
* serviceID (String)
* allAddress (List<String>)
* 返回值
* Map<String,List<String>>
*
* 样例:
* def Map<String,List<String>> evalAddress(String serviceID,List<String> allAddress) {
* //
* //[RSF]sorg.mytest.FooFacse-1.0.0 ---- Group=RSF, Name=sorg.mytest.FooFacse, Version=1.0.0
* if ( serviceID == "[RSF]sorg.mytest.FooFacse-1.0.0" ) {
* return [
* "println":[
* "192.168.1.2:8000",
* "192.168.1.2:8001",
* "192.168.1.3:8000"
* ],
* "sayEcho":[
* "192.168.1.2:8000",
* ],
* "testUserTag":[
* "192.168.1.2:8000",
* "192.168.1.3:8000"
* ]
* ]
* }
* return null
* }
* */
private Map> evalMethodLevel(String serviceID, RuleRef refRule, List all) {
InnerRuleEngine methodLevel = refRule.getMethodLevel();
if (methodLevel == null) {
return null;
}
try {
Object result = methodLevel.runRule(serviceID, all);
return (Map>) result;
} catch (Throwable e) {
logger.error("evalMethodLevel error ,message = " + e.getMessage(), e);
return null;
}
}
//
/** 脚本说明:
* 入参:
* serviceID (String)
* allAddress (List<String>)
* 返回值
* Map<String, Map<String, List<String>>>
*
* 样例:
* def Map<String, Map<String, List<String>>> evalAddress(String serviceID,List<String> allAddress) {
* //
* //[RSF]sorg.mytest.FooFacse-1.0.0 ---- Group=RSF, Name=sorg.mytest.FooFacse, Version=1.0.0
* if ( serviceID == "[RSF]sorg.mytest.FooFacse-1.0.0" ) {
* return [
* "sayEcho":[
* "sayTo_etc1":[
* "202.168.17.10:8000",
* "202.168.17.11:8000"
* ],
* "sayTo_etc2":[
* "192.168.137.10:8000",
* "192.168.137.11:8000"
* ]],
* "testUserTag":[
* "server_3":[
* "192.168.1.3:8000"
* ],
* "server_4":[
* "192.168.1.4:8000"
* ]
* ]
* ]
* }
* return null
* }
* */
private Map>> evalArgsLevel(String serviceID, RuleRef refRule, List all) {
InnerRuleEngine argsLevel = refRule.getArgsLevel();
if (argsLevel == null) {
return null;
}
try {
Object result = argsLevel.runRule(serviceID, all);
return (Map>>) result;
} catch (Throwable e) {
logger.error("evalArgsLevel error ,message = " + e.getMessage(), e);
return null;
}
}
//
private static class CacheResult {
public final Map> serviceLevel; //服务接口级
public final Map>> methodLevel; //方法级
public final Map>>> argsLevel; //参数级
//
public CacheResult() {
this.serviceLevel = new HashMap>(); //服务接口级
this.methodLevel = new HashMap>>(); //方法级
this.argsLevel = new HashMap>>>(); //参数级
}
}
}