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
Musharraf, Please review the updated content at [1] (Section 3.4.2.2). Regards, Ben [1] http://jenkinscat.gsslab.pnq.redhat.com:8080/job/doc-Red_Hat_JBoss_Fuse_Service_Works-Development_Guide_Volume_3_Governance-6-0%20%28html-single%29/lastStableBuild/artifact/tmp/en-US/html-single/index.html#sect-Activity_Server
Hello Ben, The content looks good to me. Thank you for making the changes. Regards, Musharraf Hussain
Minor change. Reviewed by reporter. Treating as verified. Changes pushed to fsw6.0-prod branch. Ready for publishing.
Published. https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse_Service_Works/6.0/html/Development_Guide_Volume_3_Governance/chap-Runtime_Governance.html#sect-Activity_Server