Verily: A Web Framework for Creating More ... - Semantic Scholar

2 downloads 154 Views 269KB Size Report
May 31, 2014 - that supports the development of verifiable web applications. Rather ... tures—Frameworks; D.2.11 [Software Engineering]: Software.
Verily: A Web Framework for Creating More Reasonable Web Applications John L. Singleton

Gary T. Leavens

University of Central Florida, Orlando, USA

University of Central Florida, Orlando, USA

[email protected]

[email protected]

ABSTRACT The complexity of web application construction is increasing at an astounding rate. Developing for the web typically crosses multiple application tiers in a variety of languages, which can result in disjoint code bases. This lack of standardization introduces new challenges for reasoning. In this paper we introduce Verily, a new web framework for Java that supports the development of verifiable web applications. Rather than requiring that programs be verified in separate a posteriori analysis, Verily supports construction via a series of Recipes, which are properties of an application that are enforced at compile time. In addition to introducing the Verily framework, we also present two Recipes: the Core Recipe, an application architecture for web applications designed to replace traditional server-side Model View Controller, and the Global Mutable State Recipe, which enables developers to use sessions within their applications without resorting to the use of unrestricted global mutable state. Demo Video: http://www.youtube.com/watch?v=TjRF7E4um3c

Categories and Subject Descriptors D.3.3 [Programming Languages]: Language Constructs and Features—Frameworks; D.2.11 [Software Engineering]: Software Architectures—Domain-specific architectures

General Terms

this has had favorable effects on productivity [14], little has been done about verification1 within web application frameworks. However, the lack of focus on verification within web applications is not surprising. Fundamentally, web applications differ from traditional applications in several ways. Unlike traditional applications, the design of HTTP ensures that portions of the application may be accessed essentially at random. Thus, to encode the logic of having a definite start state and transitions, a programmer must manually encode the logic to thread application state throughout a sequence of URLs. By contrast, in a typical graphical desktop application, a user’s actions may be limited simply by limiting the options visible. In a web application, no such restrictions may be made, as URLs are always accessible (e.g., using a browser’s “back” button). This introduces a complication that differentiates web applications from the traditional view of applications as finite automata [2, 5, 6]. An additional complication is that behaviors vary widely between frameworks. For example, many frameworks implement a form of Model View Controller (MVC) as the primary design pattern for application construction. But frameworks vary widely in their interpretation of MVC; this makes it difficult to create a general method for reasoning about web application code. Verily diverges from traditional frameworks by providing more than a skeleton of an application. Instead, Verily supports verification by providing a set of Recipes that specify desirable properties. Implementations are statically checked for compliance with these recipes. Compliance is enforced before code is allowed to run.

Verification, Languages

Keywords Model View Controller, Method Router Response, web frameworks, Verily framework

1.

INTRODUCTION

Because of the way that they encapsulate domain-specific complexity, software frameworks have become indispensable [1, 15, 17]. This applies especially to web applications, where the general focus of framework design has centered on issues of productivity. While

Permission to make digital or hard copies of all or part of this work for personal or classroom usetois make granteddigital withoutorfeehard provided thatofcopies not made or work distributed Permission copies all orarepart of this for for profit or commercial advantage and that copies bear this notice and the full citation personal or classroom use is granted without fee provided that copies are on the first page. Copyrights for components of this work owned by others than ACM not made or distributed forwith profit or iscommercial and that copies must be honored. Abstracting credit permitted. Toadvantage copy otherwise, or republish, to postthis on notice servers and or tothe redistribute to lists, specific permission and/ortoa bear full citation onrequires the firstprior page. To copy otherwise, fee. Requesttopermissions from [email protected]. republish, post on servers or to redistribute to lists, requires prior specific

permission and/or a fee. ICSE Companion’14, May 31 – June 7, 2014, Hyderabad, India ICSE ’14, May – June 7, 2014, Hyderabad, India Copyright 201431 ACM 978-1-4503-2768-8/14/05...$15.00 http://dx.doi.org/10.1145/2591062.2591069 Copyright 14 ACM 978-1-4503-2768-8/14/05 ...$15.00.

This work was supported by the US National Science Foundation under grant 1228695. 560

2.

THE CORE RECIPE

The MVC pattern, originally designed for the Smalltalk-80 system [3], is an ineffective pattern for designing web applications. While the MVC pattern has been successfully employed in desktop applications, web-based applications follow a different execution cycle. Most notably, web-based applications rely on a requestresponse model that does not easily translate to the typical desktop application’s finite automaton model. In a web application, the normal calling semantics of a program’s execution are replaced by a mapping of intents or method calls to URLs that are sent to the server in the form of plain text. The foundation of our approach is the introduction of a new design we call Method Router Response (MRR). MRR’s design has three kinds of components: application requests are processed by Methods, control flow is directed by Routers, and the resulting content (e.g., HTML or JSON) is displayed using Responses. The high level design of MRR is shown in Figure 1. 1

In this paper we use the term verification to mean any of several different reasoning activities and techniques designed to increase reliability, such as testing, formal verification, and static analysis.

must be done in transforming HTTP requests (strings) into program data. Methods define explicit guarantees for transforming requests into data and for mapping requests onto executable code. These statically-checked guarantees are as follows:

Incoming Requests

f1

f1

f2

f2

f3

Routers

Responses

Requests are Well-Formed The Methods component of the Core Recipe guarantees that function parameters are passed with the right type and arity. The idea of ensuring well-formed requests bears resemblance to the view taken by the Google Web Toolkit, but does not require client side applications to be written in JavaScript in order to take advantage of it.

Request Decoding

f3

Methods

Translation Table

URI/Class Isomorphism Methods are mapped onto the URI structure in a way that is isomorphic to the placement of Methods in classes. For example, if a Method createUser belongs to the class UserManagement, then the URI that maps to the UserManagement.createUser Method would be:

Deliver to User

http://myapp/UserManagement/createUser. Figure 1: A high-level overview of the MRR design

Router Parity Verily checks that each Method has a matching Router method defined.

The following points contrast the MVC approach with our MRR approach. No assumptions about cross-tier calls. One assumption present in MVC is that there is little (if any) penalty for method calls that cross tiers. For example, a view can require many back-and-forth calls between the controllers and models in order to perform a given display operation. (In many cases, this allows for a higher degree of modularization. Indeed, this is a major strength of the MVC model.) However, while this modularity is desirable, it is often impractical in the client-server model due to non-locality and the time penalty for crossing from the web tier to the server tier. In MRR calls that cross tiers are regarded as inherently more costly in terms of application performance and therefore should be minimized. Responses are not a manifestation of a model. In MVC, the view is presented as a manifestation of the state of a model [3, 7, 9]. In MRR, views are dependent on the evaluation of parameterized methods. The underlying data that the views represent need not be constructed from a single model. Explicitly recognizes protocol. Since web applications are delivered over HTTP, a great deal of work must be done in transforming HTTP requests, which are essentially strings of encoded parameters, into meaningful program representations. MRR provides explicit support for transforming requests into program level objects and for mapping requests onto executable code. The following subsections detail the building blocks of the MRR design.

2.1

To signal that a particular class should be scanned for Methods, a user must put the class’s source file in the methods subdirectory of their Verily project. (Classes may also contain other members, but they will not be accessible to incoming requests.)

2.2

Routers

While Methods are responsible for handling the computational logic of the application, Routers are responsible for an application’s control flow. As indicated in Figure 1, Methods and Routers exist in pairs, yet they do not strictly depend on one another. This design has the advantage that navigational logic and application logic are clearly separated and therefore may be tested independently. We show an example Router in Listing 2. public class UserManagement{ public static final Content addUser( String email, String name){ // ... return new TemplateHTMLContent(...); } }

Listing 2: Example Router addUser. Similar to Methods, Routers have some conventions that must be followed and statically-checked guarantees, which are as follows: Method Parity For each Router, there must be a correspondingly named Method with a matching classname and method name.

Methods

Methods are the individual functions that are responsible for implementing the web-facing logic of an application. In Verily Methods are simple function members of a class with the type signature public static final void(...) (see, for example, Listing 1).

Request/Call Equivalence The parameters for a Router must match those of the corresponding Method in type and name; however, Routers may declare a return type. A Router’s declared return type describes the content that it will render. This guarantee allows a static analysis that eliminates errors arising from mismatched content types. Note that Routers are never accessed directly; data always first passes through a Method.

public class UserManagement { public static final void addUser( String email, String name){ // ... } }

Listing 1: Example Method addUser.

No Mutation of Global State Routers may read from but not write to Global Mutable State, as described in Section 3. This ensures that Routers do not require state to be built up to operate and may thus be more easily tested.

Since web applications are delivered over HTTP, all data is passed to the server in plain text query strings. Thus a great deal of work

To indicate that a class should be scanned for Routers, its source file is placed in the routers directory within a project.

561

public class UserManagement{

public class UserManagement{

public static final void visitSite( WritableValue lastTs ){ // update the last timestamp lastTs.setValue(System.currentTimeMillis()); }

public static final void logoutIfIdle( ReadableValue lastTs ){ int elapsedSeconds; elapsedSeconds = (System.currentTimeMillis()lastTs.getValue())/1000L; if(elapsedSeconds >= 90){ // logout } }

}

Listing 3: Using session to track the last time a user visited. }

2.3

Listing 4: Accessing a session variable to determine if a logout should be performed.

Responses

Responses, which are types of data returned by Routers, encode how content is rendered by a browser. A Response must subclass the Content class, or use one of several provided subclasses.2 In Listing 2, the addUser Router is returning an instance of the TemplateHTMLContent class. The purpose of encoding rendering information in the data returned by Routers is twofold. First, rather than introducing domainspecific concerns like HTTP content-type headers, these concerns are instead abstracted into the different Content classes. Second, since rendering is based on data (the Response), unit tests may easily inspect these data values, instead of creating mock web browsers to interact with the application. Since much work has been done in providing templating capabilities for HTML pages, Verily uses the Freemarker3 template engine and supports its use with the TemplateHTMLContent class.

3.

a ReadableValue parameter. Listing 4 demonstrates how the previous value of lastTs may be accessed in another Method. The GMS Recipe introduces a number of useful properties. The following are its rules and guarantees. Initialization If a session-bound parameter has not been initialized in a session, it defaults to null4 . Modification Each writable session-bound parameter may only be changed within a Method (not a Router). Subsequent Access Once a session-bound parameter has been initialized, any subsequent access to that parameter returns its last assigned value within a session.

GLOBAL MUTABLE STATE RECIPE

Scope A major problem with allowing session-bound parameters is that they can be used throughout a program, like global variables. Such usage makes sufficiently large programs difficult to reason about. In Verily the scope of session-bound parameters is bipartite: they may only be altered, or writably bound within a single Method. This property is statically checked at compile-time. Any other function needing the value of the session-bound parameter may have read-only access (using the type ReadableValue). Because of this design, the name of each session-bound parameter must be unique throughout the program.

HTTP is a stateless protocol, but applications often need mutable state. For example, applications often need to associate a sequence of computations with a particular client. This requirement is present in many popular web sites; for example, when a user logs into their banking website, the information presented must be personalized. Since HTTP is a stateless protocol, web applications must invent a method for maintaining some form of state between requests of a related nature. This conversational flow between client and server is called a session. In a web application, a session behaves exactly like a global variable, since it exists in the global namespace and may be manipulated anywhere throughout the application. Global variables are an antipattern because their use increases module coupling. Worse, because requests in a traditional web application may essentially be executed in any order, any code paths that do not explicitly check for state modification will allow current and future states of an application to be erroneously or maliciously influenced by a client. The focus of the Global Mutable State (GMS) Recipe is to limit such deleterious effects of sessions, while providing a means for conversational flow. To use GMS in Verily, a user must declare the type of a sessionbound parameter as an instance of either ReadableValue or WritableValue. These generic classes mark session values that will be either read-only or writable during a session. Listing 3 shows an example of how to use the WritableValue type within a Method. The code in Listing 3 updates the value of the lastTs session variable. Subsequent requests to the application from a particular user will then be able to access this value in other methods via

4.

RELATED WORK

Hemel and Groenewegen, et al. identify the problems that creating a web application using multiple languages creates for static analysis and propose a domain specific language for the creation of web applications, WebDSL [10]. However, this approach introduces the problem of having to adopt a new language, which may be problematic if it makes existing third-party libraries unavailable. Verily is implemented in Java to demonstrate the generality of our approach, and the Recipes and ideas in Verily should be portable to other languages. In their paper on WebJinn [13], Kojarski and Lorenz introduce two programming models, DDD and XP, which address the problems that arise as a result of scattering cross-cutting concerns across code written in multiple languages. They say that MVC does not make a suitable pattern for web applications because it fails to address code scattering problems. Their proposal, like Verily, is a Java-based approach, but it focuses on moving dynamic behavior to the domain of JSP pages. Verily’s approach instead enables static analysis, and yet remains agnostic to the display technology on the client side.

2 The provided classes are: JSONContent, TextContent, HTMLContent, and TemplateHTMLContent. 3 See http://freemarker.org.

4

562

Since parameter types cannot be Java primitives, null suffices.

[3] S. Burbeck. Applications programming in Smalltalk-80tm : How to use Model-View-Controller (MVC). Smalltalk-80 v2. 5. ParcPlace, 1992. [4] P. Chalin, J. R. Kiniry, G. T. Leavens, and E. Poll. Beyond assertions: Advanced specification and verification with JML and ESC/Java2. In Proceedings of the 4th International Conference on Formal Methods for Components and Objects, FMCO’05, pages 342–363, Berlin, Heidelberg, 2006. Springer-Verlag. [5] T. S. Chow. Testing software design modeled by finite-state machines. Software Engineering, IEEE Transactions on, SE-4(3):178–187, 1978. [6] E. M. Clarke, E. a. Emerson, and a. P. Sistla. Automatic verification of finite-state concurrent systems using temporal logic specifications. ACM Transactions on Programming Languages and Systems, 8(2):244–263, Apr. 1986. [7] Z. Durdik. Towards a process for architectural modelling in agile software development. In Proceedings of the Joint ACM SIGSOFT Conference – QoSA and ACM SIGSOFT Symposium – ISARCS on Quality of Software Architectures – QoSA and Architecting Critical Systems – ISARCS, QoSA-ISARCS ’11, pages 183–192, New York, NY, USA, 2011. ACM. [8] B. George and L. Williams. A structured experiment of test-driven development. Information and Software Technology, 46(5):337–342, Apr. 2004. [9] S. Hansen and T. Fossum. Refactoring model-view-controller. Journal of Computing Sciences in Colleges, pages 120–129, 2005. [10] Z. Hemel, D. M. Groenewegen, L. C. Kats, and E. Visser. Static consistency checking of web applications with WebDSL. Journal of Symbolic Computation, 46(2):150–182, 2011. [11] C. A. R. Hoare. Proof of correctness of data representations. Acta Informatica, 1(4):271–281, 1972. [12] C. Jaspan and J. Aldrich. Checking framework interactions with relationships. In Proceedings of the 23rd European Conference on ECOOP 2009 — Object-Oriented Programming, Genoa, pages 27–51, Berlin, Heidelberg, 2009. Springer-Verlag. [13] S. Kojarski and D. H. Lorenz. Domain driven web development with WebJinn. Companion of the 18th annual ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications - OOPSLA ’03, page 53, 2003. [14] S. Moser and O. Nierstrasz. The effect of object-oriented frameworks on developer productivity. Computer, 29(9):45–51, 1996. [15] W. Pree. Meta patterns - a means for capturing the essentials of reusable object-oriented design. In Proceedings of the 8th European Conference on Object-Oriented Programming, ECOOP ’94, pages 150–162, London, UK, UK, 1994. Springer-Verlag. [16] A. Stoughton. A functional model-view-controller software architecture for command-oriented programs. Proceedings of the ACM SIGPLAN workshop on Generic programming WGP ’08, page 1, 2008. [17] J. Vlissides, R. Helm, R. Johnson, and E. Gamma. Design patterns: Elements of reusable object-oriented software. Reading: Addison-Wesley, 49:120, 1995.

This makes Verily useful for integration with client-side JavaScript applications or “single page” applications. Within web pages, interface controls are often influenced by the result of server-side operations or data. This introduces complications for unifying analysis across tiers. Jaspan and Aldrich propose a method of specifying constraints on such interactions by using a propositional logic of relationships between components [12]. Our approach is partially inspired in part by Test Driven Development (TDD), in which tests are written before application construction [8]. Just as TDD structures its workflow around the creation of tests, which must be passed before a product is shipped, our approach structures its development around Recipes, which must be satisfied before code is allowed to run. Though not specifically related to web applications, Stoughton addresses problems in structuring command-oriented functional programs by introducing a pattern called functional Model View Controller [16]. This is of interest because it is similar to Verily’s view of Methods and shares an emphasis on avoiding mutable state, however it does not directly consider the problem of marshaling function parameters over a protocol, as is the case with Verily.

5.

DEMONSTRATION PLAN

The objective of our demonstration is to show that Verily improves the reliability of problematic aspects of web application development. We will first explain how to install Verily and then demonstrate the construction of an online auction application. By the end of the demonstration the audience will have built a small but complete application in Verily. Additionally, we will cover the following supplemental topics: The JavaScript Bridge. Verily can automatically export Methods to JavaScript. This enables client-side applications to call Methods as if they were natively defined in JavaScript. We will show the use of both the synchronous and asynchronous JavaScript Bridge functionality. Verily in Single Page Applications. Single page applications rely on client-side JavaScript to manage user interaction. The demonstration will extend the sample application to take advantage of the Backbone.js JavaScript framework to demonstrate how Verily solves several problems endemic to connecting client-side JavaScript to server-side applications.

6.

CONCLUSIONS AND FUTURE WORK

In this paper we introduced the Verily framework and demonstrated how it solves several design problems endemic to traditional web application applications. The primary focus of the demonstration is to explain two of Verily’s Recipes. Verily is currently under active development. Our next areas of focus are handling issues of parameter validation as well as random execution defects. We expect to solve these problems with a combination of introducing contracts [11, 4] as well as constraint solving Recipes. Readers interested in using the Verily framework may access it on its development website at: http://goverily.org.

7.

REFERENCES

[1] J. Aldrich. The power of interoperability: Why objects are inevitable. In Proceedings of the 2013 ACM International Symposium on New Ideas, New Paradigms, and Reflections on Programming & Software, Onward! ’13, pages 101–116, New York, NY, USA, 2013. ACM. [2] E. Börger and R. F. Stärk. Abstract state machines: a method for high-level system design and analysis, volume 14. Springer Heidelberg, 2003.

563

Suggest Documents