[ https://issues.apache.org/jira/browse/KNOX-3084?focusedWorklogId=974481&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-974481 ]
ASF GitHub Bot logged work on KNOX-3084: ---------------------------------------- Author: ASF GitHub Bot Created on: 14/Jul/25 13:54 Start Date: 14/Jul/25 13:54 Worklog Time Spent: 10m Work Description: smolnar82 commented on code in PR #1059: URL: https://github.com/apache/knox/pull/1059#discussion_r2200251663 ########## gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscovery.java: ########## @@ -255,81 +257,115 @@ private boolean shouldRetryServiceDiscovery(ApiException e) { return false; } - private ClouderaManagerCluster discoverCluster(DiscoveryApiClient client, String clusterName, Collection<String> includedServices) + private ClouderaManagerCluster discoverCluster(GatewayConfig gatewayConfig, DiscoveryApiClient client, + String clusterName, Collection<String> includedServices) throws ApiException { ServicesResourceApi servicesResourceApi = new ServicesResourceApi(client); RolesResourceApi rolesResourceApi = new RolesResourceApi(client); + ServiceRoleCollector roleCollector = + ServiceRoleCollectorBuilder.newBuilder() + .gatewayConfig(gatewayConfig) + .rolesResourceApi(rolesResourceApi) + .build(); log.discoveringCluster(clusterName); + List<ApiService> serviceList = getServiceList(client.getConfig(), servicesResourceApi); + if (serviceList == null) { + return null; + } + + // if Legacy Cloudera Manager API Clients Compatibility is turned off, some HDFS settings are in CORE_SETTINGS + ApiServiceConfig coreSettingsConfig = coreSettingsConfig(client, servicesResourceApi, serviceList); + Set<ServiceModel> serviceModels = new HashSet<>(); + for (ApiService service : serviceList) { + serviceModels.addAll( + discoverService(client, clusterName, includedServices, service, servicesResourceApi, roleCollector, coreSettingsConfig)); + } - List<ApiService> serviceList = getClusterServices(client.getConfig(), servicesResourceApi); + ClouderaManagerCluster cluster = new ClouderaManagerCluster(clusterName); + cluster.addServiceModels(serviceModels); + log.discoveredCluster(clusterName); + return cluster; + } - if (serviceList != null) { - /* - Since Cloudera Manager does not have a service for itself, we will add a skeleton CM - service so that we can add CM service to topology when auto-discovery is - turned on and CM service is selected in the descriptor - */ - final ApiService cmService = new ApiService(); - cmService.setName(CM_SERVICE_TYPE.toLowerCase(Locale.ROOT)); - cmService.setType(CM_SERVICE_TYPE); - serviceList.add(cmService); - - // if Legacy Cloudera Manager API Clients Compatibility is turned off, some HDFS settings are in CORE_SETTINGS - ApiServiceConfig coreSettingsConfig = coreSettingsConfig(client, servicesResourceApi, serviceList); - - for (ApiService service : serviceList) { - final List<ServiceModelGenerator> modelGenerators = serviceModelGeneratorsHolder.getServiceModelGenerators(service.getType()); - if (shouldSkipServiceDiscovery(modelGenerators, includedServices)) { - //log.skipServiceDiscovery(service.getName(), service.getType()); - //continue; - } - log.discoveringService(service.getName(), service.getType()); - ApiServiceConfig serviceConfig = null; - /* no reason to check service config for CM or CORE_SETTINGS services */ - if (!CM_SERVICE_TYPE.equals(service.getType()) && !CORE_SETTINGS_TYPE.equals(service.getType())) { - serviceConfig = getServiceConfig(client.getConfig(), servicesResourceApi, service); - } - ApiRoleList roleList = getRoles(client.getConfig(), rolesResourceApi, clusterName, service); - if (roleList != null && roleList.getItems() != null) { - for (ApiRole role : roleList.getItems()) { - String roleName = role.getName(); - log.discoveringServiceRole(roleName, role.getType()); - - ApiConfigList roleConfig = null; - /* no reason to check role config for CM or CORE_SETTINGS services */ - if (!CM_SERVICE_TYPE.equals(service.getType()) && !CORE_SETTINGS_TYPE.equals(service.getType())) { - roleConfig = getRoleConfig(client.getConfig(), rolesResourceApi, service, role); - } - - if (modelGenerators != null) { - for (ServiceModelGenerator serviceModelGenerator : modelGenerators) { - ServiceModelGeneratorHandleResponse response = serviceModelGenerator.handles(service, serviceConfig, role, roleConfig); - if (response.handled()) { - serviceModelGenerator.setApiClient(client); - ServiceModel serviceModel = serviceModelGenerator.generateService(service, serviceConfig, role, roleConfig, coreSettingsConfig); - serviceModels.add(serviceModel); - } else if (!response.getConfigurationIssues().isEmpty()) { - log.serviceRoleHasConfigurationIssues(roleName, String.join(";", response.getConfigurationIssues())); - } - } - } - - log.discoveredServiceRole(roleName, role.getType()); - } - } + @SuppressWarnings("PMD.UnusedFormalParameter") + private Set<ServiceModel> discoverService(DiscoveryApiClient client, String clusterName, Collection<String> includedServices, + ApiService service, ServicesResourceApi servicesResourceApi, + ServiceRoleCollector roleCollector, ApiServiceConfig coreSettingsConfig) throws ApiException { + Set<ServiceModel> serviceModels = new HashSet<>(); + final List<ServiceModelGenerator> modelGenerators = serviceModelGeneratorsHolder.getServiceModelGenerators(service.getType()); + //if (shouldSkipServiceDiscovery(modelGenerators, includedServices)) { + //log.skipServiceDiscovery(service.getName(), service.getType()); + //continue; + //} + log.discoveringService(service.getName(), service.getType()); + ApiServiceConfig serviceConfig = null; + /* no reason to check service config for CM or CORE_SETTINGS services */ + if (!CM_SERVICE_TYPE.equals(service.getType()) && !CORE_SETTINGS_TYPE.equals(service.getType())) { + serviceConfig = getServiceConfig(client.getConfig(), servicesResourceApi, service); + } + ApiRoleConfigList roleConfigList = getAllServiceRoleConfigurations(client.getConfig(), roleCollector, clusterName, service); + if (roleConfigList != null && roleConfigList.getItems() != null) { + for (ApiRoleConfig roleConfig : roleConfigList.getItems()) { + ApiRole role = new ApiRole() + .name(roleConfig.getName()) + .type(roleConfig.getRoleType()) + .hostRef(roleConfig.getHostRef()); + ApiConfigList roleConfigs = roleConfig.getConfig(); + ServiceRoleDetails serviceRoleDetails = new ServiceRoleDetails(service, serviceConfig, role, roleConfigs); + + serviceModels.addAll(generateServiceModels(client, serviceRoleDetails, coreSettingsConfig, modelGenerators)); + } + } + + log.discoveredService(service.getName(), service.getType()); + return serviceModels; + } - log.discoveredService(service.getName(), service.getType()); + private Set<ServiceModel> generateServiceModels(DiscoveryApiClient client, ServiceRoleDetails serviceRoleDetails, ApiServiceConfig coreSettingsConfig, List<ServiceModelGenerator> modelGenerators) throws ApiException { + Set<ServiceModel> serviceModels = new HashSet<>(); + log.discoveringServiceRole(serviceRoleDetails.getRole().getName(), serviceRoleDetails.getRole().getType()); + + if (modelGenerators != null) { + for (ServiceModelGenerator serviceModelGenerator : modelGenerators) { + ServiceModel serviceModel = generateServiceModel(client, serviceRoleDetails, coreSettingsConfig, serviceModelGenerator); + if (serviceModel != null) { + serviceModels.add(serviceModel); + } } - ClouderaManagerCluster cluster = new ClouderaManagerCluster(clusterName); - cluster.addServiceModels(serviceModels); - return cluster; + } + + log.discoveredServiceRole(serviceRoleDetails.getRole().getName(), serviceRoleDetails.getRole().getType()); + return serviceModels; + } + + private static ServiceModel generateServiceModel(DiscoveryApiClient client, ServiceRoleDetails sd, + ApiServiceConfig coreSettingsConfig, ServiceModelGenerator serviceModelGenerator) throws ApiException { + ServiceModelGeneratorHandleResponse response = serviceModelGenerator.handles(sd.getService(), sd.getServiceConfig(), sd.getRole(), sd.getRoleConfig()); + if (response.handled()) { + serviceModelGenerator.setApiClient(client); + return serviceModelGenerator.generateService(sd.getService(), sd.getServiceConfig(), sd.getRole(), sd.getRoleConfig(), coreSettingsConfig); + } else if (!response.getConfigurationIssues().isEmpty()) { + log.serviceRoleHasConfigurationIssues(sd.getRole().getName(), String.join(";", response.getConfigurationIssues())); } return null; } + private List<ApiService> getServiceList(ServiceDiscoveryConfig config, ServicesResourceApi servicesResourceApi) throws ApiException { + List<ApiService> serviceList = getClusterServices(config, servicesResourceApi); + if (serviceList != null) { Review Comment: I'm wondering why adding the CM service skeleton cannot be done in `getClusterServices`. Any particular reason for this separation? If not, do you think moving this code back to `getClusterServices` makes sense? ########## gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscovery.java: ########## @@ -255,81 +257,115 @@ private boolean shouldRetryServiceDiscovery(ApiException e) { return false; } - private ClouderaManagerCluster discoverCluster(DiscoveryApiClient client, String clusterName, Collection<String> includedServices) + private ClouderaManagerCluster discoverCluster(GatewayConfig gatewayConfig, DiscoveryApiClient client, + String clusterName, Collection<String> includedServices) throws ApiException { ServicesResourceApi servicesResourceApi = new ServicesResourceApi(client); RolesResourceApi rolesResourceApi = new RolesResourceApi(client); + ServiceRoleCollector roleCollector = + ServiceRoleCollectorBuilder.newBuilder() + .gatewayConfig(gatewayConfig) + .rolesResourceApi(rolesResourceApi) + .build(); log.discoveringCluster(clusterName); + List<ApiService> serviceList = getServiceList(client.getConfig(), servicesResourceApi); + if (serviceList == null) { + return null; + } + + // if Legacy Cloudera Manager API Clients Compatibility is turned off, some HDFS settings are in CORE_SETTINGS + ApiServiceConfig coreSettingsConfig = coreSettingsConfig(client, servicesResourceApi, serviceList); + Set<ServiceModel> serviceModels = new HashSet<>(); + for (ApiService service : serviceList) { + serviceModels.addAll( + discoverService(client, clusterName, includedServices, service, servicesResourceApi, roleCollector, coreSettingsConfig)); + } - List<ApiService> serviceList = getClusterServices(client.getConfig(), servicesResourceApi); + ClouderaManagerCluster cluster = new ClouderaManagerCluster(clusterName); + cluster.addServiceModels(serviceModels); + log.discoveredCluster(clusterName); + return cluster; + } - if (serviceList != null) { - /* - Since Cloudera Manager does not have a service for itself, we will add a skeleton CM - service so that we can add CM service to topology when auto-discovery is - turned on and CM service is selected in the descriptor - */ - final ApiService cmService = new ApiService(); - cmService.setName(CM_SERVICE_TYPE.toLowerCase(Locale.ROOT)); - cmService.setType(CM_SERVICE_TYPE); - serviceList.add(cmService); - - // if Legacy Cloudera Manager API Clients Compatibility is turned off, some HDFS settings are in CORE_SETTINGS - ApiServiceConfig coreSettingsConfig = coreSettingsConfig(client, servicesResourceApi, serviceList); - - for (ApiService service : serviceList) { - final List<ServiceModelGenerator> modelGenerators = serviceModelGeneratorsHolder.getServiceModelGenerators(service.getType()); - if (shouldSkipServiceDiscovery(modelGenerators, includedServices)) { - //log.skipServiceDiscovery(service.getName(), service.getType()); - //continue; - } - log.discoveringService(service.getName(), service.getType()); - ApiServiceConfig serviceConfig = null; - /* no reason to check service config for CM or CORE_SETTINGS services */ - if (!CM_SERVICE_TYPE.equals(service.getType()) && !CORE_SETTINGS_TYPE.equals(service.getType())) { - serviceConfig = getServiceConfig(client.getConfig(), servicesResourceApi, service); - } - ApiRoleList roleList = getRoles(client.getConfig(), rolesResourceApi, clusterName, service); - if (roleList != null && roleList.getItems() != null) { - for (ApiRole role : roleList.getItems()) { - String roleName = role.getName(); - log.discoveringServiceRole(roleName, role.getType()); - - ApiConfigList roleConfig = null; - /* no reason to check role config for CM or CORE_SETTINGS services */ - if (!CM_SERVICE_TYPE.equals(service.getType()) && !CORE_SETTINGS_TYPE.equals(service.getType())) { - roleConfig = getRoleConfig(client.getConfig(), rolesResourceApi, service, role); - } - - if (modelGenerators != null) { - for (ServiceModelGenerator serviceModelGenerator : modelGenerators) { - ServiceModelGeneratorHandleResponse response = serviceModelGenerator.handles(service, serviceConfig, role, roleConfig); - if (response.handled()) { - serviceModelGenerator.setApiClient(client); - ServiceModel serviceModel = serviceModelGenerator.generateService(service, serviceConfig, role, roleConfig, coreSettingsConfig); - serviceModels.add(serviceModel); - } else if (!response.getConfigurationIssues().isEmpty()) { - log.serviceRoleHasConfigurationIssues(roleName, String.join(";", response.getConfigurationIssues())); - } - } - } - - log.discoveredServiceRole(roleName, role.getType()); - } - } + @SuppressWarnings("PMD.UnusedFormalParameter") + private Set<ServiceModel> discoverService(DiscoveryApiClient client, String clusterName, Collection<String> includedServices, + ApiService service, ServicesResourceApi servicesResourceApi, + ServiceRoleCollector roleCollector, ApiServiceConfig coreSettingsConfig) throws ApiException { + Set<ServiceModel> serviceModels = new HashSet<>(); + final List<ServiceModelGenerator> modelGenerators = serviceModelGeneratorsHolder.getServiceModelGenerators(service.getType()); + //if (shouldSkipServiceDiscovery(modelGenerators, includedServices)) { + //log.skipServiceDiscovery(service.getName(), service.getType()); + //continue; + //} + log.discoveringService(service.getName(), service.getType()); + ApiServiceConfig serviceConfig = null; + /* no reason to check service config for CM or CORE_SETTINGS services */ + if (!CM_SERVICE_TYPE.equals(service.getType()) && !CORE_SETTINGS_TYPE.equals(service.getType())) { + serviceConfig = getServiceConfig(client.getConfig(), servicesResourceApi, service); + } + ApiRoleConfigList roleConfigList = getAllServiceRoleConfigurations(client.getConfig(), roleCollector, clusterName, service); + if (roleConfigList != null && roleConfigList.getItems() != null) { + for (ApiRoleConfig roleConfig : roleConfigList.getItems()) { + ApiRole role = new ApiRole() + .name(roleConfig.getName()) + .type(roleConfig.getRoleType()) + .hostRef(roleConfig.getHostRef()); Review Comment: nit: formatting ########## gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java: ########## @@ -97,6 +100,26 @@ void failedToInstantiateJAASConfigurationFileImplementation(String implementatio text = "Failed to access the service role configurations ({0} / {1}) for cluster ({2}) discovery: {3}") void failedToAccessServiceRoleConfigs(String serviceName, String roleName, String clusterName, @StackTrace(level = MessageLevel.DEBUG) Exception e); + @Message(level = MessageLevel.DEBUG, + text = "Fetching service role configurations for service {0} for cluster ({1}) at offset {2} and limit {3}") + void fetchingServiceRoleConfigs(String serviceName, String clusterName, long offset, long limit); + + @Message(level = MessageLevel.WARN, + text = "Received null service role configurations for service {0} for cluster ({1})") Review Comment: nit: `null or empty` ########## gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ServiceRoleCollectorByService.java: ########## @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.knox.gateway.topology.discovery.cm; + +import com.cloudera.api.swagger.RolesResourceApi; +import com.cloudera.api.swagger.client.ApiException; +import com.cloudera.api.swagger.model.ApiRoleConfig; +import com.cloudera.api.swagger.model.ApiRoleConfigList; +import org.apache.knox.gateway.i18n.messages.MessagesFactory; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class ServiceRoleCollectorByService implements ServiceRoleCollector { + + private static final String VIEW_FULL = "full"; + private final RolesResourceApi rolesResourceApi; + private final long limit; + private final TypeNameFilter roleFilter; + private static final ClouderaManagerServiceDiscoveryMessages log = + MessagesFactory.get(ClouderaManagerServiceDiscoveryMessages.class); + + public ServiceRoleCollectorByService(RolesResourceApi rolesResourceApi, long roleConfigPageSize, + TypeNameFilter roleFilter) { + this.rolesResourceApi = rolesResourceApi; + this.limit = roleConfigPageSize; + this.roleFilter = roleFilter; + } + + @Override + public ApiRoleConfigList getAllServiceRoleConfigurations(String clusterName, String serviceName) throws ApiException { + long offset = 0; + ApiRoleConfigList allServiceRoleConfigs = new ApiRoleConfigList(); + allServiceRoleConfigs.setItems(new ArrayList<>()); + ApiRoleConfigList roleConfigList; + do { + log.fetchingServiceRoleConfigs(serviceName, clusterName, offset, limit); + roleConfigList = rolesResourceApi.readRolesConfig(clusterName, serviceName, + BigDecimal.valueOf(limit), BigDecimal.valueOf(offset), VIEW_FULL); + if (roleConfigList != null && roleConfigList.getItems() != null) { + allServiceRoleConfigs.getItems().addAll(roleConfigList.getItems()); + } else { + log.receivedNullServiceRoleConfigs(serviceName, clusterName); + } + offset += limit; + } while (configItemSizeMatchesLimit(roleConfigList, limit)); + return filterIncluded(allServiceRoleConfigs); + } + + private ApiRoleConfigList filterIncluded(ApiRoleConfigList roleConfigs) { + List<ApiRoleConfig> filteredItems = roleConfigs.getItems().stream() + .filter(this::isIncluded).collect(Collectors.toList()); + return new ApiRoleConfigList().items(filteredItems); + } + private boolean configItemSizeMatchesLimit(ApiRoleConfigList roleConfigList, long limit) { Review Comment: nit: no new line between the 2 methods ########## gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java: ########## @@ -97,6 +100,26 @@ void failedToInstantiateJAASConfigurationFileImplementation(String implementatio text = "Failed to access the service role configurations ({0} / {1}) for cluster ({2}) discovery: {3}") void failedToAccessServiceRoleConfigs(String serviceName, String roleName, String clusterName, @StackTrace(level = MessageLevel.DEBUG) Exception e); + @Message(level = MessageLevel.DEBUG, + text = "Fetching service role configurations for service {0} for cluster ({1}) at offset {2} and limit {3}") + void fetchingServiceRoleConfigs(String serviceName, String clusterName, long offset, long limit); + + @Message(level = MessageLevel.WARN, + text = "Received null service role configurations for service {0} for cluster ({1})") + void receivedNullServiceRoleList(String serviceName, String clusterName); + + @Message(level = MessageLevel.WARN, + text = "Received null service role configurations for service {0} for cluster ({1})") Review Comment: nit: `null or empty` ########## gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java: ########## @@ -97,6 +100,26 @@ void failedToInstantiateJAASConfigurationFileImplementation(String implementatio text = "Failed to access the service role configurations ({0} / {1}) for cluster ({2}) discovery: {3}") void failedToAccessServiceRoleConfigs(String serviceName, String roleName, String clusterName, @StackTrace(level = MessageLevel.DEBUG) Exception e); + @Message(level = MessageLevel.DEBUG, + text = "Fetching service role configurations for service {0} for cluster ({1}) at offset {2} and limit {3}") + void fetchingServiceRoleConfigs(String serviceName, String clusterName, long offset, long limit); + + @Message(level = MessageLevel.WARN, + text = "Received null service role configurations for service {0} for cluster ({1})") + void receivedNullServiceRoleList(String serviceName, String clusterName); + + @Message(level = MessageLevel.WARN, + text = "Received null service role configurations for service {0} for cluster ({1})") + void receivedNullServiceRoleConfigs(String serviceName, String clusterName); + + @Message(level = MessageLevel.WARN, + text = "Received null service role configurations for service {0} and role {2} for cluster ({1})") Review Comment: nit: `null or empty` ########## gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/DiscoveryApiClient.java: ########## @@ -126,55 +124,53 @@ private void configure(GatewayConfig gatewayConfig, AliasService aliasService, K setUsername(username); setPassword(password); - if (isKerberos) { + if (isKerberos()) { // If there is a Kerberos subject, then add the SPNEGO auth interceptor Subject subject = AuthUtils.getKerberosSubject(); if (subject != null) { - SpnegoAuthInterceptor spnegoInterceptor = new SpnegoAuthInterceptor(subject); - getHttpClient().interceptors().add(spnegoInterceptor); + addInterceptor(new SpnegoAuthInterceptor(subject)); } + addInterceptor(new DoAsQueryParameterInterceptor(username)); } configureTimeouts(gatewayConfig); configureSsl(gatewayConfig, trustStore); } - private void configureTimeouts(GatewayConfig config) { - OkHttpClient client = getHttpClient(); - client.setConnectTimeout(config.getServiceDiscoveryConnectTimeoutMillis(), TimeUnit.MILLISECONDS); - client.setReadTimeout(config.getServiceDiscoveryReadTimeoutMillis(), TimeUnit.MILLISECONDS); - client.setWriteTimeout(config.getServiceDiscoveryWriteTimeoutMillis(), TimeUnit.MILLISECONDS); - log.discoveryClientTimeout(client.getConnectTimeout(), client.getReadTimeout(), client.getWriteTimeout()); + private String getApiPath(GatewayConfig gatewayConfig) { + if (gatewayConfig == null) { + return API_PATH_PREFIX + GatewayConfig.DEFAULT_CLOUDERA_MANAGER_SERVICE_DISCOVERY_API_VERSION; + } else { + return API_PATH_PREFIX + gatewayConfig.getClouderaManagerServiceDiscoveryApiVersion(); + } } - @Override - public String buildUrl(String path, List<Pair> queryParams) { - // If kerberos is enabled, then for every request, we're going to include a doAs query param - if (isKerberos()) { - String user = getUsername(); - if (user != null) { - queryParams.add(new Pair("doAs", user)); - } - } - return super.buildUrl(path, queryParams); + private String getApiAddress(ServiceDiscoveryConfig serviceDiscoveryConfig, GatewayConfig gatewayConfig) { + String address = serviceDiscoveryConfig.getAddress(); + String apiPath = getApiPath(gatewayConfig); + return (address.endsWith("/") ? address + apiPath : address + "/" + apiPath); } - /** - * @return The username set from the discovery configuration when this instance was initialized. - */ - private String getUsername() { - String username = null; - Authentication basicAuth = getAuthentication("basic"); - if (basicAuth instanceof HttpBasicAuth) { - username = ((HttpBasicAuth) basicAuth).getUsername(); - } - return username; + private void addInterceptor(Interceptor interceptor) { + OkHttpClient newClient = getHttpClient().newBuilder().addInterceptor(interceptor).build(); + setHttpClient(newClient); + } Review Comment: According the my above comment, this method may be renamed to `configureInterceptors` and its signature should be change to accept a list of interceptors (instead of one). ########## gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/DiscoveryApiClient.java: ########## @@ -126,55 +124,53 @@ private void configure(GatewayConfig gatewayConfig, AliasService aliasService, K setUsername(username); setPassword(password); - if (isKerberos) { + if (isKerberos()) { // If there is a Kerberos subject, then add the SPNEGO auth interceptor Subject subject = AuthUtils.getKerberosSubject(); if (subject != null) { - SpnegoAuthInterceptor spnegoInterceptor = new SpnegoAuthInterceptor(subject); - getHttpClient().interceptors().add(spnegoInterceptor); + addInterceptor(new SpnegoAuthInterceptor(subject)); } + addInterceptor(new DoAsQueryParameterInterceptor(username)); Review Comment: As discussed offline, it'd be better if you have built a list of interceptors to use and pass that list to the `configureInterceptors(...)` method ()instead of calling and re-creating the same httpClient twice). Issue Time Tracking ------------------- Worklog Id: (was: 974481) Time Spent: 20m (was: 10m) > Update CM service discovery with the enhanced role configs endpoint > ------------------------------------------------------------------- > > Key: KNOX-3084 > URL: https://issues.apache.org/jira/browse/KNOX-3084 > Project: Apache Knox > Issue Type: Task > Components: cm-discovery > Affects Versions: 2.1.0 > Reporter: Tamás Marcinkovics > Assignee: Tamás Marcinkovics > Priority: Major > Time Spent: 20m > Remaining Estimate: 0h > > There is a new CM API endpoint to fetch all role configurations for a given > service ({{RolesResouce.readRolesConfig}}) if the supported API version is > greater than or equal to v57. This endpoint is available in the > cloudera-manager-api-swagger:7.13.1 artifact. > [https://repository.cloudera.com/service/rest/repository/browse/cloudera-repos/com/cloudera/api/swagger/cloudera-manager-api-swagger/7.13.1/] > On the Knox side, we need to change the existing {{readRoles}} and > {{readRoleConfig}} API calls to the new {{readRolesConfig}} call. > The {{view}} parameter should still remain {{full}} as > {{full_with_no_health_check}} only returns role configuration parameters with > non-default values. > As the new cloudera-manager-api-swagger artifact is using okhttp 4.10, we > also need to change {{DiscoveryApiClient}} setup and our Okhttp interceptors > from Okhttp 2.7.5 to Okhttp 4. -- This message was sent by Atlassian Jira (v8.20.10#820010)