This document discusses Ingenuity's transition to a service-oriented architecture for its software applications. Some key points:
- Ingenuity collects biological data and develops applications like IPA to analyze data for researchers.
- They identified benefits of SOA like code reuse, scalability, and faster releases. They defined service categories and a high-level architecture with services for content, algorithms, user management, and views.
- Implementation involved defining modules, packages, and components. Services use Spring remoting and a custom service discovery manager. Versioning and stability zones allow services at different lifecycle stages.
- Testing uses FitNesse for automated integration testing in a continuous integration environment. This validates
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Â
Svcc services presentation (Silicon Valley code camp 2011)
1. Proprietary and Confidential Learning to Love Services Experiences from the Transition to a Service-oriented Architecture Jeff Green Staff Software Engineer
3. Proprietary and Confidential 3 Ingenuity Systems Collect large curated, computable knowledge base of biological information Molecules (genes, chemicals) Relationships between molecules Pathways Biological processes Develop software applications to leverage knowledge base for researchers Ingenuity Pathways Analysis (IPA) iReports Next Generation Sequencing application
7. Proprietary and Confidential 7 Technologies Client: Swing-based primary client with some browser-based visualizations Server: Multi-tier Java web application in Tomcat and Jetty servlet containers Oracle database
8. Proprietary and Confidential 8 Legacy Architecture Servers separated for scalability Communicate through multicasting Early notion of services except: Significant overlap of code and data access Tightly coupled build, package, deployment Entire system released quarterly
9. Proprietary and Confidential 9 Why move toService-oriented Architecture? Code/data reuse Single definition of services and model objects Common implementation More precise scalability Scale only parts of system under stress More rapid releases Push new features and fixes out to customers faster Simplify testing Separation of responsibilities Untangle unnecessary dependencies Reduce learning curve of code
10. Proprietary and Confidential 10 Constraints IPA enhancements must continue simultaneously Changes cannot impact Production system prematurely Majority of engineering resources still focused on new development Homogeneous implementation All services will be in Java, although external clients may be Swing or browser-based. Majority of services will be private Existing public apis will remain but are exception
11. Proprietary and Confidential 11 Key Considerations High-level architecture What parts of the system should be services? Implementation How is a service defined? Communication How will consumers interact with providers? Versioning How can changes be managed? Testing How can quality be ensured?
13. Proprietary and Confidential 13 Architecture Questions What existing capabilities should become separate services? What is the responsibility of each service? What data does each service own? What are the dependencies? No circularity How granular should the system be? If too granular, hard to maintain If not granular enough, lose benefits of services (reuse, scalability, modularity, etc.)
14. Proprietary and Confidential 14 Ingenuity Service Categories Key Driver: Reuse functionality to reduce development cost and enforce consistency Biological content Provide biological content from a single source in a consistent model Algorithms Optimized for executing algorithms on data User management User records Authentication/authorization Account creation License management
15. Proprietary and Confidential 15 Ingenuity Service Categories (cont.) Views of biological entities Common rendering for reports of all biological information about a molecule, chemical, etc. Utilities Event tracking Document generation
19. Proprietary and Confidential 19 Strategy Adopt a common nomenclature, ideally somewhat similar to existing system Define simple, brief standards to guide development and ensure consistency Code organization Server directory structure For each service, pick best implementation approach Implement from scratch Customize third-party application Refactor existing code
20. Proprietary and Confidential 20 What exactly is a service anyway? A set of operations available to consumers Defined by an Application Programming Interface (API): the set of operations and the data structures that serve as their input and output Java implementation: an interface and the model objects (Plain Old Java Objects, POJOs) that serve as arguments and return values
21. Proprietary and Confidential 21 Module Encapsulates one or more related services and their implementations Source code: API, business logic, data access XML and property files Web resources Test code (both unit and integration) Vertical slice of functionality Improved modularity, reuse Buildable unit resulting in <module>.jar and other artifacts Existed in previous architecture, albeit different in nature
22. Proprietary and Confidential 22 Module Source Packages Defined new basic package structure to organize code within modules Consistency helps with finding, understanding code
23. Proprietary and Confidential 23 Module Directories Defined new basic directory structure to organize resources within modules Consistency helps with finding resources Simplifies tools
24. Proprietary and Confidential 24 Component Encapsulates one or more modules for packaging/deployment (i.e. a releasable unit) In practice, one per JVM Unit of scale and redundancy Owner of modules and schemas Biological Content Component Molecule Module Finding Module Graph Module Graph Service Molecule Service Finding Service Notation Service
25. Proprietary and Confidential 25 Why have a module? In smaller components, component = single module In larger components, additional unit of encapsulation helps to further modularize the code Clarifies code organization Forces consideration of dependencies Package boundaries not inherently enforced An attempt to fight spaghetti
26. Proprietary and Confidential 26 Tactics: Rebuild or Refactor? Rebuild where existing approach was not sufficient New licensing schemes SSO authentication (CAS implementation) Refactor where behavior should not change significantly Content, algorithms, views Changes must not impact ongoing enhancements Rebuilt components have no immediate impact Refactor on separate branch; schedule merge at appropriate time
27. Proprietary and Confidential 27 Build, Package, Deploy Before Ant script built entire system at once All components deployed together across multiple JVMs After Modified ant script builds a single component Resulting component package is union of resources in modules it owns Each component deployed separately Current Tools Hudson used to manage build/package tasks Custom installer
29. Proprietary and Confidential 29 Considerations How does a consumer locate a service provider? Once found, what is protocol for communication? Requirements Consumers and providers must be loosely coupled Flexibility to add providers without impacting consumers and vice-versa Synchronous communication is acceptable
30. Proprietary and Confidential 30 Spring Remoting Already in use in existing application Abstract data transfer from consumer and provider Provides flexibility to switch from remote to local services through configuration GraphService GraphAlgorithm GraphServiceImpl getGraph(id) GraphObj Within single component
31. Proprietary and Confidential 31 Spring Remoting Already in use in existing application Abstract data transfer from consumer and provider Provides flexibility to switch from remote to local services through configuration GraphService GraphAlgorithm GraphService HttpService HttpProxy GraphServiceImpl URL from configuration getGraph(id) getGraph(id) Http request w/ serialized objects GraphObj GraphObj Http response w/ serialized objects Across components
32. Proprietary and Confidential 32 Service Discovery Manager (SDM) Simple, custom utility provides a single (logical) point for service discovery Provider registers service Consumer requests service location SDM ServerA Algorithm Component
33. Proprietary and Confidential 33 Service Discovery Manager (SDM) Simple, custom utility provides a single (logical) point for service discovery Provider registers service Consumer requests service location SDM Provider registers at startup GraphService @ServerB ServerB ServerA Content Component Algorithm Component GraphService
34. Proprietary and Confidential 34 Service Discovery Manager (SDM) Simple, custom utility provides a single (logical) point for service discovery Provider registers service Consumer requests service location SDM 1a) Consumer requests service location GraphService @ServerB ServerB ServerA GraphService Content Component Algorithm Component GraphService
35. Proprietary and Confidential 35 Service Discovery Manager (SDM) Simple, custom utility provides a single (logical) point for service discovery Provider registers service Consumer requests service location SDM 1b) SDM responds with location GraphService @ServerB ServerB ServerA Content Component ServerB Algorithm Component GraphService
36. Proprietary and Confidential 36 Service Discovery Manager (SDM) Simple, custom utility provides a single (logical) point for service discovery Provider registers service Consumer requests service location SDM GraphService @ServerB ServerB ServerA Content Component Algorithm Component GraphService 2a) Consumer requests service directly from ServerB
37.
38.
39. Proprietary and Confidential 39 api.jar Consumers and providers must share api definition <module>-api.jar encapsulates module service interfaces and model object classes Built/published along with component providing the service Consumer picks up published jar at build time
41. Proprietary and Confidential 41 Change is Inevitable A service is defined by API, which will change over time Consumers and providers may change at different rates Goal is to minimize impact of change on consumers
42. Proprietary and Confidential 42 Types of Service Changes Implementation only No change to API; therefore no impact on consumer API addition New method or member in model object API change or deletion Service contract has changed
43. Proprietary and Confidential 43 Version Label <major>.<minor>.<build> <build> = implementation change Updated every build (svn revision number) No impact on consumer <minor> = API addition All releases with same major version are backward compatible Consumer of older service can ignore <major> = API change Consumer must adapt
44. Proprietary and Confidential 44 Usage during Service Discovery Api.jar stamped with specific version Consumer includes versioned api when built Consumer requests service with specific version SDM finds provider with = major version and >= minor version Multiple versions can coexist ServerC ServerA ServerB SDM Content Component Content Component Algorithm Component GraphService2.2 @ServerB GraphService2.3 GraphService 2.2 GraphService2.2 GraphService2.3 @ServerC ServerB or ServerC
45. Proprietary and Confidential 45 Usage during Service Discovery Api.jar stamped with specific version Consumer includes versioned api when built Consumer requests service with specific version SDM finds provider with = major version and >= minor version Multiple versions can coexist ServerC ServerA ServerB SDM Content Component Content Component Algorithm Component GraphService2.2 @ServerB GraphService2.3 GraphService 2.3 GraphService2.2 GraphService2.3 @ServerC ServerC
46. Proprietary and Confidential 46 Java Serialization Id Every Java class has serialization id Assigned by compiler or programmer Intent is to identify change If unspecified, API model object will get new id with every change Potentially breaks backwards compatibility of minor version change Solution is to specify id for all model objects
47. Proprietary and Confidential 47 Stability Level Need to separate components at different stages of lifecycle Ongoing development should not impact testing and demos Versioning not sufficient because only reflects API changes
48. Proprietary and Confidential 48 Option: Duplicate Environments Duplicate entire system for each stage of stability
49.
50.
51. Proprietary and Confidential 51 Full Service Discovery Protocol Discovery protocol involves three pieces of info Service name (i.e. full interface name) Version Zone Same SDM instance can be used across all zones ServerB ServerA SDM GraphService2.3 Stable GraphService2.3 Stable@ServerB Algorithm Component ServerC GraphService2.3 Test@ServerC GraphService 2.3 Stable GraphService2.3 Test GraphService2.3 Dev@ServerD ServerB ServerD Dev GraphService2.3
53. Proprietary and Confidential 53 Goals Ensure component meets contract defined by API Opportunity for more granular testing No user interface available Critical for individual release cycles Ensure component is backwards compatible Test component as a whole âUnit testâ where component is the testable unit Not comfortable relying solely on class unit tests Requires realistic data Automate test execution Enable more frequent updates with less cost
54. Proprietary and Confidential 54 FitNesse Framework for writing, organizing, and executing tests Acts as a consumer of the component under test Tests written in wiki-like syntax in browser client Classes called Fixtures transform data to/from API model objects Results are displayed and history is maintained
55.
56. Package includes api jars of the service it tests, just like other consumers of the service
57.
58. Proprietary and Confidential 57 CI in Practice Stable Stable Test FitNesse CI Content Component Component is implemented in a Dev zone Dev
59. Proprietary and Confidential 58 CI in Practice Stable Stable Component is built and deployed in the CI zone Test FitNesse CI Content Component Dev
60. Proprietary and Confidential 59 CI in Practice Stable Stable Component tests are deployed to the FitNesse server Test FitNesse CI Content Component Dev
61. Proprietary and Confidential 60 CI in Practice Stable Stable Tests are executed against the component Test FitNesse CI Content Component Dev
62. Proprietary and Confidential 61 CI in Practice If tests pass, component is promoted to Stable zone Stable Stable Test FitNesse CI Content Component Dev
63. Proprietary and Confidential 62 CI in Practice Stable Stable Test FitNesse CI Content Component Algorithm Component Consumers use services in the Stable zone, even during development and testing Dev
64. Proprietary and Confidential 63 CI in Practice Consumers go through the same CI workflow to be promoted to Stable Stable Stable Test FitNesse CI Content Component Algorithm Component Dev
65. Proprietary and Confidential 64 CI in Practice The process is initiated automatically once per day and the steps are automated from build to Stable promotion. Builds are still manually released to Production for now. Stable Stable Test FitNesse CI Content Component Algorithm Component Dev
66. Proprietary and Confidential 65 Backwards Compatibility Services must be backwards compatible Support consumers of all previous minor versions Ensures provider can be updated independently of consumer To validate, execute test bundles built with previous minor versions Confirms previous contract is still met Confirms api jars are still compatible
68. Proprietary and Confidential 67 Successes New applications utilized services immediately Enabled teams to focus on new innovation Previously code/capability had to be duplicated Apps used services even before IPA did Faster, more frequent releases Legacy system previously updated quarterly User management service now updated within iteration (< 2 weeks) Fixes released within a couple hours More modular code base Consistency in code structure, server layout Several servers smaller than before Improved startup time Now feasible to run/debug within IDE
69. Proprietary and Confidential 68 Challenges and Do-overs Difficult to overhaul so many aspects of the system simultaneously Major version in API package names Potentially results in âfalse positiveâ change to significant numbers of files 20% case complicated the 80% case Jar dependencies Attempt at simplification ended up being more difficult
70. Proprietary and Confidential 69 Next Steps Recently achieved milestone of porting legacy application to use services it spawned Improve service APIs, possibly rewrite Feasible now that components have clearly defined boundaries Improve test coverage Performance testing of individual components Understand load profiles to guide scalability decisions Transition to standard tools maven puppet
71. Proprietary and Confidential 70 Key Takeaways Identify early what is necessary and what is not; focus on what is necessary Take incremental steps where possible Important for remaining agile Establish simple patterns or standards to follow in implementation, packaging, and testing Helps with tools creation, understanding of system Be flexible Try new approaches and process; adapt if first try does not work out
72. Proprietary and Confidential 71 Questions? Jeff Green Staff Software Engineer Ingenuity Systems www.ingenuity.com Slides available at: http://www.slideshare.net/jenlwong/svcc-services-presentation-201110 Photo Credits: Petronas Towers: Franco Pecchio (Ai@ce, flickr.com); Coffee beans: Al Gebra (photl.com); Telegraph: Bill Bradford (mrbill, flickr.com); Chimp: Afrika Expeditionary Force (flickr.com); Mug shot: Jimmy Prescott (flickr.com); Crash test: NASA (everystockphoto.com); Trophies: Roberto Arias (Ariaski, flickr.com)