Patterns

  • submit to reddit

Continuous Integration

Patterns and Anti-patterns

By Paul Duvall

25,667 Downloads · Refcard 84 of 151 (see them all)

Download
FREE PDF


The Essential CI Patterns Cheat Sheet

Continuous Integration is the process of building software with every change committed to a projects version control repository. CI can be explained via patterns (i.e., ineffective approaches used to “fix” the specific problem) and anti-patterns associated with the process. This DZone Refcard will walk you through 40 different Patterns and Anti-patterns associated with CI and expands the notion of CI to include concepts such as Deployment and Provisioning. The end result is learning whether you are capable of delivering working software with every source change.
HTML Preview
Continuous Integration: Patterns and Anti-Patterns

Continuous Integration: Patterns and Anti-Patterns

By Paul M. Duvall

ABOUT CONTINUOUS INTEGRATION

Continuous Integration (CI) is the process of building software with every change committed to a project's version control repository.

CI can be explained via patterns (i.e., a solution to a problem in a particular context) and anti-patterns (i.e., ineffective approaches sometimes used to "fix" the particular problem) associated with the process. Anti-patterns are solutions that appear to be beneficial, but, in the end, they tend to produce adverse effects. They are not necessarily bad practices, but can produce unintended results when compared to implementing the pattern.

Continuous Integration

While the conventional use of the term Continuous Integration generally refers to the "build and test" cycle, this Refcard expands on the notion of CI to include concepts such as Deployment and Provisioning. The end result is learning whether you are capable of delivering working software with every source change.

Pattern Run a software build with every change applied to the Repository
Anti-Patterns scheduled builds, nightly builds, building periodically, building exclusively on developer's machines, not building at all

BUILD SOFTWARE AT EVERY CHANGE

A CI scenario starts with the developer committing source code to the repository. There are four features required for CI.

  • A connection to a version control repository
  • An automated build script
  • Some sort of feedback mechanism (such as e-mail)
  • A process for integrating the source code changes (manual or CI server)

ci flow diagram

Pattern Description
Private Workspace Develop software in a Private Workspace to isolate changes
Repository Commit all files to a version-control repository
Mainline Develop on a mainline to minimize merging and to manage active code lines
Codeline Policy Developing software within a system that utilizes multiple codelines
Task-Level Commit Organize source code changes by task-oriented units of work and submit changes as a Task Level Commit
Label Build Label the build with unique name
Automated Build Automate all activities to build software from source without manual configuration
Minimal Dependencies Reduce pre-installed tool dependencies to the bare minimum
Binary Integrity For each tagged deployment, use the same deployment package (e.g. WAR or EAR) in each target environment
Dependency Management Centralize all dependent libraries
Template Verifier Create a single template file that all target environment properties are based on
Staged BuildsRun remote builds into different target environments Run remote builds into different target environments
Integration Build Perform an Integration Build periodically, continually, etc.
Continuous Feedback Send automated feedback from CI server to development team
Expeditious Fixes Fix build errors as soon as they occur
Developer Documentation Generate developer documentation with builds based on checked-in source code
Independent Build Separate build scripts from the IDE
Single Command Ensure all build and deployment processes can be run through a single command
Dedicated Machine Run builds on a separate dedicated machine
Externalize Configuration Externalize all variable values from the application configuration into build-time properties
Tokenize Configuration Token values are entered into configuration files and then replaced during the Scripted Deployment
Protected Configuration Files are shared by authorized team members only
Scripted Database Script all database actions
Database Sandbox Create a lightweight version of your database
Database Upgrade Use scripts and database to apply incremental changes in each target environment
Automated Tests Write an automated test for each unique path
Categorize Tests Categorize tests by type
Continuous Inspection Run automated code analysis to find common problems
Build Threshold Use thresholds to notify team members of code aberrations
Deployment Test Script self-testing capabilities into Scripted Deployments
Scripted Deployment All deployment processes are written in a script
Headless Execution Securely interface with multiple machines without typing a command
Unified Deployment Create a single deployment script capable of running on different platforms and target environments
Disposable Container Automate the installation and configuration of Web and database containers
Remote Deployment Use a centralized machine or cluster to deploy software to multiple target environments
Environment Rollback Provide an automated Single Command rollback of changes after an unsuccessful deployment
Continuous Deployment Deploy software with every change applied to the project's version control repository
Single-Command Provisioning Run a single command to provision target environment
Decouple Installation Separate the configuration from the installation

PATTERNS AND ANTI-PATTERNS

Version Control

The patterns in this section were originally described in the book Software Configuration Management Patterns (Addison-Wesley, 2003, Berczuk and Appleton), except for 'Label Build':

Pattern Description
Private Workspace Prevent integration issues from distracting you, and from your changes causing
Repository All files are committed to version-control repository - in the deployment context, all of the configuration files and tools.
Mainline Minimize merging and keep the number of active code lines manageable by developing on a Mainline
Codeline Policy The policy should be brief, and should spell out the "rules of the road" for the codeline

Task-Level Commit

Pattern Organize source code changes by task-oriented units of work and submit changes as a Task Level Commit. (from SCM Patterns)
Anti-Patterns Keeping changes local to developer for several days and stacking up changes until committing all changes. This often causes build failures or requires complex troubleshooting.

Label Build

Pattern Label the build with unique name so that you can run the same build at another time.
Anti-Patterns Not labeling builds, Using revisions or branches as "labels."

<path id="svn.classpath">
  <fileset dir="${lib.dir}">
   <include name="**/*.jar" />
  </fileset>
</path>
<taskdef name="svn" classpahref="/sites/all/modules/dzone/assets/refcardz/084/svn.classpath" classname="org.tigris.subversion.svnant.SvnTask"/>
<target name="create-tag-from-trunk">
	
<svn username="jhancock" password="S!gnhere">
  <copy srcUrl="https://brewery-ci.googlecode.com/svn/trunk"
   <destUrl="https://brewery-ci.googlecode.com/svn/tags/brewery-1.0.0"
    <message="Tag created by jhancock on ${TODAY}" />
 </svn>
</target>

Build Management

Automated Build

Pattern Automate all activities to build software from source without manual configuration. Create build scripts that are decoupled from IDEs. Later, these build scripts will be executed by a CI system so that software is built at every change.
Anti-Patterns Continually repeating the same processes with manual builds or partially automated builds requiring numerous manual configuration activities.

<?xml version="1.0" encoding="iso-8859-1"?>
<project name="brewery" default="all" basedir=".">
  <target name="clean" />
  <target name="svn-update" />
  <target name="all" depends="clean,svn-update"/>
  <target name="compile-src" />
  <target name="compile-tests" />
  <target name="integrate-database" />
  <target name="run-tests" />
  <target name="run-inspections" />
  <target name="package" />
  <target name="deploy" />
</project>

Minimal Dependencies

Pattern Reduce pre-installed tool dependencies to the bare minimum. Eliminate required environment variables from the Automated Build and Scripted Deployment.
Anti-Patterns Requiring developer to define and configure environment variables. Require developer to install numerous tools in order for the build/deployment to work.

install JADS diagram

Binary Integrity

Pattern For each tagged deployment, the same deployment package (e.g. WAR or EAR) is used in each target environment.
Anti-Patterns Separate compilation for each target environment on the same tag.

install JADS diagram

Dependency Management

Pattern Centralize all dependent libraries to reduce bloat, classpath problems, and repetition of the same dependent libraries and transitive dependencies from project to project.
Anti-Patterns Multiple copies of the same JAR dependencies in each and every project. Redefining the same information for each project. Classpath hell!

Tools such as Ivy and Maven can be used for managing dependencies.

projects diagram

Consistent Directories

Pattern Create a simple, yet well-defined directory structure to optimize software builds and increase cross-project knowledge transfer.
Anti-Patterns Putting code, documentation and large files in the same parent directory structure, leading to long-running builds.

Template Verifier

Pattern Create a single template file that all target environment properties are based on.
Anti-Patterns Use manual verification, trial and error (when deployment fails, check the logs),or keeping files "hidden" on a machine.

Template Verifier diagram

Staged Builds

Pattern Using the Remote Deployment pattern, run remote builds into different target environments
Anti-Patterns Deploying directly to production

Build Practices

Private Build

Pattern Verify your changes will not break the Integration Build by performing a Private Build prior to committing changes to the Repository.
Anti-Patterns Checking in changes to version-control repository with running a build on developer's workstation.
Build Configuration

Integration Build

Pattern Ensure that your code base always builds reliably by doing an Integration Build periodically
Anti-Patterns "Works on My Machine" (WOMM). Continuous Compilation.

Continuous Feedback

Pattern Sending automated feedback from CI server to development team.
Anti-Patterns Minimal feedback, which prevents action from occurring. Receiving spam feedback, which causes people to ignore messages.
Examples Email, RSS, SMS, X10, Monitors, Web Notifiers

Expeditious Fixes

Pattern Fix build errors as soon as they occur.
Anti-Patterns Build entropy - problems stack up causing more complex troubleshooting and some claim that "CI" is the problem.
Fix broken builds immediately Although it is the team's responsibility, the developer who recently committed code must be involved in fixing the failed build
Run private builds To prevent Integration failures, get changes from other developers by getting the latest changes from the repository and run a full integration build locally, known as a Private Build
Avoid getting broken code If the build has failed, you will lose time if you get code from the Repository. Wait for the change or help the developer(s) fix the build failure and then get the latest code

Developer Documentation

Pattern Generate developer documentation with builds (at appropriate intervals)based on checked-in source code.
Anti-Patterns Developer documentation is manually generated, periodically. This is both a burdensome process and one in which the information becomes useless quickly because it does not reflect the checked-in source code.

Automating your documentation's generation will help you keep it up to date and thereby make it more useful for your software's users.

SchemaSpy


<property name="reports.dir" value="${basedir}"/>
<java jar="schemaSpy_3.1.1.jar" output="${reports.dir}/output.log"
error="${reports.dir}/error.log" fork="true">
  <arg line="-t mysql"/>
  <arg line="-host localhost"/>
  <arg line="-port 3306"/>
  <arg line="-db brewery"/>
  <arg line="-u root"/>
  <arg line="-p sa"/>
  <arg line="-cp mysql-connector-java-5.0.5-bin.jar"/> <arg line="-o
${reports.dir}"/>


Note: 'Private Build' and 'Integration Build' are also from Berczuk and Appleton's book Software Configuration Management Patterns (Addison-Wesley, 2003, Berczuk Staged Builds and Appleton)

Build Configuration

Independent Build

Pattern Separate build scripts from the IDE. Create build scripts that are decoupled from IDEs. Later, these build scripts will be executed by a CI system so that software is built at every change.
Anti-Patterns Automated Build relies on IDE settings. Build cannot run from the command line.

Build Configuration diagram

Single Command

Pattern Ensure all build and deployment processes can be run through a single command. This makes it easier to use, reduces deployment complexities and ensures a Headless Execution of the deployment process. Deployers, or headless processes, can type a single command to generate working software for users.
Anti-Patterns Some deployment processes require people to enter multiple commands and procedures such as copying files, modifying configuration files, restarting a server, setting passwords, and other repetitive, error-prone actions.

Single-command deployment execution using Ant:


ant-Dproperties.file=$USERHOME/projects/petstore/properties/devinstall.
properties deploy:remote:install

Dedicated Machine

Pattern Run builds on a separate dedicated machine.
Anti-Patterns Existing environmental and configuration assumptions can lead to the “but it works on my machine problem.”

When creating an integration build machine consider the following:

Recommended system resources Increase hardware resources for an integration build machine rather than wasting time waiting for slow builds.
All software assets in the version control repository See the Repository pattern.
Clean environment CI process removes any code dependencies on the integration environment. Automated build must set test data and any other configuration elements to a known state.

Externalize Configuration

Pattern All variable values are externalized from the application configuration into build-time properties.
Anti-Patterns Some hardcode these values, manually, for each of the target environments, or they might use GUI tools to do the same.

Example properties that are external to application-specific files:


authentication.type=db
application.url=http://${tomcat.server.hostname}:${tomcat.server.port}/brewery-webapp
database.type=mysql
database.server=localhost
database.port=3306
database.name=mydb
database.user=myuser!
database.password=mypa$$!
database.url=jdbc:mysql://${database.server}:${database.port}/${database.name}
tomcat.server.hostname=localhost
tomcat.server.name=default
tomcat.web.password=pa$$123!
tomcat.cobraorb.port=12748

Tokenize Configuration

Pattern Token values are entered into configuration files and then replaced during the Scripted Deployment based on Externalized Configuration properties checked into Repository.
Anti-Patterns Target-specific data is entered into configuration files in each environment.

Protected Configuration

Pattern Using the repository, files are shared by authorized team members only.
Anti-Patterns Files are managed on team members' machines or stored on shared drives accessible by authorized team members.

Protected Configuration diagram

Database

Pattern Script all database actions.
Anti-Patterns Late and manual migration of a database in the development cycle is painful and expensive.

Script all DDL and DML so that database changes can be run from the command line. Use a version-control repository to manage all database-related changes. (i.e. refer to the pattern)


<target name="db:create" depends="filterSqlFiles" description="Create the database definition">
   <sql driver="com.mysql.jdbc.Driver"
   url="jdbc:mysql://localhost:3306/"
   userid="root"
   password="root"
   classpahref="/sites/all/modules/dzone/assets/refcardz/084/db.lib.path"
   src="/sites/all/modules/dzone/assets/refcardz/084/${filtered.sql.dir}/database-definition.sql" delimiter="//"/>
</target>

Database Sandbox

Pattern
  • Create a lightweight version of your database (only enough records to test functionality)
  • Use this lightweight DML to populate local database sandboxes for each developer
  • Use this data in development environments to expedite test execution
Anti-Patterns Shared development database.

Give each developer, tester or test user a separate database instance. Install a lightweight database server in each user's test environment (e.g., MySQL, Personal Oracle), which can be installed on the user's private workstation, on a shared test server, or on a dedicated “virtual server” running on a shared server.

Database Upgrade

Pattern Use scripts and database to apply incremental changes in each target environment, which provides a centrally managed and scripted process to applying incremental changes to the database.
Anti-Patterns Manually applying database and data changes in each target environment

Running a custom SQL file from a LiquiBase change set:


build.xml
<updateDatabase changeLogFile="db.change.xml"
driver="org.apache.derby.jdbc.EmbeddedDriver" url="jdbc:derby:brewery" username="" password="" dropFirst="true" classpahref="/sites/all/modules/dzone/assets/refcardz/084/project.class.path"/>
db.change.xml
<changeSet id="1" author="phenry">
  <sqlFile path="insert-data.sql"/>
</changeSet>

Testing and Code Quality

Automated Tests

Pattern Write an automated test for each unique path.
Anti-Patterns Not running tests, no regression tests, manual testing
Examples

A Simple Unit Test
public void setUp() {
beerService = new BeerDaoStub();
}
public void testUnitGetBeer() {
Collection beers = beerService.findAll();
assertTrue(beers != null && beers.size() > 0);
}
Running a Unit Test in Ant
<junit fork="yes" haltonfailure="true" dir="${basedir}" printsummary="yes">
   <classpath refid="test.class.path" />
   <classpath refid="project.class.path"/>
   <formatter type="plain" usefile="true" />
   <formatter type="xml" usefile="true" />
   <batchtest fork="yes" todir="${logs.junit.dir}">
     <fileset dir="${test.unit.dir}">
       <patternset refid="test.sources.pattern"/>
     </fileset>
   </batchtest>
</junit>

Categorize Tests

Pattern Categorize tests by type and your builds become more agile, tests can be run more frequently, and tests no longer take hours to complete.
Anti-Patterns Tests take hours to run, leading to excessive wait times and increased expense.

Continuous Inspection

Pattern Run automated code analysis to find common problems. Have these tools run as part of continuous integration or periodic builds.
Anti-Patterns Long, manual code reviews or no code reviews.

Examples:

CheckStyle


<taskdef resource="checkstyletask.properties" classpath="${checkstyle.jar}"/>
<checkstyle config="${basedir}/cs-rules.xml" failOnViolation="false">
  <formatter toFile="${checkstyle.data.file}" type="xml" />


    <fileset casesensitive="yes" dir="${src.dir}" includes="**/*.java" />
</checkstyle>
<xslt taskname="checkstyle"
in="${checkstyle.data.file}"
out="${checkstyle.report.file}"
style="${checkstyle.xsl.file}" />

Build Threshold

Pattern Notify team members of code aberrations such as low code coverage or high cyclomatic complexity. Fail a build when a project rule is violated. Use continuous feedback mechanisms to notify team members.
Anti-Patterns Manual code reviews. Learning of code quality issues later in the development cycle.

<module name="CyclomaticComplexity">
  <property name="max" value="10"/>
</module>


Deployment Test

Pattern Script self-testing capabilities into Scripted Deployments.
Anti-Patterns Deployments are verified by running through manual functional tests that do not focus on deployment-specific aspects. No deployment tests are run..

The table below describes examples of the types of test that might be run as part of a Deployment Test smoke suite.

Example Test Type Description
Database Write an automated functional test that inserts data into a database. Verify the data was entered in the database.
Simple Mail Transfer Protocol (SMTP) Write an automated functional test to send an e-mail message from the application.
Web service Use a tool like SoapAPI to submit a Web service and verify the output.
Web container(s) Verify all container services are operating correctly.
Lightweight Directory Access Protocol (LDAP) Using the application, authenticate via LDAP.
Logging Write a test that writes a log using the application's logging mechanism.

Deployment

Scripted Deployment

Pattern All deployment processes are written in a script.
Anti-Patterns Manually installing and configuring a Web container. Use of the GUI-based administration tool provided by the container to modify the container based on a specific environment.

<available file="@{tomcat.home}/server/@{tomcat.server.name}/bin"
   property="tomcat.bin.exists"/>
<if>
   <isset property="tomcat.bin.exists"/>
<then>
   <echo message="Starting tomcat instance at @{tomcat.home} with start_tomcat" />
<exec executable="@{tomcat.home}/server/@{tomcat.server.name}/bin/start_tomcat"
   osfamily="unix" />
 </then>
 <else>
   <echo message="Starting tomcat instance at @{tomcat.home} with startup.sh" />
<exec osfamily="unix" executable="chmod" spawn="true">
   <arg value="+x" />
   <arg file="@{tomcat.home}/bin/startup.sh" />
   <arg file="@{tomcat.home}/bin/shutdown.sh" />
  </exec>
  <exec executable="sh" osfamily="unix" dir="@{tomcat.home}/bin" spawn="true">
<env key="NOPAUSE" value="true" />
<arg line="startup.sh" />
</exec>
    <exec osfamily="windows" executable="cmd" dir="@{tomcat.home}/bin" spawn="true" >
     <env key="NOPAUSE" value="true" />
      <arg line="/c startup.sh" />
    </exec>
    <sleep seconds="15" />
    </else>
</if>

Headless Execution

Pattern Securely interface with multiple machines without typing a command.
Anti-Patterns People manually access machines by logging into each of the machines as different users; then they copy files, configure values, and so on.

Build invironment diagram

Unified Deployment

Pattern Create a single deployment script capable of running on different platforms and target environments.
Anti-Patterns Some may use a different deployment script for each target environment or even for a specific machine.

Unified Deployment diagram

Disposable Container

Pattern Automate the installation and configuration of Web and database containers by decoupling installation and configuration.
Anti-Patterns Manually install and configure containers into each target environment.

Unified Deployment diagram

Disposable Container

Pattern Automate the installation and configuration of Web and database containers by decoupling installation and configuration.
Anti-Patterns Manually install and configure containers into each target environment.

Disposable Container diagram

Remote Deployment

Pattern Use a centralized machine or cluster to deploy software to multiple target environments.
Anti-Patterns Manually applying deployments locally in each target environment.

Remote Deployment diagram

Environment Rollback

Pattern Provide an automated Single Command rollback of changes after an unsuccessful deployment.
Anti-Patterns Manually rolling back application and database changes.

Environment Rollback diagram

Continuous Deployment

Pattern Deploy software with every change applied to the project's version control repository.
Anti-Patterns Deploying periodically. Manual deployments. Manual configuration of target environments.

Single-Command Provisioning

Pattern Run a single command or click a button to provision target environment.
Anti-Patterns Numerous manual and error-prone steps, often performed by other teams, leading to delays and target environment inconsistencies making errors difficult to troubleshoot.

Decouple Installation

Pattern Separate the configuration from the installation.
Anti-Patterns Saving off preconfigured images whose configuration has not been automated.

About The Author

Photo of author Paul M. Duvall

Paul M. Duvall

Paul M. Duvall is the CEO of Stelligent, a firm that helps clients create production-ready software every day. A featured speaker at many leading software conferences, he has worked in virtually every role on software projects: developer, project manager, architect, and tester. He is the principal author of Continuous Integration: Improving Software Quality and Reducing Risk (Addison-Wesley, 2007) and a 2008 Jolt Award Winner. Paul contributed to the UML 2 Toolkit (Wiley, 2003), wrote a series for IBM developerWorks called "Automation for the People", and contributed a chapter to No Fluff Just Stuff Anthology: The 2007 Edition (Pragmatic Programmers, 2007). He is passionate about automating software development and release processes and actively blogs on IntegrateButton.com and TestEarly.com.

Some of the concepts and material in this Refcard were adapted from:

Recommended Book

Continuous Integration

For any software developer who has spent days in "integration hell," cobbling together myriad software components, Continuous Integration: Improving Software Quality and Reducing Risk illustrates how to transform integration from a necessary evil into an everyday part of the development process. The key, as the authors show, is to integrate regularly and often using continuous integration (CI) practices and techniques.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.

SOA Patterns Refcard Available - Download Now

SOA patterns describe common architectures, implementations, and their areas of application to help in the planning, implementation, deployment, operation, and ongoing management and maintenance of complex systems. The patterns in this refcard are classified...

1 replies - 7513 views - 01/04/09 by Jill Tomich in Articles

SOA Patterns

By Eugene Ciurana

29,112 Downloads · Refcard 38 of 151 (see them all)

Download
FREE PDF


The Essential SOA Patterns Cheat Sheet

Service-Oriented Architecture (SOA) patterns describe common architectures, implementations, and their areas of application to help in the planning, implementation, deployment, operation, and ongoing management and maintenance of complex systems. The patterns in this DZone Refcard are classified into four major groups, and listed in alphabetical order within each group. Each pattern includes a Pattern name, Icon, Summary, Problem, Solution, Application, Diagram, Results, and Examples. This Refcard also covers SOA Fundamentals, Pattern Language, Basic Service Patterns, Architectural Patterns, Compound Patterns, and more.
HTML Preview
SOA Patterns

SOA Patterns

By Eugene Ciurana

ABOUT SOA PATTERNS

SOA patterns describe common architectures, implementations, and their areas of application to help in the planning, implementation, deployment, operation, and ongoing management and maintenance of complex systems.

SOA FUNDAMENTALS

Fundamentals

Systems are described as services independent of the underlying technology
Services are implemented through messaging.
A SOA involves service providers and service consumers.
Any participating system may act as either a provider or a consumer depending on the application's workflow.
Services and messages are stateless.
Services and consumers are often implemented in different programming languages, execute in different run-time environments, or both.
SOA involves the services themselves, a directory of available services in some form (service discovery), and public contracts for consumers to connect and use each service (service negotiation).

SOA differs from client/server architecture in that services are universally available and stateless, while client/server requires tight coupling among the implementation participants.

SOA implementation must provide consistent designs that leverage the target environment; design consistency is attained through the application of the eight SOA principles. Service must provide:

1. Normalized service contract.
2. Loose coupling between consumers and services, and between the services themselves.
3. Abstraction from implementation details; the consumers only know the contract without worrying about implementation details.
4. Ability to compose other services regardless of the complexity of the composition.
5. Run-time environment autonomy.
6. Statelessness.
7. Reusability.
8. Discoverability through meta data or public contract definitions.

These principles guide the SOA patterns described in the rest of this refcard.

PATTERN LANGUAGE

Pattern Language

Each pattern includes a Pattern name, Icon, Summary, Problem, Solution, Application, Diagram, Results, and Examples.

The icon and diagram symbols were selected for their ease of whiteboard use and availability in most diagramming tools.

The patterns in this guide are classified into four major groups, and listed in alphabetical order within each group. A complete example appears at the end of this guide showing how to combine various patterns to describe a system.

BASIC SERVICE PATTERNS

These are the building blocks of more complex patterns.

Aggregator

Combines individual messages to be handled as a single unit.

Aggregator

Problem Stateless messages will not arrive at the service endpoint in a predetermined sequence. Messages may be processed by different services at different speeds and messages will arrive at an endpoint out of order. SOA systems guarantee message delivery but not delivery order.
Solution Define an aggregator that receives a stream of data and groups related messages as a single entity for delivery to an endpoint for further processing. Aggregators are stateful intermediate processing units but deliver atomic payloads in a stateless manner.
Application Group messages flowing through a service bus based on payload type or common attributes for further routing and processing.
Results Flexibility in implementation because individual service providers can process data asynchronously without concern about state or sequence, delegating this to a workflow engine or to aggregators running in the SOA infrastructure.

Service Bus

A communications channel for message delivery from a single inbound endpoint to one or more outbound endpoints and optional "on the fly" message processing as data flows through the bus.

Service Bus

Problem Applications must communicate among them, some times using different protocols and technologies. Naïve implementations rely on point-topoint or hub-and-spoke, dedicated conduits that increase complexity, implementation time, and integration difficulty due to tight coupling between components.
Solution Provide a data- or protocol-neutral conduit with abstract entry and exit points for interconnecting applications independently of their underlying technology.
Application Heterogeneous system integration, legacy and new system interoperability, protocol abstraction.
Results Message-Oriented Middleware (MOM): publish/subscribe queuing and enterprise service buses.

Dynamic Routing

An efficient mechanism for dispatching messages to one or more destinations based on configurable, non-filtering rules applied to the message payload.

Dynamic Routing

Problem Routing messages through a distributed system based on filtering rules is inefficient because messages are sent to every destination’s filter and router for inspection and rules resolution, whether the message could be processed or not.
Solution Define a message router that includes both filtering rules and knowledge about the processing destination paths so that messages are delivered only to the processing endpoints that can act upon them. Unlike filters, message routers do not modify the message content and are only concerned with message destination.
Application Message dispatching based on application-specific data elements such as customer attributes, message type, etc.
Results Better overall message delivery and processing performance at the cost of increased delivery system complexity since the router must implement both knowledge of the destinations and heuristic, arbitrary rules. Excellent for decoupling applications by removing routing information from discrete systems.

Event-Driven Consumer

A setup that delivers messages to a services provider as soon as they appear on the channel.

Event-Driven Consumer

Problem Messaging systems based on blocking listeners or polling use unnecessary resources or idle for no good reason if the channel is starved. The message target blocks threads that the service could otherwise use for other tasks.
Solution Implementation of a bus-based or application-specific callback mechanism that’s invoked only if a message appears in its inbound channel. The messaging system may invoke the callback asynchronously or synchronously.
Application Distributed systems with a varying set of consumers and service providers with varying degrees of CPU usage based on message payload; atomic transaction processing systems that require large scalability independent of the number of service consumers.
Results Message processing is single-threaded scaling linearly with the number of dispatched messages. Threads consume messages as they become available and free up resources when done, to be reactivated when another message becomes available. Better run-time resource utilization.

Filter

A conduit that extracts data from a message or applies a function to it as it flows between consumers and services through a messaging channel.

Filter

Problem A need to implement flexible message processing between systems in a platform-independent manner and without introducing system dependencies or unnecessary coupling.
Solution Implement conduits with a simple inbound/processing/outbound interface modeled after a function or pipe that facilitates composition of daisy-chained filters by allowing data transfers from the output of one filter to the input of the next. All filters, regardless of their internal structure, must share the same external interface to facilitate integration and recombination.
Application Use of discrete functions on messages like encryption, data consolidation, redundancy elimination, data validation, etc. Filters split larger processing tasks into discrete, easy to manage units that can be recombined for use by multiple service providers.
Results Filters eliminate data and dependencies by uniform defining a contract (inbound/outbound interface) that encourages reusability through composition. Filters are also interchangeable components that enable different workflow functionality without changing the filter itself.

Router

A general mechanism for dispatching messages to one or more destinations based on configurable rules or filters applied to message payloads.

Router

Problem An application must connect with one or more application endpoints without coupling itself with any of them.
Solution Use a conduit that allows configurable delivery rules based on the message payload, data filters, or content type. Routing may be sequential (endpoints receive the payload one after another) or in parallel (all endpoints receive the payload at virtually the same time).
Application Content delivery in service buses, message dispatching, message proxies, enterprise integration applications, and other systems where messages must be delivered to endpoints following a sequence of applying a rule set.
Results The router abstraction is in use in all modern SOA systems in some forms, whether available in queuing or bus-based systems out of the box, or implemented in custom-made applications and message delivery systems because they provide an elegant and simple mechanism for systemindependent message delivery.

Translator or Transformer

A mechanism for converting a message payload from one representation to another as it flows through the messaging system.

Translator or Transformer

Problem Heterogeneous systems integration (legacy, in-house, and vendorprovided) may use different message representation for input or output.
Solution Provide a system-independent mechanism for altering the message payload and metadata (envelope) prior to delivery to an application endpoint.
Application Message translation at the application endpoint because these translations are system- or protocol-dependent, unlike filters which are generic.
Results Translators are one of the most effective message transformation mechanisms because they allow application developers and integrators to insulate, implement, test, and maintain these system components without modifying existing application workflow or business logic.

ARCHITECTURAL PATTERNS

Architectural patterns reflect solutions specific to common design issues in the definition of service-oriented system implementations.

Asynchronous Processing

A mechanism for queuing messages between one or more endpoints to decouple processing time and resources for each stage.

Asynchronous Processing

Problem Synchronous processing may result in poor server performance and reduced reliability.
Solution Consumers exchange messages with the services through a processing queue that decouples front-end (message capture) from the back-end (processing); messages arrive into the queue at a rate different from that of processing.
Application Any application that requires independent scalability of the front- and back-end functionality such as mainframe data consolidation (back-end) of e-commerce order fulfillment (front-end, middleware).
Results Processing queues are well-understood and scale horizontally or vertically, depending on the application requirements. Plenty of open-source and commercial implementations, and several reference implementations and APIs are available.

Bridge

A mechanism for connecting two or more applications over a common data path, each using a different protocol and in which messages may require processing or analysis as they flow between endpoints for routing.

Bridge

Problem Application endpoints may reside in different parts of the enterprise network, use different protoocls, or may require processing based on specific message attributes.
Solution Define a bridge between applications that provides a mechanism for routing messages, filtering them, and transform them.
Application SOA proxies between application endpoints on the cloud and application endpoints in the middleware or back-end; ESB processing.
Results Good for extending applications by focusing development only on intermediate processing between system and using existing systems as-they-are. Bridging allows easy integration of legacy and SOA systems.

Cross-Service Operation

A mechanism for coordinating multiple run-time activities which together comprise a service with guaranteed completion or roll-back capabilities.

Cross-Service Operation

Problem Two or more services, possibly running across multiple systems, must complete successfully; if one or more fail all the services associated with it and the application response must roll-back to their previous state for maximum application integrity.
Solution Granular services may be wrapped in another service that provides integrity checks and ensures successful completion or graceful degradation, if any, if the granular services fails.
Application Transactional systems.
Results May require a transaction processor (commercial, potential vendor lock-in) wrapper to collaborate with the rest of the SOA infrastructure; consumes more resources to preserve original state for each granular service in case roll-back is necessary.

Event-Driven Dispatching

A mechanism for routing messages to consumers in response to specific events in the SOA or triggered by specific applications running in the SOA.

Event-Driven Dispatching

Problem Consumers must process messages as they become available in a system but polling for such messages is inefficient.
Solution The consumers are implemented as reentrant, blocking applications that subscribe to a coummuniations channel. The consumers remain dormant until an event or message awakens them; the SOA dispatches the message or event in response to system or application states.
Application Publish/subscribe systems to support asynchronous processing applications.
Results Event-driven dispatching is hard to implement in cross-service operations. This pattern is better applied to granular services, or to treat a crossservice operation as a black box by ignoring the intermediate steps involved in the operation.

Process Aggregation

A method of combining two or more non-sequential, inter-dependent processing steps.

Process Aggregation

Problem Multiple services may be required to complete an operation but not all are known at design time, the sequence may vary depending on changing business rules, and it's not necessary to successfully complete all granular processing successfully (i.e. it requires no transactional capability).
Solution A processing service executes the granular service calls, maintains internal state, determines processing steps, and provides synchronous or asynchronous service responses to the consumers.
Application Systems that require multiple processes running in parallel but are not transactional, or have a mix of transactional and non-transactional components.
Results Process aggregation provides integration flexibility but it's hard to manage. Break it down into smaller application clusters (cross-service operations or aggregations) down functional lines, synchronicity requirements, or any other criteria.

Routing and Filtering

A formal mechanism for routing messages to application endpoints between endpoints.

Routing and Filtering

Problem Messages must be dispatched to various applications based on their payload, attributes, protocol, or all of these.
Solution Provide a formal mechanism for routing messages by recursive definition of filter, one or more routers, filters, routers, and so on.
Application Rules-based processing, workflow, event-driven dispatchers
Results The recursive nature of the definitions simplifies management. Naïve implementaters some times define filters or routers without formalizing their order, resulting in unintentional application coupling or resource exhaustion due to excessive use of filters or routers, respectively.

Replicator

Messages or payloads must be replicated across multiple endpoints with identical configurations.

Replicator

Problem Decoupled, horizontally scalable services get stuck in a bottleneck caused by shared access to a common message pool or data source.
Solution Message or data replication features are implemented as part of the SOA message flow so that independent applications or endpoints may consume them in parallel.
Application Read-only data resources or messages flowing through the SOA to increase throughput.
Results Additional cost, complexity management if replicators are allowed to proliferate unchecked. Excellent way of providing scalability when the replicators are confined to specific problem domain service paths.

COMPOUND PATTERNS

Compound patterns aggregate the basic patterns to define a cohesive representation of a system. Patterns are never used in isolation, nor are they a goal by themselves. A subsystem may be built around two or more patterns. This section shows how the basic patterns defined earlier in this refcard can be combined into more sophisticated system descriptions.

Centralized Schema

Defines a method of sharing schemas across application boundaries to avoid redundant data representation and service definition.

Centralized Schema

Problem Similar data sets must be processed by services or applications with different capabilities, resulting in unwieldy service contracts or data schemas.
Solution Define rich data schemas as entities that are separate from the service contracts and from the physical manifestation of the data as it flows through the system.
Application Any contract-first web services, regardless of implementation technology (JMS, SOAP, other) in which more than one system will transmit, transform, process, or store data.
Results Easy to implement if the developers make a conscious decision to separate the schema from the services where it's used. A good centralized schema implementation can generate different format definitions that, although incompatible with one another all have a 1:1 mapping to the data model.

Concurrent Contracts

Method for allowing multiple consumers with different abstractions or implementations to simultaneously consume the same service.

Concurrent Contracts

Problem The service contract may not be suitable for all the services potential consumers.
Solution Multiple contracts may exist for the same service, each with a different level of abstraction than the others in the same group, to fit corresponding service level agreements or to accommodate legacy systems.
Application Problem domains where various consumers need must process different subsets of the same data, like a customer master or a stock tracking system.
Results Easy to implement if it's based on a centralized schema and it uses automated transformers or rule-based systems for generating each application contract; it may become unwieldy if the application contracts are manually generated or managed instead of handled by the centralized schema or an automated catalogue.

Decomponse Capability

A way of designing services to reduce the impact of functional deconstruction if it becomes necessary due to bloat or evolution of business processes and workflow.

Decomponse Capability

Problem A service may need decomposition without altering its core functionality, including the service's contract itself.
Solution Maintain physical separation of the data schemas from the services definition, combining them only for generating specific service implementations, so that data and services may change independently of one another. Define evolutionary service changes in terms of the existing services and basic patterns like filtering, routing, and transformations.
Application Evolution of large, mission-critical systems which provide additional functionality as business requirements are implemented. Any application where incremental features built into a service result in bloat or performance bottlenecks.
Results Capability decomposition almost always results in the definition of a new service topology that supports the original functionality for legacy or older consumers while providing new functionality or additional features as needed. Decomposition should be transparent to the consumers but lead to modular service design and implementation.

Enterprise Service Bus

A communications channel for message delivery from a single inbound endpoint to one or more outbound endpoints and provides protocol handling, message filtering, transformation, and routing, and optional "on the fly" message processing.

Enterprise Service Bus

Problem Applications must communicate among them, some times using different protocols and technologies. Naïve and legacy implementations rely on point-to-point, dedicated conduits that increase complexity, implementation time, and integration difficulty due to tight coupling between components.
Solution Provide a data- or protocol-neutral conduit with abstract entry and exit points for interconnecting applications independently of their underlying technology.
Application Enterprise integration, heterogeneous system integration, legacy and new system interoperability, protocol abstraction.
Results The emergence of a family of products that implement this concept under the guise of Message-Oriented Middleware (MOM): publish/ subscribe queuing and enterprise service buses.

Fault-Tolerant Service Provider

Mechanism for deploying a service platform to achieve near-zero downtime in case one of the services providers or the platform itself have a catastrophic failure.

Fault-Tolerant Service Provider

Problem Mission-critical applications are the main candidates for SOA implementations and must provide appropriate fault-tolerance and recovery in case of catastrophic failure.
Solution Provide redundant service containers and message brokers complemented by network-level load balancing and routing; ensure that application services are stateless and re-entrant when possible.
Application Services in fast growing, high-availability environments with near-zero downtime service level agreements.
Results Easy to implement for stateless services. This pattern may be used for providing both scalability and fault-tolerance.

Wrapper

Encapsulate a legacy service API inside a generic, stateless service.

Wrapper

Problem Legacy systems may offer limited service capabilities, or their only interface with other applications may be through file data exchanges or legacy APIs.
Solution Wrap the interoperation mechanisms within a service façade that operates with the legacy system as if it were a legacy consumer, and exposes a normalized SOA interface to new consumers.
Application Integration with legacy mainframe or client/server systems to expose their capability to new services and consumers.
Results Many legacy client/server applications are tightly coupled and even a wrapper may not be enough to expose their capabilities as a service. Extensive rewrites may be required or a service may offer only readonly capabilities. If reimplementation is necessary, then implement as a stateless service and draw a migration plan to phase out the existing legacy service or system.

About The Author

Photo of author Eugene Ciurana

Eugene Ciurana

Eugene Ciurana is an open-source evangelist who specializes in the design and implementation of mission-critical, high-availability large scale systems. As Director of Systems Infrastructure for LeapFrog Enterprises, he and his team designed and built a 100% SOA-based system that enables millions of Internet-ready educational hand held products and services. As chief liaison between Walmart.com Global and the ISD Technology Council, he led the official adoption of Linux and other open-source technologies at Walmart Stores Information Systems Division.

Publications

  • Developing with the Google App Engine
  • Best Of Breed: Building High Quality Systems, Within Budget, On Time, and Without Nonsense
  • The Tesla Testament: A Thriller

Website

http://eugeneciurana.com

Recommended Book

Book cover

SOA Design Patterns is the de facto catalog of design patterns for SOA and service-orientation. The 85 patterns in this full-color book provide the most successful and proven design techniques to overcoming the most common and critical problems to achieving modern-day SOA.


Share this Refcard with
your friends & followers...

DZone greatly appreciates your support.


Your download should begin immediately.
If it doesn't, click here.