2010/09/16
16 Sep, 2010

Governance API for WSO2 Governance Registry

  • WSO2 Team
  • - WSO2

Applies To

WSO2 Governance Registry 3.5.0

Introduction

The WSO2 Governance Registry helps to govern enterprise SOA infrastructure. It mainly stores and versions service metadata, WSDLs, schemas, policies and endpoints. In addition, it provides comprehensive support for governance tasks like service validation, life-cycle management, impact analysis, subscription to notifications and service discovery.

All these features are available through the WSO2 Governance Registry management console. However, these features can be called through the WSO2 Governance APIs too.

The Governance API is a more SOA terminology friendly, convenient API written over the more general Registry API. For an example, if you use the Governance API to add a service you will construct a class named “Service” and use “ServiceManager.addService(Service service)” method to store it. If you use Registry API you will just create a registry resource with the service metadata as the content and “application/vnd.wso2-service+xml” as the media type of the resource. Then you will use the “Registry.put(String path, Resource resource)” method to store it. AS you can see the latter approach is little more complicated than the former for programmers who specifically like to focus on governance aspects. Furthermore you will have trouble over serializing your services metadata to a registry resource content as it is not a well-defined schema that is expected to be used from outside. The Governance API will help you in such situations by hiding details on how service metadata is stored in registry resources. In the section below you will be able to learn the use of Governance API to do some useful governance tasks. And also how to use the Registry API to do the same tasks too, whenever the use of the Registry API is not that complicated.

The Governance API was introduced in the WSO2 Governance Registry 3.5.0 release. It does have a few limitations. Mainly it does not support being called using a remote registry (Atom/pub or web service APIs). The fixes for these limitations and more improvements will be introduced in future releases.

The class Diagram

All the objects the Governance API uses are called governance artifacts. Currently the supported governance artifacts are schemas, WSDLs, services, endpoints, policies.  This relationship is described in the following class diagram.

Governance API

In addition to the above governance artifact classes, there will be management classes that deals with each governance artifact. We will discuss those in more details in coming sections.

GovernanceArtifact class

The API documentation for GovernanceArtifact class can be found from this link.

Governance Artifacts Attributes

Governance artifacts attributes are used to store service metadata as a multi-value map, i.e. (key, value-list) pairs. In case you don’t need to have multi-value per key, you can just store only one value for the key. There are API methods supporting both scenarios.

 

Methods that can be used in single value per key scenario:

public String getAttribute(String key);
public void setAttribute(String key, String newValue);

Methods that can be used in multi value per key scenario:

public void addAttribute(String key, String value);
public void setAttributes(String key, String[] newValues);

public String[] getAttributes(String key);

Once you modify an attribute using add/set methods, you have to call the update method of the relevant governance artifact manager.

Governance Artifacts Attachments

We can define associations among governance artifacts. For example, for a service you can attach WSDLs using the services’s attachWsdl() method. In such cases service will depend on the WSDL. You can retrieve what are the dependencies and dependents of governance artifacts using the following method.

public GovernanceArtifact[] getDependencies(); 
public GovernanceArtifact[] getDependents();

For an example if you want to get all the dependencies of a given service you will be able to use the following snip of code. (Taking 'service' as the reference to your service).

GovernanceArtifact[] dependencies = service.getDependencies();
for (GovernanceArtifact dependency: dependencies) {
    if (dependency instanceof Service) {
        Service dependingService = (Service)dependency;
    } else if (dependency instanceof Wsdl) {
        Wsdl dependingWsdl = (Wsdl)dependency;
    } else  if (dependency instanceof Schema) {
        Schema dependingSchema = (Schema)dependency;
    } 
}

 

In any case, for most of your needs, you will not use the above general methods defined in the Governance Artifact class. Rather you will use the methods of the specific sub-classes. Forexample the above code can be simplified as follows

Wsdl[] attachedWsdls = service.getAttchedWsdls();
Schema[] attachedSchemas = service.getAttachedSchemas();

For all the attachment related methods will be valid for the persisted governance artifacts only.

Now we will look at each sub-classes and the management entities of the governance artifacts.

Service

Service class represents the service hosted in your SOA infrastructure. In order to create a service entry in the governance registry you should provide a fully qualified name (A namespace and a name for the service.)

You can find the complete API documentation for the service here.

Service Attributes

Like all governance artifacts, in services too you can define your own attributes and store some values that describe the service. Please see the "Governance Artifact Attributes" section for a more detailed description of custom attributes.

In addition to the custom attributes, the service artifacts have some special set of attributes. These special attributes will be available according to your service UI configurations.

Note: You can access the service UI configurations from "Configure"-> "Service UI" menu from the Governance Registry management console.

Here is a snip of the default service UI configuration.

<service>
    <table name="Overview">
        <field type="text" required="true">

            <name>Name</name>
        </field>
    <field type="text" required="true">

            <name>Namespace</name>
        </field>
        <field type="text-area">
            <name>Description</name>

        </field>
    </table>
 
        <table name="Interface">
        <field type="text">

            <name>WSDL URL</name>
        </field>
        <field type="options">
            <name>Transport Protocols</name>

            <values>
                <value>None</value><value>HTTPS</value><value>HTTP</value><value>SMTP</value><value>TCP</value><value>XMPP</value><value>JMS</value>

            </values>
        </field>
        <field type="options">
            <name>Message Formats</name>

            <values>
                <value>None</value><value>SOAP 1.1</value><value>SOAP 1.2</value><value>XML</value><value>JSON</value><value>HTTP-REST</value><value>CSV</value><value>BINARY</value>

            </values>
        </field>
        <field type="options">
            <name>Message Exchange Patterns</name>

            <values>
                <value>None</value><value>Request Response</value><value>One Way</value>
            </values>

        </field>
    </table>
    ..
</service>

Here it defines the configuration on how your service UI should look like. For example table name "Interface" defines an HTML table/form topic with the name "Interface". The field types "WSDL URL", "Transport Protocols" defines the sub topic under the topic "Interface". (A full explanation of the service UI configuration is out of scope of this article).

We can interpret the topic and sub topics combination as a key of a service attribute and the user value as the value of the attribute. In fact we derive the attribute key of a certain field using following formula.

Service attribute-key = camel-case (topic) + "_" + camel-case(sub-topic)

So the attribute-key of the field "Interface" and "WSDL URL" can be calculated as "interface_wsdlURL" and the "Interface" and "Transport Protocols" is "interface_transportProtocols".

Similarly if there are endpoints introduced as attribute values to the key "endpoints_entry", the Governance Registry will create Endpoint entries and build the dependency tree.

Service attachments

Service can be attached to WSDLs, schemas, endpoints and policies.

// Attach/detach/retrieve wsdls
attachWSDL(Wsdl wsdl);
detachWSDL(String wsdlId);
Wsdl[] getAttachedWsdls();

 
// Attach/detach/retrieve schemas
attachSchema(Schema schema);
detachSchema(String schemaId);
Schema[] getAttachedSchemas();

 
// Attach/detach/retrieve endpoints
attachEndpoint(Endpoint endpoint);
detachEndpoint(String endpointId);
Endpint[] getAttachedEndpoints();

 
// Attach/detach/retrieve polices
attachPolicy(Policy policy);
detachPolicy(String policyId);
Policy[] getAttachedPolicies();

Service Manager

In addition to the "Service" class mentioned above, there are two more classes that deal with service management; namely "ServiceManager" and "ServiceFilter".

Service Managment classes

Add a Service

Here is the code segment to add a simple service with just the name and the namespace. To start with you should have a governance registry instance assigned to variable 'registry'.

ServiceManager serviceManager = new ServiceManager(registry);
 
Service service = serviceManager.newService(new name("https://example.com/demo/services", "ExampleService"));
serviceManager.addService(service);

After you add the service, you can invoke the attributes and attachment related operations of a service. From them when you invoke the service attachments related operations, the changes will be persisted right away so you don't need to call the updateService operation. But if you are changing the attribute of a service (or any other governance artifact), you need to call the updateService (or the related update operation of other governance artifact) to persist the changes. Here's the way to do it:

Update the Service

If you want to add an attribute to the newly created service or an existing service (retrieved through getService operation) you will need to call the updateService operation to persist you changes. Here is an example of using updateService. (Continuing from the example in the "Add a Service" section).

service.addAttribute("department", "administrator");
serviceManager.updateService(service);

Retrieve the Service

In order to retrieve the service again, you need to keep the Id of the service in your code. You can get an Id from service using the service.getId() method.

Service retrievedService = serviceManager.getService(serviceId);

Practically you will use findServices method to look for a service. We will discuss how to use findServices in the next section.

Find Services

Governance API has special method to help you find your services. Here is an example on how to retrieve all the services that have the attribute key "department" and value "administrator".

// defining the filter with the filtering requirements.
class AdminstratorDepartmentFilter  implements ServiceFilter {
        	public boolean matches(Service service) throws GovernanceException {

            		String departmentVal = service.getAttribute("department");
            		return "administrator".equals(departmentVal);
        	}

}
 
// use the find services method with the filter instance.
Service[] services = serviceManager.findServices(new AdminstratorDepartmentFilter());

Here we are writing a custom filter class implementing "ServiceFilter" interface. We should implement the "matches" method with the parameter of an instance of Service. In there you have to write the logic that return whether this service should be filtered in.

So if you return true for all the services, you will be able to get all the services stored in the registry. In fact you can use the getAllServices method of the "ServiceManager" to do that.

Remove the Service

Use the "removeService" method to remove the service.

service.removeService(service.getId());

WSDL

WSDL is also derived from GovernanceArtifact, so it inherits the methods to manipulate attributes and attachments from the GovernanceArtifact.

You can follow all the methods from the WSDL API documentation.

There are few operations specific to WSDL in Wsdl class.

// getter and setter of the wsdl
public OMElement getWsdlElement() ;
public void setWsdlElement(OMElement wsdlElement);

 
// the url of the wsdl, if the wsdl is constructed from a url
public String getUrl();

WSDL attachments

The WSDL can be attached to schemas and endpoints. It provides the following methods to manipulate attachments.

// Attach/detach/retrieve schemas
attachSchema(Schema schema);
detachSchema(String schemaId);
Schema[] getAttachedSchemas();

 
// Attach/detach/retrieve endpoints
attachEndpoint(Endpoint endpoint);
detachEndpoint(String endpointId);
Endpint[] getAttachedEndpoints();

If the WSDL content has references to schemas and endpoints, when you add the WSDL to the governance registry, it will automatically import the schema and endpoint meta data and build the attachment tree.

WSDL Manager

Similar to Service Manager, WSDL Manager provides functionalities to manage WSDLs. You can view the full WSDL Manager API
from the https://wso2.org/project/registry/3.5.0/docs/apidocs/governance/org/wso2/carbon/governance/api/wsdls/WsdlManager.html.

In order to find WSDLs you will be using the findWsdls method in the "WSDLManager" class. Here you will be implementing the "WsdlFilter" interface to provide the filtering logic as shown in following example code.

       Wsdl[] wsdls = wsdlManager.findWsdls(new WsdlFilter() {
           public boolean matches(Wsdl wsdl) throws GovernanceException {

               GovernanceArtifact[] governanceArtifacts = wsdl.getDependents();
               for (GovernanceArtifact governanceArtifact: governanceArtifacts) {

                   if (governanceArtifact instanceOf Service) {
                    if (service.getQName().equals(new QName("https://example.com/demo/services", "ExampleService")) {

                        return true;
                    }
               }
               }
               return false;
           }

       });

The above code will filter out the WSDLs who are dependencies of the service with the name "ExampleService" and with the namespace "https://example.com/demo/services".

Schema, Policy and Endpoint

The method set of the Schema, Policy and Endpoint classes goes with the same pattern as the Service and WSDL classes.
You will be able to study each of them in more details from the Governance API documentations,

https://wso2.org/project/registry/3.5.0/docs/apidocs/governance/index.html
.

Summary

The Governance API provides a convenient API to handle governance tasks programmatically.
The Governance API documentation is available online at

https://wso2.org/project/registry/3.5.0/docs/apidocs/governance/index.html
.

Author

Dimuthu Gamage, Sofware Engineer,WSO2 Inc

 

About Author

  • WSO2 Team
  • WSO2