Traceability Matrix

I work in Information Technology and part of my job is to make sure that my team and I are able to determine the impact of introducing changes in our code. Systems and components do not live in isolation. Most of the time, systems are composed of simple components strung together to make up a complicated piece of software. In the same token, some complex systems are also composed of other systems. Introducing a change in one of the basic parts of a system can affect other components or systems that depend on it. You can imagine the dependency of these systems by drawing a dependency graph. A dependency graph can be viewed as a drawing of circles and arrows connecting those circles. The direction of the arrow determines which component depends on what. In the figure below, we have component A dependent on components B and C while component D depends on component C. Likewise, there’s no reason for another component to depend on that which it depends on. For example, component C also depends on component D.




If a change was introduced in component F, we can see that components B, C, A, and D are affected. In the real world, we usually don’t draw these diagrams because for very large systems, space will just be cluttered and it is very hard to figure out the dependencies just by looking at the graph. In practice, we create a two dimensional matrix that depicts the dependencies among components. Several Enterprise Architecture tools already exists to do this automatically. However, if you are on a tight budget, you still have some tools at your disposal. This article will demonstrate how to create the dependency matrix diagram using a tool called R.

Create a csv file that contains the dependency information as shown in the diagram above. The contents of the csv file will look like this:

a,b
a,c
b,f
c,f
d,c
c,d
d,e
e,g
f,g
g,e

The first two lines of the file above simply means that A depends on both B and C. The rest of the lines can easily be read off the file. To convert this into a dependency matrix diagram, we create an R script that will read this csv file and output an image:

> x=read.csv("traceability.csv",header=F)
> z=table(x)
> image(1:ncol(z),1:nrow(z),z=t(as.matrix(z)),col=c("white","red"),xaxt="n",yaxt="n", xlab="Component B",ylab="Component A")
> abline(h=1:nrow(z)+0.5,v=1:ncol(z) +0.5,col="black")
> axis(1,at=1:ncol(z),labels=colnames(z))
> axis(2,at=1:nrow(z),labels=rownames(z))

How it works

Line 1 above reads the csv file. The output is a data frame that is assigned to the variable x. The next line creates a contingency table of the data in x. Here is a dump of the value of z:

   V2
V1  b c d e f g
  a 1 1 0 0 0 0
  b 0 0 0 0 1 0
  c 0 0 1 0 1 0
  d 0 1 0 1 0 0
  e 0 0 0 0 0 1
  f 0 0 0 0 0 1
  g 0 0 0 1 0 0

It is a matrix filled with 1’s and 0’s. A 1 means that a dependency exists between the component along the x axis to the corresponding component along the y axis.

The third line of the code creates an image of the matrix, where the color of the cells is determined by the value of the matrix t(as.matrix(z). A value of 0 will take a white color while a value of 1 will take a red color.



The resulting image does not really look nice. The next two lines of code adds grid lines and axis labels to give an image like the one below:

How to Read It

Reading the traceability matrix is not as straightforward as one would hope. This is because a change in one component can impact another component which likewise impacts a component dependent on it. This is called transitive dependency. For example, a change in component E will impact G and D (read along the x axis). However, a change in G will impact F and E, which both impacts B, C and D. B and C impacts A. In spite of the transitive dependency, it is clear that a tool like this is very important when doing impact analysis.

Advertisements

Using MDA

Some things are just not easy to familiarize. One of them is using the AndroMda tool to design and build applications. This is a set of notes I made for my own purposes so that I can remember what I did that worked. And I hope you will find something useful in it too.

I am using MagicDraw as my uml tool because it the one highly supported by AndroMDA. The steps that I am following is in the excellent Getting Started Guide on java. When doing these notes, I am doing an Out of Office tracker tool. So the name of my project is ooo. After generating the project using maven, I need to change the model.uri to file:${project.basedir}/src/main/uml/ooo.uml2 because the default does not work.
After opening the model at mda/src/main/uml/ooo.xml I created the model named “ooo model”. In this model I created the root package of my project “org.javaero.ooo”. The first thing to do is to create the business objects. So I create a package under “org.javaero.ooo” called model and created a new class diagram. Here is the screenshot of my model class diagram.

model.jpg
The mistake I commonly make is forgetting to put the stereotypes in my business objects. In the diagram above, the User class will end up as an entity bean because of the stereotype “Entity”. The class UserVO is a value object and is the object being shared between presentation layer and the business layer. This should also be labeled with a stereotype or else you will not find this generated by AndroMDA. The dependency from User and UserVO object means that in the code that is generated there will be a method to convert from the User entity to UserVO.
Under the package “org.javaero.ooo” i created another package called “service”. This will contain the service objects that will have access to the User entity through the UserDao. The UserService is the service pojo that will have access to the User entity using the dependency from it to the User class. When AndroMDA generates the code, it will give the UserService access to the UserDao where you can manipulate the User entity.
service.jpg

My UserService class has two methods namely addUser() and listUsers(). When AndroMDA generates the code, it will create a class called UserServiceImpl under the folder core/src/main/java. See the screenshot below:

servicecode.jpg

You need to open this class and provide implementation to the methods handleAddUser() and handleListUsers().

Now it’s time to put an interface to our new ejb. I added a new package under “org.javaero.ooo” called “web”. This will contain the use cases of the web interface. For each use case, i’m going to put it under a new package under “web”. Now i’ll create the use case called “Add User” and a state machine diagram that will contain the state machine for this use case. I have to put this under a new package called “adduser”. Here is the state machine diagram:

statemachine2.jpg

Never forget to put the initial state. The stereotype “FrontEndView” that labels a task means that AndroMDA will render this as a view in struts. Imagine the user entry page as containing two text fields named “First Name” and “Last Name”. The page will submit this two parameters to the server. We can model this using the transition from User Entry to Add User. Right click on that transition and open the specification. Click on the behaviour type of “Entry” and specify Activity. In the containment tree, click on this behaviour and add parameters “firstName” and “lastName” with datatype as String. Add the tag @andromda.presentation.web.view.field.type = text to these parameters. See the screenshot below to get a hint on how this is done.

addparameters2.jpg
The screenshot below shows how to set the tag @andromda.presentation.web.view.field.type to “text”.
Setting tags to render it in correct html input objects.

By specifying the tag @andromda.presentation.web.view.field.type as “text” , this will be rendered as an html text field.

Now that we already have our input page, the next thing to do is to create a controller that will accept these parameters and save them to the database. Let us create a new class under the “Add User State Machine” and call it UserController. To do this, just right-click on “Add User State Machine”->New element->Class. Name this class as UserController.

usercontroller.jpg

On the containment tree, right-click on UserController and open its specification. Create a new operation on it with signature addUser(String firstName, String lastName).

usercontroller-operations2.jpg

Now that we have our controller ready, click on the “Services” class diagram and from the containment tree, click on the UserController class and drag it to the “Services” diagram. Create a dependency from UserController to UserService class. This will allow UserController to access the UserService.

usercontroller-userservice.jpg

Now, let’s go back to the “Add User State Machine Diagram” and model the interaction of our state machine with the UserController class. Click on the Add User task and open the specification. Specify the behaviour type of Entry as Activity. In the containment tree, click on this activity and open it’s specification. Click on Node and click “Call Operation Action”. This will take you to the “Call Operation Action” specification. Click on “Operation” and choose addUser() operation from UserController. As you might have guessed, this will invoke the operation UserController.addUser() which we should implement.

calloperation1.jpg

Generate first the classes using the command “mvn install”. Then find the class UserControllerImpl and implement the “addUser()” method. Notice that method signature of addUser is different from what we specified above. Instead it’s method signature is:

public final void addUser(ActionMapping mapping, org.javaero.ooo.web.adduser.AddUserForm form, HttpServletRequest request, HttpServletResponse response) throws Exception;

The parameters firstName and lastName can actually be found in the AddUserForm. Here is a simple implementation of this method:

adduser-impl.jpg

Now it’s time to generate the tables in mysql using the command “mvn -f core/pom.xml andromdapp:schema -Dtasks=create”. You can verify that the table is created using mysql client:

mysql.jpg
To deploy the application, we issue the command:mvn -f app/pom.xml -Ddeploy

This will deploy to jboss directory. It will be a good idea to start jboss before deploying so you can see the deployment in action. After deployment, you can access the application by launching your browser and pointing to http://localhost:8080/ooo. Here is the screenshot of the page:

first-page.jpg

Finally, put some values into the two fields and submit them. Check that the values indeed end up in the database.

mysql2.jpg

Celebrating Labor Day

It’s labor day and what a fitting way to celebrate Labor day than to work!

First order of business today was to setup the MPI (Message Passing Interface) and demo programs in my computer. Since MPI is a shared-memory distributed computing platform, I need to set it up also in another laptop. I’m glad my friend Roli Balicas agreed to let me setup his laptop. He spent about 5 hours in our house. It does not really take a long time to setup MPI in two dual-core laptops. We just spent most of the time eating pizza from Pizza Hut and watching Jet Li movies. We were able to watch two full movies while I was also setting up MPI on the two laptops.

Roli’s laptop was running Ubuntu 7.10 and is not yet configured as a developer’s laptop so I had to install xorg developer packages in order to make the MPE of MPI compile with X enabled. After upgrading his laptop, I was able to recompile MPI and compile the Mandelbrot demo. Now the two laptops can run the demo.

After Roli left, I went back to my experiments on Model-Driven Architecture. I’m looking at AndroMDA, an MDA generator and MagicDraw as UML tool. I’m enjoying my explorations into this subject. However, MDA seems to have a bleak future. A lot of heavy-weight personalities don’t see any future on MDA. See for example this. Whatever may be the case, the fact that i’m enjoying it is already enough for me.