Monday, February 23, 2015

Customizing apiman Through Policy Plugins

This is the second in a series of articles exploring API management with JBoss apiman. The first article (http://java.dzone.com/articles/impatient-new-users) was a general introduction to apiman for impatient users where in only 10 minutes we installed apiman, created users and organizations, and services, policies, contracts, and applications. In this article, we'll take the first step toward customizing apiman by creating new plugins to implement service policies.

The major new feature added to release 1.0.2 of apiman (http://www.apiman.io/) is the ability to extend its features through a custom plugin framework. Since policies perform the most important apiman runtime operations, plugins that enable you to create new policies are the first type of plugins to be supported.

In this article, we'll examine all the steps that you must perform to create a new policy plugin, and then import it into apiman and configure a service to put it into use.

Prerequisites

For this article, we’ll assume that you have completed all the steps in the first article in this series. The first article guides even the most impatient user through installing and using apiman.

Accessing the Example Plugins

Like all JBoss software, apiman provides functioning example code that you can use as a starting point for your own plugins. The easiest way to create and package an apiman is as a standard maven project packaged as a .war file.

To download a copy of the example plugins, execute this git command:
 git clone https://github.com/apiman/apiman-plugins  

When the git clone operation completes, you’ll have the source code for multiple example plugins. The exact set of plugins that you have downloaded may change, depending on when you download them, as more examples are always being added. For the purposes of this article, we’ll focus on the “config-policy” example plugin. This plugin demonstrates how a plugin can be used to set the value of properties in a message being processed by a service. Specifically, this plugin defines properties in the request and response headers and enables you to set their values to “true.”

Requirements for a Plugin Implementation

The easiest way that an apiman policy plugin can be build and packaged is as a standard maven project packaged as a .war file. There are just a few modifications that are required to convert a .war into a plugin.

Let’s take a closer look at the files and directories that comprise the apiman config-policy plugin, and the changes that are needed to implement a plugin:

├---pom.xml
└---src
    └---main
       ├---apiman
       │   ├---plugin.json
       │   └---policyDefs
       │       ├---config-policyDef.json
       │       └---schemas
       │                └---config-policyDef.schema
       └---java
           └---io
               └---apiman
                   └---plugins
                       └---config_policy
                           ├---ConfigBean.java
                           └---ConfigPolicy.java

The most obvious difference is the addition of the “apiman” directory. This directory is used to contain the configuration files for the plugin. (In other words, the files that make the project a plugin.) The only project-wide configuration change that you have to make is to modify the plugin’s maven pom.xml file to include the apiman directory when the project is built. The following lines are added to the plugin’s pom.xml file:

      <resource>  
        <directory>src/main/apiman</directory>  
        <targetPath>META-INF/apiman</targetPath>  
        <filtering>true</filtering>  
       </resource>  




The result of these statements in the pom.xml file is that the contents of the apiman directory are included in the project build’s META-INF directory. (We’ll take a look at this later when we build the plugin project.) Setting filtering to true enables maven property expansion during the creation of the plugin war file.

Configuration files for the plugin are contained in the apiman directory. The primary configuration file is the “plugin.json” file. This file is required for all apiman plugins, regardless of the plugin type. The meta-data contained in this file describes the plugin and is displayed in the API Manager UI.

Since our example is contributing a policy, it must contain a JSON file that defines the policy. This JSON file is contained in the apiman/policyDefs directory and is named “config-policyDef.json.” This file defines the following fields for the policy:

  • id - A unique identifier for the policy
  • name - A user friendly (in other words, a human readable) name for the policy. This policy name is displayed in the API Manager UI
  • description - A description of the policy
  • policyImpl - This is the fully qualified classname name of the Java class that actually implements the policy. This value must be properly formatted to include information about the plugin, including placeholders for maven properties, for example, project version.
  • icon - This is the name of a Font Awesome icon (http://fortawesome.github.io/Font-Awesome/) that is displayed for the Policy in the API Manager UI.
  • formType - The type of policy configuration UI form. Our example uses JsonSchema.
  • form - This is a relative path to the policy configuration UI form contained in the plugin. Our examples uses the JSON Schema that defines the configuration data format. (More on this file in a minute.

In our example, the config-policyDef.json looks like this:


 {  
  "id" : "config-policy",  
  "name" : "Config Policy",  
  "description" : "A policy used to showcase policy configuration.",  
  "policyImpl" : "plugin:${project.groupId}:${project.artifactId}:${project.version}:${project.packaging}/io.apiman.plugins.config_policy.ConfigPolicy",  
  "icon" : "sliders",  
  "formType" : "JsonSchema",  
  "form" : "schemas/config-policyDef.schema"  
 }  

We mentioned that since our example uses the JSON schema (http://json-schema.org/documentation.html), we have to also define the configuration data format. This is done in the policyDefs/schemas/config-policyDef.schema file. This file defines the format used in the policy configuration file data and is used by the API Manager UI to generate a form that is used to fill in the values to be used to configure the policy. In our example, the policy’s JSON schema defines two properties: requestHeader and responseHeader. 

 {  
  "title" : "Configure HTTP Headers",  
  "description" : "Set the HTTP request header to populate with the value 'true' when the request is made. Also set the HTTP response header to populate with the value 'true' after the response is received from the back-end service.",  
  "type" : "object",  
  "properties": {  
   "requestHeader": {  
    "title" : "Request Header",  
    "type" : "string",  
    "minLength" : 1,  
    "maxLength" : 64  
   },  
   "responseHeader": {  
    "title" : "Response Header",  
    "type" : "string",  
    "minLength" : 1,  
    "maxLength" : 64  
   }  
  }  
 }  

That finishes the description of the policy’s configuration files. To complete the policy plugin, the example also requires the Java implementation for the policy itself. The policy implementation is contained in the src/main/java/io/apiman/plugins/config_policy/ConfigPolicy.java file. The policy is very simple as it merely appends a header to the http request and response.

Java policy classes must implement the apiman IPolicy interface. This example takes that a step further by actually extending the io.apiman.gateway.engine.policies.AbstractMappedPolicy class. By doing so, the policy Java code can take advantage of the AbstractMappedPolicy’s class use of the Jackson (https://github.com/FasterXML/jackson) JSON parser to parse the policy configuration data into a Java bean. (In this example, the bean is implemented in  src/main/java/io/apiman/plugins/config_policy/ConfigBean.java.) If the policy implemented the IPolicy interface, instead of extending AbstractMappedPolicy, then the policy Java class would have to implement its own parser.

Building the Plugin and Installing it into the Maven Repo

Building the plugin with maven is easy. Just execute this command from the directory that contains the plugin’s pom.xml file.

 mvn install  

In case you’re wondering why, we’re installing the plugin into the maven repo. The answer is simply that in the current release of apiman, the only supported install path is from the maven repo. Future releases of apiman will likely support additional installation paths.

Installing a Plugin into apiman

In apiman, a policy plugin, once installed, is available on a system-wide basis. Accordingly, plugins can only be installed by an admin user. After you login as admin, you’ll see this in the admin UI:

apiman-1.png

After selecting “Manage Plugins,” you’ll see a screen that looks like this:

apiman-2.png
And, if you then select “Add Plugin,” you’ll see this screen:

apiman-3.png

The GroupId, ArtifactId, and Version information is all available in the example plugin’s pom.xml file:

GroupId: io.apiman.plugins
ArtifactId: apiman-plugins-config-policy
Version: 1.0.3-SNAPSHOT

After you enter this information for the plugin and click on “Add Plugin,” you’ll see this displayed in the UI:

apiman-4.png
Congratulations! The plugin is installed and is ready to be used! Let’s add it to a service and see it in action.

Using the Installed Plugin

First, we have to log out of the admin account in the Admin UI and then log back in as the “serprov” service provider. Then, select our “echo” service, and create a new version of the service, based on the original version of the service:
apiman-6.png
And, when you add a new policy to the service, you’ll see the example config service that we just installed:

apiman-5.png
When you select the Config Policy, you’ll be presented with a dialog where you can specify the values for the two properties defined in the policy:

apiman-7.png

Let’s fill in some easy to remember values:

apiman-8.png

After adding the policy, you’ll see it displayed in the policies defined for the service:

apiman-9.png

Then publish the service. In order to consume the service, login to the API Manager UI as the application developer “appdev,” and create a new application that uses the new service. (We covered the creation of new applications in detail in the first article in this series - http://java.dzone.com/articles/impatient-new-users)

And when the service is invoked, you’ll see something like this:

apiman99.png

And this:

apiman100.png


In Conclusion

OK, let’s recap. apiman is a rapidly growing and developing project. Each new release brings new features. In release 1.0.2, it became possible for users to contribute custom policies into their apiman installation through the API Manager UI.

Acknowledgements

As always, the author would like to acknowledge Eric Wittmann for his (never impatient) review comments and suggestions on writing this post, and for adding new features to apiman!

References

The first article in this series - http://java.dzone.com/articles/impatient-new-users

Friday, January 9, 2015

apiman Reposted on DZone!

The apiman post from December was just reposted on DZone: http://java.dzone.com/articles/impatient-new-users

A very cool approach to API Managament!


Sunday, December 28, 2014

An Impatient New User's Introduction to API Management with JBoss apiman 1.0

API Management? Did you say “API Management?”

Software application development models are evolutionary things. New technologies are always being created and require new approaches. It’s frequently the case today, that a service oriented architecture (SOA) model is used and that the end product is a software service that can be used by applications. The explosion in growth of mobile devices has only accelerated this trend. Every new mobile phone sold is another platform onto which applications are deployed. These applications are often built from services provided from multiple sources. The applications often consume these services through their APIs.

OK, that’s all interesting, but why does this matter?

Here’s why:

If you are providing a service, you’d probably like to receive payment when it’s used by an application. For example, let’s say that you’ve spent months creating a new service that provides incredibly accurate and timely driving directions. You can imagine every mobile phone GPS app making use of your service someday. That is, however, assuming that you can find a way to enforce a contract on consumers of the API and provide them with a service level agreement (SLA). Also, you have to find a way to actually track consumers’ use of the API so that you can actually enforce that SLA. Finally, you have to have the means to update a service and publish new versions of services.

Likewise, if you are consuming a service, for example, if you want to build the killer app that will use that cool new mapping service, you have to have the means to find the API, identify the API’s endpoint, and register your usage of the API with its provider.

The approach that is followed to fulfill both service providers’ and consumers’ needs is...API Management.

JBoss apiman 1.0

apiman is JBoss’ open source API Management system. apiman fulfills service API providers’ and consumers’ needs by implementing:

  • API Manager - The API Manager provides an easy way for API/service providers to use a web UI to define service contracts for their APIs, apply these contracts across multiple APIs, and control role-based user access and API versioning. These contracts can govern access to services and limits on the rate at which consumers can access services. The same UI enables API consumers to easily locate and access APIs.

  • API Gateway - The gateway applies the service contract policies of API Management by enforcing at runtime the rules defined in the contracts and tracking the service API consumers’ use of the APIs for every request made to the services. The way that the API Gateway works is that the consumer of the service accesses the service through a URL that designates the API Gateway as a proxy for the service. If the policies defined to govern access to the service (see a later section in this post for a discussion of apiman polices), the API Gateway then proxies requests to the service’s backend API implementation.

The best way to understand API Management with apiman is to see it in action. In this post, we’ll install apiman 1.0, configure an API with contracts through the API Manager, and watch the API Gateway control access to the API and track its use.

Prerequisites

We don’t need very much to run apiman out of the box. Before we install apiman, you’ll have to have Java (version 1.7 or newer) installed on your system. You’ll also need to git and maven installed to be able to build the example service that we’ll use.

A note on software versions: In this post we’ll use the latest available version of apiman as of December 2014. As if this writing, version 1.0 of apiman was just released (December 2014). Depending on the versions of software that you use, some screen displays may look a bit different.

Getting apiman

Like all JBoss software, installation of apiman is simple. First, you will need an application server on which to install and run apiman. We’ll use the open source JBoss WildFly server release 8.2 (http://www.wildfly.org/).  To make things easier, apiman includes a pointer to JBoss WildFly on its download page here: http://www.apiman.io/latest/download.html

To install WildFly, simply download http://download.jboss.org/wildfly/8.2.0.Final/wildfly-8.2.0.Final.zip and unzip the file into the directory in which you want to run the sever.

Then, download the apiman 1.0 WildFly overlay zip file inside the directory that was created when you un-zipped the WildFly download. The apiman 1.0 WildFly overlay zip file is available here: http://downloads.jboss.org/overlord/apiman/1.0.0.Final/apiman-distro-wildfly8-1.0.0.Final-overlay.zip

The commands that you will execute will look something like this:

mkdir apiman
cd apiman
unzip wildfly-8.2.0.Final.zip
unzip -o apiman-distro-wildfly8-1.0.0.Final-overlay.zip -d wildfly-8.2.0.Final

Then, to start the server, execute these commands:

cd wildfly-8.2.0.Final
./bin/standalone.sh -c standalone-apiman.xml

The server will write logging messages to the screen. When you see some messages that look like this, you’ll know that the server is up and running with apiman installed:

13:57:03,229 INFO  [org.jboss.as.server] (ServerService Thread Pool -- 29) JBAS018559: Deployed "apiman-ds.xml" (runtime-name : "apiman-ds.xml")
13:57:03,261 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://127.0.0.1:9990/management
13:57:03,262 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://127.0.0.1:9990
13:57:03,262 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: WildFly 8.2.0.Final "Tweek" started in 5518ms - Started 754 of 858 services (171 services are lazy, passive or on-demand)

If this were a production server, the first thing that we’d do is to change the OOTB default admin username and/or password. apiman is configured by default to use JBoss KeyCloak (http://keycloak.jboss.org/) for password security. Also, the default database used by apiman to store contract and service information is the H2 database. For a production server, you’d want to reconfigure this to use a production database. Note: apiman includes DDLs for both MySQL and PostgreSQL.

For the purposes of our demo, we’ll keep things simple and use the default configuration.

To access apiman’s API Manager UI, go to: http://localhost:8080/apiman-manager, and log in. The admin user account that we’ll use has a username of “admin” and a password of “admin123!”

You should see a screen that looks like this:

apiman_1.png
Before we start using apiman, let’s take a look at how apiman defines how services and the meta data on which they depend are organized.

Policies, Plans, and Organizations

apiman uses a hierarchical data model that consists of these elements: Polices, Plans, and Organizations:


Policies

Policies are at the lowest level of the data model, and they are the basis on which the higher level elements of the data model are built. A policy defines an action that is performed by the API Gateway at runtime. Everything defined in the API Manager UI is there to enable apiman to apply policies to requests made to services.

When a request to a service is made, apiman creates a chain of policies to be applied to that request. apiman policy chains define a specific sequence order in which the policies defined in the API Manager UI are applied to service requests.

The sequence in which incoming service requests have policies applied is:

  • First, at the application level. In apiman, an application is contracted to use one or more services.
  • Second, at the plan level. In apiman, policies are organized into groups called plans. (We’ll discuss plans in the next section of this post.)
  • Third, at the individual service level.

What happens is that when a service request is received by the API Gateway at runtime, the policy chain is applied in the order of application, plan, and service. If no failures, such as a rate counter being exceeded, occur, the API Gateway sends the request to the service’s backend API implementation. As we mentioned earlier in this post, the API Gateway acts as a proxy for the service:


Next, when the API Gateway receives a response from the service’s backend implementation, the policy chain is applied again, but this time in the reverse order. The service policies are applied first, then the plan policies, and finally the application policies. If no failures occur, then the service response is sent back to the consumer of the service.

By applying the policy chain twice, both for the originating incoming request and the resulting response, apiman allows policy implementations two opportunities to provide management functionality during the lifecycle. The following diagram illustrates this two-way approach to applying policies:


Plans

In apiman, a “plan” is a set policies that together define the level of service that apiman provides for service. Plans enable apiman users to define multiple different levels of service for their APIs, based on policies. It’s common to define different plans for the same service, where the differences depend on configuration options. For example, a group or company may offer both a “gold” and “silver” plan for the same service. The gold plan may be more expensive than the silver plan, but it may offer a higher level of service requests in a given (and configurable) time period.

Organizations

The “organization” is at top level of the apiman data model.

An organization contains and manages all elements used by a company, university, group inside a company, etc. for API management with apiman. All plans, services, applications, and users for a group are defined in an apiman organization. In this way, an organization acts as a container of other elements. Users must be associated with an organization before they can use apiman to create or consume services. apiman implements role-based access controls for users. The role assigned to a user defines the actions that a user can perform and the elements that a user can manage.

Before we can define a service, the policies that govern how it is accessed, the users who will be able to access, and the organizations that will create and consume it, we need a service and a client to access that service. Luckily, creating the service and deploying it to our WildFly server, and accessing it through a client are easy.

Getting and Building and Deploying the Example Service

The source code for the example service is contained in a git repo (http://git-scm.com) hosted at github (https://github.com/apiman). To download a copy of the example service, navigate to the directory in which you want to build the service and execute this git command:

git clone git@github.com:apiman/apiman-quickstarts.git

As the source code is downloading, you'll see output that looks like this:

git clone git@github.com:apiman/apiman-quickstarts.git
Initialized empty Git repository in /tmp/tmp/apiman-quickstarts/.git/
remote: Counting objects: 104, done.
remote: Total 104 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (104/104), 18.16 KiB, done.
Resolving deltas: 100% (40/40), done.

And, after the download is complete, you'll see a populated directory tree that looks like this:

└── apiman-quickstarts
    ├── echo-service
    │   ├── pom.xml
    │   ├── README.md
    │   └── src
    │       └── main
    │           ├── java
    │           │   └── io
    │           │       └── apiman
    │           │           └── quickstarts
    │           │               └── echo
    │           │                   ├── EchoResponse.java
    │           │                   └── EchoServlet.java
    │           └── webapp
    │               └── WEB-INF
    │                   ├── jboss-web.xml
    │                   └── web.xml
    ├── LICENSE
    ├── pom.xml
    ├── README.md
    ├── release.sh
    └── src
       └── main
           └── assembly
               └── dist.xml

As we mentioned earlier in the post, the example service is very simple. The only action that the service performs is to echo back in responses the meta data in the REST (http://en.wikipedia.org/wiki/Representational_state_transfer) requests that it receives.

Maven is used to build the service. To build the service into a deployable .war file, navigate to the directory into which you downloaded the service example:

cd apiman-quickstarts/echo-service

And then execute this maven command:

mvn package

As the service is being built into a .war file, you'll see output that looks like this:

[INFO] Scanning for projects...
[INFO]
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]                                                                       
[INFO] ------------------------------------------------------------------------
[INFO] Building apiman-quickstarts-echo-service 1.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ apiman-quickstarts-echo-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /jboss/local/redhat_git/apiman-quickstarts/echo-service/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ apiman-quickstarts-echo-service ---
[INFO] Compiling 2 source files to /jboss/local/redhat_git/apiman-quickstarts/echo-service/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ apiman-quickstarts-echo-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /jboss/local/redhat_git/apiman-quickstarts/echo-service/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ apiman-quickstarts-echo-service ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ apiman-quickstarts-echo-service ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-war-plugin:2.2:war (default-war) @ apiman-quickstarts-echo-service ---
[INFO] Packaging webapp
[INFO] Assembling webapp [apiman-quickstarts-echo-service] in [/jboss/local/redhat_git/apiman-quickstarts/echo-service/target/apiman-quickstarts-echo-service-1.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/jboss/local/redhat_git/apiman-quickstarts/echo-service/src/main/webapp]
[INFO] Webapp assembled in [23 msecs]
[INFO] Building war: /jboss/local/redhat_git/apiman-quickstarts/echo-service/target/apiman-quickstarts-echo-service-1.0.1-SNAPSHOT.war
[INFO] WEB-INF/web.xml already added, skipping
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.184 s
[INFO] Finished at: 2014-12-26T16:11:19-05:00
[INFO] Final Memory: 14M/295M
[INFO] ------------------------------------------------------------------------

If you look closely, near the end of the output, you'll see the location of the .war file:

/jboss/local/redhat_git/apiman-quickstarts/echo-service/target/apiman-quickstarts-echo-service-1.0.1-SNAPSHOT.war

To deploy the service, we can copy the .war file to our WildFly server's "deployments" directory. After you copy the service's .war file to the deployments directory, you'll see output like this generated by the WildFly server:

16:54:44,313 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-7) JBAS015876: Starting deployment of "apiman-quickstarts-echo-service-1.0.1-SNAPSHOT.war" (runtime-name: "apiman-quickstarts-echo-service-1.0.1-SNAPSHOT.war")
16:54:44,397 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-16) JBAS017534: Registered web context: /apiman-echo
16:54:44,455 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 1) JBAS018559: Deployed "apiman-quickstarts-echo-service-1.0.1-SNAPSHOT.war" (runtime-name : "apiman-quickstarts-echo-service-1.0.1-SNAPSHOT.war")

Make special note of this line of output:

16:54:44,397 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-16) JBAS017534: Registered web context: /apiman-echo

This output indicates that the URL of the deployed example service is:


Remember, however, that this is the URL of the deployed example service if we access it directly. We'll refer to this as the "unmanaged service" as we are able to connect to the service directly, without going through the API Gateway.  The URL to access the service through the API Gateway ("the managed service") at runtime will be different. 

Now that our example service is installed, it’s time to install and configure our client to access the server.

Accessing the Example Service Through a Client

There are a lot of options available when it comes to what we can use for a client to access our service. We’ll keep the client simple so that we can keep our focus on apiman and simply install a REST client into the FireFox browser. The REST Client FireFox add-on (http://restclient.net/) is available here: https://addons.mozilla.org/en-US/firefox/addon/restclient/versions/2.0.3

After you install the client into FireFox, you can access the deployed service using the URL that we just defined. If you execute a GET command, you’ll see output that looks like this:

Screenshot-4.png

Now that our example service is built, deployed and running, it’s time to create the organizations for the service provider and the service consumer. The differences between the requirements of the two organizations will be evident in their apiman configuration properties.

Creating Users for the Service Provider and Consumer

Before we create the organizations, we have to create a user for each organization. We'll start by creating the service provider user. To do this, logout from the admin account in the API Manager UI. The login dialog will then be displayed.

Screenshot-5.png

Select the "New user" Option and register the service provider user:

Screenshot-6.png

Then, logout and repeat the process to register a new application developer user too:

Screenshot-7.png

Now that the new users are registered we can create the organizations.

Creating the Service Producer Organization

To create the service producer organization, log back into the API Manager UI as the servprov user and select “Create a new Organization”:

apiman_2.png

Select a name and description for the organization, and press “Create Organization”:

Screenshot-15.png

And, here’s our organization:

Screenshot-16.png

Note that in a production environment, users would request membership in an organization. The approval process for accepting new members into an organization would follow the organization's workflow, but this would be handled outside of the API Manager. For the purposes of our demonstration, we'll keep things simple.

Configuring the Service, its Policies, and Plans

To configure the service, we’ll first create a plan to contain the policies that we want applied by the API Gateway at runtime when requests to the service are made. To create a new plan, select the “Plans” tab. We’ll create a “gold” plan:
Screenshot-17.png
Once the plan is created, we will add policies to it:
Screenshot-18.png

apiman provides several OOTB policies. Since we want to be able to demonstrate a policy being applied, we’ll select a Rate Limiting Policy, and set its limit to a very low level. If our service receives more than 10 requests in a day, the policy should block all subsequent requests. So much for a “gold” level of service!

Screenshot-19.png
After we create the policy and add it to the plan, we have to lock the plan:

Screenshot-21.png

And, here is the finished, and locked plan:

Screenshot-22.png
At this point, additional plans can be defined for the service. We’ll also create a “silver” plan, that will offer a lower level of service (i.e., a request rate limit lower than 10 per day) than the gold plan. Since the process to create this silver plan is identical to that of the gold plan, we’ll skip the screenshots.


Now that the two plans are complete and locked, it’s time to define the service.

Screenshot-23.png

We’ll give the service an appropriate name, so that providers and consumers alike will be able to run a query in the API Manager to find it.

Screenshot-24.png

After the service is defined, we have to define its implementation. In the context of the API Manager, the API Endpoint is the service’s direct URL. Remember that the API Gateway will act as a proxy for the service, so it must know the service’s actual URL. In the case of our example service, the URL is:  http://localhost:8080/apiman-echo

Screenshot-25.png

The plans tab shows which plans are available to be applied to the service:

Screenshot-26.png

Let’s make our service more secure by adding an authentication policy that will require users to login before they can access the service. Select the Policies tab, and then define a simple authentication policy. Remember the user name and password that you define here as we’ll need them later on when send requests to the service.

Screenshot-27.png
After the authentication policy is added, we can publish the service to the API Gateway:

Screenshot-28.png

And, here it is, the published service:

Screenshot-29.png

OK, that finishes the definition of the service provider organization and the publication of the service.

Next, we'll switch over to the service consumer side and create the service consumer organization and register an application to connect to the managed service through the proxy of the API Gateway.

The Service Consumer Organization

We'll repeat the process that we used to create the application development organization. Log in to the API Manager UI as the “appdev” user and create the organization:

Screenshot-30.png

Unlike the process we used when we created the elements used by the service provider, the first step that we’ll take is to create a new application and then search for the service to be used by the application:

Screenshot-31.png
Searching for the service is easy, as we were careful to set the service name to something memorable:
Screenshot-32.png

Select the service name, and then specify the plan to be used. We’ll splurge and use the gold plan:  

Screenshot-33.png

Next, select “create contract” for the plan:
Screenshot-34.png

Then, agree to the contract terms (which seem to be written in a strange form of Latin in the apiman 1.0 release):

Screenshot-35.png

The last step is to register the application with the API Gateway so that the gateway can act as a proxy for the service:

Screenshot-36.png

Congratulations! All the steps necessary to provide and consume the service are complete!

There’s just one more step that we have to take in order for clients to be able access the service through the API Gateway.

Remember the URL that we used to access the unmanaged service directly? Well, forget it. In order to access the managed service through the API Gateway acting as a proxy for other service we have to obtain the managed service's URL. In the API Manager UI, head on over to the "APIs" tab for the application, click on the the “>” character to the left of the service name. This will expose the API Key and the service’s HTTP endpoint in the API Gateway:

Screenshot-37.png

In order to be able access the service through the API Gateway, we have to provide the API Key with each request. The API Key can be provided either through an HTTP Header (X-API-Key) or a URL query parameter. Luckily, the API Manager UI does the latter for us. Select the icon to the right of the HTTP Endpoint and this dialog is displayed:

Screenshot-38.png

Copy the URL into the clipboard. We’ll need to enter this into the client in a bit. The combined API Key and HTTP endpoint should look something like this:


Accessing the Managed Service Through the apiman API Gateway, Watching the Policies at Runtime

Thanks for hanging in there! The set up is done. Now, we can fire up the client and watch the policies in action as they are applied at runtime by the API Gateway, for example:


What happens first is that the authentication policy is applied and a login dialog is then displayed:

Screenshot-41.png

Enter the username and password (user1/password) that we defined when we created the authentication policy to access the service. The fact that you are seeing this dialog confirms that you are accessing the managed service and are not accessing the service directly.

When you send a GET request to the service, you should see a successful response:

Screenshot-40.png

So far so good. Now, send 10 more requests and you will see a response that looks like this as the gold plan rate limit is exceeded:

Screenshot-39.png

And there it is. Your gold plan has been exceeded. Maybe next time you’ll spend a little more and get the platinum plan!  ;-)

Wrap-up

Let’s recap what we just accomplished in this demo:

  • We installed apiman 1.0 onto a WildFly server instance.
  • We used git to download and maven to build a sample REST client.
  • As a service provider, we created an organization, defined policies based on service use limit rates and user authentication, and a plan, and assigned them to a service.
  • As a service consumer, we searched for and found that service, and assigned it to an application.
  • As a client, we accessed the service and observed how the API Gateway managed the service.

And, if you note, in the process of doing all this, the only code that we had to write or build was for the client. We were able to fully configure the service, policies, plans, and the application in the API Manager UI.

What’s Next?

In this post, we’ve only scratched the surface of API Management with apiman. To learn more about apiman, you can explore its website here: http://www.apiman.io/

Join the project mailing list here: https://lists.jboss.org/mailman/listinfo/apiman-user

And, better still, get involved! Contribute bug reports or feature requests. Write about your own experiences with apiman. Download the apiman source code, take a look around, and contribute your own additions. apiman 1.0 was just released, there’s no better time to join in and contribute!

Acknowledgements

The author would like to acknowledge Eric Wittmann for his (never impatient) review comments and suggestions on writing this post!

Downloads Used in this Article


References