This is an automated email from the ASF dual-hosted git repository.
pzampino 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 248f08c KNOX-1875 - Cloudera Manager service discovery
248f08c is described below
commit 248f08c7537cf1e9b631b768f18a7dbb6b7e5cbd
Author: pzampino <[email protected]>
AuthorDate: Fri Jan 18 12:02:56 2019 -0500
KNOX-1875 - Cloudera Manager service discovery
---
gateway-discovery-cm/pom.xml | 64 +++
.../discovery/cm/ClouderaManagerCluster.java | 100 +++++
.../cm/ClouderaManagerServiceDiscovery.java | 430 +++++++++++++++++++++
.../ClouderaManagerServiceDiscoveryMessages.java | 97 +++++
.../cm/ClouderaManagerServiceDiscoveryType.java | 37 ++
.../topology/discovery/cm/DiscoveryApiClient.java | 104 +++++
.../topology/discovery/cm/ServiceModel.java | 73 ++++
.../discovery/cm/ServiceModelGenerator.java | 39 ++
.../cm/model/AbstractServiceModelGenerator.java | 76 ++++
.../model/atlas/AtlasAPIServiceModelGenerator.java | 39 ++
.../cm/model/atlas/AtlasServiceModelGenerator.java | 60 +++
.../model/atlas/AtlasUIServiceModelGenerator.java | 39 ++
.../model/hbase/HBaseUIServiceModelGenerator.java | 58 +++
.../model/hbase/WebHBaseServiceModelGenerator.java | 58 +++
.../cm/model/hdfs/HdfsUIServiceModelGenerator.java | 51 +++
.../model/hdfs/NameNodeServiceModelGenerator.java | 60 +++
.../model/hdfs/WebHdfsServiceModelGenerator.java | 49 +++
.../cm/model/hive/HiveServiceModelGenerator.java | 65 ++++
.../cm/model/hue/HueLBServiceModelGenerator.java | 52 +++
.../cm/model/hue/HueServiceModelGenerator.java | 58 +++
.../cm/model/livy/LivyServiceModelGenerator.java | 58 +++
.../cm/model/livy/LivyUIServiceModelGenerator.java | 39 ++
.../cm/model/oozie/OozieServiceModelGenerator.java | 60 +++
.../model/oozie/OozieUIServiceModelGenerator.java | 39 ++
.../model/ranger/RangerServiceModelGenerator.java | 59 +++
.../ranger/RangerUIAPIServiceModelGenerator.java | 38 ++
.../ranger/RangerUIServiceModelGenerator.java | 38 ++
.../cm/model/solr/SolrServiceModelGenerator.java | 59 +++
.../cm/model/solr/SolrUIServiceModelGenerator.java | 38 ++
.../spark/SparkHistoryUIServiceModelGenerator.java | 59 +++
.../yarn/JobHistoryUIServiceModelGenerator.java | 70 ++++
.../ResourceManagerUIServiceModelGenerator.java | 40 ++
.../cm/model/yarn/YarnUIServiceModelGenerator.java | 70 ++++
.../model/yarn/YarnUIv2ServiceModelGenerator.java | 38 ++
.../zeppelin/ZeppelinUIServiceModelGenerator.java | 57 +++
.../zeppelin/ZeppelinWSServiceModelGenerator.java | 49 +++
...gateway.topology.discovery.ServiceDiscoveryType | 19 +
...way.topology.discovery.cm.ServiceModelGenerator | 44 +++
.../cm/ClouderaManagerServiceDiscoveryTest.java | 283 ++++++++++++++
gateway-release/pom.xml | 4 +
pom.xml | 6 +
41 files changed, 2776 insertions(+)
diff --git a/gateway-discovery-cm/pom.xml b/gateway-discovery-cm/pom.xml
new file mode 100644
index 0000000..e646c68
--- /dev/null
+++ b/gateway-discovery-cm/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.apache.knox</groupId>
+ <artifactId>gateway</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <properties>
+ <cloudera-manager.version>6.2.0</cloudera-manager.version>
+
<cloudera-manager-api-swagger.version>${cloudera-manager.version}</cloudera-manager-api-swagger.version>
+ </properties>
+
+ <artifactId>gateway-discovery-cm</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.knox</groupId>
+ <artifactId>gateway-spi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.knox</groupId>
+ <artifactId>gateway-i18n</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.knox</groupId>
+ <artifactId>gateway-util-configinjector</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.cloudera.api.swagger</groupId>
+ <artifactId>cloudera-manager-api-swagger</artifactId>
+ <version>${cloudera-manager-api-swagger.version}</version> <!--
or CM version 6.0 and above -->
+ </dependency>
+ <dependency>
+ <groupId>com.squareup.okhttp</groupId>
+ <artifactId>okhttp</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
+
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerCluster.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerCluster.java
new file mode 100644
index 0000000..66e487b
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerCluster.java
@@ -0,0 +1,100 @@
+/*
+ * 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 org.apache.knox.gateway.topology.discovery.ServiceDiscovery;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * ClouderaManager-based service discovery cluster model implementation.
+ */
+public class ClouderaManagerCluster implements ServiceDiscovery.Cluster {
+
+ private String name;
+
+ private Set<ServiceModel> serviceModels = new HashSet<>();
+
+ ClouderaManagerCluster(String clusterName) {
+ this.name = clusterName;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public List<String> getServiceURLs(String serviceName) {
+ List<String> urls = new ArrayList<>();
+
+ for (ServiceModel sm : serviceModels) {
+ if (sm.getService().equals(serviceName)) {
+ urls.add(sm.getServiceUrl());
+ }
+ }
+
+ return urls;
+ }
+
+ @Override
+ public List<String> getServiceURLs(String serviceName, Map<String, String>
serviceParams) {
+ return getServiceURLs(serviceName); // TODO: PJZ: Support things like HDFS
nameservice params for providing the correct URL(s)?
+ }
+
+ @Override
+ public ZooKeeperConfig getZooKeeperConfiguration(String serviceName) {
+ return null;
+ }
+
+ void addServiceModels(Set<ServiceModel> serviceModels) {
+ this.serviceModels.addAll(serviceModels);
+ }
+
+ static class ServiceConfiguration {
+
+ private String type;
+ private String version;
+ private Map<String, String> props;
+
+ ServiceConfiguration(String type, String version, Map<String, String>
properties) {
+ this.type = type;
+ this.version = version;
+ this.props = properties;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public Map<String, String> getProperties() {
+ return props;
+ }
+ }
+
+
+
+
+}
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
new file mode 100644
index 0000000..948f9d3
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscovery.java
@@ -0,0 +1,430 @@
+/*
+ * 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.ClustersResourceApi;
+import com.cloudera.api.swagger.RolesResourceApi;
+import com.cloudera.api.swagger.ServicesResourceApi;
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiCluster;
+import com.cloudera.api.swagger.model.ApiClusterList;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiRoleList;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import com.cloudera.api.swagger.model.ApiServiceList;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.security.SubjectUtils;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.topology.discovery.GatewayService;
+import org.apache.knox.gateway.topology.discovery.ServiceDiscovery;
+import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryConfig;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.net.URI;
+import java.net.URL;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+
+/**
+ * ClouderaManager-based service discovery implementation.
+ */
+public class ClouderaManagerServiceDiscovery implements ServiceDiscovery {
+
+ static final String TYPE = "ClouderaManager";
+
+ private static final ClouderaManagerServiceDiscoveryMessages log =
+
MessagesFactory.get(ClouderaManagerServiceDiscoveryMessages.class);
+
+ private static final String JGSS_LOGIN_MODULE =
"com.sun.security.jgss.initiate";
+
+ static final String API_PATH = "api/v32";
+
+ private static final String CLUSTER_TYPE_ANY = "any";
+ private static final String VIEW_SUMMARY = "summary";
+ private static final String VIEW_FULL = "full";
+
+ static final String DEFAULT_USER_ALIAS = "cm.discovery.user";
+ static final String DEFAULT_PWD_ALIAS = "cm.discovery.password";
+
+ private boolean debug;
+
+ @GatewayService
+ private AliasService aliasService;
+
+
+ ClouderaManagerServiceDiscovery() {
+ this(false);
+ }
+
+ ClouderaManagerServiceDiscovery(boolean debug) {
+ this.debug = debug;
+ }
+
+ @Override
+ public String getType() {
+ return TYPE;
+ }
+
+ private DiscoveryApiClient getClient(ServiceDiscoveryConfig discoveryConfig)
{
+ String discoveryAddress = discoveryConfig.getAddress();
+ if (discoveryAddress == null || discoveryAddress.isEmpty()) {
+ log.missingDiscoveryAddress();
+ throw new IllegalArgumentException("Missing or invalid discovery
address.");
+ }
+
+ DiscoveryApiClient client = new DiscoveryApiClient(discoveryConfig,
aliasService);
+ client.setDebugging(debug);
+ client.setVerifyingSsl(false);
+ return client;
+ }
+
+ @Override
+ public Map<String, Cluster> discover(GatewayConfig gatewayConfig,
ServiceDiscoveryConfig discoveryConfig) {
+ Map<String, Cluster> clusters = new HashMap<>();
+
+ DiscoveryApiClient client = getClient(discoveryConfig);
+ List<ApiCluster> apiClusters = getClusters(client);
+ for (ApiCluster apiCluster : apiClusters) {
+ String clusterName = apiCluster.getName();
+ log.discoveredCluster(clusterName, apiCluster.getFullVersion());
+
+ Cluster cluster = discover(gatewayConfig, discoveryConfig, clusterName,
client);
+ clusters.put(clusterName, cluster);
+ }
+
+ return clusters;
+ }
+
+ @Override
+ public Cluster discover(GatewayConfig gatewayConfig, ServiceDiscoveryConfig
discoveryConfig, String clusterName) {
+ return discover(gatewayConfig, discoveryConfig, clusterName,
getClient(discoveryConfig));
+ }
+
+ protected Cluster discover(GatewayConfig gatewayConfig,
+ ServiceDiscoveryConfig discoveryConfig,
+ String clusterName,
+ DiscoveryApiClient client) {
+ ServiceDiscovery.Cluster cluster = null;
+
+ if (clusterName == null || clusterName.isEmpty()) {
+ log.missingDiscoveryCluster();
+ throw new IllegalArgumentException("The cluster configuration is missing
from, or invalid in, the discovery configuration.");
+ }
+
+ try {
+ cluster = discoverCluster(client, clusterName);
+ } catch (ApiException e) {
+ log.clusterDiscoveryError(clusterName, e);
+ }
+
+ return cluster;
+ }
+
+ private static List<ApiCluster> getClusters(DiscoveryApiClient client) {
+ List<ApiCluster> clusters = new ArrayList<>();
+ try {
+ ApiClusterList clusterList = null;
+
+ ClustersResourceApi clustersResourceApi = new
ClustersResourceApi(client);
+ if (client.isKerberos()) {
+ clusterList =
+ Subject.doAs(getSubject(), (PrivilegedAction<ApiClusterList>) ()
-> {
+ try {
+ return clustersResourceApi.readClusters(CLUSTER_TYPE_ANY,
VIEW_SUMMARY);
+ } catch (Exception e) {
+ log.clusterDiscoveryError(CLUSTER_TYPE_ANY, e);
+ }
+ return null;
+ });
+ } else {
+ clusterList = clustersResourceApi.readClusters(CLUSTER_TYPE_ANY,
VIEW_SUMMARY);
+ }
+
+ if (clusterList != null) {
+ clusters.addAll(clusterList.getItems());
+ }
+ } catch (Exception e) {
+ log.clusterDiscoveryError(CLUSTER_TYPE_ANY, e); // TODO: PJZ: Better
error message here?
+ }
+
+ return clusters;
+ }
+
+
+ private static Cluster discoverCluster(DiscoveryApiClient client, String
clusterName) throws ApiException {
+ ClouderaManagerCluster cluster = null;
+
+ ServicesResourceApi servicesResourceApi = new ServicesResourceApi(client);
+ RolesResourceApi rolesResourceApi = new RolesResourceApi(client);
+
+ log.discoveringCluster(clusterName);
+
+ cluster = new ClouderaManagerCluster(clusterName);
+
+ Set<ServiceModel> serviceModels = new HashSet<>();
+ ServiceLoader<ServiceModelGenerator> loader =
ServiceLoader.load(ServiceModelGenerator.class);
+
+ ApiServiceList serviceList = getClusterServices(servicesResourceApi,
clusterName, client.isKerberos());
+ if (serviceList != null) {
+ for (ApiService service : serviceList.getItems()) {
+ String serviceName = service.getName();
+ log.discoveredService(serviceName, service.getType());
+ ApiServiceConfig serviceConfig =
+ getServiceConfig(servicesResourceApi, clusterName, serviceName,
client.isKerberos());
+ ApiRoleList roleList = getRoles(rolesResourceApi, clusterName,
serviceName, client.isKerberos());
+ if (roleList != null) {
+ for (ApiRole role : roleList.getItems()) {
+ String roleName = role.getName();
+ log.discoveredServiceRole(roleName, role.getType());
+ ApiConfigList roleConfig =
+ getRoleConfig(rolesResourceApi, clusterName, serviceName,
roleName, client.isKerberos());
+
+ for (ServiceModelGenerator serviceModelGenerator : loader) {
+ if (serviceModelGenerator.handles(service, serviceConfig, role,
roleConfig)) {
+ serviceModelGenerator.setApiClient(client);
+ ServiceModel serviceModel =
serviceModelGenerator.generateService(service, serviceConfig, role, roleConfig);
+ serviceModels.add(serviceModel);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ cluster.addServiceModels(serviceModels);
+
+ return cluster;
+ }
+
+ private static ApiServiceList getClusterServices(final ServicesResourceApi
servicesResourceApi,
+ final String
clusterName,
+ final boolean
isKerberos) {
+ ApiServiceList serviceList = null;
+ if (isKerberos) {
+ serviceList =
+ Subject.doAs(getSubject(), (PrivilegedAction<ApiServiceList>) () -> {
+ try {
+ return servicesResourceApi.readServices(clusterName,
VIEW_SUMMARY);
+ } catch (Exception e) {
+ log.failedToAccessServiceConfigs(clusterName, e);
+ }
+ return null;
+ });
+ } else {
+ try {
+ serviceList = servicesResourceApi.readServices(clusterName,
VIEW_SUMMARY);
+ } catch (ApiException e) {
+ log.failedToAccessServiceConfigs(clusterName, e);
+ }
+ }
+ return serviceList;
+ }
+
+ private static ApiServiceConfig getServiceConfig(final ServicesResourceApi
servicesResourceApi,
+ final String clusterName,
+ final String serviceName,
+ final boolean isKerberos) {
+ ApiServiceConfig serviceConfig = null;
+ if (isKerberos) {
+ serviceConfig =
+ Subject.doAs(getSubject(), (PrivilegedAction<ApiServiceConfig>) ()
-> {
+ try {
+ return servicesResourceApi.readServiceConfig(clusterName,
serviceName, VIEW_FULL);
+ } catch (Exception e) {
+ log.failedToAccessServiceConfigs(clusterName, e);
+ }
+ return null;
+ });
+ } else {
+ try {
+ serviceConfig = servicesResourceApi.readServiceConfig(clusterName,
serviceName, VIEW_FULL);
+ } catch (Exception e) {
+ log.failedToAccessServiceConfigs(clusterName, e);
+ }
+ }
+ return serviceConfig;
+ }
+
+ private static ApiRoleList getRoles(RolesResourceApi rolesResourceApi,
+ String clusterName,
+ String serviceName,
+ boolean isKerberos) {
+ ApiRoleList roleList = null;
+
+ if (isKerberos) {
+ roleList =
+ Subject.doAs(getSubject(), (PrivilegedAction<ApiRoleList>) () -> {
+ try {
+ return rolesResourceApi.readRoles(clusterName, serviceName, "",
VIEW_SUMMARY);
+ } catch (Exception e) {
+ log.failedToAccessServiceRoleConfigs(clusterName, e);
+ }
+ return null;
+ });
+ } else {
+ try {
+ roleList = rolesResourceApi.readRoles(clusterName, serviceName, "",
VIEW_SUMMARY);
+ } catch (ApiException e) {
+ log.failedToAccessServiceRoleConfigs(clusterName, e);
+ }
+ }
+
+ return roleList;
+ }
+
+ private static ApiConfigList getRoleConfig(RolesResourceApi rolesResourceApi,
+ String clusterName,
+ String serviceName,
+ String roleName,
+ boolean isKerberos) {
+ ApiConfigList roleConfig = null;
+ if (isKerberos) {
+ roleConfig =
+ Subject.doAs(getSubject(), (PrivilegedAction<ApiConfigList>) () -> {
+ try {
+ return rolesResourceApi.readRoleConfig(clusterName, roleName,
serviceName, VIEW_FULL);
+ } catch (Exception e) {
+ log.failedToAccessServiceRoleConfigs(clusterName, e);
+ }
+ return null;
+ });
+ } else {
+ try {
+ roleConfig = rolesResourceApi.readRoleConfig(clusterName, roleName,
serviceName, VIEW_FULL);
+ } catch (ApiException e) {
+ log.failedToAccessServiceRoleConfigs(clusterName, e);
+ }
+ }
+ return roleConfig;
+ }
+
+ private static Subject getSubject() {
+ Subject subject = SubjectUtils.getCurrentSubject();
+ if (subject == null) {
+ subject = login();
+ }
+ return subject;
+ }
+
+ private static Subject login() {
+ Subject subject = null;
+ String kerberosLoginConfig = getKerberosLoginConfig();
+ if (kerberosLoginConfig != null) {
+ try {
+ Configuration jaasConf = new JAASClientConfig((new
File(kerberosLoginConfig)).toURI().toURL());
+ LoginContext lc = new LoginContext(JGSS_LOGIN_MODULE,
+ null,
+ null,
+ jaasConf);
+ lc.login();
+ subject = lc.getSubject();
+ } catch (Exception e) {
+ log.failedKerberosLogin(kerberosLoginConfig, JGSS_LOGIN_MODULE, e);
+ }
+ }
+
+ return subject;
+ }
+
+ private static final class JAASClientConfig extends Configuration {
+
+ private static final Configuration baseConfig =
Configuration.getConfiguration();
+
+ private Configuration configFile;
+
+ JAASClientConfig(URL configFileURL) throws Exception {
+ if (configFileURL != null) {
+ this.configFile = ConfigurationFactory.create(configFileURL.toURI());
+ }
+ }
+
+ @Override
+ public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
+ AppConfigurationEntry[] result = null;
+
+ // Try the config file if it exists
+ if (configFile != null) {
+ result = configFile.getAppConfigurationEntry(name);
+ }
+
+ // If the entry isn't there, delegate to the base configuration
+ if (result == null) {
+ result = baseConfig.getAppConfigurationEntry(name);
+ }
+
+ return result;
+ }
+ }
+
+ @SuppressWarnings("PMD.AvoidAccessibilityAlteration")
+ private static class ConfigurationFactory {
+
+ private static final Class implClazz;
+ static {
+ // Oracle and OpenJDK use the Sun implementation
+ String implName = System.getProperty("java.vendor").contains("IBM") ?
+ "com.ibm.security.auth.login.ConfigFile" :
"com.sun.security.auth.login.ConfigFile";
+
+ log.usingJAASConfigurationFileImplementation(implName);
+ Class clazz = null;
+ try {
+ clazz = Class.forName(implName, false,
Thread.currentThread().getContextClassLoader());
+ } catch (ClassNotFoundException e) {
+ log.failedToLoadJAASConfigurationFileImplementation(implName, e);
+ }
+
+ implClazz = clazz;
+ }
+
+ static Configuration create(URI uri) {
+ Configuration config = null;
+
+ if (implClazz != null) {
+ try {
+ Constructor ctor = implClazz.getDeclaredConstructor(URI.class);
+ config = (Configuration) ctor.newInstance(uri);
+ } catch (Exception e) {
+
log.failedToInstantiateJAASConfigurationFileImplementation(implClazz.getCanonicalName(),
e);
+ }
+ } else {
+ log.noJAASConfigurationFileImplementation();
+ }
+
+ return config;
+ }
+ }
+
+ private static String getKerberosLoginConfig() {
+ return System.getProperty(GatewayConfig.KRB5_LOGIN_CONFIG, "");
+ }
+
+}
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
new file mode 100644
index 0000000..21e2049
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryMessages.java
@@ -0,0 +1,97 @@
+/*
+ * 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 org.apache.knox.gateway.i18n.messages.Message;
+import org.apache.knox.gateway.i18n.messages.MessageLevel;
+import org.apache.knox.gateway.i18n.messages.Messages;
+import org.apache.knox.gateway.i18n.messages.StackTrace;
+
+@Messages(logger="org.apache.knox.gateway.topology.discovery.cm")
+public interface ClouderaManagerServiceDiscoveryMessages {
+
+ @Message(level = MessageLevel.INFO, text = "Discovered cluster: {0} ({1})")
+ void discoveredCluster(String clusterName, String version);
+
+ @Message(level = MessageLevel.INFO, text = "Performing cluster discovery for
\"{0}\"")
+ void discoveringCluster(String clusterName);
+
+ @Message(level = MessageLevel.INFO, text = "Discovered service: {0} ({1})")
+ void discoveredService(String serviceName, String serviceType);
+
+ @Message(level = MessageLevel.INFO, text = "Discovered service role: {0}
({1})")
+ void discoveredServiceRole(String roleName, String roleType);
+
+ @Message(level = MessageLevel.ERROR,
+ text = "Failed Kerberos login {0} ({1}): {2}")
+ void failedKerberosLogin(String jaasLoginConfig,
+ String entryName,
+ @StackTrace(level = MessageLevel.DEBUG) Exception
e);
+
+ @Message(level = MessageLevel.DEBUG, text = "Using JAAS configuration file
implementation: {0}")
+ void usingJAASConfigurationFileImplementation(String implementation);
+
+ @Message(level = MessageLevel.ERROR,
+ text = "Failed to load JAAS configuration file implementation {0}: {1}")
+ void failedToLoadJAASConfigurationFileImplementation(String
implementationName,
+ @StackTrace(level =
MessageLevel.DEBUG) Exception e);
+
+ @Message(level = MessageLevel.ERROR,
+ text = "Failed to instantiate JAAS configuration file implementation
{0}: {1}")
+ void failedToInstantiateJAASConfigurationFileImplementation(String
implementationName,
+ @StackTrace(level =
MessageLevel.DEBUG) Exception e);
+
+ @Message(level = MessageLevel.ERROR, text = "No JAAS configuration file
implementation found.")
+ void noJAASConfigurationFileImplementation();
+
+ @Message(level = MessageLevel.ERROR,
+ text = "Encountered an error during cluster ({0}) discovery: {1}")
+ void clusterDiscoveryError(String clusterName, @StackTrace(level =
MessageLevel.DEBUG) Exception e);
+
+ @Message(level = MessageLevel.ERROR,
+ text = "Failed to access the service configurations for cluster ({0})
discovery")
+ void failedToAccessServiceConfigs(String clusterName, @StackTrace(level =
MessageLevel.DEBUG) Exception e);
+
+ @Message(level = MessageLevel.ERROR,
+ text = "Failed to access the service role configurations for cluster
({0}) discovery")
+ void failedToAccessServiceRoleConfigs(String clusterName, @StackTrace(level
= MessageLevel.DEBUG) Exception e);
+
+ @Message(level = MessageLevel.ERROR,
+ text = "No address for Cloudera Manager service discovery has been
configured.")
+ void missingDiscoveryAddress();
+
+ @Message(level = MessageLevel.ERROR,
+ text = "No cluster for Cloudera Manager service discovery has been
configured.")
+ void missingDiscoveryCluster();
+
+ @Message(level = MessageLevel.ERROR,
+ text = "Encountered an error attempting to determine the user for alias
{0} : {1}")
+ void aliasServiceUserError(String alias, String error);
+
+ @Message(level = MessageLevel.ERROR,
+ text = "Encountered an error attempting to determine the password for
alias {0} : {1}")
+ void aliasServicePasswordError(String alias, String error);
+
+ @Message(level = MessageLevel.ERROR,
+ text = "No user configured for Cloudera Manager service discovery.")
+ void aliasServiceUserNotFound();
+
+ @Message(level = MessageLevel.ERROR,
+ text = "No password configured for Cloudera Manager service discovery.")
+ void aliasServicePasswordNotFound();
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryType.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryType.java
new file mode 100644
index 0000000..b5949da
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryType.java
@@ -0,0 +1,37 @@
+/*
+ * 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 org.apache.knox.gateway.topology.discovery.ServiceDiscovery;
+import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryType;
+
+/**
+ * ClouderaManager-based service discovery implementation type.
+ */
+public class ClouderaManagerServiceDiscoveryType implements
ServiceDiscoveryType {
+
+ @Override
+ public String getType() {
+ return ClouderaManagerServiceDiscovery.TYPE;
+ }
+
+ @Override
+ public ServiceDiscovery newInstance() {
+ return new ClouderaManagerServiceDiscovery();
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/DiscoveryApiClient.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/DiscoveryApiClient.java
new file mode 100644
index 0000000..901586c
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/DiscoveryApiClient.java
@@ -0,0 +1,104 @@
+/*
+ * 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.client.ApiClient;
+import org.apache.knox.gateway.config.ConfigurationException;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.AliasServiceException;
+import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryConfig;
+
+import static
org.apache.knox.gateway.topology.discovery.cm.ClouderaManagerServiceDiscovery.API_PATH;
+import static
org.apache.knox.gateway.topology.discovery.cm.ClouderaManagerServiceDiscovery.DEFAULT_USER_ALIAS;
+import static
org.apache.knox.gateway.topology.discovery.cm.ClouderaManagerServiceDiscovery.DEFAULT_PWD_ALIAS;
+
+
+public class DiscoveryApiClient extends ApiClient {
+
+ private ClouderaManagerServiceDiscoveryMessages log =
+ MessagesFactory.get(ClouderaManagerServiceDiscoveryMessages.class);
+
+ private boolean isKerberos;
+
+ DiscoveryApiClient(ServiceDiscoveryConfig discoveryConfig, AliasService
aliasService) {
+ configure(discoveryConfig, aliasService);
+ }
+
+ boolean isKerberos() {
+ return isKerberos;
+ }
+
+ private void configure(ServiceDiscoveryConfig config, AliasService
aliasService) {
+ String apiAddress = config.getAddress();
+ apiAddress += (apiAddress.endsWith("/") ? API_PATH : "/" + API_PATH);
+
+ setBasePath(apiAddress);
+
+ String username = config.getUser();
+ String passwordAlias = config.getPasswordAlias();
+
+ String password = null;
+ // If no configured username, then use default username alias
+ if (username == null) {
+ if (aliasService != null) {
+ try {
+ char[] defaultUser =
aliasService.getPasswordFromAliasForGateway(DEFAULT_USER_ALIAS);
+ if (defaultUser != null) {
+ username = new String(defaultUser);
+ }
+ } catch (AliasServiceException e) {
+ log.aliasServiceUserError(DEFAULT_USER_ALIAS,
e.getLocalizedMessage());
+ }
+ }
+
+ // If username is still null
+ if (username == null) {
+ log.aliasServiceUserNotFound();
+ throw new ConfigurationException("No username is configured for
Cloudera Manager service discovery.");
+ }
+ }
+
+ if (aliasService != null) {
+ // If no password alias is configured, then try the default alias
+ if (passwordAlias == null) {
+ passwordAlias = DEFAULT_PWD_ALIAS;
+ }
+
+ try {
+ char[] pwd =
aliasService.getPasswordFromAliasForGateway(passwordAlias);
+ if (pwd != null) {
+ password = new String(pwd);
+ }
+
+ } catch (AliasServiceException e) {
+ log.aliasServicePasswordError(passwordAlias, e.getLocalizedMessage());
+ }
+ }
+
+ // If the password could not be determined
+ if (password == null) {
+ log.aliasServicePasswordNotFound();
+ isKerberos = Boolean.getBoolean(GatewayConfig.HADOOP_KERBEROS_SECURED);
+ }
+
+ setUsername(username);
+ setPassword(password);
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ServiceModel.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ServiceModel.java
new file mode 100644
index 0000000..6e4f09e
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ServiceModel.java
@@ -0,0 +1,73 @@
+/*
+ * 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 java.util.Objects;
+
+public class ServiceModel {
+
+ public enum Type {API, UI}
+
+ private final Type type;
+ private final String service;
+ private final String serviceUrl;
+
+ public ServiceModel(Type type,
+ String service,
+ String serviceUrl) {
+ this.type = type;
+ this.service = service;
+ this.serviceUrl = serviceUrl;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ public String getService() {
+ return service;
+ }
+
+ public String getServiceUrl() {
+ return serviceUrl;
+ }
+
+ @Override
+ public String toString() {
+ return getService() + '-' + getServiceUrl();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, service, serviceUrl);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ ServiceModel other = (ServiceModel) obj;
+ return getType().equals(other.getType()) &&
+ getService().equals(other.getService()) &&
+ getServiceUrl().equals(other.getServiceUrl());
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ServiceModelGenerator.java
new file mode 100644
index 0000000..6c0cdc8
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/ServiceModelGenerator.java
@@ -0,0 +1,39 @@
+/*
+ * 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.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+
+public interface ServiceModelGenerator {
+
+ void setApiClient(DiscoveryApiClient client);
+
+ boolean handles(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig);
+
+ ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException;
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/AbstractServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/AbstractServiceModelGenerator.java
new file mode 100644
index 0000000..e4badc9
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/AbstractServiceModelGenerator.java
@@ -0,0 +1,76 @@
+/*
+ * 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.model;
+
+import com.cloudera.api.swagger.client.ApiClient;
+import com.cloudera.api.swagger.model.ApiConfig;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.DiscoveryApiClient;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModelGenerator;
+
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public abstract class AbstractServiceModelGenerator implements
ServiceModelGenerator {
+
+ private DiscoveryApiClient client;
+
+ @Override
+ public void setApiClient(DiscoveryApiClient client) {
+ this.client = client;
+ }
+
+ protected ApiClient getClient() {
+ return client;
+ }
+
+ protected String getServiceConfigValue(ApiServiceConfig serviceConfig,
String key) {
+ return getConfigValue(key, serviceConfig.getItems());
+ }
+
+ protected String getRoleConfigValue(ApiConfigList roleConfig, String key) {
+ return getConfigValue(key, roleConfig.getItems());
+ }
+
+ protected String getConfigValue(String key, List<ApiConfig> items) {
+ for (ApiConfig config : items) {
+ if (key.equals(config.getName())) {
+ String value = config.getValue();
+ if (value != null) {
+ return value;
+ }
+ return config.getDefault();
+ }
+ }
+ return null;
+ }
+
+ protected String getSafetyValveValue(String safetyValve, String key) {
+ String val = null;
+ if (safetyValve != null) {
+ Pattern p = Pattern.compile("<property><name>" + key +
"</name><value>(.*?)</value></property>");
+ Matcher m = p.matcher(safetyValve.replaceAll("\\s",""));
+ if (m.find()) {
+ val = m.group(1);
+ }
+ }
+ return val;
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/atlas/AtlasAPIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/atlas/AtlasAPIServiceModelGenerator.java
new file mode 100644
index 0000000..32edd66
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/atlas/AtlasAPIServiceModelGenerator.java
@@ -0,0 +1,39 @@
+/*
+ * 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.model.atlas;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class AtlasAPIServiceModelGenerator extends AtlasServiceModelGenerator {
+ private static final String SERVICE = "ATLAS-API";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ return new ServiceModel(ServiceModel.Type.API,
+ SERVICE,
+ super.generateService(service, serviceConfig, role,
roleConfig).getServiceUrl());
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/atlas/AtlasServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/atlas/AtlasServiceModelGenerator.java
new file mode 100644
index 0000000..3888d2e
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/atlas/AtlasServiceModelGenerator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.model.atlas;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class AtlasServiceModelGenerator extends AbstractServiceModelGenerator {
+ private static final String SERVICE = "ATLAS";
+ private static final String SERVICE_TYPE = "ATLAS";
+ private static final String ROLE_TYPE = "ATLAS_SERVER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port;
+ boolean sslEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"ssl_enabled"));
+ if(sslEnabled) {
+ scheme = "https";
+ port = getRoleConfigValue(roleConfig, "atlas_server_https_port");
+ } else {
+ scheme = "http";
+ port = getRoleConfigValue(roleConfig, "atlas_server_http_port");
+ }
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/atlas/AtlasUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/atlas/AtlasUIServiceModelGenerator.java
new file mode 100644
index 0000000..43f389a
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/atlas/AtlasUIServiceModelGenerator.java
@@ -0,0 +1,39 @@
+/*
+ * 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.model.atlas;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class AtlasUIServiceModelGenerator extends
AtlasAPIServiceModelGenerator {
+ private static final String SERVICE = "ATLAS-API"; // TODO: PJZ: Should this
really be -API?
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ super.generateService(service, serviceConfig,
role, roleConfig).getServiceUrl());
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hbase/HBaseUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hbase/HBaseUIServiceModelGenerator.java
new file mode 100644
index 0000000..59fbf7d
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hbase/HBaseUIServiceModelGenerator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.model.hbase;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class HBaseUIServiceModelGenerator extends
AbstractServiceModelGenerator {
+
+ private static final String SERVICE = "HBASEUI";
+ private static final String SERVICE_TYPE = "HBASE";
+ private static final String ROLE_TYPE = "MASTER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port = getRoleConfigValue(roleConfig, "hbase_master_info_port");
+ boolean sslEnabled =
Boolean.parseBoolean(getServiceConfigValue(serviceConfig,
"hbase_hadoop_ssl_enabled"));
+ if(sslEnabled) {
+ scheme = "https";
+ } else {
+ scheme = "http";
+ }
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hbase/WebHBaseServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hbase/WebHBaseServiceModelGenerator.java
new file mode 100644
index 0000000..c47babd
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hbase/WebHBaseServiceModelGenerator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.model.hbase;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class WebHBaseServiceModelGenerator extends
AbstractServiceModelGenerator {
+
+ private static final String SERVICE = "WEBHBASE";
+ private static final String SERVICE_TYPE = "HBASE";
+ private static final String ROLE_TYPE = "HBASERESTSERVER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port = getRoleConfigValue(roleConfig, "hbase_restserver_port");
+ boolean sslEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"hbase_restserver_ssl_enable"));
+ if(sslEnabled) {
+ scheme = "https";
+ } else {
+ scheme = "http";
+ }
+ return new ServiceModel(ServiceModel.Type.API,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hdfs/HdfsUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hdfs/HdfsUIServiceModelGenerator.java
new file mode 100644
index 0000000..522f958
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hdfs/HdfsUIServiceModelGenerator.java
@@ -0,0 +1,51 @@
+/*
+ * 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.model.hdfs;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+import java.util.Locale;
+
+public class HdfsUIServiceModelGenerator extends NameNodeServiceModelGenerator
{
+ private static final String SERVICE = "HDFSUI";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port;
+ boolean sslEnabled =
Boolean.parseBoolean(getServiceConfigValue(serviceConfig,
"hdfs_hadoop_ssl_enabled"));
+ if(sslEnabled) {
+ scheme = "https";
+ port = getRoleConfigValue(roleConfig, "dfs_https_port");
+ } else {
+ scheme = "http";
+ port = getRoleConfigValue(roleConfig, "dfs_http_port");
+ }
+ String namenodeUrl = String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port);
+ return new ServiceModel(ServiceModel.Type.UI, SERVICE, namenodeUrl);
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hdfs/NameNodeServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hdfs/NameNodeServiceModelGenerator.java
new file mode 100644
index 0000000..230a1f3
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hdfs/NameNodeServiceModelGenerator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.model.hdfs;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class NameNodeServiceModelGenerator extends
AbstractServiceModelGenerator {
+ private static final String SERVICE = "NAMENODE";
+ private static final String SERVICE_TYPE = "HDFS";
+ private static final String ROLE_TYPE = "NAMENODE";
+
+ @Override
+ public boolean handles(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ boolean haEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"autofailover_enabled"));
+ String serviceUrl;
+ if(haEnabled) {
+ String nameservice = getRoleConfigValue(roleConfig,
"dfs_federation_namenode_nameservice");
+ serviceUrl = String.format(Locale.getDefault(), "hdfs://%s",
nameservice);
+ } else {
+ String hostname = role.getHostRef().getHostname();
+ String port = getRoleConfigValue(roleConfig, "namenode_port");
+ serviceUrl = String.format(Locale.getDefault(), "hdfs://%s:%s",
hostname, port);
+ }
+ return new ServiceModel(ServiceModel.Type.API, SERVICE, serviceUrl);
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hdfs/WebHdfsServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hdfs/WebHdfsServiceModelGenerator.java
new file mode 100644
index 0000000..469ac39
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hdfs/WebHdfsServiceModelGenerator.java
@@ -0,0 +1,49 @@
+/*
+ * 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.model.hdfs;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class WebHdfsServiceModelGenerator extends HdfsUIServiceModelGenerator {
+ private static final String SERVICE = "WEBHDFS";
+ private static final String WEBHDFS_SUFFIX = "/webhdfs";
+
+ @Override
+ public boolean handles(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ return super.handles(service, serviceConfig, role, roleConfig) &&
+ Boolean.parseBoolean(getServiceConfigValue(serviceConfig,
"dfs_webhdfs_enabled"));
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ String serviceUrl =
+ super.generateService(service, serviceConfig, role,
roleConfig).getServiceUrl() + WEBHDFS_SUFFIX;
+ return new ServiceModel(ServiceModel.Type.API, SERVICE, serviceUrl);
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hive/HiveServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hive/HiveServiceModelGenerator.java
new file mode 100644
index 0000000..f01ff02
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hive/HiveServiceModelGenerator.java
@@ -0,0 +1,65 @@
+/*
+ * 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.model.hive;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class HiveServiceModelGenerator extends AbstractServiceModelGenerator {
+
+ private static final String SERVICE = "HIVE";
+ private static final String SERVICE_TYPE = "HIVE";
+ private static final String ROLE_TYPE = "HIVESERVER2";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType()) && checkHiveServer2HTTPMode(roleConfig);
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ String hostname = role.getHostRef().getHostname();
+ String hs2SafetyValve = getRoleConfigValue(roleConfig,
"hive_hs2_config_safety_valve");
+ String port = getSafetyValveValue(hs2SafetyValve,
"hive.server2.thrift.http.port");
+ String httpPath = getSafetyValveValue(hs2SafetyValve,
"hive.server2.thrift.http.path");
+ boolean sslEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"hive.server2.use.SSL"));
+ String scheme = sslEnabled ? "https" : "http";
+ return new ServiceModel(ServiceModel.Type.API,
+ SERVICE,
+ String.format(Locale.getDefault(),
"%s://%s:%s/%s", scheme, hostname, port, httpPath));
+ }
+
+ private boolean checkHiveServer2HTTPMode(ApiConfigList roleConfig) {
+ String hiveServer2SafetyValve = getRoleConfigValue(roleConfig,
"hive_hs2_config_safety_valve");
+ if(hiveServer2SafetyValve != null) {
+ String transportMode = getSafetyValveValue(hiveServer2SafetyValve,
"hive.server2.transport.mode");
+ return "http".equals(transportMode);
+ }
+ return false;
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hue/HueLBServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hue/HueLBServiceModelGenerator.java
new file mode 100644
index 0000000..63eb0b6
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hue/HueLBServiceModelGenerator.java
@@ -0,0 +1,52 @@
+/*
+ * 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.model.hue;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class HueLBServiceModelGenerator extends AbstractServiceModelGenerator {
+
+ private static final String SERVICE = "HUE";
+ private static final String SERVICE_TYPE = "HUE";
+ private static final String ROLE_TYPE = "HUE_LOAD_BALANCER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme = "http";
+ String port = getRoleConfigValue(roleConfig, "listen");
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hue/HueServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hue/HueServiceModelGenerator.java
new file mode 100644
index 0000000..12e4eb3
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/hue/HueServiceModelGenerator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.model.hue;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class HueServiceModelGenerator extends AbstractServiceModelGenerator {
+
+ private static final String SERVICE = "HUE";
+ private static final String SERVICE_TYPE = "HUE";
+ private static final String ROLE_TYPE = "HUE_SERVER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port = getRoleConfigValue(roleConfig, "hue_http_port");
+ boolean sslEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"ssl_enable"));
+ if(sslEnabled) {
+ scheme = "https";
+ } else {
+ scheme = "http";
+ }
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/livy/LivyServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/livy/LivyServiceModelGenerator.java
new file mode 100644
index 0000000..48c3f9d
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/livy/LivyServiceModelGenerator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.model.livy;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class LivyServiceModelGenerator extends AbstractServiceModelGenerator {
+
+ private static final String SERVICE = "LIVYSERVER";
+ private static final String SERVICE_TYPE = "LIVY";
+ private static final String ROLE_TYPE = "LIVY_SERVER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port = getRoleConfigValue(roleConfig, "livy_server_port");
+ boolean sslEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"ssl_enabled"));
+ if(sslEnabled) {
+ scheme = "https";
+ } else {
+ scheme = "http";
+ }
+ return new ServiceModel(ServiceModel.Type.API,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/livy/LivyUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/livy/LivyUIServiceModelGenerator.java
new file mode 100644
index 0000000..3c8160a
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/livy/LivyUIServiceModelGenerator.java
@@ -0,0 +1,39 @@
+/*
+ * 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.model.livy;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class LivyUIServiceModelGenerator extends LivyServiceModelGenerator {
+
+ private static final String SERVICE = "LIVYSERVER";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String serviceUrl = super.generateService(service, serviceConfig, role,
roleConfig).getServiceUrl();
+ return new ServiceModel(ServiceModel.Type.UI, SERVICE, serviceUrl);
+ }
+
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/oozie/OozieServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/oozie/OozieServiceModelGenerator.java
new file mode 100644
index 0000000..d31c020
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/oozie/OozieServiceModelGenerator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.model.oozie;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class OozieServiceModelGenerator extends AbstractServiceModelGenerator {
+
+ private static final String SERVICE = "OOZIE";
+ private static final String SERVICE_TYPE = "OOZIE";
+ private static final String ROLE_TYPE = "OOZIE_SERVER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port;
+ boolean sslEnabled =
Boolean.parseBoolean(getServiceConfigValue(serviceConfig, "oozie_use_ssl"));
+ if(sslEnabled) {
+ scheme = "https";
+ port = getRoleConfigValue(roleConfig, "oozie_https_port");
+ } else {
+ scheme = "http";
+ port = getRoleConfigValue(roleConfig, "oozie_http_port");
+ }
+ return new ServiceModel(ServiceModel.Type.API,
+ SERVICE,
+ String.format(Locale.getDefault(),
"%s://%s:%s/oozie/", scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/oozie/OozieUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/oozie/OozieUIServiceModelGenerator.java
new file mode 100644
index 0000000..d5d8b27
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/oozie/OozieUIServiceModelGenerator.java
@@ -0,0 +1,39 @@
+/*
+ * 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.model.oozie;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class OozieUIServiceModelGenerator extends OozieServiceModelGenerator {
+ private static final String SERVICE = "OOZIEUI";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ super.generateService(service, serviceConfig,
role, roleConfig).getServiceUrl());
+ }
+
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/ranger/RangerServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/ranger/RangerServiceModelGenerator.java
new file mode 100644
index 0000000..f39f707
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/ranger/RangerServiceModelGenerator.java
@@ -0,0 +1,59 @@
+/*
+ * 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.model.ranger;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class RangerServiceModelGenerator extends AbstractServiceModelGenerator
{
+ private static final String SERVICE = "RANGER";
+ private static final String SERVICE_TYPE = "RANGER";
+ private static final String ROLE_TYPE = "RANGER_ADMIN";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port;
+ boolean sslEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"ssl_enabled"));
+ if(sslEnabled) {
+ scheme = "https";
+ port = getServiceConfigValue(serviceConfig, "ranger_service_https_port");
+ } else {
+ scheme = "http";
+ port = getServiceConfigValue(serviceConfig, "ranger_service_http_port");
+ }
+ return new ServiceModel(ServiceModel.Type.API,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/ranger/RangerUIAPIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/ranger/RangerUIAPIServiceModelGenerator.java
new file mode 100644
index 0000000..b635547
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/ranger/RangerUIAPIServiceModelGenerator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.model.ranger;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class RangerUIAPIServiceModelGenerator extends
RangerServiceModelGenerator {
+ private static final String SERVICE = "RANGER";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ super.generateService(service, serviceConfig,
role, roleConfig).getServiceUrl());
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/ranger/RangerUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/ranger/RangerUIServiceModelGenerator.java
new file mode 100644
index 0000000..5ffd097
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/ranger/RangerUIServiceModelGenerator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.model.ranger;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class RangerUIServiceModelGenerator extends RangerServiceModelGenerator
{
+ private static final String SERVICE = "RANGERUI";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String serviceUrl = super.generateService(service, serviceConfig, role,
roleConfig).getServiceUrl();
+ return new ServiceModel(ServiceModel.Type.UI, SERVICE, serviceUrl);
+ }
+
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/solr/SolrServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/solr/SolrServiceModelGenerator.java
new file mode 100644
index 0000000..bc6472b
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/solr/SolrServiceModelGenerator.java
@@ -0,0 +1,59 @@
+/*
+ * 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.model.solr;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class SolrServiceModelGenerator extends AbstractServiceModelGenerator {
+ private static final String SERVICE = "SOLR";
+ private static final String SERVICE_TYPE = "SOLR";
+ private static final String ROLE_TYPE = "SOLR_SERVER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port;
+ boolean sslEnabled =
Boolean.parseBoolean(getServiceConfigValue(serviceConfig, "solr_use_ssl"));
+ if(sslEnabled) {
+ scheme = "https";
+ port = getRoleConfigValue(roleConfig, "solr_https_port");
+ } else {
+ scheme = "http";
+ port = getRoleConfigValue(roleConfig, "solr_http_port");
+ }
+ return new ServiceModel(ServiceModel.Type.API,
+ SERVICE,
+ String.format(Locale.getDefault(),
"%s://%s:%s/solr/", scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/solr/SolrUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/solr/SolrUIServiceModelGenerator.java
new file mode 100644
index 0000000..301ba0f
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/solr/SolrUIServiceModelGenerator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.model.solr;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class SolrUIServiceModelGenerator extends SolrServiceModelGenerator {
+ private static final String SERVICE = "SOLR";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String serviceUrl = super.generateService(service, serviceConfig, role,
roleConfig).getServiceUrl();
+ return new ServiceModel(ServiceModel.Type.UI, SERVICE, serviceUrl);
+ }
+
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/spark/SparkHistoryUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/spark/SparkHistoryUIServiceModelGenerator.java
new file mode 100644
index 0000000..62b122c
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/spark/SparkHistoryUIServiceModelGenerator.java
@@ -0,0 +1,59 @@
+/*
+ * 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.model.spark;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class SparkHistoryUIServiceModelGenerator extends
AbstractServiceModelGenerator {
+ private static final String SERVICE = "SPARKHISTORYUI";
+ private static final String SERVICE_TYPE = "SPARK_ON_YARN";
+ private static final String ROLE_TYPE = "SPARK_YARN_HISTORY_SERVER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port;
+ boolean sslEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"ssl_enabled"));
+ if(sslEnabled) {
+ scheme = "https";
+ port = getRoleConfigValue(roleConfig, "ssl_server_port");
+ } else {
+ scheme = "http";
+ port = getRoleConfigValue(roleConfig, "history_server_web_port");
+ }
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/JobHistoryUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/JobHistoryUIServiceModelGenerator.java
new file mode 100644
index 0000000..b9f5609
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/JobHistoryUIServiceModelGenerator.java
@@ -0,0 +1,70 @@
+/*
+ * 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.model.yarn;
+
+import com.cloudera.api.swagger.ServicesResourceApi;
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class JobHistoryUIServiceModelGenerator extends
AbstractServiceModelGenerator {
+ private static final String SERVICE = "JOBHISTORYUI";
+ private static final String SERVICE_TYPE = "YARN";
+ private static final String ROLE_TYPE = "JOBHISTORY";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port;
+
+ if(isSSLEnabled(service, serviceConfig)) {
+ scheme = "https";
+ port = getRoleConfigValue(roleConfig,
"mapreduce_jobhistory_webapp_https_address");
+ } else {
+ scheme = "http";
+ port = getRoleConfigValue(roleConfig,
"mapreduce_jobhistory_webapp_address");
+ }
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+ private boolean isSSLEnabled(ApiService service, ApiServiceConfig
serviceConfig)
+ throws ApiException {
+ ServicesResourceApi servicesResourceApi = new
ServicesResourceApi(getClient());
+ String clusterName = service.getClusterRef().getClusterName();
+ String hdfsService = getServiceConfigValue(serviceConfig, "hdfs_service");
+ ApiServiceConfig hdfsServiceConfig =
servicesResourceApi.readServiceConfig(clusterName, hdfsService, "full");
+ return Boolean.parseBoolean(getServiceConfigValue(hdfsServiceConfig,
"hdfs_hadoop_ssl_enabled"));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/ResourceManagerUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/ResourceManagerUIServiceModelGenerator.java
new file mode 100644
index 0000000..6954045
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/ResourceManagerUIServiceModelGenerator.java
@@ -0,0 +1,40 @@
+/*
+ * 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.model.yarn;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class ResourceManagerUIServiceModelGenerator extends
YarnUIServiceModelGenerator {
+ private static final String SERVICE = "RESOURCEMANAGER";
+ private static final String RM_WS_SUFFIX = "/ws";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ String url = super.generateService(service, serviceConfig, role,
roleConfig).getServiceUrl() + RM_WS_SUFFIX;
+ return new ServiceModel(ServiceModel.Type.API, SERVICE, url);
+ }
+
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/YarnUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/YarnUIServiceModelGenerator.java
new file mode 100644
index 0000000..25136cb
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/YarnUIServiceModelGenerator.java
@@ -0,0 +1,70 @@
+/*
+ * 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.model.yarn;
+
+import com.cloudera.api.swagger.ServicesResourceApi;
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class YarnUIServiceModelGenerator extends AbstractServiceModelGenerator
{
+ private static final String SERVICE = "YARNUI";
+ private static final String SERVICE_TYPE = "YARN";
+ private static final String ROLE_TYPE = "RESOURCEMANAGER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ String hostname = role.getHostRef().getHostname();
+ String scheme;
+ String port;
+
+ if(isSSLEnabled(service, serviceConfig)) {
+ scheme = "https";
+ port = getRoleConfigValue(roleConfig,
"resourcemanager_webserver_https_port");
+ } else {
+ scheme = "http";
+ port = getRoleConfigValue(roleConfig, "resourcemanager_webserver_port");
+ }
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+ private boolean isSSLEnabled(ApiService service, ApiServiceConfig
serviceConfig)
+ throws ApiException {
+ ServicesResourceApi servicesResourceApi = new
ServicesResourceApi(getClient());
+ String clusterName = service.getClusterRef().getClusterName();
+ String hdfsService = getServiceConfigValue(serviceConfig, "hdfs_service");
+ ApiServiceConfig hdfsServiceConfig =
servicesResourceApi.readServiceConfig(clusterName, hdfsService, "full");
+ return Boolean.parseBoolean(getServiceConfigValue(hdfsServiceConfig,
"hdfs_hadoop_ssl_enabled"));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/YarnUIv2ServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/YarnUIv2ServiceModelGenerator.java
new file mode 100644
index 0000000..b71a7fe
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/YarnUIv2ServiceModelGenerator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.model.yarn;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+public class YarnUIv2ServiceModelGenerator extends YarnUIServiceModelGenerator
{
+ private static final String SERVICE = "YARNUIV2";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) throws
ApiException {
+ String serviceUrl = super.generateService(service, serviceConfig, role,
roleConfig).getServiceUrl();
+ return new ServiceModel(ServiceModel.Type.UI, SERVICE, serviceUrl);
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/zeppelin/ZeppelinUIServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/zeppelin/ZeppelinUIServiceModelGenerator.java
new file mode 100644
index 0000000..72b4e8c
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/zeppelin/ZeppelinUIServiceModelGenerator.java
@@ -0,0 +1,57 @@
+/*
+ * 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.model.zeppelin;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+import
org.apache.knox.gateway.topology.discovery.cm.model.AbstractServiceModelGenerator;
+
+import java.util.Locale;
+
+public class ZeppelinUIServiceModelGenerator extends
AbstractServiceModelGenerator {
+ private static final String SERVICE = "ZEPPELINUI";
+ private static final String SERVICE_TYPE = "ZEPPELIN";
+ private static final String ROLE_TYPE = "ZEPPELIN_SERVER";
+
+ @Override
+ public boolean handles(ApiService service, ApiServiceConfig serviceConfig,
ApiRole role, ApiConfigList roleConfig) {
+ return SERVICE_TYPE.equals(service.getType()) &&
ROLE_TYPE.equals(role.getType());
+ }
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme = "http";
+ String port = getRoleConfigValue(roleConfig, "zeppelin_server_port");
+// boolean sslEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"ssl_enabled"));
+// if(sslEnabled) {
+// scheme = "https";
+// } else {
+// scheme = "http";
+// }
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/zeppelin/ZeppelinWSServiceModelGenerator.java
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/zeppelin/ZeppelinWSServiceModelGenerator.java
new file mode 100644
index 0000000..bdf91b5
--- /dev/null
+++
b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/zeppelin/ZeppelinWSServiceModelGenerator.java
@@ -0,0 +1,49 @@
+/*
+ * 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.model.zeppelin;
+
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+import java.util.Locale;
+
+public class ZeppelinWSServiceModelGenerator extends
ZeppelinUIServiceModelGenerator {
+ private static final String SERVICE = "ZEPPELINWS";
+
+ @Override
+ public ServiceModel generateService(ApiService service,
+ ApiServiceConfig serviceConfig,
+ ApiRole role,
+ ApiConfigList roleConfig) {
+ String hostname = role.getHostRef().getHostname();
+ String scheme = "ws";
+ String port = getRoleConfigValue(roleConfig, "zeppelin_server_port");
+// boolean sslEnabled = Boolean.parseBoolean(getRoleConfigValue(roleConfig,
"ssl_enabled"));
+// if(sslEnabled) {
+// scheme = "wss";
+// } else {
+// scheme = "ws";
+// }
+ return new ServiceModel(ServiceModel.Type.UI,
+ SERVICE,
+ String.format(Locale.getDefault(), "%s://%s:%s",
scheme, hostname, port));
+ }
+
+}
diff --git
a/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.ServiceDiscoveryType
b/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.ServiceDiscoveryType
new file mode 100644
index 0000000..e199dfb
--- /dev/null
+++
b/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.ServiceDiscoveryType
@@ -0,0 +1,19 @@
+##########################################################################
+# 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.
+##########################################################################
+
+org.apache.knox.gateway.topology.discovery.cm.ClouderaManagerServiceDiscoveryType
diff --git
a/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.cm.ServiceModelGenerator
b/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.cm.ServiceModelGenerator
new file mode 100644
index 0000000..b4f485c
--- /dev/null
+++
b/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.cm.ServiceModelGenerator
@@ -0,0 +1,44 @@
+##########################################################################
+# 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.
+##########################################################################
+
+org.apache.knox.gateway.topology.discovery.cm.model.atlas.AtlasServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.atlas.AtlasAPIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.atlas.AtlasUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.hbase.HBaseUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.hbase.WebHBaseServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.hdfs.NameNodeServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.hdfs.HdfsUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.hdfs.WebHdfsServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.hive.HiveServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.hue.HueServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.hue.HueLBServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.livy.LivyServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.livy.LivyUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.oozie.OozieServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.oozie.OozieUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.ranger.RangerServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.ranger.RangerUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.ranger.RangerUIAPIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.solr.SolrServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.solr.SolrUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.spark.SparkHistoryUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.yarn.JobHistoryUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.yarn.ResourceManagerUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.yarn.YarnUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.yarn.YarnUIv2ServiceModelGenerator
+
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
new file mode 100644
index 0000000..7c32c43
--- /dev/null
+++
b/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
@@ -0,0 +1,283 @@
+/*
+ * 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.client.ApiException;
+import com.cloudera.api.swagger.client.ApiResponse;
+import com.cloudera.api.swagger.model.ApiConfig;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiHostRef;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiRoleList;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import com.cloudera.api.swagger.model.ApiServiceList;
+import com.squareup.okhttp.Call;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.topology.discovery.ServiceDiscovery;
+import org.apache.knox.gateway.topology.discovery.ServiceDiscoveryConfig;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+
+public class ClouderaManagerServiceDiscoveryTest {
+
+ @Test
+ public void testWebHDFSServiceDiscovery() {
+ GatewayConfig gwConf = EasyMock.createNiceMock(GatewayConfig.class);
+ EasyMock.replay(gwConf);
+
+ ServiceDiscoveryConfig sdConfig = createMockDiscoveryConfig();
+
+ // Create the test client for providing test response content
+ TestDiscoveryApiClient mockClient = new TestDiscoveryApiClient(sdConfig,
null);
+
+ // Prepare the service list response for the cluster
+ ApiServiceList serviceList = EasyMock.createNiceMock(ApiServiceList.class);
+ EasyMock.expect(serviceList.getItems())
+
.andReturn(Collections.singletonList(createMockApiService("NAMENODE-1",
"HDFS")))
+ .anyTimes();
+ EasyMock.replay(serviceList);
+ mockClient.addResponse(ApiServiceList.class, new
TestApiServiceListResponse(serviceList));
+
+ // Prepare the HDFS service config response for the cluster
+ Map<String, String> serviceProps = new HashMap<>();
+ serviceProps.put("hdfs_hadoop_ssl_enabled", "false");
+ serviceProps.put("dfs_webhdfs_enabled", "true");
+ ApiServiceConfig hdfsServiceConfig =
createMockApiServiceConfig(serviceProps);
+ mockClient.addResponse(ApiServiceConfig.class, new
TestApiServiceConfigResponse(hdfsServiceConfig));
+
+ // Prepare the NameNode role
+ ApiRole nnRole =
createMockApiRole("HDFS-1-NAMENODE-d0b64dd7b7611e22bc976ede61678d9e",
"NAMENODE", "test-host-1");
+ ApiRoleList nnRoleList = EasyMock.createNiceMock(ApiRoleList.class);
+
EasyMock.expect(nnRoleList.getItems()).andReturn(Collections.singletonList(nnRole)).anyTimes();
+ EasyMock.replay(nnRoleList);
+ mockClient.addResponse(ApiRoleList.class, new
TestApiRoleListResponse(nnRoleList));
+
+ // Configure the NameNode role
+ Map<String, String> roleProperties = new HashMap<>();
+ roleProperties.put("dfs_federation_namenode_nameservice", "nameservice1");
+ roleProperties.put("namenode_port", "50070");
+ roleProperties.put("dfs_http_port", "50071");
+ ApiConfigList nnRoleConfigList = createMockApiConfigList(roleProperties);
+ mockClient.addResponse(ApiConfigList.class, new
TestApiConfigListResponse(nnRoleConfigList));
+
+ // Invoke the service discovery
+ ClouderaManagerServiceDiscovery cmsd = new
ClouderaManagerServiceDiscovery(true);
+ ServiceDiscovery.Cluster cluster = cmsd.discover(gwConf, sdConfig,
"test-cluster", mockClient);
+ assertNotNull(cluster);
+ assertEquals("test-cluster", cluster.getName());
+ List<String> webhdfsURLs = cluster.getServiceURLs("WEBHDFS");
+ assertNotNull(webhdfsURLs);
+ assertEquals(1, webhdfsURLs.size());
+ assertEquals("http://test-host-1:50071/webhdfs", webhdfsURLs.get(0));
+ }
+
+ @Test
+ public void testHiveServiceDiscovery() {
+ GatewayConfig gwConf = EasyMock.createNiceMock(GatewayConfig.class);
+ EasyMock.replay(gwConf);
+
+ ServiceDiscoveryConfig sdConfig = createMockDiscoveryConfig();
+
+ // Create the test client for providing test response content
+ TestDiscoveryApiClient mockClient = new TestDiscoveryApiClient(sdConfig,
null);
+
+ // Prepare the service list response for the cluster
+ ApiServiceList serviceList = EasyMock.createNiceMock(ApiServiceList.class);
+ EasyMock.expect(serviceList.getItems())
+
.andReturn(Collections.singletonList(createMockApiService("HIVE-1", "HIVE")))
+ .anyTimes();
+ EasyMock.replay(serviceList);
+ mockClient.addResponse(ApiServiceList.class, new
TestApiServiceListResponse(serviceList));
+
+ // Prepare the HIVE service config response for the cluster
+ ApiServiceConfig hiveServiceConfig = createMockApiServiceConfig();
+ mockClient.addResponse(ApiServiceConfig.class, new
TestApiServiceConfigResponse(hiveServiceConfig));
+
+ // Prepare the HS2 role
+ ApiRole hs2Role =
createMockApiRole("HIVE-1-HIVESERVER2-d0b64dd7b7611e22bc976ede61678d9e",
"HIVESERVER2", "test-host-1");
+ ApiRoleList hiveRoleList = EasyMock.createNiceMock(ApiRoleList.class);
+
EasyMock.expect(hiveRoleList.getItems()).andReturn(Collections.singletonList(hs2Role)).anyTimes();
+ EasyMock.replay(hiveRoleList);
+ mockClient.addResponse(ApiRoleList.class, new
TestApiRoleListResponse(hiveRoleList));
+
+ // Configure the HS2 role
+ Map<String, String> roleProperties = new HashMap<>();
+ roleProperties.put("hive_hs2_config_safety_valve",
+
"<property><name>hive.server2.transport.mode</name><value>http</value></property>\n"
+
+
"<property><name>hive.server2.thrift.http.port</name><value>10001</value></property>\n"
+
+
"<property><name>hive.server2.thrift.http.path</name><value>cliService</value></property>");
+ ApiConfigList hiveRoleConfigList = createMockApiConfigList(roleProperties);
+ mockClient.addResponse(ApiConfigList.class, new
TestApiConfigListResponse(hiveRoleConfigList));
+
+ // Invoke the service discovery
+ ClouderaManagerServiceDiscovery cmsd = new
ClouderaManagerServiceDiscovery(true);
+ ServiceDiscovery.Cluster cluster = cmsd.discover(gwConf, sdConfig,
"test-cluster", mockClient);
+ assertNotNull(cluster);
+ assertEquals("test-cluster", cluster.getName());
+ List<String> hiveURLs = cluster.getServiceURLs("HIVE");
+ assertNotNull(hiveURLs);
+ assertEquals(1, hiveURLs.size());
+ assertEquals("http://test-host-1:10001/cliService", hiveURLs.get(0));
+ }
+
+ private ServiceDiscoveryConfig createMockDiscoveryConfig() {
+ return createMockDiscoveryConfig("http://localhost:1234", "itsme");
+ }
+
+ private ServiceDiscoveryConfig createMockDiscoveryConfig(String address,
String username) {
+ ServiceDiscoveryConfig config =
EasyMock.createNiceMock(ServiceDiscoveryConfig.class);
+ EasyMock.expect(config.getAddress()).andReturn(address).anyTimes();
+ EasyMock.expect(config.getUser()).andReturn(username).anyTimes();
+ EasyMock.expect(config.getPasswordAlias()).andReturn(null).anyTimes();
+ EasyMock.replay(config);
+ return config;
+ }
+
+ private ApiService createMockApiService(String name, String type) {
+ ApiService s = EasyMock.createNiceMock(ApiService.class);
+ EasyMock.expect(s.getName()).andReturn(name).anyTimes();
+ EasyMock.expect(s.getType()).andReturn(type).anyTimes();
+ EasyMock.replay(s);
+ return s;
+ }
+
+ private ApiRole createMockApiRole(String name, String type, String hostname)
{
+ ApiRole r = EasyMock.createNiceMock(ApiRole.class);
+ EasyMock.expect(r.getName()).andReturn(name).anyTimes();
+ EasyMock.expect(r.getType()).andReturn(type).anyTimes();
+ ApiHostRef hostRef = EasyMock.createNiceMock(ApiHostRef.class);
+ EasyMock.expect(hostRef.getHostname()).andReturn(hostname).anyTimes();
+ EasyMock.replay(hostRef);
+ EasyMock.expect(r.getHostRef()).andReturn(hostRef).anyTimes();
+ EasyMock.replay(r);
+ return r;
+ }
+
+ private ApiServiceConfig createMockApiServiceConfig() {
+ return createMockApiServiceConfig(Collections.emptyMap());
+ }
+
+ private ApiServiceConfig createMockApiServiceConfig(Map<String, String>
properties) {
+ ApiServiceConfig serviceConfig =
EasyMock.createNiceMock(ApiServiceConfig.class);
+ List<ApiConfig> serviceConfigs = new ArrayList<>();
+
+ for (Map.Entry<String, String> property : properties.entrySet()) {
+ ApiConfig config = EasyMock.createNiceMock(ApiConfig.class);
+
EasyMock.expect(config.getName()).andReturn(property.getKey()).anyTimes();
+
EasyMock.expect(config.getValue()).andReturn(property.getValue()).anyTimes();
+ EasyMock.replay(config);
+ serviceConfigs.add(config);
+ }
+
+
EasyMock.expect(serviceConfig.getItems()).andReturn(serviceConfigs).anyTimes();
+ EasyMock.replay(serviceConfig);
+ return serviceConfig;
+ }
+
+ private ApiConfigList createMockApiConfigList(Map<String, String>
properties) {
+ ApiConfigList configList = EasyMock.createNiceMock(ApiConfigList.class);
+ List<ApiConfig> roleConfigs = new ArrayList<>();
+
+ for (Map.Entry<String, String> property : properties.entrySet()) {
+ ApiConfig config = EasyMock.createNiceMock(ApiConfig.class);
+
EasyMock.expect(config.getName()).andReturn(property.getKey()).anyTimes();
+
EasyMock.expect(config.getValue()).andReturn(property.getValue()).anyTimes();
+ EasyMock.replay(config);
+ roleConfigs.add(config);
+ }
+
+ EasyMock.expect(configList.getItems()).andReturn(roleConfigs).anyTimes();
+ EasyMock.replay(configList);
+ return configList;
+ }
+
+ private static class TestDiscoveryApiClient extends DiscoveryApiClient {
+
+ private Map<Type, ApiResponse<?>> responseMap = new HashMap<>();
+
+ TestDiscoveryApiClient(ServiceDiscoveryConfig sdConfig, AliasService
aliasService) {
+ super(sdConfig, aliasService);
+ }
+
+ void addResponse(Type type, ApiResponse<?> response) {
+ responseMap.put(type, response);
+ }
+
+ @Override
+ boolean isKerberos() {
+ return false;
+ }
+
+ @Override
+ public <T> ApiResponse<T> execute(Call call, Type returnType) throws
ApiException {
+ return (ApiResponse<T>) responseMap.get(returnType);
+ }
+ }
+
+ private static class TestResponseBase<T> extends ApiResponse<T> {
+ protected T data;
+
+ TestResponseBase(T data) {
+ super(200, Collections.emptyMap());
+ this.data = data;
+ }
+
+ @Override
+ public T getData() {
+ return data;
+ }
+ }
+
+ private static class TestApiServiceListResponse extends
TestResponseBase<ApiServiceList> {
+ TestApiServiceListResponse(ApiServiceList data) {
+ super(data);
+ }
+ }
+
+ private static class TestApiServiceConfigResponse extends
TestResponseBase<ApiServiceConfig> {
+ TestApiServiceConfigResponse(ApiServiceConfig data) {
+ super(data);
+ }
+ }
+
+ private static class TestApiRoleListResponse extends
TestResponseBase<ApiRoleList> {
+ TestApiRoleListResponse(ApiRoleList data) {
+ super(data);
+ }
+ }
+
+ private static class TestApiConfigListResponse extends
TestResponseBase<ApiConfigList> {
+ TestApiConfigListResponse(ApiConfigList data) {
+ super(data);
+ }
+ }
+
+}
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index b500844..b8f2b4a 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -366,6 +366,10 @@
</dependency>
<dependency>
<groupId>org.apache.knox</groupId>
+ <artifactId>gateway-discovery-cm</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.knox</groupId>
<artifactId>gateway-adapter</artifactId>
</dependency>
<dependency>
diff --git a/pom.xml b/pom.xml
index e235ae1..a9ae1b7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,6 +71,7 @@
<module>gateway-i18n-logging-sl4j</module>
<module>gateway-spi</module>
<module>gateway-discovery-ambari</module>
+ <module>gateway-discovery-cm</module>
<module>gateway-server</module>
<module>gateway-server-launcher</module>
<module>gateway-server-xforwarded-filter</module>
@@ -1049,6 +1050,11 @@
</dependency>
<dependency>
<groupId>org.apache.knox</groupId>
+ <artifactId>gateway-discovery-cm</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.knox</groupId>
<artifactId>gateway-release</artifactId>
<version>${project.version}</version>
</dependency>