Automated Coder

Exploring the Code of CruiseControl.Net

Posts Tagged ‘Ideas’

Changing to Messages

Posted by Craig Sutherland on 28 January, 2009

There’s Too Many Arguments!

Recently I added dynamic parameters to CruiseControl.Net. This caused a large number of method signatures to change – in multiple classes. After the project lead saw these changes, he mentioned that we’re probably not using the best approach for passing arguments, especially as in future we could potentially add more arguments!

At the same time this offers some possibilities for future-proofing. While we can’t move to WCF (at least for a while yet), we can set things up so a move to WCF is easy.

Some Messaging Approaches

Before I implement messaging, the question arises as to what is the best way to do it? There are a number of different models for messaging, so I’m going to quickly look at three.

One Way Messaging

Messaging-OneWay

In this model messages are sent from the client to the server. Nothing comes back from the server at all.

While this is nice and simple, there is no way of checking that the server has received the message and that the message is valid. It’s kind of like dropping a message into a black hole and hoping that it works.

This is how CruiseControl.Net Remoting works in many ways. When a force/abort build, start/stop project or other similar request is sent, it is assumed that they will work. As part of the security changes I turned on exception reporting, but this is using .Net Remoting instead of a reply from the server.

Two Way Messaging

Messaging-TwoWay

This is similar to one-way messaging, except the server also sends back a response. Depending on the action, this response could be immediate or it could take a long time.

Most of the information requests to CruiseControl.Net use this model (e.g. get snapshot, get projects statuses, etc.) The server gets the request, processes it immediately and sends back the response.

Asynchronous Two Way Messaging

Messaging-TwoWayAsync

In this model the request and response are decoupled. Instead an acknowledgement is returned (ack for short) letting the message sender know that the message has been received. When the server receives the message it sends an ack and then processes the request. Finally, once the request has been completed it sends the response (optionally waiting for an ack that the client received it).

CruiseControl.Net doesn’t use this model at all, although the project build queuing does provide part of the model (the only part missing is the response at the end). While I foresee this as being very useful for clients in the future, I’m not going to attempt this (basically because of its complexity.)

Additional Models

These are three of the common messaging models – there are many other patterns also (I haven’t covered routing, composition, transactions, reliability, etc.) As this are the simple models I’m going to leave it here and instead move onto how we can use them in CruiseControl.Net.

Aiming For Consistency

With this background I can now begin to look at adding messaging. But first, some goals:

  • Consistency – every message should have the same common elements, and every message should use the same model
  • No exceptions – errors should be part of a message, rather than being outside of messaging
  • Decoupling – the client should not be forced to wait on the server

The first two are readily achievable – the final goal will have to wait until I look at a common communications library.

For consistency, I want to move every message to a two-way model. This means that even the current one-way messages (e.g. force/abort build, start/stop project, etc.) will return a response to the client. In most scenarios this means the server will send a “success” response (e.g. I have received your force build request and added it to the queue), but it also allows for sending errors back to the client.

Currently an error is returned using an exception, which is a security hole (it allows external parties to see the structure of the code and potentially helps them to hack in). With the new model, errors will be returned as part of the response, allowing us much greater control over what is actually sent.

Next, I want to split the messages into two parts – a body and a header. The header contains information about the request that doesn’t directly apply to the message. At the moment I’m thinking about adding a project identifier, the session token and a message identifier.

The project identifier is a unique way of identifying every project. This identifier must be globally unique since the dashboard can handle multiple servers. As such this identifier will consist of the server name plus the the project name. If the request is a server-level request, then just the server name is required.

While this may seem like some duplicate of data (e.g. the server name is part of both the protocol and the message) it allows for consistency, plus provides some avenues for message validation later.

The session token is new to security. It allows a client to tell the server who is using it. Currently it is only used for active requests (e.g. force/abort build, start/stop project, etc.) plus security requests (e.g. change password, list users, etc.) I think this would also be useful for every request – both for consistency, plus for the future options it allows.

And finally, a message identifier. This would be a unique identifier for each message. While there is no requirement for it at the moment I foresee it being useful in security (for preventing message-repeat attacks). Ideally this should be combined with a timestamp to narrow the window of attack.

Laying the Foundation

Since this post is mainly about my plans for messaging, I’m not going to include any coding. Instead I’ll finish off with my design for the messages. Now this isn’t the full design, instead it’s an example of how the classes will be built:

Requests

The base class that every request needs to inherit from is ServerRequest. This contains the common “header” data for every request. Additionally, methods that need no further information can use this request directly.

Requests that inherit from this just add the additional properties that they require. For example, ProjectRequest just adds the project name. Any methods that just needs the project name (e.g. start/stop project) could then use this request.

More specialised requests can then inherit from these classes depending on what base information they need (e.g. ChangePasswordRequest inherits from ServerRequest while ForceBuildRequest and SendMessageRequest inherit from ProjectRequest).

Each request must be serialisable so it can be passed via .Net Remoting. Additionally I’m thinking of marking them up with XML serialisation attributes to help with HTTP requests.

Responses are very similar:

Responses

This is very similar – one root class (Response) plus some specialised classes.

The basic idea with these is to use any existing class if possible, otherwise add a new class to provide the custom request/response.

What About the Future?

With these request/response classes it should be fairly easy to port them to WCF. Just add the data contract attributes and then write a contract interface, plus implementation.

So this approach should also handle the move to WCF.

That’s a Wrap

So, that’s my intentions for messaging. Next I’ll have a go at implementing them and see how things work out.

Posted in CruiseControl.Net | Tagged: | 3 Comments »

A Couple More Ideas for Enhancements

Posted by Craig Sutherland on 5 January, 2009

Some Background

Since I’ve become involved in developing for CruiseControl.Net I’ve working on a couple of changes that have forced some reasonably major flow-on changes. The biggest area for this is the interface between the client and the server (aka ICruiseManager).

Now I had just accepted this as a limitation of CruiseControl.Net and not worried (or even thought) about it. In retrospect this probably wasn’t very smart of me :( When Dave Cameron saw one set of changes I had added he had the brilliant idea of wrapping some of these changes into a “build-request object”. When I read his idea it was like the light-bulb going on and I felt dumb for not having thought of it before.

Now don’t take this as a criticism of CruiseControl.Net. Instead this has occurred because we’re trying to take the product in new directions that the original developers might not have thought of. To this day I still love the product and there are many, many areas I haven’t even looked at in the code :) These ideas are just suggestions I thought of to improve the product.

Messaging

Currently all requests to the server are as .Net Remoting calls (HTTP goes via the web dashboard to the server, but in the end is still a .Net Remoting call). These calls treat the server as just a remote object and use the standard method call interface (with .Net Remoting taking care of all the communications). This has lead to changes every time new parameters are required to multiple interfaces and classes.

Additionally there is no way of returning error information (e.g. security violations, bad project references, etc.) At the moment the only way to do this is an exception, which means serialising/deserialising an entire Exception over the wire. Likewise, it is assumed that all method-calls succeed, when in reality they might have failed.

What I would like to propose is to change a number of method calls to use a messaging-type approach. To make a request, the client builds a message and sends it to the server. The server receives the message, processes the contents and send back a response message telling the client the outcome.

This would not use a messaging framework (.Net Remoting is still fine), just the concept of messaging.

A request message would consist of the content (which project, build parameters, etc.) plus header information (session token, target server, etc.) A response message would contain an outcome (success/failure) plus any additional information (e.g. errors, details on what has happened, etc.)

In the future, when we have new enhancements, we would just extend the message formats to include the new items, rather than needing to modify lots of interfaces and classes.

Which brings me to my next idea:

Common Communications Layer

At the moment all communications with the server is via .Net Remoting. If a server wants to check on another server, it uses .Net Remoting. Web dashboard only uses Remoting to check on servers. CCTray is the only exception, but when it uses HTTP, it only connects to a dashboard instance, which in turn uses Remoting. CruiseControl.Net has a heavy emphasis on Remoting at its heart.

Note: I have written some extensions which allow WCF communications, but these are purely extensions. Until CruiseControl.Net moves to .Net 3.0+ there is no way we can move these into the Core.

Additionally each client has its own set of classes for connecting to the server (including when the server is a client). And all of these sets are slightly different – both in their methods and classes, and in terms of inputs and outputs.

This means I can’t take the HTTP transport from CCTray and just add it to the dashboard to allow HTTP communications with another dashboard. Likewise the server always uses .Net Remoting for its remote build triggers, and if this protocol is blocked by the firewall, that’s just too bad!

What I am thinking of is to add a new library to the product. This library would provide an abstraction of the communications layer, plus a couple of implementations of the “standard” protocols (e.g. .Net Remoting and HTTP). This library would effectively wrap the messaging changes I suggested above.

This library would expose a factory class for creating the server connection, and then the clients would use this server connection class for passing all the requests.

Then, we could modify the clients so it uses these instead of direct .Net Remoting. This would then allow a wider range of connections from these applications.

Anyway, just my thoughts – does anyone have any comments to add?

Posted in CruiseControl.Net | Tagged: | 3 Comments »