Introduction

Knox currently supports a number of Hadoop services, for which it can dynamically determine endpoint URLs from Ambari. Anyone is welcome to submit a patch to provide support for additional services, which in most cases won't require any code changes. The process for this will be outlined herein. Further, there may be cases where a permanent addition is not immediately desired or necessary (e.g., a proof-of-concept, a customer solution, etc...). For these cases, this article will describe the process for extending Knox's service discovery support without modifying Knox at all.

 

Service URL Construction

The knowledge about converting arbitrary service configuration properties into correct service endpoint URLs is defined in a configuration file internal to the Ambari service discovery module.

Configuration Details

This internal configuration file (ambari-service-discovery-url-mappings.xml) in gateway-discovery-ambari-<KNOX_VERSION>.jar is used to specify a URL template and the associated configuration properties to populate it. A limited degree of conditional logic is supported to accommodate things like http vs https configurations.

The simplest way to describe its contents will be by examples.

Example 1

The simplest example of one such mapping involves a service component for which there is a single configuration property which specifies the complete URL

 
<!-- This is the service mapping declaration. The name must match what is specified as a Knox topology service role -->
<service name="OOZIE">

  <!-- This is the URL pattern with palceholder(s) for values provided by properties -->
  <url-pattern>{OOZIE_URL}</url-pattern>

  <properties>
 
    <!-- This is a property, which in this simple case, matches a template placeholder -->
    <property name="OOZIE_URL">

      <!-- This is the component whose configuration will be used to lookup the value of the subsequent config property name -->
      <component>OOZIE_SERVER</component>
 
      <!-- This is the name of the component config property whose value should be assigned to the OOZIE_URL value -->
      <config-property>oozie.base.url</config-property>

    </property>
  </properties>
</service>


The OOZIE_SERVER component configuration is oozie-site
If oozie-site.xml has the property named oozie.base.url with the value http://ooziehost:11000 , then the resulting URL for the OOZIE service will be http://ooziehost:11000

 

Example 2

A slightly more complicated example involves a service component for which the complete URL is not described by a single detail, but rather multiple endpoint URL details

<service name="WEBHCAT">
  <url-pattern>http://{HOST}:{PORT}/templeton</url-pattern>
  <properties>
    <property name="HOST">
      <component>WEBHCAT_SERVER</component>
 
      <!-- This tells discovery to get the hostname for the WEBHCAT_SERVER component from Ambari -->
      <hostname/>
    </property>
    <property name="PORT">
      <component>WEBHCAT_SERVER</component>
 
      <!-- This is the name of the component config property whose value should be assigned to the PORT value -->
      <config-property>templeton.port</config-property>
</property>
  </properties>
</service>

The WEBHCAT_SERVER component configuration is webhcat-site
If webhcat-site.xml has the property named templeton.port with the value 50111 , then the resulting URL for the WEBHCAT service will be http://webhcathost:50111/templeton

 

Example 3

An even more complicated example involves a service for which HTTPS is supported, and which employs the limited conditional logic support

<service name="ATLAS">
  <url-pattern>{SCHEME}://{HOST}:{PORT}</url-pattern>
  <properties>
 
    <!-- Property for getting the ATLAS_SERVER component hostname from Ambari -->
    <property name="HOST">
      <component>ATLAS_SERVER</component>
      <hostname/>
    </property>

    <!-- Property for capturing whether TLS is enabled or not; This is not a template placeholder property -->
    <property name="TLS_ENABLED">
      <component>ATLAS_SERVER</component>
      <config-property>atlas.enableTLS</config-property>
    </property>
    <!-- Property for getting the http port ; also NOT a template placeholder property -->
    <property name="HTTP_PORT">
      <component>ATLAS_SERVER</component>
      <config-property>atlas.server.http.port</config-property>
    </property>

    <!-- Property for getting the https port ; also NOT a template placeholder property -->
    <property name="HTTPS_PORT">
      <component>ATLAS_SERVER</component>
      <config-property>atlas.server.https.port</config-property>
    </property>

    <!-- Template placeholder property, dependent on the TLS_ENABLED property value -->
    <property name="PORT">
      <config-property>
        <if property="TLS_ENABLED" value="true">
          <then>HTTPS_PORT</then>
          <else>HTTP_PORT</else>
        </if>
      </config-property>
    </property>
 
    <!-- Template placeholder property, dependent on the TLS_ENABLED property value -->
    <property name="SCHEME">
      <config-property>
        <if property="TLS_ENABLED" value="true">
          <then>https</then>
          <else>http</else>
        </if>
      </config-property>
    </property>
  </properties>
</service>

 

Adding official support for a service will involve modifying the source of this configuration in the gateway-discovery-ambari module of Knox.

 

External Configuration

The internal configuration for URL construction can be overridden or augmented by way of a configuration file in the gateway configuration directory, or an alternative file specified by a Java system property.

The default file, for which Knox will search first, is {GATEWAY_HOME}/conf/ambari-discovery-url-mappings.xml

If Knox doesn't find that file, it will check for a Java system property named org.apache.gateway.topology.discovery.ambari.config, whose value is the fully-qualified path to an XML file. This file's contents must adhere to the format outlined above.

If this configuration exists, Knox will apply it as if it were part of the internal configuration.

 

Example

If Apache SOLR weren't supported, then it could be added by creating the {GATEWAY_HOME}/conf/ambari-discovery-url-mappings.xml file with the following content:

<?xml version="1.0" encoding="utf-8"?>
<service-discovery-url-mappings>
  <service name="SOLR">
    <url-pattern>http://{HOST}:{PORT}</url-pattern>
    <properties>
      <property name="HOST">
        <component>INFRA_SOLR</component>
        <hostname/>
      </property>
      <property name="PORT">
        <component>INFRA_SOLR</component>
        <config-property>infra_solr_port</config-property>
      </property>
    </properties>
  </service>
</service-discovery-url-mappings>

 

N.B. Knox must be restarted for changes to this external configuration to be applied.

 

 

Component Configuration Mapping

To support URL construction from service configuration files, Ambari service discovery requires knowledge of the service component types and their respective relationships to configuration types. This knowledge is defined in a configuration file internal to the Ambari service discovery module.

Configuration Details

This internal configuration file (ambari-service-discovery-component-config-mapping.properties) in gateway-discovery-ambari-<KNOX_VERSION>.jar is used to define the mapping of Hadoop service component names to the configuration type from which Knox will lookup property values.

Example

NAMENODE=hdfs-site
RESOURCEMANAGER=yarn-site
HISTORYSERVER=mapred-site
OOZIE_SERVER=oozie-site
HIVE_SERVER=hive-site
WEBHCAT_SERVER=webhcat-site

 

External Configuration

The internal configuration for URL construction can be overridden or augmented by way of a configuration file in the gateway configuration directory, or an alternative file specified by a Java system property.

The default file, for which Knox will search first, is {GATEWAY_HOME}/conf/ambari-discovery-component-config.properties

If Knox doesn't find that file, it will check for a Java system property named org.apache.knox.gateway.topology.discovery.ambari.component.mapping, whose value is the fully-qualified path to a properties file. This file's contents must adhere to the format outlined above.

If this configuration exists, Knox will apply it as if it were part of the internal configuration.

Example

Following the aforementioned SOLR example, Knox needs to know in which configuration file to find the INFRA_SOLR property, so {GATEWAY_HOME}/conf/ambari-discovery-component-config.properties must be created with the following content:

INFRA_SOLR=infra-solr-env
 

This tells Knox to look for the infra_solr_port property in the infra-solr-env configuration.

N.B. Knox must be restarted for changes to this external configuration to be applied.