Bug 1181771 - Section "3.4.2.2. Querying Activity Units" is talking about returning a List of "Activity Units". Is it right?
Summary: Section "3.4.2.2. Querying Activity Units" is talking about returning a List ...
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: JBoss Fuse Service Works 6
Classification: JBoss
Component: Documentation
Version: 6.0.0
Hardware: All
OS: All
high
high
Target Milestone: ---
: ---
Assignee: belong
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-01-13 17:42 UTC by Musharraf Hussain
Modified: 2019-03-22 07:32 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Build Name: 22588, Development Guide Volume 3: Governance-6-6 Build Date: 25-11-2014 13:39:38 Topic ID: 21430-566391 [Specified]
Last Closed: 2015-03-02 04:02:22 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker FUSEDOC-326 0 Major Closed Section "3.4.2.2. Querying Activity Units" is talking about returning a List of "Activity Units". Is it right? 2015-12-23 17:45:34 UTC

Description Musharraf Hussain 2015-01-13 17:42:44 UTC
Title: Querying Activity Units

Describe the issue:
The section  "3.4.2.2. Querying Activity Units" is talking about returning a List of "Activity Units". Is it right? Because as per the following client implementation of Activity Server, the URL "/overlord-rtgov/activity/unit" URL does not return a List of "ActivtiyUnit" and the REST client example provided in this section refers to the "​// <host>/overlord-rtgov/activity/query" URL which only returns "List<ActivityType>" not "List<ActivityUnit>" . Check out the following source code.

The following code of "org.overlord.rtgov.activity.server.rest.client.RESTActivityServer" shows you the actual implementation of the REST client which invokes both the URLs to fetch the data from the REST server.
~~~
package org.overlord.rtgov.activity.server.rest.client;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.overlord.rtgov.activity.model.ActivityType;
import org.overlord.rtgov.activity.model.ActivityUnit;
import org.overlord.rtgov.activity.model.Context;
import org.overlord.rtgov.activity.server.ActivityServer;
import org.overlord.rtgov.activity.server.QuerySpec;
import org.overlord.rtgov.activity.util.ActivityUtil;

import org.overlord.rtgov.common.util.RTGovConfig;

/**
 * This class provides the REST client implementation of the activity server.
 *
 */
@Singleton
public class RESTActivityServer implements ActivityServer {

    private static final Logger LOG=Logger.getLogger(RESTActivityServer.class.getName());
    
    private static final String STORE="/overlord-rtgov/activity/store";
    private static final String UNIT="/overlord-rtgov/activity/unit";
    private static final String QUERY="/overlord-rtgov/activity/query";
    private static final String EVENTS="/overlord-rtgov/activity/events";
    
    @Inject @RTGovConfig
    private String _serverURL="http://localhost:8080";
            ...

    /**
     * {@inheritDoc}
     */
    public ActivityUnit getActivityUnit(String id) throws Exception {
        ActivityUnit ret=null;
        
        URL queryUrl = new URL(_serverURL+UNIT+"?id="+id);
        
        if (LOG.isLoggable(Level.FINER)) {
            LOG.finer("RESTActivityServer["+queryUrl+"] getActivityUnit: "+id);
        }
        
        HttpURLConnection connection = (HttpURLConnection) queryUrl.openConnection();
        
        initAuth(connection);

        connection.setRequestMethod("GET");

        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setUseCaches(false);
        connection.setAllowUserInteraction(false);
        connection.setRequestProperty("Content-Type",
                    "application/json");

        java.io.InputStream is=connection.getInputStream();
        
        byte[] b=new byte[is.available()];
        
        is.read(b);
        
        is.close();
        
        ret = ActivityUtil.deserializeActivityUnit(b);
        
        if (LOG.isLoggable(Level.FINER)) {
            LOG.finer("RESTActivityServer getActivityUnit result: "+ret);
        }
        
        return (ret);
    }
...

    /**
     * {@inheritDoc}
     */
    public List<ActivityType> query(QuerySpec query) throws Exception {
        List<ActivityType> ret=null;
        
        URL queryUrl = new URL(_serverURL+QUERY);
        
        if (LOG.isLoggable(Level.FINER)) {
            LOG.finer("RESTActivityServer["+queryUrl+"] query: "+query);
        }
        
        HttpURLConnection connection = (HttpURLConnection) queryUrl.openConnection();
        
        initAuth(connection);

        connection.setRequestMethod("POST");

        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setUseCaches(false);
        connection.setAllowUserInteraction(false);
        connection.setRequestProperty("Content-Type",
                    "application/json");

        java.io.OutputStream os=connection.getOutputStream();
        
        byte[] b=ActivityUtil.serializeQuerySpec(query);
        os.write(b);
        
        os.flush();
        os.close();
        
        java.io.InputStream is=connection.getInputStream();

        b = new byte[is.available()];
        is.read(b);
        
        ret = ActivityUtil.deserializeActivityTypeList(b);
        
        is.close();
        
        if (LOG.isLoggable(Level.FINER)) {
            LOG.finer("RESTActivityServer result: "+ret);
        }
        
        return (ret);
    }

...
~~~

As you can see here, the "List<ActivityType> query(QuerySpec query)" method shows the implementation behind calling the "overlord-rtgov/activity/query" URL which returns the java.util.List of "ActivityType" objects.

The result returning ActivityUnit which is implemented in the "ActivityUnit getActivityUnit(String id)" method above, takes an activity unit ID. And returns a single ActivityUnit object. Now it's the responsibility of "ActivityUtil.deserializeActivityUnit(..)" method to deserialize the incoming records into "ActivityUnit" type.
~~~
package org.overlord.rtgov.activity.util;
...
/**
 * This class provides utility functions for the activity
 * model.
 *
 */
public final class ActivityUtil {
    
...
    /**
     * This method deserializes an Activity event from a JSON representation.
     * 
     * @param act The JSON representation of the activity
     * @return The Activity event
     * @throws Exception Failed to deserialize
     */
    public static ActivityUnit deserializeActivityUnit(byte[] act) throws Exception {
        ActivityUnit ret=null;
        
        java.io.ByteArrayInputStream bais=new java.io.ByteArrayInputStream(act);
        
        ret = MAPPER.readValue(bais, ActivityUnit.class);
        
        bais.close();
        
        return (ret);
    }
...

    /**
     * This method deserializes an ActivityType event list from a JSON representation.
     * 
     * @param act The JSON representation of the activity
     * @return The ActivityType event list
     * @throws Exception Failed to deserialize
     */
    public static java.util.List<ActivityType> deserializeActivityTypeList(byte[] act) throws Exception {
        java.util.List<ActivityType> ret=null;
        
        java.io.ByteArrayInputStream bais=new java.io.ByteArrayInputStream(act);
        
        ret = MAPPER.readValue(bais, ACTIVITY_TYPE_LIST);
        
        bais.close();
        
        return (ret);
    }
...
~~~


Now the code snippet from the documentation says this :
~~~
​        QuerySpec qs=........
​        java.net.URL queryUrl = new java.net.URL(....);   
​        // <host>/overlord-rtgov/activity/query
​
​        java.net.HttpURLConnection connection = (java.net.HttpURLConnection) queryUrl.openConnection();
​
​        String userPassword = username + ":" + password;
​        String encoding = org.apache.commons.codec.binary.Base64.encodeBase64String(userPassword.getBytes());
​
​        connection.setRequestProperty("Authorization", "Basic " + encoding);
​
​        connection.setRequestMethod("POST");
​        connection.setDoOutput(true);
​        connection.setDoInput(true);
​        connection.setUseCaches(false);
​        connection.setAllowUserInteraction(false);
​        connection.setRequestProperty("Content-Type", "application/json");
​
​        java.io.OutputStream os=connection.getOutputStream();
​
​        ObjectMapper mapper=new ObjectMapper();    
​        // Use jackson to serialize the query spec
​        mapper.writeValue(os, qs);
​
​        os.flush();
​        os.close();
​
​        java.io.InputStream is=connection.getInputStream();
​
​        java.util.List<ActivityUnit> activities = mapper.readValue(is, new TypeReference<java.util.List<ActivityUnit>>() {});
~~~

However I think it is not correct and the last line could have been misplaced from the implementation of the "/overlord-rtgov/activity/store" REST URL which stores a List of ActivityUnit objects, as shown below.

~~~
package org.overlord.rtgov.internal.activity.server.rest;
...
/**
 * This class represents the RESTful interface to the activity server.
 *
 */
@Path("/activity")
@ApplicationScoped
public class RESTActivityServer {

    private static final Logger LOG=Logger.getLogger(RESTActivityServer.class.getName());
    
    //@javax.inject.Inject
    private ActivityServer _activityServer=null;

...

    /**
     * This method stores the supplied list of activity events.
     * 
     * @param acts The list of activity events
     * @return A response indicating success or failure
     * @throws Exception Failed to perform store operation
     */
    @POST
    @Path("/store")
    public Response store(String acts) throws Exception {
 
        if (LOG.isLoggable(Level.FINEST)) {
            LOG.finest("Store activities="+acts);        
        }
        
        java.util.List<ActivityUnit> activities=
                    ActivityUtil.deserializeActivityUnitList(acts.getBytes());
        
        if (LOG.isLoggable(Level.FINEST)) {
            LOG.finest("Store "+activities.size()+" activities");        
        }
        
        if (_activityServer == null) {
            return Response.status(Status.SERVICE_UNAVAILABLE).entity("Activity Server is not available").build();
        }

        try {
            _activityServer.store(activities);
            
            return Response.status(Status.OK).entity("Activities stored").build();
        } catch (Exception e) {
            return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Failed to store activities: "+e).build();
        }
    }
...

~~~


~~~
package org.overlord.rtgov.activity.util;
...
/**
 * This class provides utility functions for the activity
 * model.
 *
 */
public final class ActivityUtil {
    
    protected static final ObjectMapper MAPPER=new ObjectMapper();

    private static final TypeReference<java.util.List<ActivityUnit>> ACTIVITY_UNIT_LIST=
            new TypeReference<java.util.List<ActivityUnit>>() { };
    private static final TypeReference<java.util.List<ActivityType>> ACTIVITY_TYPE_LIST=
            new TypeReference<java.util.List<ActivityType>>() { };
    
    private static ObjectWriter ATLIST_WRITER=null;

...
    /**
     * This method deserializes an ActivityType event list from a JSON representation.
     * 
     * @param act The JSON representation of the activity
     * @return The ActivityType event list
     * @throws Exception Failed to deserialize
     */
    public static java.util.List<ActivityType> deserializeActivityTypeList(byte[] act) throws Exception {
        java.util.List<ActivityType> ret=null;
        
        java.io.ByteArrayInputStream bais=new java.io.ByteArrayInputStream(act);
        
        ret = MAPPER.readValue(bais, ACTIVITY_TYPE_LIST);
        
        bais.close();
        
        return (ret);
    }
...
~~~

Can you please review it and clarify it in the documentation if there is any missing link?

Suggestions for improvement:
- Please see above.

Additional information:
URL:
https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse_Service_Works/6/html/Development_Guide_Volume_3_Governance/chap-Run-Time_Governance.html#sect-Activity_Events_Collection

Comment 7 Musharraf Hussain 2015-01-26 09:46:06 UTC
Hello Ben,

The content looks good to me. Thank you for making the changes.


Regards,
Musharraf Hussain

Comment 8 belong 2015-01-28 02:39:26 UTC
Minor change. Reviewed by reporter. Treating as verified. 

Changes pushed to fsw6.0-prod branch. Ready for publishing.


Note You need to log in before you can comment on or make changes to this bug.