Service Oriented Architecture is fundamentally based on metadata descriptions, schemas, URIs and policies. The key to a successful SOA deployment is to manage this data in a structured repository. WSO2 Registry is an open source product that enables you to store, catalog, index and manage your enterprise metadata in a simple, scalable and easy-to-use model. In fact, the WSO2 Registry can not only store such metadata but any other kind of data and maintain it in a versioned and URI-accessible manner. Think of the registry as a structured wiki designed to help you manage your metadata in a simple business-friendly system. Registry allows the storage of unstructured data such as Word documents, Excel spreadsheets and text formats. Using these approaches, you can build a catalog of services and service descriptions. A simple, RESTful programming API allows any and all resources stored in the WSO2 Registry to become a part of your dynamic SOA infrastructure- for example, by storing policies in the registry and using them for runtime policy enforcement. Built in community features allow WSO2 Registry users to comment on, tag and rate resources stored in the registry. Registry can be navigated using the given Web application, via an AtomPub API or via Java API (for both local and remote registries via AtomPub).
This document applies to version 1.0 of the WSO2 Registry.
Installing the WSO2 registry is a matter of copying wso2resgistry.war file into a servlet container such as Apache Tomcat. We recommend you use the latest version of Tomcat, version 6.* but it should work with version 5.*s as well. In Apache Tomcat, drop the .war file into webapps directory. (We assume that you have Java v1.5 at least.)
By default, data you store in the registry will be saved in a database embedded in the WAR file and the files themselves will be located within the exploded WAR directory. It is recommended to configure an external data source or a JDBC connection as explained in the section below using Apache Derby or MySQL databases. If your application server does not automatically unpack the WAR file (e.g., JBossAS), then the built in database may not work. In such cases, you must always use a external database.
In both scenarios, you need to create database tables using scripts bundled in the source distribution. After deploying the .war file, start the application server, if it has not already.
Below are the steps for configuring WSO2 Registry with Apache Derby database. Note that the following database commands are for linux platform. Please replace file paths to match Windows, if you are using this in Windows platform.
<wso2regsitry>
<currentConfig>derby-db</currentConfig>
<dbconfig name="in-memory"> <url>jdbc:hsqldb:mem:aname</url> <userName>sa</userName> <password/> <driverName>org.hsqldb.jdbcDriver</driverName> </dbconfig> <dbconfig name="sample"> <url>jdbc:hsqldb:$basedir$/sample/sample-db;shutdown=true</url> <userName>sa</userName> <password/> <driverName>org.hsqldb.jdbcDriver</driverName> </dbconfig>
<dbconfig name="derby-db">
<url>jdbc:derby://localhost:1527/db</url>
<userName>regadmin</userName>
<password>regadmin</password>
<driverName>org.apache.derby.jdbc.ClientDriver</driverName>
</dbconfig>
......
......
</wso2registry>
11. Restart the servlet container. Now WSO2 Registry is running using the Apache Derby database!
After successfully deploying the WSO2 Registry webapp, launch a Web browser and point it to the the following URL:http://localhost:8080/wso2registry(you may need to change the port if your servlet runtime is listening on a different port).
This takes you to the welcome page of the registry console as given below:
Figure: Welcome page on WSO2 Registry's UI console
Note: By default the welcome screen displays the resources page of the root folder. Please Refer the 'Resources' section of this documentation for details on features provided on this page.
The option to sign in is available as a link on the top right hand corner of the welcome screen.
User will be logged in upon entering valid credentials.
The default system has an administrator configured with username/password combination as 'admin'/'admin'.
Navigation bar on the top right hand corner consists of the following options:
We will now discuss each of these menu options in detail:
This is the default option activated upon log-in.
In the left hand side column of the resources page you'll find three blocks, namely, Information, Entries and Permissions.
Information block includes details of a chosen resource including the creation date and time under the 'Created' label with 'Author' information, 'Last Updated' date and time with author information related to the update as 'By', link to different versions available through 'Versions' label and ratings for resources including current user rating and average rating. A 'Description' for the selected resource is also available.
Upon selecting "Edit Description" command button, an editor will be provided to insert a description for the chosen resource. Users can type a description and select the "Save" button to save updates.
Adding a resource could be done for a collection of resources or for an individual resource. To add a collection or directory, click on the button provided and a page will be presented to fill in the required information. Optionally, a description can be included for the resource in question.
Note : Adding and and deleting resources within the registry are considered version operations. Therefore, provision is made to rollback or restore a resource to any previous version. Refer Versions for additional information on this topic.
To delete a resource , click on the cylindric icon provided. However, upon doing so a resource will not be removed from the database but instead marked as deleted. This provides the opportunity to restore a previously deleted resource.
Using the 'entries' block, users are able to add additional resources and collections to the active folder.
To add a new resource:
1. Select the add resource icon provided on the top right hand corner of the entries block as illustrated in the diagram below
2. To add a file in the local machine as a resource, select "import content from file" option and browse and select the file. To import a remote resource, select the "Import content from URL" option and give the URL.
3. Change the name of the resource, media type and the description, if required.
4. Click "Add" button to add the new resource.
To add a new collection
1. Select the add collection icon in the entries block.
2. Type the name of the new collection.
3. Select a media type for the collection and type a description, if necessary. Note that the normal collections have the "default" media type.
4. Click "Add" button to add the new collection.
Using the following screen, WSO2 Registry permissions can be assigned to different roles and individual users.
The top half of the permission's screen is used to define user roles and the bottom half for defining role permissions.
To assign permissions to users or roles follow the steps given below:
1. select user/role from User/Role drop down
2. choose an action from the 'Action' drop down menu
3. select permission type. users are able to choose 'Allow' or 'Deny' by selecting appropriate option button.
4. Click 'Add Permission' to apply selection
Existing permissions can be changed by selecting and clearing the check boxes for required permissions and clicking the "Apply All Permissions" button.
Note: 'User permissions' have higher priority over 'role permissions'. 'Deny' permissions have higher priority over 'allow' priorities. Essentially, this means that permissions assigned to users overrides permissions assigned for a role and that a deny permission always overrides an 'allow' permission assigned to a user.
The right side of the resources page houses 3 additional blocks, namely: Tags, Comments and Versions.
Provides space to enter tags for a given resource. These tags can be used when searching for a resource as key words for search criteria.
Users can enter as many tags as they like provided individual tags are separated by commas and a given tag is not used by the same author to identify the same resource repeatedly.
Users can either comment or refer comments made by others using the comments block.
To add a new comment:
1. select the "ADD" icon located on the title of the bar of the comments block
2. enter comment in the text box provided
3. click the 'Add' button to continue.
Versions block provides version-specific information including different versions of a given resource. These include last modified date & time and By(username). Links are provided to visit a resource's specific version page, together with provision to rollback back to a chosen version of a resource.
Selecting "People" option on the navigation menu opens up the following screen. Authorized users could manage users and roles using options given.
A list of "users" with details including User name, Name and Action appears on the left side column of the window together with a list of "roles" including Role Name and Action available on the right side column.
"Username" column lists the username assigned for users with the "Name" column providing the friendly name. Under the "Actions" column action delete is indicated as an icon that provides the facility to delete chosen users from the users list.
To add new users:
1. select "Add New user" icon from the title bar of the users window
2. enter user details including Username, Password, Confirm Password and Role type in the space provided
3. upon completion selection a user role for the new user and click "Add" button to continue.
4. the newly created user will be listed as the last item in the users list.
Note:If an attempt is made by unauthorized users to create new users, the system will not allow this and will respond displaying the following error message: "User is unauthorized to perform the action". Sign in with valid credentials before attempting this activity.
Note:Icon next to add new user/add new role icon is an expand/collapse icon to switch between the two views.
The 'Activity' options presents the user with a search facility for searching activities performed on the Registry. The block titled "Search Activities" consists of space to enter search criteria such as Username, Path, Date and Filter by drop down in searching for recent activities. A screen shot of Search Activities block is given below. Notice the list of sample activities provided at the bottom of the block for the given Username.
This toggle option provides the ability to sign in into WSO2 registry or sign out of WSO2 Register, as needed.
WSO2 Registry can be embedded inside other Java applications as a library to provide resource/community oriented features. Once embedded, Java applications can access all the features of the registry using the Registry API (org.wso2.registry.Registry). To start with, place the WSO2 Registry Core library (wso2registry-core-1.1.jar) and all dependency jar files in the class path of your application. First an EmbeddedRegistry instance has to be created using the desired configuration. EmbeddedRegistry acts as a factory for registry instances. Configuration for the EmbeddedRegistry has to be written in a registry.xml file. You can take the registry.xml file shipped with the registry and edit it to fit you requirements. Datasources for persisting the registry data, handler configurations and life cycle configurations are given in this registry.xml file.
RegistryContext registryContext = new RegistryContext("/home/user1/registry.xml");EmbeddedRegistry embeddedRegistry = new EmbeddedRegistry(registryContext);
There is a special EmbeddedRegistry which is based on an inmemory database. It can be used to get a quick start to the registry without having to configure an external database. Please note the data put into the inmemory registry will be lost once the JVM is shutdown.
EmebeddedRegistry embeddedRegistry = new InMemoryEmbeddedRegistry();
Once an EmbeddedRegistry instance is created, it can be used to get UserRegistry instances for all registry users. UserRegistry instances provide the session management for the registry and provide user's authorization detailes for the underlying registry components.
// get the user registry for the admin user UserRegistry adminRegistry = embeddedRegistry.getUserRegistry("admin", "admin");
// get the user registry intance for the "user1" (note that the user1 has to be created in the registry before creating a user registry for user1) UserRegistry user1Registry = embeddedRegistry.getUserRegistry("user1", "pass1");
UserRegistry implements the org.wso2.registry.Registry interface, which provides access to all the operations of the registry. Therefore, you can use this UserRegistry intance to perform the tasks listed below.
In simple words, the RemoteRegistry is a Java API for interacting with a Registry instance. Regardless of where a given Registry instance is located, either locally or remotely, we can still talk to it using RemoteRegistry. The RemoteRegistry is yet another implementation of org.wso2.registry.Registry interface. However, the difference between the RemoteRegistry and a standard Registry is that, the RemoteRegistry is not an actual registry but a client for interacting with a registry instance.
Communication between the Registry and the RemoteRegistry takes place using the Atom Publishing Protocol (APP). When we deploy registry files (registry.war) in an application server, an atom feed is generated . Thereafter, if you browse http://localhost:8080/wso2registry/atom (this address changes depending on your application server settings), you'd be able to see the atom feed from the registry. The structure and format of the feed is described in the following location: http://www.wso2.org/wiki/display/registry/Registry+Protocol.
To create an instance of the RemoteRegistry, what we need first is the URL of a registry. If the root of the registry is http://foo.com/, the URL for the RemoteRegistry instance would be http://foo.com/atom. Once we have the URL figured out, we can create an instance of the RemoteRegistry using the following code:
RemoteRegistry remote_registry = new RemoteRegistry(new
URL("http://localhost:8080/wso2registry"));
Creating an instance of the RemoteRegistry in this manner, is similar to accessing a registry without login into it with communication taking place as an anonymous user.
If you have a user name and password for the registry, you can pass them along when creating the remote_registry instance. At that point, all permissions granted for the particular username/password pair will apply to the owner of the remote_registry instance. Creating the remote_registry with user name and the password can be done using:
RemoteRegistry remote_registry = new RemoteRegistry(new
URL("http://localhost:8080/wso2registry"), "admin", "admin");
In this example, we have created the remote_registry instance with username="admin" and the password as also "admin".
Once we have the registry instance in place (embedded registry or remote registry), navigation is straightforward. It is the same as working with the Registry API. Say we have a resource called "/foo/c1" in the Registry and you can access it using the registry instance as given below:
Resource resource = registry.get("/foo/c1");
The resource object will represent the actual resource object in the Registry. But if the resource is a collection, then the object will, of course, represent the collection.
As you can see in the code sample above, once we have a registry instance we do not need to pass a complete URL for all invocations. It is adequate to pass only a relative path to a resource.
To add a resource to the registry instance, first thing we need to do is to create a Resource object and then to call its put method:
First let's try to cerate a collection called "/foo/c2"
Resource resource = new Resource();
registry.put("resource", resource);
If you call the get method then you'd be able to access that resource created.
Now let's try to add a resource with content. For that, we need to first create a Resource object and then set content.
Resource r1 = new Resource();
String str = "My Content";
r1.setContent(str.getBytes());
registry.put("/c1/c2/r1", r1);
We can use the following code to confirm whether the resource exists:
boolean value = registry.resourceExists("/c1/c2/r1");
If the resource does exist, a boolean value of true will be returned, else false.
Additionally, we can use the registry instance to delete resources. Deleting a resource is a matter of calling the delete method of the registry. Let's just say we want to delete "/c1/c2/r1". Then we can use the following code:
registry.delete("/c1/c2/r1");
We can rename individual resources but but we cannot rename collections. To rename a resource, use the following lines of code.
registry.rename("/c1/c2/r1", "/c1/c2/r2");
Above line of code renames "/c1/c2/r1" to "/c1/c2/r2"
Resources are automatically versioned when they are added or updated. But collections are not versioned automatically due to performance considerations. However, you can create versions of collections using the API. It is recommended that collection versions are created only for making checkpoints of the subtree you are working on.
registry.createVersion("/c1/c2");
We can list all of the versions of a given resource using the code given below. The result would be an array of String, containing links to the different versions of the resource.
String [] versions = registry.getVersions("/c1/c2");
Since the Registry comes with versioning, we can restore a resource to any of its versions. This can be done using the registry as well. In the previous section, we discussed how to retrieve versions for a give resource. The following line of code demonstrates we can restore back an old version of the registry instance.
registry.restoreVersion ("/c1/c2;version=2");
We can perform tagging operations using the registry. To tag a resource, we need the resource path and the tagging words. Let's say we need to tag a resource named "/c1/c2/r2" as "rename resource". We can do this as:
registry.applyTag("/c1/c2/r2" , "rename resource");
We can use the registry to retrieve tags for a give resource. It will return an array of Tag type and we can iterate the array to see the content.
Tag[] tags = registry.getTags("/c1/c2/r2");
We can remove a tag using the tag name. Use the following code:
registry.removeTag("/c1/c2/r2","rename resource");
We can also comment on a resource using the registry. Here, we will create a comment object and call the registry instance. Following lines of code illustrates how we can achieve this:
Comment c1 = new Comment();
c1.setText("This is my comment");
String commentpath = registry.addComment("/c1/c2/r2", c1);, c1);
The above lines of code will add a comment to the resource named: "c1/c2/r2 ".
We can also make changes to comments we have already made using the registry instance. Here, we need the path and new text for the comment we are adding. Say we want to change from "This is my comment" to "This is cool", For that, we can do the following:
registry.editComment(commentpath,"This is cool");
In order to rate a resource based on our judgment, we can again use the registry instance. Rating a resource can be done using following line of code:
registry.rateResource("c1/c2/r2 " , 4);
In addition to the above operations, there are a number of others that we can perform using the registry instance. In this document we have discussed only the most commonly used operations.
Embedded Registry provides transactions support where multiple Registry API methods can be executed as an atomic operation. Start of a transaction is marked by the beginTransaction() method provided in the Registry API. Once a transactional operation is compeleted, commitTransaction() method has to be called to mark the end of the transaction. If an error occures while a transactional operation is being performed, rollbackTransaction() method has to be called to undo all the operations performed since the transaction is started. Note that currently the UserManager operations do not participate in the registry transactions.
try {
registry.beginTransaction();
// perform registry operations
.........
registry.commitTransaction();
} catche (Exception e) {
registry.rollbackTransaction();
}
We can use the RemoteRegistry to export our entire local file system into the Registry. What we need to do is to give the location of the file system and the location where we want to put them in the Registry. Once we do that, inside the registry it will create the same structure as the file system and upload all files into the Registry. We can consider this as any check-in operation on any kind of version management system. Following code demonstrates how to import a local file system into the Registry:
File file = new File("Path of the file");
RemoteRegistry remote_registry = new RemoteRegistry(new
URL("http://localhost:8080/wso2registry"), "admin", "admin");
RegistryClientUtils.importToRegistry(file ,
"/myfile/filesystem" ,remote_registry);
In the previous section, we discussed how to import a local file system into the Registry. There is another way round of this and it is to check-out the Registry to a local file system. To export, we can select either the entire Registry or a selected node. Depending on the node we select, the remote_registry instance will create the same structure within the file system. Even if we have the resource with binary data, then it will create all of the necessary files in the file system.
Let's say we want to export "/myfile/filesystem" into my local file system then we can use the following code:
File toFile = new File("Path of the new file");
RemoteRegistry remote_registry = new RemoteRegistry(new
URL("http://localhost:8080/wso2registry"), "admin", "admin");
RegistryClientUtils.importToRegistry( toFile,
"/myfile/filesystem" ,remote_registry);
We need to keep in mind when exporting the Registry to a file system, that it will only export the resources but not the comments, tags and any rating associated.
Typically many resources in your Registry, such as service descriptions, are going to progress through a series of "lifecycle stages" - for instance, a service may start off as "created", then after QA has confirmed it works it moves to "tested". After testing, the service moves to a "deployed" state, at which point it is released into production. Eventually the service is taken down or replaced and it moves into a "deprecated" state.
The WSO2 Registry makes using and managing state-based Lifecycles easy. Out of the box, the Registry includes a default lifecycle which implements exactly the state transitions defined in the last paragraph. This section will explain how to use lifecycles, and how to configure your own custom lifecycles to match your organizational requirements.
If you click the "addition" button on the Lifecycles pane, you'll see something like this:
In the dropdown you'll see all the available lifecycles that have been configured in the registry.xml file. You can select one and then click "add", which will associate the given lifecycle with the Resource. After association has succeeded, the lifecycle pane will always show you the current state of the Resource in the lifecycle:
Once a Lifecycle has been successfully associated with a Resource, you'll also notice the available actions, which could be "promote", "demote", or both. By clicking "promote", you attempt to move the Resource to the next lifecycle state. Assuming any necessary conditions (see next section) are met, you'll see "Action invoked successfully" at the top of the screen and you'll notice the state indicator moves to the next state. The "promote" action is not available (and won't be visible) once the Resource is in the final state of the lifecycle.
The "demote" action is the opposite of promote - it moves the Resource *back* to the previous state. Since you can't demote beyond the beginning of the lifecycle, the "demote" action will not be available in the first state.
You configure a custom lifeycle like this in registry.xml:
<aspect name="MyLifecycle" class="org.wso2.registry.aspects.Lifecycle">
<state name="untested">
<condition property="tests.passed"
condition="equals"
value="true"/>
</state>
<state name="tested"/>
</aspect>
(Note that to use our standard lifecycle implementation you MUST use the exact classname specified above)
This is a simple two-state lifecycle. When a Resource is initially associated with this lifecycle, it will be placed in the "untested" state. To promote this Resource into the "tested" state, the specified condition must be met - so if the "promote" action is selected by the user and the "tests.passed" property has not been set to "true", an error will be raised and the promotion will fail.
The basic pattern is to include as many "<state>" elements as you need, each of which has a name and (optionally) any conditions necessary to promote a resource from that state to the next.
Condition declarations involve a property, a condition (one of "equals", "isNull", "contains", "greaterThan" or "lessThan"), and a value. If the condition is "greaterThan" or "lessThan", the value is treated as an integer. Multiple conditions may be specified for a given transition - in this case ALL specified conditions must be satisfied before a successful promote.
Lifecycles are a particular instance of a more general concept called an Aspect. Aspects are a way of associating custom behaviors (implemented in Java classes) with Registry Resources. The basic things you can do with an Aspect are:
registry.invokeAspect()
API. Just as the Aspect implementation can decide whether or not to allow an association, it
is in complete control of exactly what (if anything) occurs as a result of invoking an action.Installing an aspect in the Registry is as easy as a) making sure your class is available on the classpath (for a webapp this typically means dropping the .class file in WEB-INF/classes, or a .jar file in WEB-INF/lib), and b) configuring it in registry.xml like so:
<aspect name="MyAspect" class="my.package.ClassName"/>
Your Aspect class can have either a default constructor (with no arguments), or, if you want it to be able to parse custom configuration, you can implement a constructor that takes an OMElement (org.apache.axiom.om.OMElement), like this:
class MyLifecycle extends Aspect {
public MyLifecycle(OMElement config) {
String myName = config.getAttributeValue(new QName("name"));
... parse rest of configuration here ...
}
}
If a constructor like this is present, the Registry will hand it the OMElement corresponding to the <aspect> declaration in the registry.xml file. This will allow you to read any attributes or child elements. (See the Axiom documentation at http://ws.apache.org/commons/axiom for more details)
The methods you need to implement from the Aspect interface are:
void associate(Resource resource, Registry registry) throws RegistryException
void invoke(RequestContext context, String action) throws RegistryException
String [] getAvailableActions(RequestContext context)
More to come here....