Eclipse Yoxos Services Downloads Blogs About
Home > Blogs >

Moritz Post

on Feb 12th, 2010Agile Thoughts (Part I)

In the last few weeks i was confronted with several projects and developers, who were trying to incorporate the scrum process into their project environment. The following remarks will pinpoint some of the problems and challenges several of the projects had and what a possible solution might look like (your mileage may vary).

Upfront i have to say, that i am a strong believer in scrum and its gains. This opinion originates from the fact, that i have worked in scrum projects which turned out very well. Why did they work well? Because they applied scrum! ;-)

The Fundamentals

We all know the sentence “yeah, we are an agile team”. And next they present you their fixed road map with milestones etc. The opposite is the “no planning agility”. We just fiddle along on a daily basis. That is not agile either.

I think the sweetspot is where scrum enters the stage. The product backlog dictates your workload and the sprint backlog defines your daily work. What’s the gain? Transparency and flexibility. The two virtuoso every one wants, most people claim and the fewest projects actually have. Lets see what these two words actually mean.

Transparency - Like a glass window transparency has two sides. When looking at the team we want to know what the team is actually working on and what their progress state is. The scrum wall with its small tasks and the sprint burndown is the place to find these information. When looking at the product owner, it is his job to provide a well formed backlog. Well formed means stories with clear scope and manageable volume. From both perspectives you have the ability to intervene when necessary.

Flexibility - Flexibility allows to refocus the course of the development efforts while being way under way. Only after you have finished the current sprint you plan the next one with the stories you need the most. After your project time has elapsed you can be certain that everything that is in your project right now is what you really need. No extras. Just the right features. Admittedly we could miss a few features but that would simply require more man power or more time. Most importantly: the scope is spot on because of constant corrections of the project plan.

So that is great theory. Now on to the problems…

Oh wait. This blog post is getting to long and i have to many points on my list. So lets take a break here and discuss the above until part II is ready.

Are you applying scrum? What are the biggest gains for you?

on Nov 2nd, 2009Extending Google Wave

A few days ago i gave Google Wave a spin. I was already quite familiar with the conversation features and thought it was time to extend the wave by some custom functionality. I therefore created a robot extension to enrich a wave conversation with some additional functionality. The idea was to fetch details about an eclipse bugzilla bug when a bug is referenced in a wave conversation. To see how that works check out the screencast below (click the image).

buggy Extending Google Wave

The development of the robot was rather straight forward. The robot itself is deployed on the google appengine and communicates with the wave via HTTP REST calls and uses JSON as its language dialect. The communication was encapsulated in a client library which did have some bugs though. Working with the app engine was a joy i must add. Deployment and management of the application was quite cool. Fetching the bugzilla data was also easy as it is able to spill out bug details in XML format.

All in all i am very excited to see how easy it is to provide additional wave capabilities and am hopping that the wave will make its way into every days life. Also the appengine gets a thumbs up from me (at least for such simple tasks as this wave robot). You can fetch the source of the robot project here.

on Feb 27th, 2009Tip: Validation with a MultiValidator

In the last blog entry regarding databinding, we learned how to create a custom observable for a DateTime widget. Starting with Eclipse 3.5 there is a new approach to creating custom observables as described by Matthew Hall in the comments to that post. Which ever way you choose, we will now use the observable to showcase another cool databinding feature: Crossvalidation. Crossvalidation was introduced with Eclipse 3.4 and describes the process of validating one IObservable based on the value or state of another IObservable. A classic example is the input  of a date ranges where the start of the period can not be after the end of the period.

Databinding Cross Validation

As we can see on the screenshot above, the status message informs us of a violated validation constrain. So, how is such  kind of crosscutting validation achieved? First of we need some kind of model, to hold the start and end value. Next we need the two DateTime widgets and the corresponding DateTimeObservableValue. The observables can than be tied to the bean model, holding the start and end values. In order to create a crosscutting validation for the dates, we introduce a custom PeriodValidator extending a MultiValidator, which is in fact an implementation of a ValidationStatusProvider.The MultiValidator lets us implement a validate() method, returning an IStatus corresponding to our validation results. Since we are implicitly implementing a ValidationStatusProvider, the state of our validation can be bound to any party interested in the validation result. Here is the implementation of the PeriodValidator, comparing the start and end date (ignore the shortcomings of the Date class):

public class PeriodValidator extends MultiValidator {

private final IObservableValue start;
private final IObservableValue end;

public PeriodValidator(final IObservableValue start, final IObservableValue end) {
this.start = start;
this.end = end;
}

@Override
protected IStatus validate() {
Date startDate = (Date) this.start.getValue();
Date endDate = (Date) this.end.getValue();
IStatus status = ValidationStatus.ok();

if ((this.start != null) && (this.end != null)) {
     if (startDate.after(endDate)) {
          status = ValidationStatus.error(”The start date has to be before the end date.”);
     }
}
return status;
}
}

As we can see, there is not much magic going on in the PeriodValidator. Lets have a look at the broader context, in which this MultiValidator is applied. The following code demonstrates the overall setup of the databinding. Note how the validation status (wrapped in an IObservableValue) is obtained from the PeriodValidator and bound to the status Text widget.

private void createDatabinding() {

DateTimeObservableValue startObservable = new DateTimeObservableValue(this.dateTimeStart);
DateTimeObservableValue endObservable = new DateTimeObservableValue(this.dateTimeEnd);
DataBindingContext context = new DataBindingContext();

// bind start and end
UpdateValueStrategy modelToTarget = new UpdateValueStrategy(
UpdateValueStrategy.POLICY_UPDATE);
UpdateValueStrategy targetToModel = new UpdateValueStrategy(
UpdateValueStrategy.POLICY_UPDATE);
context.bindValue(
     startObservable,
     BeansObservables.observeValue(this.period,Period.PROP_START), targetToModel, modelToTarget);

context.bindValue(endObservable,
     BeansObservables.observeValue(this.period, Period.PROP_END), targetToModel, modelToTarget);

// bind status
PeriodValidator periodValidator = new PeriodValidator(startObservable, endObservable);
modelToTarget = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE);
modelToTarget.setConverter(new Converter(IStatus.class, String.class) {

public Object convert(final Object arg) {

if (arg instanceof IStatus) {
     IStatus status = (IStatus) arg;
     return status.getMessage();
}

return null;
}
});

targetToModel = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE);
context.bindValue(
     SWTObservables.observeText(this.status),
     periodValidator.getValidationStatus(), targetToModel, modelToTarget);
}

The validation status of the period validator is updated everytime any of the DateTime widgets is changed. In turn the validation message is updated to reflect the validation state.

You can download the the entire project containing the sample snippets here.

Also note that you will need to adjust the elements on the classpath. See the .project file for the required libs.

I hope you found these hints valuable and am looking forward to your comments and suggestions.

on Feb 3rd, 2009Databinding: A Custom Observable for a Widget

The introduction of the databinding framework in Eclipse 3.3 is with no doubt one of the most useful tools in the hands of the form developer. The ability to transform and validate user input in such a flexible and reusable way is a great enhancement. But where there is light, there is shadow. Sometimes there is just no IObservable available for your target or model object. This blog entry will demonstrate how easy it can be to create a custom IObservable for a DateTime widget.

The DateTime widget represents one value: a java.util.Date. This Date object is the one we want to get and set on the target (target being the UI widget). Therefore we wrap the DateTime in an IObservableValue by extending the AbstractObservableValue class. Essentially an IObservable* offers methods to get and set data, to determine the type of data and to register listeners to be notified of changes. The following code demonstrates a skeleton implementation of an IObservableValue.

public class DateTimeObservableValue extends AbstractObservableValue {

  private final DateTime dateTime;
  Listener listener = new Listener() { ... };

  public DateTimeObservableValue(final DateTime dateTime) {
    this.dateTime = dateTime;
    this.dateTime.addSelectionListener(this.listener);
  }

  @Override
  protected Object doGetValue() {
    // the utility method creates a Date from the DateTime
    return dateTimeToDate();
  }

  @Override
    protected void doSetValue(final Object value) {
      if (value instanceof Date) {
        // the utility method sets the date on the DateTime
        dateToDateTime((Date) value);
      }
  }

  @Override
    public Object getValueType() {
    return Date.class;
  }

  @Override
    public synchronized void dispose() {
    this.dateTime.removeSelectionListener(this.listener);
    super.dispose();
  }
}

The implementation details are not very special. The getValueType() method has to return the type represented by this IObservableValue (which is the type Date). The do methods set and get the Date value. Since the observable has to propagate changes in the DateTime widget as soon as they ocurre, we attach a listener on the DateTime widget to inform any registered IValueChangeListener of the event. The listener implementation looks like the following:

Listener listener = new Listener() {

  @Override
  public void handleEvent(final Event event) {
    Date newValue = dateTimeToDate();

    if (!newValue.equals(DateTimeObservableValue.this.oldValue)) {
      fireValueChange(Diffs.createValueDiff(DateTimeObservableValue.this.oldValue, newValue));
      DateTimeObservableValue.this.oldValue = newValue;
    }
  }
};

In the DateTime listener we inform any interested IValueChangeListener of our DateTimeObservableValue. In order to avoid unnecessary propagation of update events in the databinding context, we compare the last set Date in the IObservableValue with the new value. Next we create a ValueDiff from our new date value and fire the the value change event. The advantage of listening to the changes in the DateTime widget, is that we are able to fire events which are either invoked by the user changing the DateTime widget or by programmatic changes of the IObservableValues wrapped Date.

You can download the full listing of the observable class here: DateTimeObservableValue.zip

As we can see, it is quite easy to write a custom observable for any kind of widget or datastructure, represented by a single value…  So, how do you embed your data in custom observables? Any obstacles you had to overcome? Problems you faced? Share them with us. :)

on Jan 15th, 2009Toggling a Command contribution

Every once in a while something just doesn’t happen to be as intiutive as you would have liked it to be. Lately I was trying to contribute a simple command based toggle button to the workbench. Although it is simple to actually provide the menu contribution and to put the button in visual “toggle” mode, it was so straight forward to actually obtain the state of the button in the UI.

To make the menu contribution show up as a toggleable button you have to provide the style value “toggle” on your commands menu contribution:

<extension point="org.eclipse.ui.menus">
  <menuContribution locationURI="...">
    <command commandId="org.eclipse.example.command.toggle"
              style="toggle" />
  </menuContribution>
</extension>

Next we have too keep track of our actual toggle state. Since it is possible to have multiple menu contributions for the same command, we have to keep track of the state in a central place. Imagine a toggle button triggerable from the main menu and a views toolbar. The state of these buttons are keept in sync by storing the state directly in the command.  The key to this is the org.eclipse.jface.commands.ToggleState. This implementation of org.eclipse.core.commands.State is a wrapper for a boolean. To attach such a State object to a command, it is provided during the command declaration:

<command id="org.eclipse.example.command.toggle"
         name="Toggle Me">
  <state class="org.eclipse.jface.commands.ToggleState"
         id="org.eclipse.example.command.toggleState" />
</command>

The state element takes the ToggleState class as a state provider and attaches itself to the command. The id of the state has to be unique to identfy the state. With the state attached to our command, how can we access it? In the Handler, reacting to the invocation of the menu contribution, we have to access the current state keept in the ToggleState. The following code demonstrates just that:

ICommandService service =
(ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
Command command = service.getCommand("org.eclipse.example.command.toggle");
State state = command.getState("org.eclipse.example.command.toggleState");
state.setValue(!(Boolean) state.getValue());

We obtain our command from the ICommandService and ask it for our toggleState stored within the command. Next we just flip the boolean as to create the new state. Now we can just do whatever we want to do in our Handler using the new state. Great, isn’t it? Of course the ToggleState is only one possible implementation of State. One could also imagine multiple states, radio states, text states etc. Also the State class has a specialization (PersistableState), which can be persisted to the preferences as to keep track of the (toggle) states of your buttons.

But there is thing left to do: what happens to this other button which is also a menu contribution for our command? We need to toggle the pressed state of it, as to reflect the state of the first button. To do so, a Handler has to implement IElementUpdater providing the method updateElements(…). It gets an UIElement as a parementer, which can be used to trigger the toggle state:

public void updateElement(UIElement element, Map paramters) {
  element.setChecked(isSelected);
}

To broadcast the refresh event to all menu contributions we use the ICommandService in our Handlers:

commandService.refreshElements(executionEvent.getCommand().getId(), null);

I hope you find the information here valuable and i am looking forward to your comments.

on Oct 22nd, 2008Performance Testing RAP on the Cloud

A recurring question in the RAP community is, “How good is the performance of my RAP application”? Now you can measure it for yourself on the Amazon cloud. In this tutorial I will show you how to set up your own load testing for a RAP application deployed on Amazon’s rent-by-the-hour servers, also know as the Amazon Elastic Compute Cloud (EC2) infrastructure. We will setup a server inside EC2 with a ready-to-run RAP application and use JMeter to simulate concurrent users.

Creating an Amazon Web Services Account

To access the Amazon Compute Cloud (EC2) you must create an Amazon Web Service account first. The EC2 sign-up requires you to provide your credit card details, so that so that Amazon can charge you a small fee for the time you use their services. To sign-up go to the EC2 homepage and click on “Sign up for Amazon EC2″.

Setting up EC2

In order to interact with EC2 we are going to use the AWS tooling provided by the g-Eclipse project. The g-Eclipse project, originally developed to support grid computing, provides tools to interface with Amazon Web Services.

The latest g-Eclipse milestone build can be found here (latest release: gEclipse 1.0M10) or grab gEclipse from Yoxos On Demand. If you need an in depth “Getting Started” guide on setting up g-Eclipse, you can find it in the Eclipse Help (Help > Help Contents > g-Eclipse User Guide > Getting Started).

geclipse aws 300x230 Performance Testing RAP on the Cloud

Once you have g-Eclipse installed, switch to the “g-Eclipse User” perspective (Window > Open Perspective… > Other > g-Eclipse (User)).

Now you need to associate a “Grid Project” with your AWS account: Create a new Grid Project via the New Project wizard (File > New > Grid Project). Enter a project name (“EC2Grid”) and hit “Next”.

On the second page of the wizard choose “Edit VOs…” to open the “VO-Declarations” preference page. This will allow you to create a Virtual Organization (i.e. your AWS account credentials) and attach those to your Grid Project. Define a new AWS Virtual Organization (Add… > AWS VO) and provide a name (eg. AWS VO) and your AWS Access Id (which is found under “Your Account > AWS Access Identifiers” in the top right menu on the Amazon website). Choose “Finish” to create the Virtual Organization and return to the Wizard. The “VO Selection Page” should show your newly created virtual organization. There should be a check mark next to it. Choose “Finish” to create your Grid Project.

grid project view with aws project Performance Testing RAP on the Cloud

Inside the “g-Eclipse User” perspective you can find the “Grid Projects” View. This view is your gateway to the Amazon EC2 infrastructure. The setup project should look like the image to the right.

Running a RAP enabled EC2 Instance

In order to test our RAP application, we will need to fire up an Amazon Machine Image (AMI). This is a binary Linux image that has been preconfigured for certain tasks. In our use case we want to launch an Image capable of running RAP applications. To make things easiert, we already provide a pre-configured Image containing Java, Tomcat and RAP.

Before we can launch the Image we need to set up secure access to it.

Setting up a Security Group

A security group is required so that specific network ports on a running EC2 instance can be made accessible. By the way, an instance is a virtual server in the cloud.

To create a security group, expand the ‘AWS VO’ and ‘Services’ folders. Select the ‘Securit Group’ folder and choose “Create Security Group“ from the context menu. Enter a suitable name (e.g. “rap server”) and an optional description and click “Finish”.

The first time you do this, you will see the “Authentication Token” dialog. In this dialog you will be asked to authenticate yourself, by entering the Secret Access Key that matches the Access Key in your virtual organization. This is similar to entering a password — the Access Key is your usedid and the Secret Acess Key your password.. You can find the secret key under “Your Account > AWS Access Identifiers” on the Amazon website. Select “Finish” after entering the key.

Once the group has been created, you have to collapse and expand the Security Groups branch in order to see your new security group. Right click on the entry and choose “Edit Security Group”. This starts a wizard where you can specify which ports and protocols you want to open on a running Instance. This is similar to configuring a firewall. Use the “Add CIDR” button to add individual rules.

edit security group 300x251 Performance Testing RAP on the Cloud

Typical ports to open for our scenario are 22 (ssh), and 80/8080 (webserver/tomcat). You can of course, add other ports depending on your application’s needs.

Creating a Private Key

Next, we need to prepare a private key. This key will allow us to log-in to a running instance, without entering a password. To create the keypair right-click on “Services > Keypairs” and select “Create Keypair”. The wizard will allow you to name the keypair and set a storage location for the private key file. A common place for this private key file is /ssh.

Then we need to make this private key file available to g-Eclipse. Go to Eclipse Preferences (Window > Preferences) and under “General > Network Connections > SSH2″ add our private key to the list of “Private Keys”. This will allow us to log into the running EC2 instance via the build in the SSH terminal.

Launching the RAP EC2 Instance

We have now covered the security setup and are ready to launch our server instance. Go to the “Services > Images > All Images” folder and find the AMI with the id “ami-d59276bc“. Right click on it and from the context menu select “Launch AMI”. This will bring up the launch configuration dialog. In this dialog you can configure the parameters for launching your custom EC2 instance.

Most of the configuration parameters are already filled in for you but some require your attention. Luckily you can fill-out most fields by clicking on “Populate from EC2″ in the lower right corner of the dialog. Now the only things you need to provide are:

1. The private key (In the ‘Key:’ drop-down, select the key you created earlier)
2. The security group (Edit > Move “rap server” from ‘available’ to ‘selected’ > Ok)

You can use the default settings for all other items. Some settings might be of interest though. For example you might want to choose the type of hardware your instance runs on (Instance Type).

After making your final adjustments, click “Run”, which laun
ches the instance on the EC2 infrastructure. Important: after this point you are being charged an hourly fee for each running instance. Remember to terminate your instances when you no longer need them (see below). You can monitor the state of your running instances by expanding the “Computing” branch. (Contracting then expanding the tree will refresh).

Because we’ve provided a private key when we launched the instance, it is possible to open a passwordless ssh session on that instance. Expand the ‘Computing’ node, select your instance and choose “Open SSH terminal…” from the context menu. In the dialog that follows, we enter the user name “root” and and click “Finish”. This opens the terminal view with a logged-in shell on that instance.

Accessing the RAP Instance

We now have the instance running and are logged in via SSH. Where is the RAP application? By default the EC2 instance runs the RAP workbench demo application. This generic application is a good starting point for learning about the various features of the RAP platform.

To access the application in a browser, select the running EC2 instance under the “Computing” node and open the “Properties” view (Window > Show View > Properties). The row “DNS Name” contains the publicly accessible domain name of your instance. Copy this entry to your browser and append the path “/demo/rap” to it. The entire URL should look something like “http://ec2-12-234-56-78.compute-1.amazonaws.com/demo/rap“.

Alternatively, you can open the tomcat manager application with the path “/manager/html” and use the login credentials admin/nimda.

On the server side you can find the tomcat application server under “/opt/tomcat/”. You can find the packaged demo application under “/opt/tomcat/webapps/demo.war”. The demo application is based on a recent integration build (RAP 1.1.1, 20080714).

Running JMeter Performance Tests

With the RAP demo application up and running we can now apply some load to it. The tool we are using for this task is Apache JMeter. It simulates concurrent users accessing the same web resource. You can download JMeter here. As of this writing the latest version is JMeter 2.3.2. Extract the download and launch JMeter by running “/bin/jmeter.(bat|sh)” (needs Java).

jmeter 300x213 Performance Testing RAP on the Cloud

To get you started with your own performance tests we have created an example test plan, which mimics a typical user on the RAP demo application. You can download the zipped test plan here.

Unzip the file and choose “File > Open” from the JMeter menu to open “demo-testplan.jmx”. From the tree on the left choose the node “HTTP Request Default Settings”. This node will allow you to specify the target of your load test. You will need to replace the “Server Name or IP” with the DNS name of our currently running instance.

We are now ready to launch the performance test. Choose “Run > Start” in the application menu. You will see the thread count increasing in the upper right corner of the JMeter window. Also you will see how the number of sessions increases for the demo application when using the tomcat manager application.

Test Procedure

The test is setup to create 200 threads over a ramp up period of 400 seconds, which means a new thread is spawned every 2 seconds. Each thread executes around 80 clicks on the RAP demo application with an average delay of 7,5 seconds between each click. After the series of clicks is executed the thread starts a new session on the tomcat server and repeats the click cycle.

To see the average time need to answer each request select the node “Summary Report” in the tree. You can also check the responsiveness of your RAP application yourself, by using your application in your webbrowser while the performance test is running.

You can change the test parameters in two ways. You can edit the ramp up/number of threads parameter under “Thread Group” or change the delay between clicks under “Uniform Random Timer”. The “RAP Load Testing” page on the Eclipes Wiki has a few more tips for fine tuning your performance tests.

Advanced Performance Testing [optional]

In order to execute long running tests, the test client can be on the EC2 cloud as well. To do this we created another AMI with the id “ami-ec927685“. It contains a ready-to-run installation of the JMeter client which can be invoked in headless mode. JMeter is installed under “/opt/jmeter”. To start a long running test the invocation should look like “/opt/jmeter/bin/jmeter -n -t /opt/testplans/demo-testplan.jmx -l /mnt/demo-testplan.jtl”. It is also possible to use the “nohup” directive to detach the process from the current shell.

Since the server address of the targeted RAP application is dynamic, the correct DNS name needs to be inserted in the test plan under “/opt/testplans/demo-testplan.jmx” (line 33). Also the JMeter application needs to have access to the ports 32767-65535, which should be defined in an appropriate security group.

IMPORTANT: Terminating the RAP Instance

Be sure to terminate the running instance as soon as your tests are complete. Remember: you are paying for your instance by the hour! To shutdown the server instance select the “Terminate Instance” action from the context menu of a running instance. This will initiate the shutdown procedure which takes approximately 30 seconds.

Summary

In this short article we have seen how to run performance tests against a RAP application on the Amazon Cloud Computing infrastructure. We have created the necessary AWS accounts and activated the EC2 functionality. We obtained the g-Eclipse application to interact with the cloud infrastructure and performed the setup required for security groups and private keys. After launching the RAP demo application server, we logged in via SSH and accessed the application via a browser. With the application up and running we used JMeter to apply some load onto the RAP application.

And how does your rap application perform?

Leave a comment and let us know what you think.

Get Adobe Flash playerPlugin by wpburn.com wordpress themes
© EclipseSource 2008 - 2009