Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This page covers adding a UI proxy service to Apache Knox.

You may want to review the Apache Knox User’s Guide and Developer’s Guide before reading this. Also the excellent article written by Kevin Minder http://kminder.github.io/knox/2015/11/16/adding-a-service-to-knox.htmlMinder Adding a Service to Knox that is used as a template here should be read so that you have the basics under your belt with regards to REST services, service definition files, rewrite files, rewrite rules and how they all play together.

If you are new to Knox you may also want to check out ’Setting up Apache Knox in three easy steps’.

...

There is a README that should help you get started. The crux of it is this if you have Node.js and npm installed already:git clone 
Code Block
git clone https://github.com/angular/quickstart

...

 my-proj

...


cd

...

 my-proj

...

npm install

...


npm install
npm start

This will get you to a very basic hello world page on localhost:3000. So point your browser to this URL:
Code Block
http://localhost:3000/
We now want to get to a URL like the one below which goes through Knox. Don’t try this now, it won’t work until later! 

Code Block
https://localhost:8443/gateway/sandbox/example/

 

So the fundamental job of the gateway is to translate the effective request URL it receives to the target URL and then transfer the request and response bodies. We will at first ignore the request and response bodies and focus on the request URL and then so some interesting things to the response body to make it all look right. For all this to happen we will create a new Service called 'EXAMPLEUI'.
 
Lets take a look at how the two request URLs are related.

...

PartDetails
httpsThe gateway has SSL/TLS enabled: See ssl.enabled in gateway-site.xml
localhostThe gateway is listening on 0.0.0.0: See gateway.host in gateway-site.xml
8443The gateway is listening on port 8443: See gateway.port in gateway-site.xml
gatewayThe gateway context path is ‘gateway’: See gateway.path in gateway-site.xml
sandboxThe topology file that includes the WEATHER EXAMPLEUI service is named sandbox.xml
example The unique root of all EXAMPLE UI service URLs. Identified in service’s service.xml  

...

First you need to create a directory to hold your new service definition files. There are two conventions at work here that ultimately (but only loosely) relate to the content of the service.xml it will contain. Below the <GATEWAY_HOME>/data/services directory you will need to create a parent and child directory example/0.0.1. As a convention the names of these directories duplicate the values in the attributes of the root element of the contained service.xml.

Create the two files with the content shown below and place them in the directories indicated. The links also provide the files for your convenience.

 

<GATEWAY_HOME>/data/services/example/0.0.1/service.xml

Code Block
<service role="EXAMPLEUI"name="exampleui"version="0.0.1">


    <policies>


        <policy role="webappsec"/>


        <policy role="authentication"name="Anonymous"/>


        <policy role="rewrite"/>


        <policy role="authorization"/>


    </policies>


    <routes>


        <route path="/example">


        </route>


        <route path="/example/**">


        </route>


    </routes>


    <dispatch classname="org.apache.hadoop.gateway.dispatch.PassAllHeadersDispatch"/>

</service>


<GATEWAY_HOME>/data/services/example/0.0.1/rewrite.xml

 
Code Block
<rules>


    <rule dir="IN"name="EXAMPLEUI/exampleui/inbound/root"pattern="*://*:*/**/example/">


        <rewrite template="{$serviceUrl[EXAMPLEUI]}/"/>


    </rule>


    <rule dir="IN"name="EXAMPLEUI/exampleui/inbound/path"pattern="*://*:*/**/example/{**}">


        <rewrite template="{$serviceUrl[EXAMPLEUI]}/{**}"/>


    </rule>

</rules>
 

Once that is complete, the topology file must be updated to activate this new service in the runtime. In this case the sandbox.xml topology file is used but you may have another topology file such as default.xml. Edit which ever topology file you prefer and add the… markup shown below. If you aren’t using sandbox.xml be careful to replace sandbox with the name of your topology file through these examples.


<GATEWAY_HOME>/conf/topologies/sandbox.xml


 
Code Block
<topology>


  ...

  <service>

   
<role>EXAMPLEUI<
 <role>EXAMPLEUI</role>   

   
<url>http
 <url>http://
localhost
localhost:
3000<
3000</url>

  </service>

</topology>

With all of these changes made you must restart your Knox gateway server. Often times this isn’t necessary but adding a new service definition under [<GATEWAY_HOME>/data/services requires restart.

You should now be able to URL from way back at the top that accesses the UI via the gateway.

 

Code Block
https://localhost:8443/gateway/sandbox/example/

 

*Please note* the slash at the end in the above URL. We need to do some more work to get rid of that dependency and that is explained in a section further. 
For now you should be able to access the page after getting past some certification warning if you don’t have a ‘proper’ certificate installed.
Now that the new service definition is working lets go back and connect all the dots. This should help take some of the mystery out of the configuration above. The most important and confusing aspect is how values in different files are interrelated. I will focus on that.

service.xml

The service.xml file defines the high level URL patterns that will be exposed by the gateway for a service. If you are getting HTTP 404 errors there is probably a problem with this configuration.

Code Block
<service role=“EXAMPLEUI"

  • The role/implementation/version triad is used through Knox for integration plugins.
  • Think of the role as an interface in Java.
  • This attribute declares what role this service “implements”.
  • This will need to match the topology file’s <topology><service><role> for this service.

Code Block
<service name=“exampleui"

  • In the role/implementation/version triad this is the implementation.
  • Think of this as a Java implementation class name relative to an interface.
  • As a matter of convention this should match the directory beneath <GATEWAY_HOME>/data/services
  • The topology file can optionally contain <topology><service><name> but usually doesn’t. This would be used to select a specific implementation of a role if there were multiple.

 

Code Block
<service version="0.0.1"
  • As a matter of convention this should match the directory beneath the service implementation name.
  • The topology file can optionally contain <topology><service><version> but usually doesn’t. This would be used to select a specific version of an implementation there were multiple. This can be important if the protocols for a service evolve over time.

Code Block
<service><routes><route path=“/example/**"

  • This tells the gateway that all requests starting starting with /example/ are handled by this service.
  • Due to a limitation this will not include requests to /example (i.e. no trailing /) so we need another rule for that
  • The ** means zero or more paths similar to Ant.
  • The scheme, host, port, gateway and topology components are not included (e.g. https://localhost:8443/gateway/sandbox)
  • Routes can, but typically don’t, take query parameters into account.
  • In this simple form there is no direct relationship between the route path and the rewrite rules!

rewrite.xml

The rewrite.xml is configuration that drives the rewrite provider within Knox. It is important to understand that at runtime for a given topology, all of the rewrite.xml files for all active services are combined into a single file. This explains some of the seemingly complex patterns and naming conventions.

 

Code Block
<rules><rule dir="IN"
  • Here dir means direction and IN means it should apply to a request.
  • This rule is a global rule meaning that any other service can request that a URL be rewritten as they process URLs. The rewrite provider keeps distinct trees of URL patterns for IN and OUT rules so that services can be specific about which to apply.
  • If it were not global it would not have a direction and probably not a pattern in the element.
Code Block
<rules><rule name=“EXAMPLEUI/exampleui/inbound"

  • Rules can be explicitly invoked in various ways. In order to allow that they are named.
  • The convention is role/name/<service specific hierarchy>.
  • Remember that all rules share a single namespace.
Code Block
<rules><rule pattern="*://*:*/**/example/{**}"

  • Defines the URL pattern for which this rule will apply.
  • The * matches exactly one segment of the URL.
  • The ** matches zero or more segments of the URL.
  • The {**} matches zero or more query parameters and provides access to them by name.
  • The values from matched {…} segments are “consumed” by the rewrite template below.
Code Block
<rules><rule><rewrite template="{$serviceUrl[EXAMPLEUI]}/{path=**}?{**}"
  • Defines how the URL matched by the rule will be rewritten.
  • The $serviceUrl[EXAMPLEUI]} looks up the <service><url> for the <service><role>EXAMPLEUI. This is a implemented as rewrite function and is another custom extension point.
  • The {**} extracts any “unused” parameters and uses them as query parameters.

sandbox.xml

Code Block
<topology><service><role>EXAMPLEUI
  • This causes the service definition with role EXAMPLEUI to be loaded into the runtime.
  • Since <name> and <version> are not present, a default is selected if there are multiple options.
http
Code Block
<topology><service><url>
<topology><service><url>http://localhost:3000

  • This populates the data used by {$serviceUrl[EXAMPLEUI]} in the rules with the correct target URL.

 

 

Hopefully all of this provides a more gentle introduction to adding a service to Apache Knox than might be offered in the Apache Knox Developer’s Guide. If you have more questions, comments or suggestions please join the Apache Knox community. In particular you might be interested in one of the mailing lists