2142 Introduction to the CaliberRM SDK

Download Report

Transcript 2142 Introduction to the CaliberRM SDK

2142
Introduction to the
CaliberRM SDK
Lilac Ezer
President
Code Alloy, LLC
Objective
Learn how the CaliberRM SDK can be
used to develop custom utilities and
integrations to create end-to-end
software lifecycle solutions.
Lilac Ezer
• President of Code Alloy, LLC
• 10 years of software development
experience (primarily Java)
• Extensive experience developing
customizations for Borland StarTeam and
CaliberRM
About You
• Software Configuration Managers
• Project Managers / Executives
• Software Developers
Presentation Agenda
– Business need for customization
– CaliberRM SDK architecture
– Accessing CaliberRM objects with the
SDK
– Event notification model
– Vendor Add-Ins for CaliberRM
– Questions
Requirements
• Requirements drive your software
development process
• Requirements involve all project
participants
• Requirements management is an
ongoing process
End-to-end SDLC
• Requirements are at the center of the
cycle
• Requirements can be traced to models,
source code, and test cases
• Requirements are workflow based
– Approval process
– Feedback loop
Challenges
• Tools come from different vendors, and may not
integrate out of the box.
• Often, lack of proper integration leads to
neglecting requirements once project has
started, and scope is not properly managed.
• Not all project stakeholders are technical enough
to use a requirements management tool, and
may need to view requirements and provide
feedback from a simpler interface.
CaliberRM Customization
• CaliberRM SDK
– Application programming interface that allows
developers to access and manipulate CaliberRM
data, including requirements and traces, using
virtually any programming language.
• CaliberRM Add-In Modules
– Allow custom screens to be developed in Visual
Basic to provide traceability between requirements
stored in CaliberRM, and project artifacts stored in
external systems. The custom screens appear
inside the CaliberRM Client interface.
Real World Applications
• CaliberRM Web Client
• CaliberRM DataMart
• CaliberRM and StarTeam integration
• Multiple CaliberRM integrations with
external products available from
Borland
What is the Caliber SDK?
• Set of APIs provide access to
application data
• Object-oriented
• Programming language independent
SDK Client Architecture
Advantages of Using the
SDKs vs. Changing DB data
•
CaliberRM databases may be complex, with encrypted data
•
SDKs have built in business logic and security (why
reinvent the wheel?)
•
Data integrity
•
SDKs are always backwards compatible, the database may
not be
•
Instead of triggers, the MPX Event model is now available
•
Making modifications to the DB will invalidate your support
agreement with Borland!
Learning the Caliber API
• CaliberRM SDK Developer’s Guide
• The API JavaDocs and COM API
Reference
• The key to traversing these documents is
understanding containment
• An editor with code completion is also
useful
• Keep a Caliber Client open to view
available objects and properties
Supported Programming
Languages
• Original APIs were developed in Java
• Wrapped with JNI to provide COM
version (both early and late binding)
– VB
– C++
– Scripting languages: PHP, ASP, etc..
• 2005 release will contain native .NET
APIs
– VB.NET
– C#
– J# (cross-compiling)
CaliberRM SDK
Development Environment
• Java:
– Add caliberrm-sdk.jar to your classpath
• VB (or other COM language):
– Register library CaliberRMSDK65.dll
Developer Responsibilities
• The CaliberRM SDK will:
– Enforce business logic
– Enforce security permissions
• The SDK Client developer should:
– Trap for known exceptions
– Check for security permissions before
attempting to perform an operation
CaliberRM SDK Packages
• com.starbase.caliber - contains the core CaliberRM objects
• com.starbase.caliber.attribute - contains classes for
working with user-defined attributes
• com.starbase.caliber.event - contains classes that deal
with the event-listener model in CaliberRM
• com.starbase.caliber.external - contains classes for
working with external traceability
• com.starbase.caliber.security - contains classes that deal
with security management
• com.starbase.caliber.server - contains classes related to
connecting to the CaliberRM server
CaliberRM Object Model
• Many of the core classes in the CaliberRM are
named appropriately for the CaliberRM objects that
they represent
• The containment hierarchy is the same as in the
CaliberRM Client. A server contains projects, which
contain baselines, which in turn contain
requirements that can contain subrequirements and
traces
• CaliberObject is the abstract base class for many
objects contained within a Caliber server.
Containment
• Many Caliber objects live within the context of other
objects:
-> Session
-> Project
-> Baseline
-> Requirement Type
->Requirement
-> Attribute
-> Discussion
• An object instance is always aware of their Session
and their immediate parent
– getSession
– getProject, getBaseline, getRequirementType,
getRequirement
Unique Identifiers
• CaliberObjectID
• Unique across all objects on a server
• Internal ID (don’t confuse with Requirement
Number)
• getID() retrieves the CaliberObjectID
• id.getIDNumber() retrieves the unique number for
the ID
• Can be used for locating an object by ID only
(without knowing type, or context)
– Session.getCaliberObject(id)
CaliberRM Object Model 1
CaliberRM Object Model 2
CaliberObject
•
getID() - Every subclass of CaliberObject contains an ID that
uniquely identifies the object within the server instance. This ID
can later be used to access the object directly without navigating
through the caliber object hierarchy, by using the
"get(CaliberObjectID calObjID)" convenience methods on
classes such as CaliberObjectManager and Session.
•
getManager() - A CaliberObjectManager manages a group of
CaliberObjects. It is responsible for managing access to the
objects for the session representing the user currently logged in,
and caching objects to optimize performance.
•
getSession() - The Session representing the view of the data
available to the logged in user based on security permissions,
from which this CaliberRM object was retrieved.
MutableCaliberObject
• Abstract subclass of Caliber Object
• Represents objects that can be created or modified
using the CaliberRM SDK
• The CaliberRM SDK does not make changes directly
on the server, but instead allows creating new
objects and editing object properties in memory
before committing changes
Caching
• Remote calls are very expensive
• CaliberRM uses an internal caching mechanism
– Item properties are retrieved upon first request
– Properties are then cached
• Data is not saved to the repository until the save()
command is called.
• The following methods indicate an item that requires
updating:
– isModified()
– isNew()
MutableCaliberObject
Methods
•
isNew() - Indicates whether this object has not yet been saved
to the server.
•
isModified() - Indicates whether this object contains changes
that have not yet been saved to the server.
•
save() - Saves the new object, or changes to the object to the
CaliberRM Server. This method must be called to commit
changes.
•
rollback() - Aborts any changes made to the object, without
saving those changes back to the server.
•
remove() - Removes the object from the server. Subsequent
attempts to access or modify the object will throw an
ObjectDoesNotExistException.
LockableCaliberObject
• Abstract subclass of MutableCaliberObject
• Contains methods to manage locking for objects
such as Requirements and Traces:
– lock() - Locks the object under the currently logged in
user account. An ObjectLockedException may be
thrown if this operation is attempting to lock an object
that is already locked by another user
– unlock() - Unlocks the object
CaliberObjectManager
• Object manager provide convenience
utilities for managing specific types of
objects, often only using the
CaliberObjectID
• For example,
LockableCaliberObjectManager has a
lock(CaliberObjectID id) function, which
allows locking without resolving the
CaliberObject
Connecting to the
CaliberRM Server
• CaliberServer(address)
• Server.login(username, pass)
Connecting to the
CaliberRM Server
import com.starbase.caliber.*;
import com.starbase.caliber.server.*;
public class MyCaliberTest{
static String address = "127.0.0.1"; // Server
static String username = "testuser"; // Login
static String password = "pass"; // Pass
public static void Main(String[] args){
// Create a CaliberServer object
CaliberServer myServer = new CaliberServer(address);
try{
// Log in to Caliber
Session mySession =
myServer.login(username,password);
}catch(Exception e){
System.out.println("Log In Failed:" + e);}
}
}
The Session Object
• Represents the view of the CaliberRM
data from the perspective of the user
who is logged in
• Use the Session object as the starting
point for locating CaliberRM objects
(getProjects()) and object managers
(ex:getSecurityManager())
Exception Handling
• The CaliberRM has a fairly robust declarative
exception model
• For example, the login method is declared to throw
RemoteServerException,
NoAvailableLicenseException,
InvalidLoginException, AccountDisabledException,
UserMustChangePasswordException, and
LicenseExpirationException
• Many declared exceptions that can be thrown from
the CaliberRM SDK are subclasses of
RemoteServerException. At a minimum, the
developer should catch RemoteServerExceptions for
appropriate handling.
Security
•
CaliberSecurityException
– Thrown if logged in user does not have permission
– Declared exception for many methods
– Extends java.lang.RuntimeException
•
CaliberSecurityManager
– Provides methods for checking user permissions.
– Accessed via getSecurityManager() method on the Session
object
• checkPermission - Throws a CaliberSecurityException if the
user does not have the requested permission on the class
type, unique identifier, and action.
ACTION_CREATE, ACTION_EDIT, ACTION_DELETE, ACTION_READ
• checkReqModPermission - Check the permissions to modify
an attribute on a requirement by attribute ID or number.
Throws a CaliberSecurityException if the user does not
have permission to edit the attribute.
Example: Checking Security
CaliberSecurityManager secMgr =
session.getSecurityManager();
boolean hasPermission;
try{
secMgr.checkPermission(Requirement.class,
req1.getID(),
CaliberSecurityManager.ACTION_EDIT);
hasPermission = true;
}
catch(CaliberSecurityException se){
hasPermission = false;
}
Requirements in the SDK
• Requirements live within a Baseline
• A Requirement belongs to a
RequirementType (ie: Business
Requirements, Functional Requirements)
• Requirements may be versioned
• Requirements can have multiple user
defined attributes
Retrieving Requirements
• Multiple ways of retrieving requirements
– Baseline.getRequirements() – retrieves
array representing top-level requirements
– Baseline.getRequirementTypes() – retrieves
requirement types, then call
.getRequirements(baseline) to get
requirements of this type in the baseline
– Baseline.getRequirementTree() – tree
representing project, requirementtype,
requirement hierarchy
Retrieving Requirements
...
function printRequirement(Requirement req) throws
RemoteServerException{
System.out.println(req.idNumber+":"+req.getDescription());
Requirements[] children = req.getChildRequirements();
for (int i=0; i<children.length; i++){
printRequirement(children[i]);
}
}
...
try{
Baseline myBaseline = myProject.getCurrentBaseline();
Requirement[] topRequirements =
myBaseline.getRequirements();
for (int i=0; i < topRequirements.length; i++){
printRequirement(topRequirements[i]);
}
}
catch(RemoteServerException e){
e.printStackTrace();
}
RequirementTree
• Represents a tree of requirements.
• Can be retrieved from a baseline via the
getRequirementTree() method
• Nodes represented by RequirementTreeNode class
– The getRoot() method on the RequirementTree
retrieves the root RequirementTreeNode
– RequirementTreeNode can represent the Project
(top-level node), Requirement Types, and
Requirements.
– Includes the following useful methods:
• isProjectNode(), isRequirementNode(),
isRequirementTypeNode()
• getAssociatedObjectID()
• getChildren()
• getName(), getRequirementTypeTag(),
getSerialNumberTag()
Traversing the
RequirementTree
...
void printNode(RequirementTreeNode node) throws
RemoteServerException{
System.out.println(node.getSerialNumberTag()+"
"+node.getName());
RequirementTreeNode[] children = node.getChildren();
for (int i=0; i<children.length; i++){
printNode(children[i]);
}
}
...
try{
Baseline myBaseline = myProject.getCurrentBaseline();
RequirementTree tree =
myBaseline.getRequirementTree();
printNode(tree.getRoot());
}
catch(RemoteServerException e){
e.printStackTrace();
}
Requirement Properties
• Many core requirement properties can be
retrieved via get methods on the
Requirement object
• Standard properties include:
– Description
– Priority
– IDNumber
– Version
– Owner
List Properties
•
Priority and Status properties are of type UDAListValue
– getSelectedValue() - selected value for single-select lists,
or the first selected value for multi-select lists, or -1 if none
selected
– getSelectedObjects() - selected objects
– getSelectedIndex() - selected index in the ListEntries array
for single-select lists, first selected value for multi-select, or 1 if none selected
– getSelectedIndices() - selected indexes in the ListEntries
array for multi-select lists
– getListEntries() - a list of all the acceptable values for this
property
User Defined Attributes
•
Can be accessed from the getAttributeValues() method on a
Requirement instance.
•
The AttributeValue abstract base class is extended by classes that
represent the various types of user defined attributes:
UDABooleanValue, UDADateValue, UDAFloatValue,
UDAIntegerValue, UDAListValue, UDATextValue
•
Most of these classes contain getValue() and setValue() methods for
retrieving and modifying the value of the attribute
•
The getAttribute() method retrieves the Attribute associated with the
AttributeValue, which is a subclass of CaliberObject.
•
Attribute is an abstract base class extended by UDABoolean, UDADate,
UDAFloat, UDAInteger, UDAList, and UDAText.
•
Modifying an attribute value will automatically modify the requirement in
which it is contained. It is necessary to call the save() method on the
requirement to commit the changes to the CaliberRM repository.
Modifying Requirements
• Always call lock() to lock the
requirement
• Make the modification
– Standard properties- use the set
method
– UDAs – cast to the appropriate
UDAValue subclass and set
• Call save() to persist the change
Example: UDAs
req1.lock();
…
AttributeValue[] atts = req1.getAttributeValues();
for (int i = 0 ; i < atts.length; i++){
AttributeValue att = atts[i];
Attribute attribute = att.getAttribute();
System.out.print("Atrribute: "+attribute.getName()+": ");
// identify the UDA type, and cast to the correct object
if (att instanceof UDATextValue){
System.out.println(((UDATextValue)att).getValue());
((UDATextValue)att).setValue("test");
}
….
req1.save();
req1.unlock();
Retrieving Traces
•
The Requirement class also has methods to retrieve the traces
that it is tied to:
– getTracesFrom() - retrieves an array of Traces that trace
from another object to this Requirement
– getTracesTo() - retrieves an array of Traces that trace from
this Requirement to another object
•
The Session object provides access to traces via the following
methods:
– getTraces() - retrieves an array of Trace objects for all
objects available to the Session
– getTraces(ProjectID[] projectIDs) - retrieves an array of
Trace objects which involve objects contained withint the
projectIDs specified.
The Trace Object
•
getTraceFromID(), getTraceToID() - returns the
CaliberObjectID for the objects in the relationship
•
getFromObject(), getToObject() - resolves the CaliberObjects
that are represented in the relationship
•
isSuspect() - identified whether this trace is flagged as
"suspect"
Creating Traces
•
To create a Trace instance, the CaliberObjectIDs for the two
objects is required. The following constructor can be used:
– Trace(CaliberObjectID traceFromID, CaliberObjectID
traceToID, Session session) - creates a new trace based on
the CaliberObjectID parameters. The save() method must be
called before this trace is persisted to the Caliber RM
Server.
•
TraceManager
– createTrace(CaliberObject traceFrom, CaliberObject
traceTo, boolean suspect) - creates a Trace from
CaliberObjects.
– createTrace(CaliberObjectID traceFromID, CaliberObjectID
traceToID, boolean suspect) - creates a Trace from IDs.
– deleteTrace(Trace traceToDelete) - removes a Trace from
the Caliber Server
– get(int traceIDNumber) - retrieves a trace by its ID number
Example: Creating a Trace
...
Requirement[] reqs =
session.getProjects()[0].getCurrentBaseline().getRequirements()
;
Requirement req1 = reqs[0];
Requirement req2 = reqs[1];
System.out.println("Creating trace between:
"+req1.getName()+" and "+req2.getName());
…
TraceManager traceMgr = session.getTraceManager();
Trace trace = traceMgr.createTrace(req1, req2, false);
trace.save();
MPX Event Listeners
• Since the availability of the MPX
Message Broker for CaliberRM, and
event model has been in the SDK
• Not a well documented feature
• Can be used for creating “triggers” to
execute processes when objects (like
requirements) are added, modified, or
removed
Event Listeners
• Event classes are in the
com.starbase.caliber.event package
• Based on Java event model:
java.util.EventListener
• EventListener interfaces
– ContainmentListener – object added / removed to
another object
– DiscussionMessageListener – message posted/ read /
replied to
– RequirementTreeListener – requirement tree object gets
added / removed
– StateListener – object created / deleted / modified /
locked / unlocked
Event Listener Example
// create the listener
StateListener myListener = new StateAdapter() {
public void objectCreated(StateEvent event){
System.out.println("Object Created!");
}
.. };
// get EventManager and add the listener
EventManager evtMgr = session.getEventManager();
LocalEventSource src = evtMgr.getLocalEventSource();
src.addStateListener(com.starbase.caliber.Requirement.class,
myListener);
External Traceability
•
Requirements in CaliberRM can be traced to any external
object.
– Select Enterprise, Test Director, and external File traces are
explicitly supported in the CaliberRM SDK
– Other external object integrations can be supported with the
XGenericObject class, found in the
com.starbase.caliber.external.xgeneric package.
•
createFileTrace(Requirement internalParticipant, boolean
traceFromInternalObj, java.lang.String name, java.lang.String
path)
– creates a new trace to a file located on the operating
system.
Example: File Traceability
...
Class fileClass =
com.starbase.caliber.external.xgeneric.File.cla
ss;
XGenericObjectManager fileMgr =
(XGenericObjectManager)mySession.getManager(fil
eClass);
File f = extGenObjMgr.createFileTrace(req1,
true, "foo.txt", "C:\\temp\\");
...
Integrations
•
Integrations between CaliberRM and an external system are
represented in the CaliberRM SDK by the Integration class.
•
IntegrationManager
– retrieved from getIntegrationManager() method on a Session
instance
– manages Integrations, and also provides convenience
methods for creating traces between CaliberRM
requirements and integration objects.
• getIntegrationByName(java.lang.String systemName) retrieves an Integration object by a named identifier
• get(CaliberObjectID id) method -retrieves the Integration
by its CaliberObjectID.
Integration Class
• Contains a name, icon, library name, and configuration
file for the external integration that is represents
• Provides access to a collection of views, representing the
data available in the external application: IntegrationView
class
– Contains a unique identifier, and a collection of
IntegrationObject classes.
• Objects that resides in an external system, and could
potentially be traced to a CaliberRM Requirement
• Methods for accessing properties such as icon, name,
short name, and a list of available operations to perform
on the object
• May be hierarchal, and contain child IntegrationObjects
Example: Retrieving
Available Integrations
...
IntegrationManager intMgr=
mySession.getIntegrationManager();
Integration[] integrations =
intMgr.getAll();
for (int i=0; i < integrations.length;
i++){
System.out.println("Integration:
"+integrations[i].getName());
}
...
Vendor Add-Ins for
CaliberRM
• CaliberRM provides a mechanism for creating custom
interfaces to external applications
• Displayed to users within the CaliberRM desktop client
interface, allowing them to visually trace requirements to
external objects.
• Vendor Add-Ins are typically developer in Visual Basic, or
another COM-based language.
• Many Vendor Add-Ins are available for free from Borland,
including integrations with Rational Rose.
VB Templates for Add-Ins
• Visual Basic Templates are provided to give
developers a foundation for creating CaliberRM AddIns
• By using the templates, CaliberRM will take care of
generating the forms, you just provide info on
connecting and displaying available remote objects
• Add-Ins need to identify the following:
– View of external objects: typically in a list or tree structure
– External object properties: objects must have a unique identifier,
and can optionally have additional properties and a display icon
VB Add-In Classes
•
The Visual Basic Templates contain the following classes
– VendorSession - provides publicly-exposed methods that CaliberRM
clients can use to interact with the add-in. The VendorSession
corresponds with the Integration object available in the SDK.
– VendorView - provides a view of external objects contained in the
integration. The collection of VendorView objects can be retrieved
from the VendorSession’s GetVendorViews method. The VendorView
class corresponds to the IntegrationView class in the SDK.
– VendorObject - exposes properties of an external object available
from the integration server. A collection of these objects can be
retrieved from the VendorView's GetVendorObjects method. It
corresponds to the IntegrationObject class in the SDK.
Deploying Add-Ins
•
Deploying add-ins downloaded from Borland or created using
the Visual Basic add-ins can be accomplished in the CaliberRM
Framework Administrator interface under the External
Traceability tab
•
Create a new Integration - vendor name, library name, icon
•
Optionally, a path to the configuration file can be provided. This
configuration file may contain information required by the add-in
application to connect to the external system.
•
The vendor add-in then becomes available for registration in any
CaliberRM client that will require external traceability for the addin type.
Deploying Add-Ins
Bonus Tip: HTML-based
descriptions
• CaliberRM requirements can include HTML tags
in their descriptions, which can cause problems
when exporting to other applications
• Class com.caliber.util.HTMLHelper has useful
methods for converting between HTML and plain
text, and HTML and DOM-based XML docs:
– htmlToPlainText
– plainTextToHTML
– toDocument(String)
– toHTML(org.w3c.dom.Document)
Bonus Tip: Searching
Requirements
• RequirementManager has search utilities:
– searchForName(java.lang.String text,
ProjectID projectID, boolean caseSensitive,
boolean wholeTextOnly)
– searchForDescription(java.lang.String text,
ProjectID projectID, boolean caseSensitive,
boolean wholeTextOnly)
Summary
• Every software development lifecycle process is different,
and can only be successfully enforced by development
tools that provide flexibility to be customized and
integrated with other tools.
• Borland's CaliberRM SDK provides customizability and
extensibility options that can effectively include
requirements management in your entire software
development lifecycle process.
Questions?
Thank You
2142 – Introduction to the CaliberRM SDK
Please fill out the speaker evaluation
Office Hours:
Wed, Sept 15 12:30pm-1:30pm
You can contact me further at [email protected]
Source code and additional material will be posted on:
http://www.codealloy.com