SOA enables agility as compared to a monolithic software solution or other tightly coupled approaches. An application can make use of one or more services, and the services may in turn use other services. Services are stateless and loosely coupled with platform independent interfaces.
For large software designs, this architecture is absolutely a great idea. However, Conway's Law
tells us that software architecture can mimic organization structure. One can observe very similar effects in the case of SOA. Organizations grow around services, with each organizational unit responsible for one or more services.
This can give rise to complicated interaction between teams with different priorities and success criteria. A new functionality will frequently require new capabilities from one or more services. Let's explore ways to handle such dependencies while running Scrum.
Scrum in SOA
The project includes all service teams.
In this case, just use the Scrum of Scrums. Since teams handling all of the involved services and applications are part of the project, they can all come together a few times a week for a Scrum of Scrums. It's relatively easy to align priorities to the project.
The project depends on other Agile teams.
The first step here is to recognize that even the nicest teams working on different priority lists are not the same as teams working on the same project.
The project depends on non-Agile teams.
Create a product backlog as early as possible.
Start backlog grooming sessions; create and maintain dependency lists in the grooming sessions.
Work with other teams to add dependencies as deliverables in their backlogs.
Move stories up/down in the product backlog as their dependencies become available.
The need to synchronize with non-Agile teams adds another level of complexity. Cycle times may be significant. Let's assume that our project needs new functionalities a, b, and c from services A, B, and C. The best way is to create stubs for test and integration.
Create a product backlog for My Project.
Create and maintain a dependency list for the product backlog.
Create stubs to simulate all services that the project depends on.
Add dummy functionality to simulate the dependencies until they become available.
Yeah! That's easier said than done. Who would create a dummy service? We may not even have the skills on our team or the budget to spend time on this. A little bit of creativity may help. Here are some ideas:
Consider creating a virtual machine (VM) and run a copy of the service in the VM. Another way to create a stub is to record interactions with a service and then use the request-response pairs to create a proxy/stub for the service. Now point the project or application under development to use the stub.
If the service owners can provide test data also, it will be best. In case the service owners can't, then we could try using the stubs only for the new functionalities a, b, and c.
Once the new functionalities (dependencies) are available, add a story to update paths and test with the actual services.
In SOA, services are stateless. Calls to SOA service are input-output pairs. Adding new calls to a stubbed service involves defining new input-output pairs, which is not very effort intensive.
Getting test data may pose a challenge, which needs a custom solution. Random data generators may help, and in some cases it may be possible to use a copy of production data.
It's a good practice to always have an internal version of every service. In terms of dollars, the virtual machines should almost always be cheaper than longer test cycles and extended delivery times
In a large setup using SOA, it may be complicated to effect any change. There may also be other issues beyond software agility and cost. So we should instead strive for closer cooperation and openness.
Each team will make available an easy modifiable version of its service for internal test.
The service team will separate test data from service so it survives even if the code is messed up.
The service team will provide clean and simple documentation on how to add new calls to the service stub.