Контекст безопасности Hystrix в потоке Hystrix - PullRequest
0 голосов
/ 17 мая 2019

Я использую пружинный ботинок 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.Тем не менее, он теряет контекст.image

Редактировать: Я пытался использовать пользовательскую стратегию параллелизма, она тоже не работает.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);
    }
...