«Jo˜o Coutinho dos Santos Roxo Neves a Disserta¸ao para obten¸˜o do Grau de Mestre em c˜ ca Engenharia Inform´tica e de Computadores a J´ ri u ...»
On Preserving Domain Consistency for an Evolving
Jo˜o Coutinho dos Santos Roxo Neves
Disserta¸ao para obten¸˜o do Grau de Mestre em
Engenharia Inform´tica e de Computadores
Presidente: Prof. Doutor M´rio Rui Fonseca dos Santos Gomes
Orientador: Prof. Doutor Jo˜o Manuel Pinheiro Cachopo
Vogal: Prof. Doutor David Manuel Martins de Matos
Julho de 2011
The work of this master thesis dissertation was carried out with the support and inspiration of several people. I would like to thank everyone in the ESW Software Engineering Group, especially my advisor, Professor Jo˜o Cachopo, to whom I owe his guidance and determination. Much of the quality a of this work was achieved thanks to the sharing of his knowledge, and his decisive thoughts on the subject.
I would also like to thank my current work colleagues at the F´nix Project: Luis Cruz, Susana e Fernandes, Ricardo Rodrigues, Pedro Santos, S´rgio Silva, Artur Ventura, and former colleagues Paulo e Abrantes, and Jo˜o Figueiredo. For their encouragement, a few friends from younger years deserve a a special cheer: Bruno Almeida, Cl´udio Diniz, S´rgio Gomes, Carlos Jacinto, Jo˜o Lemos, Diogo Oliveira, a e a Filipe Paup´rio, Inˆs Perdig˜o, Jo˜o Reis, and David Seixas.
e e a a Last but never least, a special mention for their understanding and unending conﬁdence goes to Luisa and Paulo, without whom none of this work would have been possible.
Lisboa, July 14, 2011 Jo˜o Coutinho dos Santos Roxo Neves a Resumo Muitos dos sistemas de informa¸˜o existentes s˜o aplica¸˜es empresariais, orientadas ao dom´ ca a co ınio, que manipulam um grande volume de dados complexos. Tipicamente, estes sistemas mantˆm os dados orgae nizados segundo um denso grafo de objectos que devem satisfazer complexas regras de consistˆncia. A e F´nix Framework permite ao programador de
Many of today’s existing information systems are domain-intensive enterprise applications that manage and store vast volumes of complex data. Typically, these systems keep their data organized as a graph of highly interrelated objects, which must satisfy complex domain consistency rules. The F´nix Framework e allows the programmer to deﬁne consistency rules, by implementing consistency predicates that objects must satisfy. The framework uses these predicates to verify the consistency of the data, as it changes over time.
Even though the F´nix Framework already supported consistency predicates before, it did not take e into account the aspects of data persistence and incremental development, both of which are common in enterprise applications. In fact, these applications evolve over time, often with incompatible changes on their behavior and consistency rules, and still always need to preserve their data. Thus, it is crucial for the framework to verify the consistency of the data, as the code changes over time.
This dissertation describes a few extensions to the F´nix Framework, which relies on atomic actions e at the programming language level to implement consistency predicates. It shows why persistence and incremental development make the task of verifying these rules so diﬃcult, and proposes pragmatical solutions to address these issues.
In particular, with this proposal, the framework becomes aware of changes within consistency rules:
it is able to detect both new and old rules, and takes action accordingly. Also, it supports inconsistency tolerance to help in establishing new consistency rules on already existing, and possibly inconsistent data.
Finally, it gives the programmer explicit and structured information about the existing inconsistencies within the data.
Palavras Chave Consistˆncia dos Dados e Regras de Consistˆncia e Invariantes Persistˆncia dos Dados e Tolerˆncia a Inconsistˆncias a e Altera¸oes de Regras c˜ An´lise de Impacto de Altera¸˜es a co Keywords Data Consistency Consistency Rules Invariants Data Persistence Inconsistency Tolerance Rule Changes Change Impact Analysis Contents
Introduction To satisfy their clients’ needs, software companies design enterprise applications that manipulate large volumes of complex data. This data is composed of many small interrelated parcels of important information, which only make sense together, as a consistent whole. To guarantee a good quality of service, it is crucial for the companies to ensure that their clients always perceive a consistent view of the data.
Many modern enterprise applications [Fowler, 2002] must implement a rich, complex domain model.
Their domain is typically implemented with a dense graph of classes and relationships in some objectoriented programming language. Developing such a complex domain model is often a challenging task for most development teams.
To tackle this problem, the F´nix Framework1 provides a Domain Modeling Language (DML) and e a Software Transactional Memory (STM) [Cachopo, 2007, Cachopo and Rito-Silva, 2006]. Its goal is to simplify the development of rich domain models that follow a domain-driven design approach [Evans, 2003]. It separates their structure, which is implemented in DML, from their behavior, which is implemented in Java. Also, to keep the data consistent, it separates the implementation of consistency rules, which are implemented with consistency predicates.
The consistency predicates allow programmers to implement consistency rules that the application’s data must satisfy, independently of the implementation of the application’s behavior. They are checked automatically at the end of each business transaction to ensure that all the consistency rules were followed, in which case the transaction can commit. Otherwise, if any consistency rule was violated, the transaction aborts to prevent introducing inconsistencies in the application’s data.
However, the original proposal of this approach assumed an execution model where the application keeps all of its data in transient memory. The application would start from an empty state, and run forever without updates to its code. Clearly, this is not the common case for enterprise applications, which must persist their data and are incrementally developed over a long period of time.
Under these conditions, the application’s structure, its behavior, and its consistency predicates are all subject to code changes. Still, each new version of the code must deal with the previously persisted data. New consistency rules are often added for already existing data, which may be inconsistent according to the new rules. Therefore, it is important to deal with these rule changes as pragmatically as possible.
develops an enterprise application in Java. They support applications where the data is persisted and where the domain code evolves.
This document describes how to keep information about the existing consistency predicates across diﬀerent executions of an application. It shows how to detect changes in the implementation of consistency predicates, and how to deal with these changes. Moreover, this work introduces the concept of inconsistency tolerance to handle existing inconsistent data, and describes how the consistency predicates support it.
The remainder of this document is organized as follows:
• Chapter 3 discusses the limitations of the original consistency predicates when used in an evolving application.
• Chapter 4 shows the existing related work of consistency rules and evolving applications.
• Chapter 5 proposes a new domain model to deal with the code changes that involve the consistency predicates.
• Chapter 7 validates the new implementation with examples of evolving applications.
• Chapter 8 describes a few ideas for future work to further improve the consistency predicates.
• Chapter 9 draws some conclusions from this work.
• Appendix A contains a few guidelines that establish an initial set of best practices, to help the programmer in using the consistency predicates.
2.1 DML - Domain Modeling Language This work is aimed at enterprise applications with rich domain models that are incrementally developed using an object-oriented programming paradigm. In such applications, the domain generally consists of a complex graph of classes, representing entities with relations among them. All of these entities and their relationships represent the structure of the domain.
The F´nix Framework provides a domain speciﬁcation language to allow the programmer to specify e the structure of his applications’ domain. This language is called DML - Domain Modeling Language.
The goal of the DML is to separate the structure of the application’s domain from its behavior.
Inside a DML ﬁle, a developer speciﬁes a set of domain classes in a simple syntax that is similar to Java. Each class can contain several slots of certain value types or primitives. A domain class may extend another class, so domain class hierarchies are supported. If a domain class does not specify an explicit superclass, it will extend the AbstractDomainObject by default. The AbstractDomainObject is the top
superclass of all domain class hierarchies. It is not declared in the DML ﬁle; it is a regular abstract Java class.
Figure 2.1 and Figure 2.
2 provide examples of DML declarations of two domain classes of a hypothetical banking application. This application will serve as an example throughout this dissertation.
relation. Independently of the multiplicity, relations are bidirectional. None of the two entities owns the other, but either entity can use the relation to obtain the other.
Figure 2.3 illustrates a DML relation between a Client and all of its Accounts.
The relation contains two entries, one for each domain entity, on each side of the intended relation. On each entry, the text on the left side of the playsRole keyword speciﬁes the class name of the entity. The text on the right side speciﬁes the name of the role that the entity has in that relation. The code generator will use this role name to create getter and setter methods for each entity. Also, the default multiplicity is 1. So, each client may have several accounts, and each account may have only a single client.
Figure 2.4 presents an UML class diagram of the banking domain example created so far in DML.
Figure 2.4: UML class diagram of the domain model of the banking example with the Client and the Account.
The F´nix framework also implements a code generator to create the application’s structure in Java.
e The code generator processes the DML ﬁle containing the domain classes and their relations. It creates a Java class for each DML class. It also generates getter and setter methods for each slot inside the domain classes, and for each relation between classes. Figure 2.5 provides an example of the use of the generated getter methods for the Client and the Account.
Note that, in this ﬁgure, the getTotalBalance() method is part of the application’s behavior, and must be implemented by the developer. However, the code generator created the Java class of the Client as an empty class for the developer to use. It also created the superclass Client Base that contains framework code, and is not meant to be edited manually. Thus, the DML ﬁle contains only the high-level description of the domain’s structure and contents. It is separated from the operations of the domain that are still implemented in plain old Java classes.
that deals with the transactionality and persistence of the domain objects, their slots, and relations.
Overall, the DML is one of the central parts of the F´nix Framework that is integrated with the rest e of its features. The developer only needs to provide a correct modeling of the application domain in a separate DML ﬁle, and implement the domain behavior in Java. The framework will guarantee that the resulting runtime is transactional, concurrent-friendly, and persistent.
2.2 JVSTM - Java Versioned Software Transactional Memory The Java Versioned Software Transactional Memory (JVSTM) [Cachopo, 2007] is a Java-based Software Transactional Memory. Software Transactional Memory (STM) in general will be described in greater detail in Chapter 4. In short, STM systems provide transactions as an eﬃcient and easy to use synchronization approach for highly concurrent applications. Transactions are an alternative to the traditional use of locks, which induce implementation complexity and deadlocks. Transactions avoid these problems by allowing an all-or-none, atomic execution of a sequence of operations, with the added beneﬁt of fault recovery.
The F´nix Framework includes the JVSTM, which provides transactions with ReadSets and WriteSets e to track the operations they performed, and on which parts of the data. To identify the parts of the data, the JVSTM also provides versioned memory locations, which are called versioned boxes (VBoxes).
A VBox stores a history of values, one for each version of the world.
Each transaction starts at a certain moment in time, and acquires a version number to use. Afterwards, it reads only values that existed at this version of the world, so that it can perceive a snapshot of the application state. This allows other concurrent transactions to write to the same VBoxes simultaneously (on higher versions) without generating conﬂicts.
The previous section has shown that the code generator creates code inside the base classes of each DML domain class. This code will already contain VBoxes in the correct locations to make sure that the contents of each domain class are transactional. Therefore, the framework assures that every single piece of domain data is contained inside VBoxes. Moreover, every single operation that the system executes is included inside a transaction.