Я использую пружинный ботинок 1.5 и hystrix (spring-cloud-starter-hystrix).Я использую стратегию изоляции семафоров, но все еще в резервном методе, Аутентификация не доступна в SecurityContext.Однако, согласно документации, SecurityContext будет поддерживаться с изоляцией SEMAPHORE.Что нужно сделать, чтобы это исправить?Вот что я попробовал:
@CachePut(cacheNames = Constants.CACHE_NAME_ALL_COLLIBRA_ASSETS_BY_DOMAIN_ID_BACKUP, key = "#domainId")
@HystrixCommand(fallbackMethod = "getAssetsFromBackup", commandKey = "getMetadataAssets", commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE")
})
public String getAssetsByDomain(String domainId) {
String assets = null;
try {
Map<String, Object> queryParams = new HashMap<>();
queryParams.put("domainId", domainId);
queryParams.put("limit", Constants.COLLIBRA_GET_ALL_ASSETS_LIMIT);
queryParams.put("offset", Constants.COLLIBRA_GET_ALL_ASSETS_OFFSET);
ResponseEntity<String> response = collibraProxy.callCollibra(GET_ALL_ASSETS_ENDPOINT, HttpMethod.GET, null, queryParams);
if (response.getStatusCode() == HttpStatus.OK) {
assets = response.getBody();
} else {
throw new FGCollibException("Exception while getting OK response from Collibra: " + response.getStatusCode());
}
} catch (FGCollibException e) {
logger.error("Error in getting assets from collibra for domainId {}", domainId, e);
throw new FgException("Error getting response from collibra");
}
return assets;
}
public String getAssetsFromBackup(String domainId) {
try {
logger.info("Executing fallback logic for collibra backup");
CacheEntry entry = cacheService.get(Constants.CACHE_NAME_ALL_COLLIBRA_ASSETS_BY_DOMAIN_ID_BACKUP, domainId);
if (entry != null) {
return (String) entry.getV();
}
} catch (Exception e) {
logger.error("Error in getting assets from collibra backup for domainId {}", domainId, e);
}
return null;
}
Время ожидания вызова collibraProxy.callCollibra(GET_ALL_ASSETS_ENDPOINT, HttpMethod.GET, null, queryParams);
и метод запасного вызова getAssetsFromBackup
.Тем не менее, он теряет контекст.
Редактировать: Я пытался использовать пользовательскую стратегию параллелизма, она тоже не работает.ConcurrencyStrategy:
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
public SecurityContextConcurrencyStrategy(
HystrixConcurrencyStrategy existingConcurrencyStrategy) {
this.existingConcurrencyStrategy = existingConcurrencyStrategy;
}
@Override
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getBlockingQueue(maxQueueSize)
: super.getBlockingQueue(maxQueueSize);
}
@Override
public <T> HystrixRequestVariable<T> getRequestVariable(
HystrixRequestVariableLifecycle<T> rv) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getRequestVariable(rv)
: super.getRequestVariable(rv);
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
HystrixProperty<Integer> corePoolSize,
HystrixProperty<Integer> maximumPoolSize,
HystrixProperty<Integer> keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getThreadPool(threadPoolKey, corePoolSize,
maximumPoolSize, keepAliveTime, unit, workQueue)
: super.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize,
keepAliveTime, unit, workQueue);
}
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy
.wrapCallable(new DelegatingSecurityContextCallable<T>(callable))
: super.wrapCallable(new DelegatingSecurityContextCallable<T>(callable));
}
}
Конфигурация:
@Configuration
public class HystrixContextAutoConfiguration {
@Autowired(required = false)
private List<HystrixCallableWrapper> wrappers = new ArrayList<>();
@Autowired(required = false)
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
@PostConstruct
public void init() {
HystrixPlugins.reset();
// Keeps references of existing Hystrix plugins.
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
.getEventNotifier();
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
.getMetricsPublisher();
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
.getPropertiesStrategy();
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance()
.getCommandExecutionHook();
HystrixPlugins.reset();
// Registers existing plugins excepts the Concurrent Strategy plugin.
HystrixPlugins.getInstance().registerConcurrencyStrategy(
new SecurityContextConcurrencyStrategy(existingConcurrencyStrategy));
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
}