You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by sm...@apache.org on 2024/03/28 14:07:59 UTC
(knox) branch master updated: KNOX-3026 - End-users can exclude certain services or roles from CM service discovery (#893)
This is an automated email from the ASF dual-hosted git repository.
smolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new af09c1d4e KNOX-3026 - End-users can exclude certain services or roles from CM service discovery (#893)
af09c1d4e is described below
commit af09c1d4e90941c9e545a6667af561c3b9c3a717
Author: Sandor Molnar <sm...@apache.org>
AuthorDate: Thu Mar 28 15:07:53 2024 +0100
KNOX-3026 - End-users can exclude certain services or roles from CM service discovery (#893)
---
.../cm/ClouderaManagerServiceDiscovery.java | 34 +++++++++++++
.../ClouderaManagerServiceDiscoveryMessages.java | 3 ++
.../cm/ClouderaManagerServiceDiscoveryTest.java | 59 ++++++++++++++++++++--
.../gateway/config/impl/GatewayConfigImpl.java | 12 +++++
.../org/apache/knox/gateway/GatewayTestConfig.java | 10 ++++
.../apache/knox/gateway/config/GatewayConfig.java | 12 +++++
6 files changed, 125 insertions(+), 5 deletions(-)
diff --git a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscovery.java b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscovery.java
index 8d1227a56..532dcec04 100644
--- a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscovery.java
+++ b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscovery.java
@@ -52,6 +52,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
/**
@@ -92,6 +93,8 @@ public class ClouderaManagerServiceDiscovery implements ServiceDiscovery, Cluste
private final AtomicInteger retryAttempts = new AtomicInteger(0);
private final int retrySleepSeconds = 3; // It's been agreed that we not expose this config
private int maxRetryAttempts = -1;
+ private Collection<String> excludedServiceTypes = Collections.emptySet();
+ private Collection<String> excludedRoleTypes = Collections.emptySet();
ClouderaManagerServiceDiscovery(GatewayConfig gatewayConfig) {
this(false, gatewayConfig);
@@ -116,9 +119,15 @@ public class ClouderaManagerServiceDiscovery implements ServiceDiscovery, Cluste
if (gatewayConfig != null) {
repository.setCacheEntryTTL(gatewayConfig.getClouderaManagerServiceDiscoveryRepositoryEntryTTL());
configureRetryParams(gatewayConfig);
+ excludedServiceTypes = getLowercaseStringCollection(gatewayConfig.getClouderaManagerServiceDiscoveryExcludedServiceTypes());
+ excludedRoleTypes = getLowercaseStringCollection(gatewayConfig.getClouderaManagerServiceDiscoveryExcludedRoleTypes());
}
}
+ private Collection<String> getLowercaseStringCollection(Collection<String> original) {
+ return original == null ? Collections.emptySet() : original.stream().map(serviceType -> serviceType.toLowerCase(Locale.ROOT)).collect(Collectors.toSet());
+ }
+
private void configureRetryParams(GatewayConfig gatewayConfig) {
final int configuredMaxRetryAttempts = gatewayConfig.getClouderaManagerServiceDiscoveryMaximumRetryAttempts();
if (configuredMaxRetryAttempts > 0) {
@@ -356,6 +365,14 @@ public class ClouderaManagerServiceDiscovery implements ServiceDiscovery, Cluste
final ApiServiceList serviceList = servicesResourceApi.readServices(serviceDiscoveryConfig.getCluster(), VIEW_SUMMARY);
services = serviceList == null ? new ArrayList<>() : serviceList.getItems();
+ services = services.stream().filter(service -> {
+ if (excludedServiceTypes.contains(service.getType().toLowerCase(Locale.ROOT))) {
+ log.skipServiceDiscovery(service.getName(), service.getType());
+ return false;
+ }
+ return true;
+ }).collect(Collectors.toList());
+
// make sure that services are populated in the repository
services.forEach(service -> repository.addService(serviceDiscoveryConfig, service));
} catch (ApiException e) {
@@ -409,6 +426,8 @@ public class ClouderaManagerServiceDiscovery implements ServiceDiscovery, Cluste
log.noRoles();
}
+ roles = excludeRoles(roles);
+
// make sure that role is populated in the service discovery repository to avoid subsequent CM calls
if (roles != null && roles.getItems() != null) {
repository.addRoles(serviceDiscoveryConfig, service, roles);
@@ -422,6 +441,21 @@ public class ClouderaManagerServiceDiscovery implements ServiceDiscovery, Cluste
return roles;
}
+ private ApiRoleList excludeRoles(ApiRoleList roles) {
+ if (roles == null || roles.getItems() == null) {
+ return roles;
+ }
+ final ApiRoleList filteredRoles = new ApiRoleList();
+ roles.getItems().forEach(role -> {
+ if (excludedRoleTypes.contains(role.getType().toLowerCase(Locale.ROOT))) {
+ log.skipRoleDiscovery(role.getName(), role.getType());
+ } else {
+ filteredRoles.addItemsItem(role);
+ }
+ });
+ return filteredRoles;
+ }
+
private ApiConfigList getRoleConfig(ServiceDiscoveryConfig serviceDiscoveryConfig, RolesResourceApi rolesResourceApi, ApiService service, ApiRole role) throws ApiException {
log.lookupRoleConfigsFromRepository();
// first, try in the service discovery repository
diff --git a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java
index fd77c3552..285c09b68 100644
--- a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java
+++ b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java
@@ -48,6 +48,9 @@ public interface ClouderaManagerServiceDiscoveryMessages {
@Message(level = MessageLevel.INFO, text = "Discovering service role: {0} ({1}) ...")
void discoveringServiceRole(String roleName, String roleType);
+ @Message(level = MessageLevel.INFO, text = "Skipping role discovery: {0} ({1})")
+ void skipRoleDiscovery(String roleName, String roleType);
+
@Message(level = MessageLevel.INFO, text = "Discovered service role: {0} ({1})")
void discoveredServiceRole(String roleName, String roleType);
diff --git a/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java b/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
index 76843e11f..9d98643ba 100644
--- a/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
+++ b/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
@@ -64,6 +64,7 @@ import org.junit.Test;
import java.lang.reflect.Type;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -402,7 +403,26 @@ public class ClouderaManagerServiceDiscoveryTest {
}
@Test
- public void testWebHCatDiscovery() {
+ public void testIncludeHiveServiceIncludeWebHCatDiscovery() {
+ testWebHCatDiscovery(true, true);
+ }
+
+ @Test
+ public void testExcludeHiveServiceIncludeWebHCatDiscovery() {
+ testWebHCatDiscovery(false, true);
+ }
+
+ @Test
+ public void testIncludeHiveServiceExcludeWebHCatDiscovery() {
+ testWebHCatDiscovery(true, false);
+ }
+
+ @Test
+ public void testExcludeHiveServiceExcludeWebHCatDiscovery() {
+ testWebHCatDiscovery(false, false);
+ }
+
+ private void testWebHCatDiscovery(boolean excludeHiveService, boolean excludeWebHCatRole) {
final String hostName = "webhcat-host";
final String port = "22222";
final String expectedURL = "http://" + hostName + ":" + port + "/templeton";
@@ -417,12 +437,18 @@ public class ClouderaManagerServiceDiscoveryTest {
"HIVE-1-WEBHCAT-1",
WebHCatServiceModelGenerator.ROLE_TYPE,
Collections.emptyMap(),
- roleProperties);
+ roleProperties,
+ false,
+ excludeHiveService ? WebHCatServiceModelGenerator.SERVICE_TYPE : null,
+ excludeWebHCatRole ? WebHCatServiceModelGenerator.ROLE_TYPE : null);
List<String> urls = cluster.getServiceURLs("WEBHCAT");
assertNotNull(urls);
- assertEquals(1, urls.size());
- assertEquals(expectedURL, urls.get(0));
+ final boolean expectExclusion = excludeHiveService || excludeWebHCatRole;
+ assertEquals(expectExclusion ? 0 : 1, urls.size());
+ if (!expectExclusion) {
+ assertEquals(expectedURL, urls.get(0));
+ }
}
@Test
@@ -1168,6 +1194,17 @@ public class ClouderaManagerServiceDiscoveryTest {
return doTestDiscovery(hostName, serviceName, serviceType, roleName, roleType, serviceProperties, roleProperties, false);
}
+ private ServiceDiscovery.Cluster doTestDiscovery(final String hostName,
+ final String serviceName,
+ final String serviceType,
+ final String roleName,
+ final String roleType,
+ final Map<String, String> serviceProperties,
+ final Map<String, String> roleProperties,
+ boolean testRetry) {
+ return doTestDiscovery(hostName, serviceName, serviceType, roleName, roleType, serviceProperties, roleProperties, testRetry, null, null);
+ }
+
private ServiceDiscovery.Cluster doTestDiscovery(final String hostName,
final String serviceName,
final String serviceType,
@@ -1175,7 +1212,9 @@ public class ClouderaManagerServiceDiscoveryTest {
final String roleType,
final Map<String, String> serviceProperties,
final Map<String, String> roleProperties,
- boolean testRetry) {
+ boolean testRetry,
+ String excludedServiceType,
+ String excludedRoleType) {
final String clusterName = "cluster-1";
GatewayConfig gwConf = EasyMock.createNiceMock(GatewayConfig.class);
@@ -1185,6 +1224,16 @@ public class ClouderaManagerServiceDiscoveryTest {
}
EasyMock.expect(gwConf.getIncludedSSLCiphers()).andReturn(Collections.emptyList()).anyTimes();
EasyMock.expect(gwConf.getIncludedSSLProtocols()).andReturn(Collections.emptySet()).anyTimes();
+ if (excludedServiceType == null) {
+ EasyMock.expect(gwConf.getClouderaManagerServiceDiscoveryExcludedServiceTypes()).andReturn(Collections.emptySet()).anyTimes();
+ } else {
+ EasyMock.expect(gwConf.getClouderaManagerServiceDiscoveryExcludedServiceTypes()).andReturn(Arrays.asList(excludedServiceType)).anyTimes();
+ }
+ if (excludedRoleType == null) {
+ EasyMock.expect(gwConf.getClouderaManagerServiceDiscoveryExcludedRoleTypes()).andReturn(Collections.emptySet()).anyTimes();
+ } else {
+ EasyMock.expect(gwConf.getClouderaManagerServiceDiscoveryExcludedRoleTypes()).andReturn(Arrays.asList(excludedRoleType)).anyTimes();
+ }
EasyMock.replay(gwConf);
ServiceDiscoveryConfig sdConfig = createMockDiscoveryConfig(clusterName);
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
index 01858a597..1b6e967a7 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
@@ -297,6 +297,8 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
private static final String CLOUDERA_MANAGER_SERVICE_DISCOVERY_CONNECT_TIMEOUT = GATEWAY_CONFIG_FILE_PREFIX + ".cloudera.manager.service.discovery.connect.timeout.ms";
private static final String CLOUDERA_MANAGER_SERVICE_DISCOVERY_READ_TIMEOUT = GATEWAY_CONFIG_FILE_PREFIX + ".cloudera.manager.service.discovery.read.timeout.ms";
private static final String CLOUDERA_MANAGER_SERVICE_DISCOVERY_WRITE_TIMEOUT = GATEWAY_CONFIG_FILE_PREFIX + ".cloudera.manager.service.discovery.write.timeout.ms";
+ private static final String CLOUDERA_MANAGER_SERVICE_DISCOVERY_EXCLUDED_SERVICE_TYPES = GATEWAY_CONFIG_FILE_PREFIX + ".cloudera.manager.service.discovery.excluded.service.types";
+ private static final String CLOUDERA_MANAGER_SERVICE_DISCOVERY_EXCLUDED_ROLE_TYPES = GATEWAY_CONFIG_FILE_PREFIX + ".cloudera.manager.service.discovery.excluded.role.types";
private static final long CLOUDERA_MANAGER_SERVICE_DISCOVERY_CONNECT_TIMEOUT_DEFAULT = 10000;
private static final long CLOUDERA_MANAGER_SERVICE_DISCOVERY_READ_TIMEOUT_DEFAULT = 10000;
@@ -1301,6 +1303,16 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
return getInt(CLOUDERA_MANAGER_SERVICE_DISCOVERY_MAX_RETRY_ATTEMPS, DEFAULT_CM_SERVICE_DISCOVERY_MAX_RETRY_ATTEMPTS);
}
+ @Override
+ public Collection<String> getClouderaManagerServiceDiscoveryExcludedServiceTypes() {
+ return getTrimmedStringCollection(CLOUDERA_MANAGER_SERVICE_DISCOVERY_EXCLUDED_SERVICE_TYPES);
+ }
+
+ @Override
+ public Collection<String> getClouderaManagerServiceDiscoveryExcludedRoleTypes() {
+ return getTrimmedStringCollection(CLOUDERA_MANAGER_SERVICE_DISCOVERY_EXCLUDED_ROLE_TYPES);
+ }
+
@Override
public boolean isServerManagedTokenStateEnabled() {
return getBoolean(TOKEN_STATE_SERVER_MANAGED, false);
diff --git a/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java b/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index b179b0a9c..e3f2ddab5 100644
--- a/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++ b/gateway-spi-common/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@ -871,6 +871,16 @@ public class GatewayTestConfig extends Configuration implements GatewayConfig {
return -1;
}
+ @Override
+ public Collection<String> getClouderaManagerServiceDiscoveryExcludedServiceTypes() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Collection<String> getClouderaManagerServiceDiscoveryExcludedRoleTypes() {
+ return Collections.emptySet();
+ }
+
@Override
public boolean isServerManagedTokenStateEnabled() {
return false;
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
index c2cbc3692..352aabbe5 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
@@ -750,6 +750,18 @@ public interface GatewayConfig {
*/
int getClouderaManagerServiceDiscoveryMaximumRetryAttempts();
+ /**
+ * @return a collection of comma separated service types that should be excluded
+ * from CM service discovery (e.g. HDFS, KNOX, RANGER, HIVE, etc...)
+ */
+ Collection<String> getClouderaManagerServiceDiscoveryExcludedServiceTypes();
+
+ /**
+ * @return a collection of comma separated role types that should be excluded
+ * from CM service discovery (e.g. KNOX_GATEWAY, IDBROKER, DATANODE, HIVEMETASTORE, etc...)
+ */
+ Collection<String> getClouderaManagerServiceDiscoveryExcludedRoleTypes();
+
/**
* @return true, if state for tokens issued by the Knox Token service should be managed by Knox.
*/