You can use the API to create a custom review process that defines specific states and reviews scenarios. To learn how to use the API, use the example Bugzilla client available in the BugzillReview.jar, located in the following directory: http://host:port/com.ibm.ram.repository.web/extensionExamples/customReviewProcess/BugzillaReview.jar, where host and port are the name and port number for your Rational® Asset Manager server.
Open the Java archive file located in the following directory: http://host:port/com.ibm.ram.repository.web/extensionExamples/customReviewProcess/CustomReviewAPI.jar, where host and port are the name and port number for your Rational Asset Manager server.
package com.ibm.ram.extension.demo.review; import java.io.InputStream; import java.net.URL; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.*; import org.xml.sax.helpers.DefaultHandler; import com.ibm.ram.extension.ConfigurationDetails; import com.ibm.ram.extension.CustomReviewProcess;
When a review process starts in Rational Asset Manager, this extension creates a problem in the Bugzilla client to track the review process. Each problem in the Bugzilla client has an associated problem ID, or 'bug ID'. This ID is returned from the start(...) method in this extension and is stored in Rational Asset Manager. Subsequent method calls include the 'bug ID' in the instance data so that the extension can match a specific review process instance with a Bugzilla 'bug ID'. The following examples describe the method calls for instances in the review process:
public class BugzillaReviewProcess extends CustomReviewProcess {
The 'VERIFIED' Bugzilla state represents the approved state in Rational Asset Manager. Assets that are approved can be found and reused in the repository.
public static final String[] APPROVED_STATES = {BugzillaConstants.VERIFIED};
The 'CLOSED' Bugzilla state represents the rejected state in Rational Asset Manager. Assets that are rejected are returned to the editable draft state.
public static final String[] REJECTED_STATES = {BugzillaConstants.CLOSED};
The 'NEW', 'ASSIGNED', and 'RESOLVED' Bugzilla states will be used for the review process in Rational Asset Manager.
public static final String[] NON_FINAL_STATES = {BugzillaConstants.NEW, BugzillaConstants.ASSIGNED,
BugzillaConstants.RESOLVED};
public static final String USER = "user";
public static final String PASSWORD = "password";
public static final String TITLE = "title"; public static
final String PRODUCT = "product";
public static final String COMPONENT = "component";
public static final String PLATFORM = "platform";
public static final String SEVERITY = "severity";
public static final String PRIORITY = "priority";
public static final String OPERATING_SYSTEM = "operatingSystem";
public static final String VERSION = "version";
public static final String URL = "url";
When you connect to a Rational Asset Manager server, you must configure the following Bugzilla client details: the server URL, user name, and password. You can configure optional details, such as the name of the review process, as the details relate to a specific review process.
public static final ConfigurationDetails[] CONFIG_DETAILS = {
new ConfigurationDetails (URL, "URL", "The URL of the Bugzilla home page",false, true),
new ConfigurationDetails (USER,"User", "The user account that will be used to access bugzilla", false, true),
new ConfigurationDetails (PASSWORD, "Password","The password for the account that will be used to access bugzilla", true, true),
new ConfigurationDetails(TITLE, "Title", "The title for the submitted review", false, false),
new ConfigurationDetails(PRODUCT, "Product","Prodcut", "TestProduct", false, false),
new ConfigurationDetails(COMPONENT, "Component","Component", "TestComponent", false, false),
new ConfigurationDetails(PLATFORM, "Platform","Platform", "PC", false, false),
new ConfigurationDetails(SEVERITY, "Severity","Severity", "blocker", false, false),
new ConfigurationDetails(PRIORITY, "Priority","Priority", "P1", false, false),
new ConfigurationDetails(OPERATING_SYSTEM,"Operating system","Operating System", "Windows", false, fals),
new ConfigurationDetails(VERSION, "Version","Version", "other", false, false),
};
The following codeadds an ID for an unknown Bugzilla client bug entry.
public static final String UNKNOWN_CUSTOM_ID = "-1";
public void end(String ramAssetId, String assetVersion, String customAssetId,Map configurationValues, boolean aborted) {
The following method returns the configuration details that you defined.
public String getName() {
return "Bugzilla 2.22.2 review process"; }
The following method returns the description of the Bugzilla process.
public String getDescription() {
return "A custom review process that integrates with Bugzilla 2.22.2"; }
The following method returns the approved state names that you defined. When the asset reaches this state, it moves to the Approved state in Rational Asset Manager.
public String[] getApprovedStateNames(String assetId, String assetVersion,
String instanceData, Map configurationValues) {
return APPROVED_STATES;
}
The following method returns the non-final state names that you defined. While the asset is in one of these states, the review process will be active and reviewers will have access to review the asset.
public String[] getNonFinalStateNames() {
return NON_FINAL_STATES;
}
The following codecommunicates with the Bugzilla server to determine the state of the problem ID that is provided in the instance data.
public String getState(String assetId, String assetVersion, String instanceData,Map configurationValues)
{
return (String)getStatus(getBugId(instanceData),configurationValues).get(BugzillaXMLHandler.BUG_STATUS_NODE);
}
The following codereturns the URL of a specific problem based on the 'bug ID' in the instance data.
public String getURL(String assetId, String assetVersion, String instanceData,Map configurationValues)
{
int bugId = getBugId(instanceData);String url = BugzillaClient client = new BugzillaClient(new URL((String)configurationValues.get(URL)));
if(!String.valueOf(bugId).equals(UNKNOWN_CUSTOM_ID))
{
url = client.getURL(bugId).toString();
}
catch(Exception e) {e.printStackTrace();
}
return url;""; try
{
The following codeis called each time you submit a review. At this point, you must communicate with the Bugzilla client to fetch the problem that is associated with this review process, which is determined by the instanceData. You must then continue to update the status of the problem by entering the review comment of the user and noting whether the user has accepted or rejected the review.
public String handleReviewSubmitted
(String assetId, String assetVersion, String instanceData, String username, bool accepted, String comment, InputStream uploadedContent, String fileName, Map configurationValues)
{
String acceptText = accepted ? "approved" : "rejected"; try
{
BugzillaClient client = new BugzillaClient(new URL((String)configurationValues.get(URL)));
Map bugStatus = getStatus(getBugId(instanceData),configurationValues);client.updateBug
(
(String)configurationValues.get(USER),
(String)configurationValues.get(PASSWORD),getBugId(instanceData),BugzillaConstants.KEEP_CURRENT_STATE,
(String)bugStatus.get(BugzillaXMLHandler.PRODUCT_NODE),
(String)bugStatus.get(BugzillaXMLHandler.COMPONENT_NODE),
(String)bugStatus.get(BugzillaXMLHandler.PLATORM_NODE),
(String)bugStatus.get(BugzillaXMLHandler.SEVERITY_NODE),
(String)bugStatus.get(BugzillaXMLHandler.PRIORITY_NODE),
(String)bugStatus.get(BugzillaXMLHandler.OP_SYS_NODE),
(String)bugStatus.get(BugzillaXMLHandler.VERSION_NODE),"http://",
(String)bugStatus.get(BugzillaXMLHandler.TITLE_NODE), username + " has " + acceptText + " with comment: " + comment);
}
catch(Exceptione)
{
e.printStackTrace();
}
return instanceData;
}
The following code communicates with the Bugzilla client to determine if the given review process is in an accepted state.
public boolean isApproved(String assetId, String assetVersion,String instanceData, Map configurationValues)
{
return BugzillaConstants.VERIFIED_XML.equals(getState(assetId,assetVersion, instanceData, configurationValues));
}
The following code communicates with the Bugzilla client to determine if the given review process is in a rejected state.
public boolean isRejected(String assetId, String assetVersion,
String instanceData,Map configurationValues)
{
return BugzillaConstants.CLOSED_XML.equals(getState(assetId,assetVersion, instanc Data, configurationValues));
}
The following code is called when the review process is started. Rational Asset Manager supplies the asset ID, asset version, and configuration values for this review process. You must communicate with the Bugzilla client to create a problem for this review process. After you create a problem for the review process, the 'bug ID' associated with the problem returns to Rational Asset Manager. In all subsequent calls for this review process, the String that returned from the method (the bug ID) will be passed in as the instance parameter.
public String start(String assetId, String assetVersion, Map configurationValues)
{
String customId; try
{
BugzillaClient client = new BugzillaClient
(newURL((String)configurationValues.get(URL))); customId = String.valueOf(client.enterBug((String)configurationValues.get(USER),
(String)configurationValues.get(PASSWORD),
(String)configurationValues.get(PRODUCT),
(String)configurationValues.get(COMPONENT),
(String)configurationValues.get(PLATFORM),
(String)configurationValues.get(SEVERITY),
(String)configurationValues.get(PRIORITY),
(String)configurationValues.get(OPERATING_SYSTEM),
(String)configurationValues.get(VERSION),"http://",
(String)configurationValues.get(TITLE), "Review started"));
}
catch(Exception e)
{
e.printStackTrace();customId = UNKNOWN_CUSTOM_ID;
}
return customId;
}
The following codecommunicates
with the Bugzilla client to determine the status of a specific problem
ID or 'bug ID'.@param bugzillaAssetId
@param configurationValues
@return
private Map getStatus(int bugzillaAssetId, Map configurationValues)
{
BugzillaXMLHandler handler = new BugzillaXMLHandler();
try
{
BugzillaClient client = new BugzillaClient(new URL((String)configurationValues.get(URL))); SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(false); SAXParser sp = factory.newSAXParser(); sp.parse(client.getBugStatus((String)configurationValues.get(USER),
(String)configurationValues.get(PASSWORD), bugzillaAssetId), handler);
}
catch(Exception e)
{
e.printStackTrace();
}
return handler.getResult();
}
The following codedetermines the Bugzilla 'bug ID' from the instance data stored in Rational Asset Manager.
public class BugzillaXMLHandler extends DefaultHandler {
public static final String BUG_ID_NODE = "bug_id";
public static final String PRODUCT_NODE = "product";
public static final String COMPONENT_NODE = "component";
public static final String VERSION_NODE = "version";
public static final String PLATORM_NODE = "rep_platform";
public static final String OP_SYS_NODE = "op_sys";
public static final String BUG_STATUS_NODE = "bug_status";
public static final String PRIORITY_NODE = "priority";
public static final String SEVERITY_NODE = "bug_severity";
public static final String TITLE_NODE = "short_desc";
private String node;
private Map valueMap = new HashMap();
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
node = qName;
}
public InputSource resolveEntity(String publicID, String systemID)
{
return new InputSource(BugzillaReviewProcess.class.getResourceAsStream("bugzilla.dtd"));
}
public void characters (char ch[], int start, int length)
{
if(node.equals(BUG_ID_NODE)
|| node.equals(PRODUCT_NODE)
|| node.equals(COMPONENT_NODE)
|| node.equals(VERSION_NODE)
|| node.equals(PLATORM_NODE)
|| node.equals(OP_SYS_NODE)
|| node.equals(BUG_STATUS_NODE)
|| node.equals(PRIORITY_NODE)
|| node.equals(BUG_ID_NODE)
|| node.equals(SEVERITY_NODE)
|| node.equals(TITLE_NODE)) {
valueMap.put(node,new String(ch, start, length));
}
}
public Map getResult()
{
return valueMap;
}
}
}