Pular para o conteúdo principal

The GateIn Management/Navigation API

Consuming popular APIs is very interesting and cool. You can in a few minutes seek in the web some how-to, or a sample application and create yours. After create a lot of these kind of applications I got myself bored and no motivation to keep posting. For example, a Twitter app will be only another twitter app and there's a lot of API needing clients or needing to be explored.

So I started to look new APIs to explore. One of these not well recognized, but very well designed in REST terms is GateIn Management API. GateIn is the JBoss Java Portal an it is a great tool with a big community behind it.



The GateIn 3.2 API is not hard to understand and you can learn more about it in this great documentation. Basically we have the base resource called... Resource. The Resource contains all the possible operations and their children. You can navigate by the children and find more operations. You will notice that the more notable feature of this API is the presence of HATEOAS. The API also serve data in XML and JSON formats. You can test the API, but you will need to have the GateIn running somewhere to access. Here is a sample of the response body when you access the base URL in my local installation(I'm using EPP, the enterprise product from Red Hat based in GateIn, so the context may change for pure GateIn installation):

GET on http://192.168.56.101:8080/rest/private/managed-components/
{"description": "Available operations and children (sub-resources).","children": [{"name": "mop","description": "MOP (Model Object for Portal) Managed Resource, responsible for handling management operations on navigation, pages, and sites.","link": {"rel": "child","href": "http://192.168.56.101:8080/rest/private/managed-components/mop"}}],"operations": [{"operation-name": "read-resource","operation-description": "Lists information about a managed resource, including available operations and children (sub-resources).","link": {"rel": "self","href": "http://192.168.56.101:8080/rest/private/managed-components"}}]}

I made a very simple command line app to consume this API and learn more about it. It was used RESTEasy Client API. It is important to say that this API requires authentication since it exposes information of all GateIn groups.

package org.gateinmanager.test.model;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

import javax.ws.rs.core.MediaType;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.gateinmanager.model.Child;
import org.gateinmanager.model.Link;
import org.gateinmanager.model.Operation;
import org.gateinmanager.model.Resource;
import org.jboss.resteasy.client.ClientExecutor;
import org.jboss.resteasy.client.ClientRequest;
import org.jboss.resteasy.client.ClientRequestFactory;
import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor;

/**
 * 
 * It will just test the request is being parsed to domain objects...
 * 
 * @author jesuino
 * 
 */
@SuppressWarnings("deprecation")
public class TestModel {
    private static final String USERNAME = "root";
    private static final String PASSWORD = "gtn";

    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws Exception {

        ClientRequestFactory factory = createFactory(USERNAME, PASSWORD);
        Scanner sc = new Scanner(System.in);
        String in;

        Resource resource = null;
        System.out.println("\t\t*****GateIn Management API*****\n\n");

        System.out
                .println(">> Enter the HOST to start navigating or press"
                        + " Q to quit (the base URL is "
                        + "http://192.168.56.101:8080/rest/private/managed-components)\n");
        while (!(in = sc.next()).startsWith("Q")) {
            // Entered a URL, just load Resource and print it
            if (in.startsWith("http://")) {
                ClientRequest cr = factory.createRequest(in);
                cr.accept(MediaType.APPLICATION_XML);
                try {
                    System.out.println("Loading...");
                    resource = (Resource) cr.get().getEntity(Resource.class);
                    System.out.println("Resource loaded!");
                } catch (Exception e) {
                    System.out
                            .println("\n\n>>>  Something went wrong when loading your URL...\n");
                    e.printStackTrace();
                }
            } else {
                System.out
                        .println("\nPlease enter a valid URL or press Q to quit...");
            }
            if (resource != null)
                printResource(resource);
            System.out.println("\n>> Enter URL or Q to quit: ");
        }

    }

    public static ClientRequestFactory createFactory(String username,
            String password) throws URISyntaxException {
        // Setting Credentials though an HttpExecutor
        Credentials credentials = new UsernamePasswordCredentials(username,
                password);
        HttpClient httpClient = new HttpClient();
        httpClient.getState().setCredentials(AuthScope.ANY, credentials);
        httpClient.getParams().setAuthenticationPreemptive(true);
        ClientExecutor clientExecutor = new ApacheHttpClientExecutor(httpClient);

        // creating the factory
        return new ClientRequestFactory(clientExecutor, new URI(""));
    }

    public static void printResource(Resource resource) {
        System.out.println("**\t" + resource.getDescription() + "\t**\n");
        System.out.println("Possible Operations:");
        List<Operation> operations = resource.getOperations();
        if (operations != null) {
            for (Operation operation : operations) {
                Link link = operation.getOperationLink();
                System.out.println("\t* " + operation.getOperationName() + ": "
                        + operation.getOperationDescription() + "\n\t   rel: "
                        + link.getRel() + ". Located at " + link.getHref());
            }
        }

        Set<Child> children = resource.getChildren();
        if (children != null) {
            System.out.println("\nChildren:");
            for (Child child : children) {
                Link link = child.getLink();
                System.out.println("\t* " + child.getName() + ": "
                        + child.getDescription() + "\n\t   rel: "
                        + link.getRel() + ". Located at " + link.getHref());
            }
        }

    }
}



The authentication part of this code is the most boring. We need to set it in the Executor, which who will make the authentication behind RESTEasy calls. We use RESTEasy factory to create requests based on the URI supplied by the user of the application. From the response, we retrieve the body as object using the model objects from GateIn REST API source code. Here is the application running:


*****GateIn Management API*****

>> Enter the HOST to start navigating or press Q to quit (the base URL is http://192.168.56.101:8080/rest/private/managed-components)
http://192.168.56.101:8080/rest/private/managed-components
Loading...
Resource loaded!
** Available operations and children (sub-resources). **
Possible Operations:
* read-resource: Lists information about a managed resource, including available operations and children (sub-resources).
  rel: self. Located at http://192.168.56.101:8080/rest/private/managed-components
Children:
* mop: MOP (Model Object for Portal) Managed Resource, responsible for handling management operations on navigation, pages, and sites.
  rel: child. Located at http://192.168.56.101:8080/rest/private/managed-components/mop
>> Enter URL or Q to quit:
http://192.168.56.101:8080/rest/private/managed-components/mop
Loading...
Resource loaded!
** Available site types. **
Possible Operations:
* read-resource: Lists available site types for a portal
  rel: self. Located at http://192.168.56.101:8080/rest/private/managed-components/mop
* export-resource: Exports any resources with an export operation handler registered.  This operation is recursive until an operation handler is found.
  rel: content. Located at http://192.168.56.101:8080/rest/private/managed-components/mop.zip
* import-resource: Imports mop data from an exported zip file.
  rel: operation. Located at http://192.168.56.101:8080/rest/private/managed-components/mop
Children:
* portalsites: Management resource responsible for handling management operations on a specific site type for a portal.
  rel: child. Located at http://192.168.56.101:8080/rest/private/managed-components/mop/portalsites
* usersites: Management resource responsible for handling management operations on a specific site type for a portal.
  rel: child. Located at http://192.168.56.101:8080/rest/private/managed-components/mop/usersites
* groupsites: Management resource responsible for handling management operations on a specific site type for a portal.
  rel: child. Located at http://192.168.56.101:8080/rest/private/managed-components/mop/groupsites
>> Enter URL or Q to quit:
Q

I have a critic to this REST API that is the use of the ".xml" in some URIs , but the API design is good for the portal management for its composite architecture (Everything is a resource and has children). I hope post something more graphical in next weeks :-D

Comentários

  1. Thanks for the sample of code.

    It is interesting and helpfull.

    I'll use it to build my site with GateIn :

    http://www.presta-expert.com/pexpalctnr/pcr

    Antoine

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

Simplest JavaFX ComboBox autocomplete

Based on this Brazilian community post , I've created a sample Combobox auto complete. What it basically does is: When user type with the combobox selected, it will work on a temporary string to store the typed text; Each key typed leads to the combobox to be showed and updated If backspace is type, we update the filter Each key typed shows the combo box items, when the combobox is hidden, the filter is cleaned and the tooltip is hidden:   The class code and a sample application is below. I also added the source to my personal github , sent me PR to improve it and there are a lot of things to improve, like space and accents support.

Dancing lights with Arduino - The idea

I have been having fun with Arduino these days! In this article I am going to show how did I use an electret mic with Arduino to create a Dancing Lights circuit. Dancing Lights   I used to be an eletronician before starting the IT college. I had my own electronics maintenance office to fix television, radios, etc. In my free time I used to create electronic projects to sell and I made a few "reais" selling a version of Dancing lights, but it was too limited: it simply animated lamps using a relay in the output of a 4017 CMOS IC. The circuit was a decimal counter  controlled by a 555. 4017 decimal counter. Source in the image When I met Arduino a few years ago, I was skeptical because I said: I can do this with IC, why should I use a microcontroller. I thought that Arduino was for kids. But now my pride is gone and I am having a lot of fun with Arduino :-) The implementation of Dancing Lights with Arduino uses an electret mic to capture the sound and light leds...

Creating custom Work Item Handler in BPM Suite/jBPM 6

Hi all! In this post I am going to share my experience creating a work item handler for BPM Suite 6.0.3 (which is very similar to jbpm as explained in a previous post ). The Hello World Work Item Handler Let's create a really simple WorkItemHandler just to print "Hello World" in the console. Of course you can implement more feature and make it receive parameters, access database, web services, etc. But in this post we will keep it simple. Really simple. First thing to do is to create a maven project for my WorkItemHandler. Here's the pom.xml of my Maven project: Notice that we are importing jbpm dependency so we can find the java interface that is used to create work item handlers. Now we can start coding. Let's create a class name HelloWorkItemHandler in package org.jugvale.jbpm, here is the simple code: Now we can build our project and go to BPM Suite to configure it so we can use this workitem. Registering the WorkItemHandler UPDATE...