tag:blogger.com,1999:blog-47192894178356127862024-03-13T17:08:34.372-07:00Sys 2 SysA blog about making systems talk to each other...Jameshttp://www.blogger.com/profile/01390650972189795908noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-4719289417835612786.post-51056495539662364052015-03-08T10:58:00.000-07:002015-03-08T10:58:18.220-07:00Restful services: to XSD or not to XSD? That is the question<div dir="ltr" style="text-align: left;" trbidi="on">
<div>
<br /></div>
<div>
A questions I've been considering lately is “should we be using XSD to describe and validate our Restful payloads?”. A lot of REST APIs are described in a bit of a loose way (e.g. example payloads not strict definitions). Obviously XSD can define any XML structure, but in an RPC world, the XSD is tied to the operation not a stateful entity. Does this make a difference? Is there a reason XSD is any less applicable to REST services, than to a service defined in WSDL?</div>
<div>
</div>
<div>
There’s surprisingly little I can find in the blogosphere about the pros and cons of this – most of the blogs around XSD and REST are more about how to implement using different frameworks / technologies (so obviously it can be done). One blog explicitly said that XSD was a “bad idea for REST”, but not why – so that’s hardly a strong argument. I got to thinking from first principles and after a bit of thought, and some conversations with colleagues at the coffee machine, we agreed that XSD validation is entirely possible, and probably desirable. That said (like a lot of REST use) there are some rules to follow – and this post gives my humble opinion as to what they are.</div>
<div>
<br /></div>
<h3 style="text-align: left;">
Foundation Concepts</h3>
<div>
As a starting point, it’s worth outlining some things I think of are true of all services (feel free to disagree in the comments section).</div>
<div>
<b><br /></b></div>
<div>
<b>F1 - Service contracts are good:</b> </div>
<div>
It’s vital for service consumers to know what a service does and how to interact with it. This applies to all component software where Encapsulation and Information Hiding are foundational concepts.</div>
<div>
<b><br /></b></div>
<div>
<b>F2 - Machine readable contracts are better: </b></div>
<div>
It’s better to have a contract that code can read, rather than one in word/a wiki/or on paper. It’s also great if your contract and validation rules are from the same source, that way there’s no chance of disagreement between what the service claims to do, and what the validation allows it to do. This is one reason I’m such a big fan of XSD and so many of the other open standards.</div>
<div>
<b><br /></b></div>
<div>
<b>F3 - Open standards are a good thing</b></div>
<div>
REST is built upon the HTTP standards for transport, XML should be based on the open XSD standard for validation. Of course the are other standards (JSON to name but one) – but if you’re using XML, then XSD seems a sensible way to both document and validate you messages – everyone understands it and there is a mass of tooling (both free and commercial) to help.</div>
<div>
<b><br /></b></div>
<div>
<b>F4 - Service contracts are not unrestful</b></div>
<div>
Knowing how to represent your state is key to being able to transfer your state. Of course to be RESTful (regardless of how you describe it) the contract needs to be entity focused and not RPC focussed e.g. an XSD “Customer” object, not an XSD “AddCustomer” object.</div>
<div>
<br /></div>
<div>
<h3 style="text-align: left;">
The Rules</h3>
<div>
OK, hopefully we’re in agreement so far. In this case how do we do XSD REST validation? It’s actually quite simple but as we discussed various different scenarios we found some basic rules needed to be followed or else we got into a bit of a mess. These rules make a REST XSD quite different to an RPC XSD:</div>
<div>
<br /></div>
<div>
<b>Rule 1: Entities must be described with one schema, regardless of ACTION</b></div>
<div>
Perhaps quite intuitive – if something is mandatory/optional when you create (POST) an object, it follows that it is mandatory when you GET it later, or PUT it back. It also follows that the format of an object remains fixed throughout the life of that object - If not, how is it the same object?</div>
<div>
<br /></div>
<div>
This obviously doesn't mean the state of the object won’t change (that would be silly). Values can change and optional fields can be filled in which were previously missing. What it does mean is:</div>
<div>
<ul style="text-align: left;">
<li>No fundamental changes to structure (e.g. the root element won’t change name)</li>
<li>No change to element cardinality (e.g. MinOccurs=1 changing to 0, or MaxOccurs=1 changing to unbounded)</li>
<li>No change to data types (e.g. integers change their min/max values or become strings)</li>
</ul>
</div>
<div>
The key here is that data validation must be about structure, and the core of what makes an object valid - not about a particular use case. For example in a given organisation a “Customer” might always be invalid without a Surname – this is essentially the same sort of rules we apply in database create table statements.</div>
<div>
<br /></div>
<div>
<b>Rule 2: No partial updates - Entities are created/updated/retrieved as a whole</b></div>
<div>
In order for XSD validation to occur cleanly we can't allow partial updates by POST (or shock horror by PUT). If we trying to write an XSD which allows partial POST updates, it becomes so lax it can’t actually achieve validation. Either everything becomes optional, or there are lots of “choices”. In either case invalid XMLs can slip through the gaps and the XSD will report them as valid.</div>
<div>
<br /></div>
<div>
We did explore the idea of having different XSDs (or an XSD with a choice in it) for different scenarios (e.g. one which describes everything needed for a full update, and another which is used for partial updates. This is possible, but very quickly becomes unstuck because:</div>
<div>
<ul style="text-align: left;">
<li>REST has no procedures - At a conceptual level, attempting to impose “scenarios” on REST is fundamentally troubling, and has the potential to get everyone out of the RESTful mindset.</li>
<li>More concretely, there isn't a way to tie different scenarios to different XSDs – the client wouldn't know which XSD to use for a given scenario other than by convention (so you break <b>Foundation Concept F2</b>). Even if you could somehow specify that we use <i>object_get.xsd </i>for the GET action, and <i>object_put.xsd </i>for the PUT action, <b>Rule 1</b> explains why you shouldn't want to.</li>
</ul>
</div>
<div>
OK, but what about the <a href="https://tools.ietf.org/html/rfc5789" target="_blank">PATCH operation</a>? The pros can cons of PATCH are beyond the scope of this blog, but in terms of XSD, PATCH doesn't really help:</div>
<div>
<ul style="text-align: left;">
<li>The patch object (as described very well in <a href="http://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/" target="_blank">William Durand's blog</a>) isn't the same format as our object – so can't use our XSDs.</li>
<li>These patch operations have similar issues of being so loose that things slip though the gaps and it doesn't solve the <b>F2 </b>or <b>Rule 1 </b>concerns in the previous bullets.</li>
</ul>
<div>
<div>
OK, so if we follow the rules laid down above is everything easy? Well, almost. There are a few awkward scenarios we identified so it’s worth highlighting them.</div>
<div>
<br /></div>
<h3 style="text-align: left;">
Scenarios & Examples</h3>
<h4 style="text-align: left;">
<b>Scenario 1: Elements null on initial POST, then mandatory afterwards.</b></h4>
<div>
<i>Example 1: The primary key is missing in POST but needed in PUT</i></div>
<div>
<br /></div>
<div>
This is OK and breaks no rules, in fact this is normal procedure for the REST spec. The key is in the URL and not in the payload so we’re OK.</div>
<div>
<br /></div>
<div>
<i>Example 2: Some fields are “generated” by the system we POST to, and from then on they are mandatory e.g. creating a “user” object sets their home folder which we want to be mandatory.</i></div>
<div>
<br /></div>
<div>
This obviously breaks <b>Rule 1</b> – we’re asking for the validation rules of POST to be different to those of PUT. What we do about it depends on the scenario in question: </div>
<div>
<ul style="text-align: left;">
<li>Is this actually mandatory from a data validity perspective – only from a business process perspective? Namely is the attribute mandatory at this point in an object’s lifecycle but it might not be later? If this is business process logic, then XSD is the wrong tool for the job - the check should be in application logic.</li>
<li>Is this a separate entity? If so then should it be created by its own POST and then passed by reference to this entity’s POST? In DB terms should do we need to create a foreign key object before we create this object?</li>
<li>If neither then we're into the horrible territory of either having a lax schema, or making it mandatory but the POST method knowing to ignore the value sent in (and explaining to the client that they have to send nonsense). None of these is ideal obviously.</li>
</ul>
</div>
</div>
</div>
</div>
<div>
<h4 style="text-align: left;">
Scenario 2: The consumer has the rights to GET the whole object, but only has the authority to update a subset of the fields</h4>
<div>
<i>Example: A consumer can GET an Order, but only has rights to update the “comments” section.</i></div>
<div>
<br /></div>
<div>
This doesn't break a rule. This is talking about if they’re authorised to change a field, not if the change is valid (authorisation is not validation).</div>
<div>
<br /></div>
<div>
The consumer can PUT the object as normal – the XSD will validate that the submitted data is VALID. If the data is valid then the API needs to see if they've tried to do something they shouldn't (i.e. change a field they’re not allowed to) that’s not an XSD problem:</div>
<div>
<ul style="text-align: left;">
<li>If an unauthorised change has been made, then return a code <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes" target="_blank">403 – forbidden</a></li>
<li>If this is an authorised change then PUT is OK and return a standard response in the 2xx range.</li>
</ul>
</div>
<div>
This might be inefficient (comparing the whole object to ensure no unauthorised changes have been made, but it’s not unrestful and it keeps to the rules. To improve efficiency we might be better to spin up an OrderComments API with a PUT to allow this action to only change comments.</div>
</div>
<div>
<br /></div>
<div>
<h4 style="text-align: left;">
Scenario 3: Consumer doesn't have access to view every part of an object (some are obscured/removed based on their profile), but wishes to PUT.</h4>
<div>
<i>Example 1: Depending on profile some consumers see a customer’s phone number, others see 07**********12</i></div>
<div>
<br /></div>
<div>
This doesn't break a rule, and is just another form of Scenario 2 – the consumer doesn't have rights to change this field, so they just pass back the masked phone number.</div>
<div>
<br /></div>
<div>
<i>Example 2: Depending on profile some consumers see an Order’s payment information, for other consumers it is omitted entirely</i> <i>(e.g. what happens with <a href="http://support.mashery.com/docs/read/mashery_api/30/resources/services/endpoints/methods/responsefilters" target="_blank">Mashery Response Filters</a>).</i></div>
<div>
<i><br /></i></div>
<div>
In order for the message to validate against the XSD, the fields which were removed cannot be mandatory – otherwise the GET would fail its own XSD (which would obviously be bad).</div>
<div>
<br /></div>
<div>
As long as a value of the PUT contains what was in the GET then the consumer isn't breaking <b>Rule 1</b> and from their point of view they're passing back the whole object, so they're not breaking <b>Rule 2</b> either. As with Scenario 2, the responsibility is with the API to manage. This could also be inefficient and is possibly a bad idea, but the issue is with API design and not with the validation.</div>
<div>
<br /></div>
</div>
<h3 style="text-align: left;">
Conclusion</h3>
<div>
As far as I can tell XSD is perfectly doable with Rest so long as certain rules are followed. Within these constraints, and with good API design, we can both document and validate our payloads using XSD. There are some use cases where we push these rules, but I've not yet found a scenario under which the rules break. </div>
<div>
<br /></div>
<div>
If anyone would like to feed back any comments I'd be glad to hear them.</div>
</div>
Jameshttp://www.blogger.com/profile/01390650972189795908noreply@blogger.com0tag:blogger.com,1999:blog-4719289417835612786.post-88280583717092627162013-09-25T08:30:00.002-07:002013-09-25T08:30:27.399-07:00Security Radar Graphs (2) - Implications of security requirements<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: left;">
As seen in the last post, radar graphs are a useful way of capturing the security requirements of a service or set of services. As promised, this second part both defines what is meant by the different levels on each axis and notes some basic considerations which need to be made when making a selection for any given aspect of SOA security.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
To recap, the radar graph in question looks a little like this:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifdeO4SQyoJsME4IFpfjK7M0lTq6UVsS-RXnsHiqXcv3tv_S1xgj8RCAHlFBb2Yz520FgrD2MNFwnSdG1HsdeeispGoOy8RE_ATbWplHoy40eKmdf0hyl1olJVrZogr-bIonON8sWhJd4/s1600/radar.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="305" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifdeO4SQyoJsME4IFpfjK7M0lTq6UVsS-RXnsHiqXcv3tv_S1xgj8RCAHlFBb2Yz520FgrD2MNFwnSdG1HsdeeispGoOy8RE_ATbWplHoy40eKmdf0hyl1olJVrZogr-bIonON8sWhJd4/s400/radar.jpg" width="400" /></a></div>
<br />
<br />
So if we take each axis in turn are the descriptions and the considerations which they warrant. Sorry the formatting is a bit ugly - Blogger doesn't seem to support tables very well. </div>
<h3 style="text-align: left;">
Network Filtering</h3>
The level to which your network security filters who can get access to your SOA.<br />
<ul style="text-align: left;">
<li><b>None: </b>Anyone on the internet can access services </li>
<ul>
<li>No reduction in traffic by the network layer, this increases the need to carefully consider network separation to prevent common attacks.</li>
</ul>
<li><b>Firewall: </b>Partners access services over the internet - restricted by firewall settings (e.g. IP filtering)</li>
<ul>
<li>IP spoofing is possible. </li>
<li>Cloud partners can often change IP addresses - can be difficult to maintain an accurate white-list and a given IP range can't be guaranteed to be that of a trusted partner. </li>
<li>Multiple potential consumers exist within the partner network (in the partner IP range). These consumers are indistinguishable based on IP address. </li>
<li>Therefore... whilst more secure than "None", network separation and/or authentication are still important.</li>
</ul>
<li><b>VPN/Leased Line:</b> Selected partners can access services via a secured channel</li>
<ul>
<li>Some external providers (especially cloud providers) may not accommodate such a channel </li>
<li>This potentially exposes the core network outside of the data centre - consider the importance of firewall rules to restrict the services that can be accessed (e.g. just the ESB) as well as authZ/authN.</li>
</ul>
<li><b>Closed Network:</b> No off site access to services </li>
<ul>
<li>No benefits of partnerships, outsourcing, cloud technology etc </li>
<li>Whilst secure, this may not be a possibility given other these considerations</li>
</ul>
</ul>
<h3 style="text-align: left;">
Network Separation</h3>
The level to which your network security isolates your SOA from external access.<br />
<ul style="text-align: left;">
<li><b>None/Reverse Proxy:</b> Basic reverse proxy (not XML aware gateway) is used to separate consumers from the ESB. This sort of proxy may be able to provide SSL but not WS-Security. It cannot detect attacks SOA specific types of attacks (e.g. XML injection)</li>
<ul>
<li>The whole ESB must be considered externally facing (whatever network filtering determines 'external' is). </li>
<li>If network filtering is 'none' (i.e. open to the internet) this approach is woefully inadequate, if the only external access is via a VPN from a trusted partner then this may be acceptable. </li>
</ul>
<li><b>Second ESB:</b> Have an 'externally facing' ESB (behind the reverse proxy) before messages get to the internal ESB (e.g. this <a href="http://msdn.microsoft.com/en-us/library/aa578706.aspx" target="_blank">MSDN pattern</a>)</li>
<ul>
<li>This can mitigate against certain problems (e.g. DoS attacks impacting the internal ESB), and can provide a layer of separation. </li>
<li>It won't guard against attacks as thoroughly as an XML Gateway. </li>
<li>Will likely require more custom code/detailed config to detect attacks than a COTS XML gateway would do as a mater of course. </li>
<li>As with 'None/Reverse Proxy', the nature of the network filtering will influence the applicability of this solution.</li>
<li>This solution also necessitates additional services to pass traffic from outside to the internal ESB - thus additional config/maintenance and licensing costs to implement the 2nd ESB.</li>
</ul>
<li><b>XML Gateway: </b>Buy a COTS XML gateway specifically designed for exposing services to the internet (e.g. Vordel/<a href="http://www.oracle.com/us/products/middleware/identity-management/api-gateway/overview/index.html" target="_blank">Oracle API Gateway</a>, <a href="http://www-03.ibm.com/software/products/us/en/datapower/" target="_blank">IBM DataPower</a>, <a href="http://www.cisco.com/en/US/products/ps7314/index.html" target="_blank">Cisco ACE</a>). This is significantly more powerful than a reverse proxy because it's XML aware, and has inbuilt security and threat detection</li>
<ul>
<li>Initial cost outlay can be high, although the ease of configuration vs a second 'external ESB' can balance this a bit.</li>
<li>The hardening of such devices is more expertly developed and tested than custom config/code so is not only better able to detect complex attacks but also gives better peace of mind.</li>
<li>These devices can offer additional benefits in terms of security policy management (see below). </li>
</ul>
</ul>
<h3 style="text-align: left;">
Security Location</h3>
Where in the architecture security is enforced.<br />
<ul style="text-align: left;">
<li><b>Perimeter: </b>Security is only applied at the perimeter, internal traffic is considered 'trusted'.</li>
<ul>
<li>Only protects against external threats, despite <a href="http://www.simplysecurity.com/2012/09/28/most-data-security-threats-are-internal-forrester-says/" target="_blank">research suggesting </a>70% of breaches are internal. </li>
<li>In an increasingly interconnected service oriented world, is this internal/external split an oversimplification - can we keep thinking in these terms? </li>
</ul>
<li><b>ESB: </b>Security is applied to consumers of ESB services, but no security exists between the ESB and back-end systems</li>
<ul>
<li>Is there anything to stop consumers going direct to a back-end service if only the ESB services are secured (e.g. internal firewalls)? If not this may not be good enough. </li>
</ul>
<li><b>Endpoint (trusting): </b>Services on the ESB <b>and </b>back-end services are secured, however back-end services only validate that their consumer is the ESB, and trust the ESB to perform downstream validation.</li>
<ul>
<li>This is a generally good model so long as the answers to the following questions are 'yes':<br /><ol>
<li>Do system/data owners trust the ESB development and security governance structures?</li>
<li>Does this trust delegation meet the audit requirements for back end services (the back-end system doesn't need to record the ultimate consumer)?</li>
<li>Are services accessed only via ESB and not directly?</li>
</ol>
</li>
</ul>
<li><b>Endpoint (aware): </b>Services on both the ESB and back-end are secured, and validate the ultimate consumer. The ESB merely mediates the connection but doesn't break the security chain.</li>
<ul>
<li>Must be done carefully to maintain SOA decoupling principles - if back-end systems are aware of which systems are accessing them it makes change more difficult and blows a hole in the idea of fully decoupled systems. So long as this is done with some thought it's not a big problem (e.g. by separating security from service configuration and with appropriate governance).</li>
<li>Endpoint security might not be an option for many legacy systems and certainly not distributed policy based endpoint security. This is especially true if the ESB is connecting via an adaptor rather than by calling a web/rest service.</li>
<li>Even if this possible, systems may require re-engineering to achieve this. </li>
</ul>
</ul>
<h3 style="text-align: left;">
Policy Separation</h3>
The level of separation between security policies and service implementation.<br />
<ul style="text-align: left;">
<li><b>None: </b>Security hard coded into service endpoint</li>
<ul>
<li>A reasonably bright 6 year old should be able to point out why this is a bad idea so I'm not going to say much about it. Unless it's impossible to avoid, this a bad option. </li>
</ul>
<li><b>Config: </b>Security in service but separated into configuration rather than code - can be changed without redeployment</li>
<ul>
<li>This is more sensible, and is often the way that policy is applied. It makes ongoing maintenance a bit more difficult than with a central policy, but there may be any number of good reasons to do this:</li>
<ul>
<li>Technology doesn't support central security policy.</li>
<li>There isn't the desire to pay for a central management. </li>
<li>There isn't sufficient governance to drive a more joined up approach, each service developer has to do the best they can (not a perfect reason obviously). </li>
</ul>
</ul>
<li><b>Central Policy: </b>A policy is configured and maintained at a central policy server location and disseminated to endpoints automatically</li>
<ul>
<li>The nirvana of policy administration is having all policy regardless of what/where it's applied stored in a central security policy server. </li>
<li>Obviously there are cost implications and many existing services/technologies may not support this (as ever legacy is a big challenge). </li>
<li>This is interesting and complex enough to write whole books about - here we'll just say it's nice if you can do it.</li>
</ul>
</ul>
<h3 style="text-align: left;">
Authentication - System</h3>
The way a service identifies which consumer is invoking it.<br />
<ul style="text-align: left;">
<li><b>None: </b>Anyone can consume service</li>
<ul>
<li>Even if service has no security requirements this makes it difficult to enforce governance (i.e. registration) and keep track of consumers. This governance answer can alternatively be addressed with a UDDI registry but if that's not your approach then authentication can be useful to ensure you've not got any unknown consumers. </li>
<li>If you don't know who is consuming a service how can you know when it can be switched off?</li>
</ul>
<li><b>Transport: </b>The transport medium confirms consumer identity (e.g. mutual SSL certificates)</li>
<ul>
<li>This can be more difficult to manage and change than credential based authentication. </li>
<li>It can also be harder to handle multiple 'hops' across intermediates whilst still keeping track of the originator's identity.</li>
</ul>
<li><b>Credential: </b>A credential embedded in the message identifies the consumer</li>
<ul>
<li>Credentials can authenticate the sender however this relies on the message being secure to ensure the message isn't altered, and to ensure the credentials aren't captured and used to send future messages. </li>
<li>Unless the network is completely secure (if there is such a thing) this requires a level of encryption (see 'Data in flight').</li>
</ul>
<li><b>Digital Signature: </b>The message is hashed and digitally signed</li>
<ul>
<li>Signatures can prove not only the identity of the sender, but also confirm that the message has not been altered in flight. This can also useful if the message is sent over an insecure medium as the credentials cannot be read and replayed.</li>
<li>As with message level encryption (below), if the credentials have to be passed downstream then the message cannot be altered. This makes the decoupling (type mapping) benefits of SOA more difficult to realise.</li>
<li>On one hand keys can be a little more difficult to manage than credentials, then again given their asymmetric nature they can be distributed easily and securely because only the public key needs to be sent from the consumer to the provider and can be done so without any concern about interception.</li>
</ul>
</ul>
<h3 style="text-align: left;">
Authentication - User</h3>
The way a service identifies what end-user has caused the service to be invoked.<br />
<ul style="text-align: left;">
<li><b>None: </b>No end user identification or user involvement</li>
<ul>
<li>For example a system calls a service based on a timer.</li>
</ul>
<li><b>Trust: </b>User is validated by the consuming system and any authN/authZ in the middleware is based purely on that system (see Authentication - system)</li>
<ul>
<li>Can the end-system be trusted to restrict access? If so the service can delegate this responsibility and merely authenticate that the consumer is a trusted system.</li>
<li>This assumes that audit requirements in the back-end system do not require knowledge of end user. If the service is performing an update this might not be true.</li>
</ul>
<li><b>Corporate: </b>Access is controlled based on credentials held in an organisation's user list (e.g. against corporate Active Directory)</li>
<li><b>Partner: </b>Access is controlled based on credentials for internal users or partners users (e.g. against Active Directory Federation Services)</li>
<ul>
<li>Do both partner organisations have federated AD?</li>
</ul>
<li><b>Global:</b> Access is controlled based on global user Ids / social sign-on e.g. For self service user accounts for websites</li>
<ul>
<li>Much more complex identify management suites required - although it's hard to imagine when this sort of end user account would be trusted within the SOA rather than used at a web/mobile gateway and trusted.</li>
</ul>
</ul>
<h3 style="text-align: left;">
Data in flight</h3>
The protection given to data whilst in transit between consumer and provider or vis-versa.<br />
<ul style="text-align: left;">
<li><b>None: </b>Unencrypted</li>
<ul>
<li>Is any data sensitive? </li>
<li>Is it on a trusted network (e.g. internal data centre, not the internet)</li>
</ul>
<li><b>Transport Encryption: </b>Encrypted transport e.g. HTTPS or queue encryption.</li>
<ul>
<li>At any point where the transport terminated this terminating system (e.g. ESB/proxy/gateway) must be trusted. Support staff can review this information, the system may log this in plain text. If the intermediaries are trusted this maybe sufficient.</li>
</ul>
<li><b>Partial Message Encryption: </b>Key message elements are encrypted e.g. XML Encryption of payment details.</li>
<ul>
<li>Where intermediates are not trusted this is a great solution. There are no problems with intermediaries, and it makes the whole question of masking (see 'Data at rest') far easier if any messages logged by the middleware are logged as encrypted messages.</li>
<li>There are downsides however: </li>
<ul>
<li>Once encrypted, the data in the message cannot be validated by the middleware. This reduces some of the benefits of the middleware in stopping potentially poor data 'at the front door'. </li>
<li>This can also introduce security problems of its own, as the perimeter security cannot be as thoroughly applied to encrypted messages. For example an encrypted message (or encrypted element) can't be scanned - e.g. for SQL injection, XML explosion attacks.</li>
</ul>
</ul>
<li><b>Full Message Encryption: </b>The whole message is encrypted.</li>
<ul>
<li>The same as the above but the downsides are exacerbated.</li>
</ul>
</ul>
<h3 style="text-align: left;">
Data at rest</h3>
The protection given to data when not in transit over the network.<br />
<ul style="text-align: left;">
<li><b>None: </b>Data at rest within the architecture is not protected</li>
<ul>
<li>This is fairly common from what I've seen - data at rest is stored within the core of the network and not encrypted although obviously it's protected by the OS/network security. </li>
</ul>
<li><b>Masking:</b> Data is masked when written to intermediate storage e.g. ESB logs</li>
<ul>
<li>One of the key considerations which needs to be made for each service is can data be logged to audit/exception logs? If not how do we implement field level masking? Are only some fields masked or do we mask all body data? </li>
<li>How does this impact the ability of support teams debugging? </li>
</ul>
<li><b>Encrypted:</b> Data is encrypted as it's written either in part (field level encryption) or at the level of complete message or even complete database encryption.</li>
<ul>
<li>Is logging done to a DB or file system? Does the FS/DB support encryption? Are messages already encrypted? How frequently do these need to be retrieved? Can the support staff easily decrypt to be able to fix issues?</li>
</ul>
</ul>
Right that's all for now - sorry that turned into a longer post than I'd expected when I started thinking about this topic. Any thoughts, omissions etc feel free to add them in the comments below.
</div>
</div>
Jameshttp://www.blogger.com/profile/01390650972189795908noreply@blogger.com0tag:blogger.com,1999:blog-4719289417835612786.post-61026883466025487292013-09-22T22:39:00.001-07:002013-09-23T00:54:50.570-07:00Security Radar Graphs - Capturing SOA security requirements<div dir="ltr" style="text-align: left;" trbidi="on">
Securing an SOA is a complicated business. It isn't a single concept but
various moving parts such as: encryption, authentication, and
non-repudiation. Not only is there no "one size fits all", but this
multi-dimensional nature means there isn’t even a single sliding scale
for low, medium and high security. One service might need transport
encryption (e.g. SSL) and non-repudiation but have no need for
encryption at rest behind the firewall; another requires encryption
end-to-end including at rest, but not need non-repudiation - neither is
more secure, merely differently secure. In an SOA some security
requirements will be enterprise wide (e.g. perimeter security), whilst
others will vary on a service by service basis (e.g.
authentication/encryption levels). This quickly becomes a complex
picture.<br />
<br />
Aside from the wasted expense, applying unnecessary
security can reduce flexibility, increase complexity, and deny the
benefits of the cloud. Obviously business requirements come first (it's
why we're here after all), and tight budgets mean security needs to be
targeted to where it's really needed. In this security vs flexibility
consideration, one final aspect is worth considering: how does security
affect SOA benefits? There's one obvious example, message level
encryption can reduce the ability of intermediaries to validate
messages, so the ESB or XML firewall can't stop invalid messages. Here a
security option can directly impact a non-security aspect of the
solution.<br />
<br />
It's obvious that defining SOA security is complicated
to say the least. This was a challenge we had whilst discussing security
requirements recently. The solution we found was a radar graph showing
options which looked a bit like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcD3bS30aNv7eX3dakK3XdyWQbQtB7V84GMk-wvwtZBHgt27Ki_PYHu-Bf3L7WRSNafwXutgDd0ZXOgZUsBA4SVt9k2xZbUpgTzfMtV-OkEK-0t-TUqgFXGmD9MtJ9YBOW22MUTUoQ7gc/s1600/radar.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="305" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcD3bS30aNv7eX3dakK3XdyWQbQtB7V84GMk-wvwtZBHgt27Ki_PYHu-Bf3L7WRSNafwXutgDd0ZXOgZUsBA4SVt9k2xZbUpgTzfMtV-OkEK-0t-TUqgFXGmD9MtJ9YBOW22MUTUoQ7gc/s400/radar.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
Looking at the graph:<br />
<ul>
<li> The three axes above the horizontal
(Network filtering, Network separation, Security location) will usually be
determined for the architecture as a whole.</li>
<li> The two horizontal
axes (policy separation, data at rest) could be decided on a service by
service basis but will likely have wider impacts if security is
increased (i.e. introducing central policy management will require new
products, masking audit logs will potentially impact all services if a
common logger is used.</li>
<li> The three axes below the horizontal can
be determined on a service by service basis and as such can be included
in the service NFR template.</li>
</ul>
<br />
In a future post I'll discuss
the impact of the various options on each axis in terms of cost,
flexibility and any other knock on effects.</div>
Jameshttp://www.blogger.com/profile/01390650972189795908noreply@blogger.com0tag:blogger.com,1999:blog-4719289417835612786.post-73613848529196598952013-07-04T13:17:00.005-07:002013-07-04T13:17:54.036-07:00SoapUI: Data Driven Testing (without going pro)<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
One of the neat things which <a class="tiddlyLink tiddlyLinkNonExisting" href="http://www.blogger.com/null" title="The tiddler 'SoapUI' doesn't yet exist">SoapUI</a> Pro offers is called data driven testing <a class="tiddlyLink tiddlyLinkNonExisting" href="http://www.blogger.com/null" title="The tiddler 'http://www.soapui.org/Data-Driven-Testing/functional-tests.html' doesn't yet exist">http://www.soapui.org/Data-Driven-Testing/functional-tests.html</a>.
The idea is that you can run a test several times and pull data out of a
data source (file, database etc) to use in your tests. Sadly not all of
us have <a class="tiddlyLink tiddlyLinkNonExisting" href="http://www.blogger.com/null" title="The tiddler 'SoapUI' doesn't yet exist">SoapUI</a> Pro but it's entirely possible to do something similar with <a class="tiddlyLink tiddlyLinkNonExisting" href="http://www.blogger.com/null" title="The tiddler 'SoapUI' doesn't yet exist">SoapUI</a> free (as Theo Marinos demonstrates in his<a href="http://things-i-do.co.uk/2012/06/15/data-driven-testing-with-soapui-free-edition/"> excellent blog on the subject</a>).<br /><br />The
above blog chooses a random value from a file each time you run a test
in order to test a service. This is great for load testing, or if all
you want to prove is that a service works correctly with one of a given
set of values, but what if you want to test that for a given input (or
inputs) to the service returns a given output (or outputs). Well that's
also quite easy to do to. I've put together a simple example which reads
every value in a csv file, calls a web service using the input value and
ensures the response contains the expected response from the same line
of the file.<br />
<br />
<br />
<h3 style="text-align: left;">
Creating a service to test</h3>
As I didn't have a real service to test, the first thing I did was to create a SoapUI mock test service based on a <a href="http://www.tutorialspoint.com/wsdl/wsdl_example.htm">very simple WSDL</a>. In the mock service I put some groovy to generate a response based on the input message<br /><blockquote class="tr_bq">
<em>def holder = new com.eviware.soapui.support.<a class="tiddlyLink tiddlyLinkNonExisting" href="http://www.blogger.com/null" title="The tiddler 'XmlHolder' doesn't yet exist">XmlHolder</a>( mockRequest.requestContent )<br />def name = holder["firstName"];<br />if (name.substring(0,2)=="Mr")<br /> requestContext.greeting="Hello "+name;<br />else <br /> requestContext.greeting="Howdy "+name;</em></blockquote>
<em></em>This
generates a "greeting" variable. If the "firstName" element starts with
Mr then it responds "Hello <name>", otherwise it replies "Howdy
<name>" - simple. Then in the mock service I put this greeting
variable to use<em>:</em><blockquote class="tr_bq">
<em><soapenv:Envelope xmlns:xsi="http:</em>www.w3.org/2001/<a class="tiddlyLink tiddlyLinkNonExisting" href="http://www.blogger.com/null" title="The tiddler 'XMLSchema-instance' doesn't yet exist">XMLSchema-instance</a>" xmlns:xsd="<a class="externalLink" href="http://www.w3.org/2001/XMLSchema" target="_blank" title="External link to http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>" xmlns:soapenv="<a class="externalLink" href="http://schemas.xmlsoap.org/soap/envelope/" target="_blank" title="External link to http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/</a>" xmlns:urn="urn:examples:helloservice"><br /> <soapenv:Header/><br /> <soapenv:Body><br /> <urn:sayHelloResponse soapenv:encodingStyle="<a class="externalLink" href="http://schemas.xmlsoap.org/soap/encoding/" target="_blank" title="External link to http://schemas.xmlsoap.org/soap/encoding/">http://schemas.xmlsoap.org/soap/encoding/</a>"><br /> <greeting xsi:type="xsd:string"><b><span style="color: red;">${greeting}</span></b></greeting><br /> </urn:sayHelloResponse><br /> </soapenv:Body><br /></soapenv:Envelope></blockquote>
<h3 style="text-align: left;">
Creating some test data</h3>
OK so now we have something to test lets generate some test data. A simple CSV:<br /><blockquote class="tr_bq">
req_firstName, resp_greeting<br />Bob, Howdy Bob<br />Fred, Howdy Fred<br />Mr Jones, Hello Mr Jones<br />Jill, Howdy Jill</blockquote>
<br />The
first line is the name of the properties these will be stored in, the
other lines are the values of those variables. As will become apparent
in a second the groovy is completely generic and doesn't need changing
as it can read any number of values into variables based on the first
line.<br />
<br />
So now we have a service to test and some data we need to setup a test...<br />
<h3 style="text-align: left;">
Configuring the test</h3>
<div style="text-align: left;">
I setup a project with a very simple Test Case. It only has 4 test steps:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge27cgblm-YTm1AwK_3kMCxGxkDv3U7CwnE9MXt3wAtTkb-B3emP3mfqQMyo4mURXeJAVFUPz9unxrNLu5PNhLSP0bjrdrgw5vfaKbH0USYO-tsB9JxxU77b9on5d6VSXOjFguaassbgA/s553/1-steps.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge27cgblm-YTm1AwK_3kMCxGxkDv3U7CwnE9MXt3wAtTkb-B3emP3mfqQMyo4mURXeJAVFUPz9unxrNLu5PNhLSP0bjrdrgw5vfaKbH0USYO-tsB9JxxU77b9on5d6VSXOjFguaassbgA/s320/1-steps.jpg" width="233" /></a></div>
<ol>
<li> A groovy script to load the given values from the file</li>
<li> A soap test step to call the mock web service</li>
<li> A conditional goto step to return to the start</li>
<li> A step called "End" (the name here is important as we'll see below but the step can be of any type - in my case I used a delay test step)</li>
</ol>
The other thing which is needed is some properties in the test case:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJWExPUZAIGZ_bwowifQhceRypba0HZGtDFHx8hdMnBlXPHmzpyb4PNEef9rFFs2RXVOSiWL35K8Pyid1nQmw_U_ogkvaC3Xoa9xDDCCfsJ0i25UezzaWRfHN-3Kg36a7E5LIY9jriHYk/s553/2-properties.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJWExPUZAIGZ_bwowifQhceRypba0HZGtDFHx8hdMnBlXPHmzpyb4PNEef9rFFs2RXVOSiWL35K8Pyid1nQmw_U_ogkvaC3Xoa9xDDCCfsJ0i25UezzaWRfHN-3Kg36a7E5LIY9jriHYk/s320/2-properties.jpg" width="233" /></a></div>
<br />
<ul style="text-align: left;">
<li>TEST_FILE: the name (with path) of the csv file created above</li>
<li>One property for each column in the CSV (with the same name as the header row i,e, req_firstName and resp_greeting)</li>
</ul>
The only property which needs to be named as above is the TEST_FILE as all the others are user defined. <br />
<h4 style="text-align: left;">
1. Groovy </h4>
<blockquote class="tr_bq">
<i> tc = testRunner.testCase;<br /><br />// First run through: initiation<br />if (context.fileReader == null){<br /> log.info ("##Starting Data run... File="+tc.getPropertyValue("TEST_FILE").toString());<br /> context.fileReader = new BufferedReader(new FileReader(tc.getPropertyValue("TEST_FILE")));<br /> line = (String)context.fileReader.readLine();<br /><br /> // Get variable names<br /> context.variableNames = line.split(",");<br />}<br /><br />// Process each line<br />context.valueLine = context.fileReader.readLine();<br /><br />// Data to process: load values<br />if (context.valueLine!=null){<br /> // Assign the parts of the line to the properties<br /> for (int i=0;i<context.variableNames.length;i++){<br /> variable = context.variableNames[i].trim();<br /> value= context.valueLine.split(",")[i].trim();<br /> log.info "Assigning: $variable=$value";<br /> tc.setPropertyValue(variable, value);<br /> }<br />}<br />// No data to process: tidy up<br />else{<br /> context.fileReader.close();<br /> context.fileReader=null;<br /> context.variableNames=null;<br /> testRunner.gotoStepByName("End");<br />}</i></blockquote>
The above can be pasted into a groovy step unchanged for any number of properties read from any csv data file. <br />
<h4 style="text-align: left;">
2. SOAP Test</h4>
My soap test step request contains a reference to the request property:<br />
<blockquote class="tr_bq">
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:examples:helloservice"><br /> <soapenv:Header/><br /> <soapenv:Body><br /> <urn:sayHello soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><br /> <firstName xsi:type="xsd:string"><span style="color: red;"><b>${#TestCase#req_firstname}</b></span></firstName><br /> </urn:sayHello><br /> </soapenv:Body><br /></soapenv:Envelope></blockquote>
The assertion in the test script (of type xpath) checks the response has the right value in it (again based on the csv value.<br />
Declare:<br />
<blockquote class="tr_bq">
declare namespace urn='urn:examples:helloservice';<br />declare namespace soapenv='http://schemas.xmlsoap.org/soap/envelope/';<br />/soapenv:Envelope/soapenv:Body/urn:sayHelloResponse/greeting</blockquote>
Expected Result:<br />
<blockquote class="tr_bq">
${#TestCase#resp_greeting}</blockquote>
<h4 style="text-align: left;">
3. Conditional goto </h4>
The goto step should always go back to the groovy step. When all the rows in the file are completed, the groovy code above will jump to "End" and thus stop the loop - this is why the end test step has to be called "End". In order to make the conditional goto unconditional we just need to make the condition always true - by use of the xpath true() function.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8QE0vqHgFnh9yoYJnBAumGe-USA-_2IteqABolx0nOnQANBGTC8iV7boOXjwdd4vKC3z0CDFYvLHU2JdBD_2URJ2IOxOhJ8XYSbbLMjM-9bQaKc66iPzBDpIg_8ziRJETWQIHrpJPc7I/s547/goto.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8QE0vqHgFnh9yoYJnBAumGe-USA-_2IteqABolx0nOnQANBGTC8iV7boOXjwdd4vKC3z0CDFYvLHU2JdBD_2URJ2IOxOhJ8XYSbbLMjM-9bQaKc66iPzBDpIg_8ziRJETWQIHrpJPc7I/s320/goto.jpg" width="320" /></a></div>
<br />
<h4 style="text-align: left;">
4. End</h4>
Finally the End step is just needed so they groovy script can jump out of the loop. It doesn't matter what this step does so long as there is a step called "End" after the goto step.<br />
<h3 style="text-align: left;">
Running the test</h3>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMdlmlg5Bdx6CSuZ-sQO31PjfTMyousPq8Zg5ZRUk2NtBgEwhGJ0gK6M1Julkwd5qat91ElLZsWxyZYNwyS1hnMX0lun0P_ULWd6memd0sNtJ2SKZquOOucZmEU65a0rQpw7GJlBkadaQ/s611/3-result.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMdlmlg5Bdx6CSuZ-sQO31PjfTMyousPq8Zg5ZRUk2NtBgEwhGJ0gK6M1Julkwd5qat91ElLZsWxyZYNwyS1hnMX0lun0P_ULWd6memd0sNtJ2SKZquOOucZmEU65a0rQpw7GJlBkadaQ/s400/3-result.jpg" width="262" /></a></div>
So as the above shows there were 14 test steps (the first 3 steps executed four times for the four people in the csv, then the first and last steps executed to end the cycle). The request and response variables contain the values of the last line in the file as I didn't clear them. From here I could add more variables to the file or add a different set of tests - each test case is self contained so each one can have a different TEST_FILE property and different variables. Simple.<br />
<br />
If the service didn't give the expected response to one of the values then the soap test step would fail because of the assertion. <br />
<h3 style="text-align: left;">
Licensing</h3>
All the above is open source under the <a href="http://www.gnu.org/licenses/">GPLv3 license</a> without any guarantees or promises, that said it's not very complicated and seems to work well enough - hope it's useful.<br />
<br /></div>
Jameshttp://www.blogger.com/profile/01390650972189795908noreply@blogger.com11tag:blogger.com,1999:blog-4719289417835612786.post-5933730547276346262013-07-01T14:57:00.000-07:002013-07-01T14:57:00.182-07:00Starting SOA - Hints and Tips<div dir="ltr" style="text-align: left;" trbidi="on">
<h1>
</h1>
<h2>
<span style="font-family: inherit;">Introduction</span></h2>
<span style="font-family: inherit;">Building
SOA on solid foundations is really important. I've come across so many
SOA implementations which have kicked off without really considering, or
perhaps just misunderstanding some key concepts of SOA and so making
some mistakes which are difficult to fix in retrospect (especially when a
project is over and the funding is gone). Initially I was going to
write a set of principles for SOA, but this was a bit of a grand title
for an unstructured cooks tour of "stuff I've seen go wrong and how to
avoid them". These cover ground from both the big picture (governance,
standards etc) and low level (how to best construct XSD interfaces) side
of the messaging picture. So in no particular order...</span><br />
<span style="font-family: inherit;"><br /></span>
<h2>
<span style="font-family: inherit;">
1. Make interfaces strict</span></h2>
<span style="font-family: inherit;">One
of the things I come across surprisingly often is the idea that to be
"reusable" an interface should be as lax (as unrestrictive) as possible.
Before we start considering this, it's probably worth defining what I
mean by a lax and a strict interface definition. So ignoring if the data
type below is a good example or not, here’s an example "person" data
type. The first would be a strict interface:</span><br />
<ul>
<li><span style="font-family: inherit;"> <b>Title: </b>Required, Enumeration [Mr, Mrs, Miss, Ms, Dr]</span></li>
<li><span style="font-family: inherit;"> <b>Surname: </b>Required, String (conforming to regular expression ^[a-zA-Z\-\']{2,25}$ - i.e. 2-25 chars in length, containing only letters and hyphens/apostrophes) </span></li>
<li><span style="font-family: inherit;"> <b>Firstname: </b>Optional, String (confirming to regular expression ^[a-zA-Z]{1,25}$ - i.e. 1-25 chars in length, containing only letters)</span></li>
</ul>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">However a lax version would be:</span><br />
<ul>
<li><span style="font-family: inherit;"> <b>Title: </b>Optional string</span></li>
<li><span style="font-family: inherit;"> <b>Surname: </b>Optional string</span></li>
<li><span style="font-family: inherit;"> <b>Firstname: </b>Optional string</span></li>
</ul>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The
differences should be fairly obvious, the lax interface will allow
almost any values, the strict interface is very prescriptive about
exactly what is acceptable.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Although I disagree with the argument
for lax, I'll try to give it a fair hearing. The argument seems to go
something like this: "if we make the interfaces restrictive then we
can't reuse the interface (e.g. with another back-end system, or change
the back end) without having to alter it". Put another way if add a new
system (either with content based routing or to replace the existing
one), and this new system has surnames can be up to 50 chars, or the
title can now include "Admiral", then the lax interface can be reused,
whereas the strict interface can’t. That is indeed true to a point, but
there are some massive disadvantages of a lax interface:</span><br />
<ol>
<li><span style="font-family: inherit;">
Service consumers aren't aware of what is allowed - or if they are it's
in a document, or comments field which has more chance of being ignored
or misunderstood</span></li>
<li><span style="font-family: inherit;"> Neither the service consumer, nor the service
provider can do real-time validation of messages to the level required
to stop errors. In the above lax interface I can validate that the
message passes some values called Title, Surname and Firstname, and that
it doesn't pass something called "Nickname" but that's about it.
Passing in a surname 30 characters long, and a title of "Master of the
Universe" would be perfectly valid according to the interface. Because
it’s valid the message would be passed to the back end system. Given
that this is invalid, it's likely this would cause an error - if the
system doesn't validate the input either, then an error would be created
when you tried to write an overly long string to the database. This
isn't great for several reasons: first the errors are all the way down
in an application log, secondly they might not be easy to identify the
cause as an invalid message (it might look like an internal application
DB error). The back-end may or may not pass an error back to the
consumer and the error might or might not mean anything (e.g. a generic
DB error). None of this is great, but there is also a worse scenario: if
the back end is a creaking old mainframe/or C application which has
fixed length variables. The title variable is 4 characters long (to save
memory because Miss is the longest allowed title), and writing "Master
of the universe" overflows this variable straight into the memory
allocated for something else with unpredictable consequences. That's a
little less likely, but as a rule propagating bad data around the system
is never a good idea when it could be caught at the front door.</span></li>
<li><span style="font-family: inherit;">
One final option. Assuming it's agreed that stopping errors before they
hit the backend is a good idea, there's no reason that you can't do
some validation in the ESB and still have a lax interface. True. There's
no need to encode this in a WSDL/XSD. This would get over the problems
of the errors not occurring in the right place or breaking the back end,
but there are problems here too. If you're doing real-time testing you
have to write some rules rather than just click the "validate" checkbox
in that nice expensive ESB tool you bought. Secondly (and going back to
point 1) the consumer can't validate their messages whilst unit testing
unless they write some complicated test harness (rather than just
generating a mock service from your interface (say in [soapui.org]) -
and who is to say if this test harness is the same as your test code.
This makes unit testing harder and more expensive, and means you'll be
less likely to find errors before link/integration testing - and as the
old adage goes: the earlier you find an error the cheaper it is to fix.
Finally you're losing the supposed benefit of having a lax interface:
the ability to reuse without change as you’d need to change the ESB
rules, and your test harness anyway! </span></li>
</ol>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">There is one last
thing to consider which speaks against the myth of lax interface
benefits. Adding a new backend will almost always have some impact on a
service consumer and/or interface. Change isn’t bad, unmanaged change
is. This all comes to the need for governance (see below). At least if
you've got strict interfaces, you understand what the current state of
play is. If the new system takes 24 character names then you know
there's a problem just be looking at the existing interface, if it takes
30 character names you can either continue as you go (you're just not
using the full length - useful if running two back-ends as you're taking
the lesser of the two) or you can re-version the interface and inform
consumers they can make their surnames longer if they wish to by using
the new version. If you're just taking open strings it's not at all
obvious if this is an issue or not because you've no idea what rules
everyone else is playing by. After all, an interface definition is
merely a contract saying what is required, if a back end system requires
a surname to be there, but you make it optional then all you're doing
is drafting a contract you can’t meet. If a consumer sends a message
with no surname (fulfilling their part of the deal), then rather than
sending back a positive response you send an error - which isn't very
fair.</span><br />
<span style="font-family: inherit;"><br /></span>
<h2>
<span style="font-family: inherit;">
2. Decouple systems don’t just separate</span></h2>
<span style="font-family: inherit;">Decoupling
systems is more than separating them by putting an ESB between them. To
get the benefits of decoupling (reuse, hiding the complexity of
multiple back ends behind a single service, isolating the impact of
change etc) it takes much more than just passing the message through an
ESB. <a href="http://en.wikipedia.org/wiki/Enterprise_service_bus">An ESB</a> <span style="color: red;"><b>is not</b></span> a <a href="http://en.wikipedia.org/wiki/Reverse_proxy">reverse proxy</a>.
I have on more than one occasion seen an architect tell developers to
“just use the XSD from the backend” as the XSD for the front end
(sometimes with a different namespace – sometimes not even that)! Why
you'd do this I'll never know (unless it’s to tick a box saying “I used
the ESB like I was told to”. In order to actually decouple systems, you
need to encapsulate the implementation in a suitable service. It's
always going to be difficult to have truly system independent data
types, but by trying to generalise the interface and considering
carefully what functions are required means you might get some actual
benefit of using an ESB. </span><br />
<span style="font-family: inherit;"><br /></span>
<h2>
<span style="font-family: inherit;">
3. Development standards and libraries</span></h2>
<span style="font-family: inherit;">As
with any component based development it's important to have a view on
how the software will be constructed. This will come from the Technical
Architect or senior developers. Whilst this will be expanded during the
first few projects, even the first services need some guidance about:</span><br />
<ul>
<li><span style="font-family: inherit;"> What are the reusable components in the middleware (e.g. logging service, security module)</span></li>
<li><span style="font-family: inherit;"> What is the structure of development projects, source repository etc</span></li>
<li><span style="font-family: inherit;"> What coding standards will be followed. Depending on the tool this might be based on industry standards (e.g. for <a href="http://www.jboss.org/jbossesb">JBoss ESB</a> the Java standards will be followed). Even if there are some
standards to follow, these will need to be expanded for this SOA
implementation to answer questions like: is the preferred method of
mapping XSL, XPath, or ESQL? What is the naming convention for elements, types and enumerations in XSD/WSDLs? What is the naming convention for queues, namespaces, endpoint URLs?
These don't take a long time to map out, but are worth doing up front
as having each developer coming up with their own way of doing things
just make maintenance difficult. </span></li>
</ul>
<span style="font-family: inherit;"></span><br />
<h2>
<span style="font-family: inherit;">
4. Start your governance early</span></h2>
<span style="font-family: inherit;">T<span style="font-family: inherit;">here are lots of cool governance tools out there, from RegistryRepository
tools, to real-time management and monitoring suites. These allow you
to do real-time service discovery, manage subscribers, throttle services, give differing QoS
to different consumers, and even scale your infrastructure from the
cloud based on demand. It's all very cool stuff. Then again, if you're
just getting started then your first few services don't need any of this
- a few simple and relatively easy to implement governance steps can
pay dividends in allowing you to grow and</span> alter your SOA without running
into trouble, and will allow you to switch to the shiny toys at a later
date.</span><br />
<ol style="text-align: left;">
<li><span style="font-family: inherit;"><b>Governance structure: </b>Setup a governance structure and process, in my experience this is usually two tier:</span></li>
<ul>
<li><span style="font-family: inherit;"><b>Technical board: </b>to sign off designs, approve deviation from standards, discuss and decide on new standards - meets frequently (e.g. every two weeks)</span></li>
<li><span style="font-family: inherit;"><b>Steering group: </b>to set stratigic aims, approve the standards in the first place, manage pipeline etc - meets less frequently (e.g. quaterly)</span></li>
</ul>
<li><span style="font-family: inherit;"><b>Version services: </b>after all, they're going to
change eventually (especially if you've got prescriptive interfaces).
Change isn't a problem, but does need managing. Most SOA toolkits can
happily run multiple versions of the same service along side each other,
so if the service is properly versioned you can upgrade clients one at a
time rather than having a big bang release (or more dangerously
altering a service without a consumer knowing it's going to happen until
it's too late).</span></li>
<li><span style="font-family: inherit;"> <b>Document your services: </b>In addition to the XSD/WSDL each service should have a contract (document, wiki page etc)<b> </b>to define additional data around the service. This can hold non-functional details (e.g. max response time, maximum expected load, maximum message size); invocation details which aren't in the XSD (is this at least one, at most once or exactly once - so is the consumer expected to retry until it gets a reply ot not); another thing of use is a sample message so anyone wanting to use the service can see an example and use the example in their unit testing - this isn't a substitute for strict service definition but can be useful.<b> </b></span></li>
<li><span style="font-family: inherit;"><b>Create a service catalogue: </b>there are a lot of
reasons for a service catalogue and quite a few things to record.
Eventually you can consider adopting a RegistryRepository tool if
your SOA grows to a sufficient size, but to start with a spreadsheet is
usually sufficient. The service catalogue allows people to find existing
services and allows you to manage them. You might want to have two
levels of catalogue: business services (exposed to the world for use
across the enterprise) and technical services (re-used within the ESB
either for common functions like auditing or, as building blocks to make
composite business services). At a minimum every good service catalogue
should include:</span><ul>
<li><span style="font-family: inherit;"> <b>Service name: </b>The logical name of your service</span></li>
<li><span style="font-family: inherit;">
<b>Description:</b> A short description of the service, to allow future
consumers to identify if this is what they're looking for, and so you
can see what you've got before you accidentally build duplicates</span></li>
<li><span style="font-family: inherit;">
<b>Version: </b>The version of this service, this means you can track more
than one version of the same service - the name and description might
not change but the items below will be different between service
versions</span></li>
<li><span style="font-family: inherit;"><b>Consumers: </b>Who uses this version of
the service? This is important as eventually you'll want to turn
services off (an often used rule of thumb is to keep consumers at most
one version behind the latest, and decommission older services). Knowing
who uses a service can ensure you avoid suddenly breaking an important
application who is on an obsolete service version</span></li>
<li><span style="font-family: inherit;"><b>Status: </b>What
phase of the service lifecycle is this service in - there are various
granularities in a service lifecycle but at a high level this generally
looks to be: </span></li>
<ul>
<li><span style="font-family: inherit;">Identified (as a viable/useful service to build)</span></li>
<li><span style="font-family: inherit;">In Development (including analysis, build, test etc)</span></li>
<li><span style="font-family: inherit;">Live (in the production environment)</span></li>
<li><span style="font-family: inherit;">Deprecated
(an old version of a service scheduled for closure - new users
shouldn't start using this version but existing users may still be doing
so </span><span style="font-family: inherit;">whilst planning to upgrade)</span></li>
<li><span style="font-family: inherit;">Closed (retired, deleted, gone)</span></li>
</ul>
</ul>
</li>
</ol>
<h2>
<span style="font-family: inherit;">
5. SOA principles and standards</span></h2>
<span style="font-family: inherit;">In
addition to the development standards (point 3), there are also higher
level architecture standards. These have probably been at least
partially considered when deciding to go down an SOA route, and doing
product selection (i.e. if you've got an ESB and a BPM product there is
presumably a vision for how these will be used), however these can be
expanded to give more technology guidance at a level above that of
development coding standards but below that of the enterprise vision.
These would include things like:</span><br />
<ol>
<li><span style="font-family: inherit;">When to use the SOA: in many large organisations there are a combination of integeration tools for managed file transfer, EAI, and ETL in addition to the ESB. On occasion I've seen "the bus is the answer" mentality creep in. With a step back these are obviously different challenges with widely different use cases but just because the ESB is the tool of the moment doesn't mean it should suddenly be processing overnight runs of terabytes of data. Nor should all interfaces suddenly be rewritten to use the bus if there is no hope of reuse. </span></li>
<li><span style="font-family: inherit;">Messaging approaches (SOAP
vs Rest, JMS/MSMQ/WMQ, when to use queues vs http, when batch is more
appropriate than real-time, should services be WS-I compliant)</span></li>
<li><span style="font-family: inherit;">
Security standards: do services need to be secured, encrypted, can
messages be logged in plain text, how are third parties connected to the
ESB (if they ever can be), how can the internet connect to services?</span></li>
<li><span style="font-family: inherit;">
Components of the SOA: ESB, UDDI server, registry/repository, BPM, etc.
What should be the domain of each product (e.g. what should be composed
in BPEL, and what in BPM). </span></li>
</ol>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Of course as with all
principles these things can be contravened if there's a good reason to
(through the governance process above). An example would be a principle that
"get" services go over HTTP, but "update" messages will go over JMS
(especially if reliability is required). If a system cannot send JMS (say
for firewall reasons) but reliability is still required then for this
service <a class="tiddlyLink tiddlyLinkNonExisting" href="http://en.wikipedia.org/wiki/WS-ReliableMessaging" title="The tiddler 'WS-ReliableMessaging' doesn't yet exist">WS-ReliableMessaging</a>
could be implemented, if reliability wasn't needed then the service could use http and either be retried or not if it when failures occur. In general JMS might make sense for an
organisation using Oracle Service Bus, because it's based on Java and
JMS is generally easier to interact with the WS-ReliableMessaging.</span><br />
<span style="font-family: inherit;"><br /></span>
<h2>
<span style="font-family: inherit;">
6. Service isn't SOAP, SOAP isn't HTTP</span></h2>
<span style="font-family: inherit;">Having
some basic guidance for what to use is a good idea as discussed above,
but there is one myth I have hit on a few occasions so I’ll put it
straight here: SOA doesn't mean SOAP, SOAP doesn't mean you always use
HTTP (it can be sent over JMS or SMTP for example). It may be that when
defining your principles you select SOAP, which is fine (I'm not against
SOAP - see note below), but there may well be times when XML over JMS,
or a JSON REST service would be appropriate. If it looks like I’m
picking a specific example of the wider point from #5, then that’s
because I am. This is just a case of exceptions to a principle, but I
keep seeing people try to make SOAP do everything, or use HTTP for
everything when XML over JMS, or when a binary message would be better.
First the principle shouldn’t just say SOAP over HTTP (unless you never
need reliability, you have a reason not to use a queueing technology, or
because you like the WS-*
extensions) – most SOA architectures need both HTTP and a queue (be it
MSMQ, IBM WMQ or JMS), but furthermore SOAP isn’t the answer to
everything. </span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Note on SOAP: As a slight aside, a lot of people
don’t like SOAP but I do. Not because of the elegance of the
specification (I personally think WSDL is as ugly a standard as you
might expect from a committee), but because there are so many tools
available which can automatically present/consume SOAP messages (e.g.
wsdl2java), or test them (e.g. <a class="tiddlyLink tiddlyLinkNonExisting" href="http://www.soapui.org/" title="The tiddler 'soapui' doesn't yet exist">soapui</a>).
Plus who needs the hassel of writing their own custom standard? I can
see the arguments behind REST, and if you want smaller messages JSON is a
very fine approach. The argument I don't quite understand is that "SOAP
is inefficient". XML is verbose and as such a bit bloated and
inefficient (that’s true), but I don't see that SOAP is any more
inefficient than XML. XML vs JSON I get, but SOAP vs XML? Nope. For the
price of a couple of extra envelope nodes, you get all the
interoperability of the SOAP stack. You don't have to do dynamic
discovery or use the WS header standards if you don't want to. </span><br />
<span style="font-family: inherit;"><br /></span>
<h2>
<span style="font-family: inherit;">
That’s all folks</span></h2>
<span style="font-family: inherit;">Well that rather lengthy selection is my tips for common pit falls of “doing SOA”. Hope it helps.</span></div>
Jameshttp://www.blogger.com/profile/01390650972189795908noreply@blogger.com0tag:blogger.com,1999:blog-4719289417835612786.post-91939211620715358022013-05-31T12:13:00.001-07:002013-05-31T12:13:34.060-07:00XSLTUnit with XSLT2.0 (and without exslt)<div dir="ltr" style="text-align: left;" trbidi="on">
Recently whilst working on a little <a href="http://sourceforge.net/projects/stoix/">XSL project of mine</a>, I came across a rather nifty unit testing suite for XSLT called <a href="http://xsltunit.org/">XSLTUnit</a>. It's a simple way of expressing test conditions for your XSL stylesheet by writing a test style sheet (which xsl:imports the stylesheet it's testing) and expressing a set of assertions. Now this is all well and good (in fact really quite neat) - but when I came to try to use it I came a cropper when using my favourite XSL sandpit <a href="http://kernowforsaxon.sourceforge.net/">Kernow</a>, and also when using the xsl extensions to <a href="http://netbeans.org/">NetBeans</a>. The error I got from Kernow (just so it's indexed on google) was:<br />
<blockquote class="tr_bq">
net.sf.saxon.trans.XPathException: Cannot find a matching 1-argument function named {http://exslt.org/common}node-set(). There is no Saxon extension function with the local name node-set<br />Cannot find a matching 1-argument function named {http://exslt.org/common}node-set(). There is no Saxon extension function with the local name node-set</blockquote>
<br />This is essentially because XSLTUnit uses the exslt extensions, whilst Kernow uses SaxonHE (<a href="http://www.saxonica.com/documentation/index.html#!extensions/functions/exslt">which doesn't support exslt</a>). Quite frankly I'm loathed to pay for SaxonPE/EE just for this, especilly as it restricts anyone else wanting to run the unit tests (which is a recipe for unit testing being ignored). Fortunately in the years since Eric van der Vlist wrote XSLTUnit in 2002, the wonders of XSLT2.0 have burst into the world, and hapilly XSLT2.0 treats results as nodes without the need for the node-set extension.<br /><br />This meant it wasn't a hard job to ammend the XSLTUnit library and sample test sheet to XSLT2.0 and get it working in Kernow (and anything else which is XSLT2.0 aware (given that it came out in 2007 it isn't like it's bleeding edge). This tweaking basically involved taking the exsl attributes out of the stylesheet, changing the stylesheet version from 1.0 to 2.0, and changing "exsl:node-set($nodes1)" to "$nodes1" - it really was that easy.<br />
<br />
Whilst I was at it, I made one other small change to the test xsl sheet (tst_library.xsl is the example from xsltunit.org). This was to apply the sheets to the standard xslt input stream rather than "<i>document('library.xml')/<xpath></i>". I couldn't work out why you'd want to include the name of the input xml in the stylesheet itself as it just cuts down the flexibility to run your unit test with lots of input files. After that it all worked a treat.<br /><br />I did send this back to Eric, but I don't know if he's actively maintaining xsltunit or if he wants to make it xslt 2. Therefore if it's of any use to anyone, I've put this all into a <a href="http://jameslees.net/stuff/xsltunit2.zip">zip for anyone to download</a> - everything except tst_library2.xsl and xslunit2.xsl are the originals from xsltunit.org. The two files with 2 at the end are merely alterations to the same files without the 2 suffix (as described above).<br /><br />
<h4 style="text-align: left;">
Licensing</h4>
<div style="text-align: left;">
As stated on the xsltunit site:<br /></div>
<blockquote class="tr_bq">
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:<br /><br /> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.<br /> The name of the authors when specified in the source files shall be kept unmodified.<br /><br />THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ERIC VAN DER VLIST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</blockquote>
<div style="text-align: left;">
<br />My alternations are made in the same spirit, copyright of all the origional bits remain with Eric van der Vlist 2001, 2003.<br /></div>
</div>
Jameshttp://www.blogger.com/profile/01390650972189795908noreply@blogger.com0tag:blogger.com,1999:blog-4719289417835612786.post-49106745266322432332013-05-17T14:17:00.001-07:002013-05-17T14:17:24.225-07:00Running SOAPui Tests from Jenkins/Hudson/Ant<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div class="western" style="margin-bottom: 0cm;">
<h2 style="text-align: left;">
The challenge</h2>
A while ago I came
across a problem which I suspect has been tackled by a lot of people
over the years: running one/many SOAPUI unit test packs from Jenkins.
So far all the solutions I've seen from the web basically involve
putting an exec call into your ant script, and pointing it at the
testrunner cmd/sh script. This is fine and does work, but below is a
slightly more complete solution which I hope is easy to just drop in
and configure - plus I included some report generation stuff which is useful from a QA audit perspective if anyone wants to check what testing you've been doing.<br />
<br />
<br />
<div class="western" style="margin-bottom: 0cm;">
Essentially this blog
covers a simple ant build script which includes:</div>
<div class="western" style="margin-bottom: 0cm;">
</div>
<ul>
<li><div class="western" style="margin-bottom: 0cm;">
A generic way of
calling soapui from ant (using a re-usable ant macrodef)</div>
</li>
<li><div class="western" style="margin-bottom: 0cm;">
HTML report
generation - generating a junit style html report on the result of
your tests
</div>
</li>
<li><div class="western" style="margin-bottom: 0cm;">
A command line so
you can invoke the build script and enter the test to
run (although the only reason you'd not do this from the soapUI GUI is if you wanted
the html report for a single test suite).</div>
</li>
<li><div class="western" style="margin-bottom: 0cm;">
An “all”
target (far more useful) which can be configured to run all the
tests in the test suites, and can be invoked from Jenkins (which is
sort of the point).</div>
</li>
</ul>
<br />
<h2 style="text-align: left;">
Getting Started</h2>
<div class="western" style="margin-bottom: 0cm;">
</div>
<div class="western" style="margin-bottom: 0cm;">
Before
we get going I assume you have (or need to get) the following:</div>
<ol>
<li><div class="western" style="margin-bottom: 0cm;">
<a href="http://soapui.org/"> SoapUI</a>: I originally wrote the script using
soapUI 3.6.1 so I know it's good to go with that version and
presumably any version since.</div>
</li>
<li><div class="western" style="margin-bottom: 0cm;">
<a href="ttp://ant.apache.org">Apache Ant</a>: If you wish to generate test reports
you need version 1.5 or higher.</div>
</li>
<li><div class="western" style="margin-bottom: 0cm;">
<a href="http://sourceforge.net/projects/ant-contrib/">AntContrib</a>:
v0.3 or higher to be added to your ant lib folder.</div>
</li>
</ol>
<div class="western" style="margin-bottom: 0cm;">
To
start with there's a <a href="http://jameslees.net/stuff/SoapuiWithAnt.zip">simple zip of stuff </a>to be working with. It
includes:</div>
<ol>
<li><div class="western" style="margin-bottom: 0cm;">
build.xml -<b> </b>A sample ant build file – this is the crux of
everything we'll look at.</div>
</li>
<li><div class="western" style="margin-bottom: 0cm;">
VerySimpleProject – a soap UI project with 2 test suites
</div>
</li>
<li><div class="western" style="margin-bottom: 0cm;">
VerySimpleProject2 – another soap UI project with a single test
suite</div>
</li>
<li><div class="western" style="margin-bottom: 0cm;">
junit-noframes.xsl – a modified verison of the xsl which comes
with ant but has been altered to make it work better with the SOAPUI</div>
</li>
</ol>
<br />
<h2 style="text-align: left;">
Making build.xml your own</h2>
<h3 style="text-align: left;">
Configuuring Properties</h3>
<div>
The xml file has a number of properties which need to be configured specific to your environment and/or project. They are:</div>
<div>
<ul style="text-align: left;">
<li><b>jar.soapui: </b>The name of the soapui JAR file, which is sadly version specific</li>
<li><b>dir.soapui: </b>Self explanatory really, this is the directory soapui is in on the machine running ant</li>
<li><b>dir.temp: </b>a directory to store temporary files created during the execution. This is created upon build and <b>deleted once the run has completed</b>, so make sure it's specific to this purpose and not c:\. Generally ./temp is good enough so shouldn't need to be changed</li>
<li><b>dir.reports: </b>a directory where the report outputs are stored (this needs to exist before the script is run)</li>
<li><b>dir.xsl: </b>the directory the custom xsl for generating reports is stored in, this is by default ./xsl which shouldn't need to be altered</li>
<li><b>java.executable: </b>the full path to java on this machine</li>
<li><b>test.report.title: </b>The title placed at the top of your output report (passed as a parameter to the report generating xsl)</li>
</ul>
</div>
<h3 style="text-align: left;">
Configuring build all</h3>
<div>
Once these are set, you're nearly ready to go. All you need to do is say which tests to run. The best way of doing this is to put all the tests in the "all" target and then ant will invoke them all each time. Due to the naming convention I was using at the time this assumes a default test suite called "Full Test" and as such if you don't specify a suite name it will default to that. If you want to call other test suites you just need to name them. This can be seen in the all target example below:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-a-zc5C8r82ADaH9JtJphCPkOg1hnEhz5YMxih9R8O_43N80jIzr6VTngYRG1v4O66y2CcYnIGJjh5JL5vLG9tUMkpB5NPRQ6imHItkte1P2lVUk0nDhvL4H3Q-PFXXB2cVeg0kBkW2g/s1600/antall.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-a-zc5C8r82ADaH9JtJphCPkOg1hnEhz5YMxih9R8O_43N80jIzr6VTngYRG1v4O66y2CcYnIGJjh5JL5vLG9tUMkpB5NPRQ6imHItkte1P2lVUk0nDhvL4H3Q-PFXXB2cVeg0kBkW2g/s1600/antall.jpg" /></a></div>
<div>
<br /></div>
<div>
So this calls:</div>
<div>
<ol style="text-align: left;">
<li>clean - a general tidy up target and creation of the temporary directory (dir.temp)</li>
<li>runTest macro - as no suiteName property is passed to defaults to "Full Test".</li>
<li>calls runTest with a different suite from the same sample project</li>
<li>calls runTest with a suite from a second soapui project</li>
<li>calls the report target. The report target:</li>
<ul>
<li>generates a single html report covering all the tests which have been run (since the last clean - step 1 in this case) </li>
<li>zips up the test runner output log/error files - in case a test fails and you want to look at these detailed logs</li>
<li>Sets the names of both the zip and the html to include the date and time the ant script started running - this is just so subsequent runs don't overwrite it</li>
</ul>
<li>calls tidyup to delete the log directory and a couple of the soapui files left over from the job.</li>
</ol>
<h3 style="text-align: left;">
Default target</h3>
<div>
The default target of the build.xml is "test" which will expect keyboard inputs for the name of the project file (without the .xml on the end) and the test suite. This can occasionally be useful if you want to test and report on a single report, however you might find it more useful to set the project default from test to all.</div>
<div>
<br /></div>
<div>
Really that's all you need to know to get this up and running... but just for completeness I'll do a quick tour of the runTest macro and the reports target if you're interested in understanding the nuts and bolts. If not then you're ready to go.</div>
</div>
<div>
<br /></div>
<h2 style="text-align: left;">
What's under the covers?</h2>
<h3 style="text-align: left;">
Run Test</h3>
<div>
The run test macro essentially invokes soapui, but rather than calling the cmd/sh script to do it it does it directly (hence the need to know where java was in the properties steps above). Most of this is quite obvious from looking at the code and you can play with the output, and the max memory should you need to. </div>
<div>
<br /></div>
<div>
The macro does pass a number of arguments to soapUI, which are explained on <a href="http://www.soapui.org/Test-Automation/functional-tests.html">their website</a>. Of these we only use:</div>
<div>
<ul style="text-align: left;">
<li>a to ensure verboseness in the output of errors</li>
<li>j to tell soapui to generate the xml which gets turned into the html report</li>
<li>s to tell it the name of the test suite to run</li>
<li>f to say where to put the outputs</li>
</ul>
<div>
Optionally, if you have any properties which are used in your tests (in our case we had a jdbc connection string as a property) you can get ant to pass these in, that way you can externalise these for running on different environments without the need to change your test scripts. These can be set for the developers environment within the soapUI project, and then ant will merely overwrite them on the continuous integration environment - cool huh?</div>
</div>
<div>
<br /></div>
<div>
Finally there's some tidy up in renaming the outputs to ensure that two project files with the same test suite name (e.g. Full Test) won't overwrite each other.</div>
<h3 style="text-align: left;">
Reports </h3>
<div>
The reports target is very simple, which is largely because it uses the standard junitreport functionality, and because most of the work I did here was hacking the xslt to be more soapUI friendly (describing that is too big a job for today). </div>
<div>
<br /></div>
<div>
Essentially it grabs the xml files for all the test suites run since last clean (each renamed to be unique by the runTest macro above) and runs the junit-noframes.xsl on them. Unlike the standard ant one, the xsl now has three parameters:</div>
<div>
<ul style="text-align: left;">
<li>runDateTime (because unlike java SoapUI doesn't include this in the output xml)</li>
<li>resultsFile - which means the html can have some text to say which zip contains the full logs</li>
<li>title - the title of the html report</li>
</ul>
<div>
Finally, all the logs are zipped into a file in the reports folder, and the html is moved from the temp folder to the reports folder, as it would be a shame for the tidyup job to delete it after we've only just created it.</div>
</div>
<div>
<br /></div>
<h2 style="text-align: left;">
Licensing</h2>
<div>
...and finally: </div>
<div>
<br /></div>
<div>
The <i>junit-noframes.xsl</i> is under the<a href="http://www.apache.org/licenses/LICENSE-2.0"> apache 2.0 license</a> - and my updates to it fall under the same.</div>
<div>
The custom <i>build.xml</i> is open source under the <a href="http://www.gnu.org/licenses/">GPLv3 license</a> - hope it's useful.</div>
<div>
<br /></div>
</div>
</div>
Jameshttp://www.blogger.com/profile/01390650972189795908noreply@blogger.com6