A FRAMEWORK FOR MIGRATING WEB APPLICATIONS TO WEB SERVICES SIL A
Transcript of A FRAMEWORK FOR MIGRATING WEB APPLICATIONS TO WEB SERVICES SIL A
A FRAMEWORK FOR MIGRATING WEB APPLICATIONS TO
WEB SERVICES
by
ASIL A. ALMONAIES
A thesis submitted to the
School of Computing
in conformity with the requirements for
the degree of Doctor of Philosophy
Queen’s University
Kingston, Ontario, Canada
March 2013
Copyright © Asil A. Almonaies, 2013
Abstract
Service Oriented Architecture (SOA) is an increasingly important software architecture, de-
signed to flexibly connect separate components in response to rapid changes in the business
environment. SOA focuses on the exchange of information between independent software
components and on the reusability of the components by separating communication inter-
face from internal implementation. There are several features of SOA that make legacy
system modernization to SOA appealing in today’s world. These are loose coupling, ab-
straction of underlying logic, agility, flexibility, reusability, autonomy, statelessness, dis-
coverability and reduced cost.
Migration of legacy systems to SOA is an important problem. While migration of
legacy data processing systems has been widely studied, migration of legacy web appli-
cations has not. In this thesis we review existing strategies for migration of monolithic
legacy web applications to web services, noting the unique challenges due to the highly
dynamic nature of the systems, poorly structured code, and weakly typed languages in web
applications, and the need for automation to assist in the process.
We present a new semi-automated framework for the analysis and migration of mono-
lithic web applications to web services using source analysis and transformation tech-
niques, and outline a set of source transformation steps that can be used to migrate ex-
isting legacy web applications to web services form. We demonstrate our framework on
the analysis and automated restructuring of two large existing web applications to extract
and migrate integrated internal features to independent, reusable web services.
i
Co-Authorship
All published papers resulting from this thesis have been co-authored with my supervisors
Dr. James R. Cordy and Dr. Thomas R. Dean, along with my post-doctoral mentor Dr.
Manar H. Alalfi. In particular, the following publications are based on chapters of this
thesis:
• A. Almonaies, J.R. Cordy and T.R. Dean,
"Legacy System Evolution Towards Service-Oriented Architecture",
Proc. SOAME 2010, International Workshop on SOA Migration and Evolution,
Madrid, Spain, March 2010, pp. 53-62.
is based on Chapter 2.
• A. Almonaies, M. Alalfi, J.R. Cordy and T.R. Dean,
"Towards a Framework for Migrating Web Applications to Web Services",
Proc. CASCON’11, 21st IBM Centre for Advanced Studies International Conference
on Computer Science and Software Engineering,
Toronto, November 2011, pp. 229-241.
is based on Chapter 3.
In all cases I am the primary author.
ii
Acknowledgments
First and foremost, praises and thanks to Allah, the Almighty, for giving me strength to
complete this thesis.
I am very much grateful to my great supervisors professors James R. Cordy and Thomas
R. Dean, this thesis would not have been possible without their help, support, patience, and
encouragement, whether on an academic or a personal level, for which I am extremely
thankful and forever grateful.
I would like to thank Dr. Manar H. Alalfi, for serving as a mentor and a second super-
visor through the course of completing this thesis, her help, guidance and friendship are
much appreciated.
My sincere thanks also to my committee members for their time, questions, and encour-
agement. I would also want to thank professor Hossam S. Hassanein, for his continuous
support and encouragement.
Words cannot express how grateful I am to my father and my mother for all the sacri-
fices that they made on my behalf. I owe a lot to both of them. A special thanks to all my
family, especially my brother Omar Almonaies for always stepping in when I needed him
the most.
I would also want to thank my mother-in-law and father-in-law for their continuous
support and prayers. I owe my deepest gratitude to my beloved husband, Dr. Hisham
iv
Alassousi for his endless love and for supporting and encouraging me throughout this ex-
perience. To my two lovely boys, Ibrahim and Abdullah, thank you for your unconditional
love that always lift my spirit.
I would also like to thank my colleagues and friends in the school of computing for their
support and kindness. Especially, I would like to thank, Karolina Zurowska and Gehan
Selim for their friendship and support.
Special thanks also to my friend Dr. Hanady Abdulsalam, for her continuous guidance
and support. I would also like to thank my best friend Shorouq Almonaies for always being
there for me. I also wish to thank my friends Layla Alkandari and Sondos Ashkanani for
their sincere friendship.
I would like to express my gratitude to Queen’s University for giving me the opportunity
to complete my PhD degree.
v
Statement of Originality
I, Asil A. Almonaies, certify that the research work presented in this thesis is my own and
was conducted under the supervision of Dr. James R. Cordy and Dr. Thomas R.Dean. All
references to the work of other people are properly cited.
vi
Contents
Abstract i
Co-Authorship ii
Dedication iii
Acknowledgments iv
Statement of Originality vi
Contents vii
List of Tables x
List of Figures xi
Chapter 1: Introduction 11.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Thesis Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Contributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.4 Organization of the dissertation . . . . . . . . . . . . . . . . . . . . . . . . 5
Chapter 2: Background 62.1 Service-Oriented Architecture . . . . . . . . . . . . . . . . . . . . . . . . 72.2 Legacy Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72.3 Comparison Criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82.4 Replacement of Legacy Systems . . . . . . . . . . . . . . . . . . . . . . . 92.5 Wrapping Strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5.1 Overview of wrapping techniques . . . . . . . . . . . . . . . . . . 112.5.2 Comparison of the techniques . . . . . . . . . . . . . . . . . . . . 13
2.6 Redevelopment Strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.6.1 Overview of redevelopment techniques . . . . . . . . . . . . . . . 152.6.2 Comparison of the techniques . . . . . . . . . . . . . . . . . . . . 16
2.7 Migration Strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
vii
2.7.1 Overview of migration techniques . . . . . . . . . . . . . . . . . . 182.7.2 Comparison of the techniques . . . . . . . . . . . . . . . . . . . . 20
2.8 Choosing A Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.9 Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.10 The Need for Automation . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.11 Source Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.12 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Chapter 3: Web Application to SOA Migration Framework 253.1 A Migration Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.1.1 Service Identification . . . . . . . . . . . . . . . . . . . . . . . . . 263.1.2 Service Separation & Migration . . . . . . . . . . . . . . . . . . . 27
3.2 Automating Service Migration . . . . . . . . . . . . . . . . . . . . . . . . 283.2.1 Candidate Service Refactoring . . . . . . . . . . . . . . . . . . . . 293.2.2 Candidate Service Separation . . . . . . . . . . . . . . . . . . . . . 303.2.3 Parameter Type Inference . . . . . . . . . . . . . . . . . . . . . . . 313.2.4 Service Component Conversion . . . . . . . . . . . . . . . . . . . 323.2.5 Database Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.3 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Chapter 4: Service Refactoring 354.1 Candidate Service Identification . . . . . . . . . . . . . . . . . . . . . . . 364.2 A Running Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374.3 Candidate Service Markup . . . . . . . . . . . . . . . . . . . . . . . . . . 394.4 Refactoring Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Chapter 5: Type Inference 455.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455.2 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465.3 Instrumentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485.4 Exercising the Instrumented Code . . . . . . . . . . . . . . . . . . . . . . 495.5 Adding Inferred Parameter Types . . . . . . . . . . . . . . . . . . . . . . . 515.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Chapter 6: Service Component Conversion and Database Refactoring 536.1 Service Component Architecture . . . . . . . . . . . . . . . . . . . . . . . 536.2 SCA for PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556.3 Converting a Candidate Service Class to SCA . . . . . . . . . . . . . . . . 57
6.3.1 Service Data Objects . . . . . . . . . . . . . . . . . . . . . . . . . 586.3.2 Object Serialization . . . . . . . . . . . . . . . . . . . . . . . . . . 606.3.3 Serialization of Service Operations . . . . . . . . . . . . . . . . . . 616.3.4 Serialization of Service Calls . . . . . . . . . . . . . . . . . . . . . 63
viii
6.3.5 Service Class Conversion to SCA . . . . . . . . . . . . . . . . . . 646.3.6 Web Application Conversion to SCA . . . . . . . . . . . . . . . . . 676.3.7 Database Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Chapter 7: Case Studies 717.1 Case Study 1: Moodle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
7.1.1 The Moodle Login Process . . . . . . . . . . . . . . . . . . . . . . 727.1.2 Step 1: Login Service Identification . . . . . . . . . . . . . . . . . 747.1.3 Step 2: Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . . 777.1.4 Step 3: Type Inference . . . . . . . . . . . . . . . . . . . . . . . . 807.1.5 Step 4: Conversion to SCA . . . . . . . . . . . . . . . . . . . . . . 847.1.6 Moodle / SOA: Testing the Result . . . . . . . . . . . . . . . . . . 90
7.2 Case Study 2: SCARF . . . . . . . . . . . . . . . . . . . . . . . . . . . . 957.2.1 The SCARF Paper Management Subsystem . . . . . . . . . . . . . 957.2.2 Step 1: Paper Management Service Identification . . . . . . . . . . 957.2.3 Step 2: Refactoring . . . . . . . . . . . . . . . . . . . . . . . . . . 967.2.4 Step 3: Type Inference . . . . . . . . . . . . . . . . . . . . . . . . 1007.2.5 Step 4: Conversion to SCA . . . . . . . . . . . . . . . . . . . . . . 1027.2.6 SCARF / SOA: Testing the Result . . . . . . . . . . . . . . . . . . 107
7.3 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Chapter 8: Conclusions and Future Work 1098.1 Contributions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1098.2 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1118.3 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
ix
List of Tables
2.1 Summary of Wrapping Techniques . . . . . . . . . . . . . . . . . . . . . . 14
2.2 Summary of Redevelopment Techniques . . . . . . . . . . . . . . . . . . . 17
2.3 Summary of migration techniques . . . . . . . . . . . . . . . . . . . . . . 18
2.4 Summary of modernization strategies . . . . . . . . . . . . . . . . . . . . 21
x
List of Figures
3.1 A Migration Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.2 Service identification Tagging Using XML . . . . . . . . . . . . . . . . . . 27
3.3 Steps of our Automated Process for Service Migration . . . . . . . . . . . . 29
3.4 Example Tagged Candidate Service Operation . . . . . . . . . . . . . . . . 30
3.5 Example Class Generated by the Refactoring Step . . . . . . . . . . . . . . 30
3.6 Example Refactored and Separated Candidate Service Class . . . . . . . . 31
3.7 Example Refactored and Separated Service Class after Type Inference . . . 32
3.8 Example Converted to SCA Web Service . . . . . . . . . . . . . . . . . . . 34
4.1 Candidate Service Refactoring Process . . . . . . . . . . . . . . . . . . . . 36
4.2 The Candidate Service Separation Step . . . . . . . . . . . . . . . . . . . . 36
4.3 A Running Example Web Application . . . . . . . . . . . . . . . . . . . . 38
4.4 Marked Candidate Service Operation . . . . . . . . . . . . . . . . . . . . . 39
4.5 Running Example with Potential Service Operation Markup . . . . . . . . . 40
4.6 Result of the Candidate Service Class Refactoring and Separation Trans-
formation for the Running Example . . . . . . . . . . . . . . . . . . . . . 42
4.7 Result of the Candidate Service Client Side Refactoring for the Running
Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.1 Dynamic Type Inference Using Candidate Service Class Instrumentation . . 47
5.2 Original Generated Candidate Service Class . . . . . . . . . . . . . . . . . 48
xi
5.3 Instrumented Version of the Generated Candidate Service Class . . . . . . . 49
5.4 Merged Instrumentation Output File . . . . . . . . . . . . . . . . . . . . . 50
5.5 Typed Generated Candidate Service Class . . . . . . . . . . . . . . . . . . 51
6.1 Service Component Architecture (adapted from [54]) . . . . . . . . . . . . 54
6.2 Simple Example PHP SCA Service Class . . . . . . . . . . . . . . . . . . 56
6.3 Loading a WSDL Service in a PHP Client . . . . . . . . . . . . . . . . . . 57
6.4 Candidate Service Class Conversion to SCA . . . . . . . . . . . . . . . . . 58
6.5 Simple Example XML DTD Class Schema . . . . . . . . . . . . . . . . . . 60
6.6 Typed Candidate Service Class . . . . . . . . . . . . . . . . . . . . . . . . 61
6.7 Serialized Candidate Service Class . . . . . . . . . . . . . . . . . . . . . . 62
6.8 Refactored Web Application Client Side Before Serialization . . . . . . . . 64
6.9 Refactored Web Application Client Side After Serialization . . . . . . . . 65
6.10 Final SCA Annotated Service Class for the Running Example . . . . . . . . 66
6.11 Generated WSDL Service Description for the Running Example . . . . . . 68
6.12 Final Adapted Wep Application as SCA Service Client . . . . . . . . . . . 69
7.1 Moodle login/index.php with Potential Service Operation Markup (Part 1
of 2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
7.2 Moodle login/index.php with Potential Service Operation Markup (Part 2
of 2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
7.3 Refactored Moodle Candidate Service Class (Part 1) . . . . . . . . . . . . . 77
7.4 Refactored Moodle Candidate Service Class (Part 2) . . . . . . . . . . . . . 78
7.5 Generated Result Value Classes for the Moodle Candidate Service . . . . . 79
7.6 Moodle Candidate Service Class with Type Instrumentation . . . . . . . . . 81
7.7 Merged Instrumentation Type Information Output for the Moodle Candi-
date Service Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
xii
7.8 Typed Moodle Candidate Service Class after Type Inference (Part 1) . . . . 83
7.9 Typed Moodle Candidate Service Class after Type Inference (Part 2) . . . . 84
7.10 Serialized Moodle Candidate Service Class (Part 1) . . . . . . . . . . . . . 85
7.11 Serialized Moodle Candidate Service Class (Part 2) . . . . . . . . . . . . . 86
7.12 Final SCA-annotated Service Class (Part 1 of 3) . . . . . . . . . . . . . . . 87
7.13 Final SCA-annotated Service Class (Part 2 of 3) . . . . . . . . . . . . . . . 88
7.14 Final SCA-annotated Service Class (Part 3 of 3) . . . . . . . . . . . . . . . 89
7.15 Final Migrated Moodle Web Application (Part 1 of 3) . . . . . . . . . . . . 91
7.16 Final Migrated Moodle Web Application (Part 2 of 3) . . . . . . . . . . . . 92
7.17 Final Migrated Moodle Web Application (Part 3 of 3) . . . . . . . . . . . . 93
7.18 Screenshot of the Login Page of the Converted Moodle Web Application . . 94
7.19 SCARF Application Pages with Potential Service Operation Markup (Part 1) 97
7.20 SCARF Application Pages with Potential Service Operation Markup (Part 2) 98
7.21 SCARF Application Pages with Potential Service Operation Markup (Part 3) 99
7.22 Generating and Merging Candidate Service Class Operations from Multiple
Web Application Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
7.23 Instrumented Merged Candidate Service Class for SCARF Paper Manage-
ment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
7.24 Type Instrumentation Output of the SCARF Candidate Service Class . . . 102
7.25 Final Migrated SCARF Paper Management Service Class (Part 1 of 3) . . . 104
7.26 Final Migrated SCARF Paper Management Service Class (Part 2 of 3) . . . 105
7.27 Final Migrated SCARF Paper Management Service Class (Part 3 of 3) . . . 106
7.28 Screenshot of the Edit Paper Page of the Converted SCARF Web Application108
xiii
1
Chapter 1
Introduction
1.1 Motivation
Service-oriented architecture (SOA) is an increasingly popular software style based on the
idea of identifying critical components within a system defined by their inputs and out-
puts. An SOA architecture represents software functionality as discoverable services on
the network.
Service-oriented architecture is based on the idea of a collection of services that com-
municate with each other. The communication can involve simple data passing, or it can
involve two or more services coordinating some activity. In either case, some means of
connecting services to each other is needed. The combination of services, whether they are
internal and external to an organization, makes up a service-oriented architecture. SOA can
be viewed as an architecture for flexible connection of separate components in response
to rapid changes in the business environment. The main advantage is that service-oriented
architectures hide the complexity of today’s heterogeneous IT environments from business
users.
In SOA, applications are split into independent services that can be maintained inde-
pendently and easily reused, represented as a collection of loosely-coupled, distributed
1.1. MOTIVATION 2
services that communicate and inter-operate via agreed standards. Applications are crafted
by combining these services using a client-server style. The main advantage is that the
invoking application does not need to know the implementation details of any transaction,
such as the language it is written in, the representation of its internal data, or what route the
message may take along the way.
Service-oriented architecture is not a new concept. The Common Object Request Bro-
ker Architecture (CORBA) and the Distributed Component Object Model (DCOM) pro-
vide similar functionality. However, these existing approaches have several problems such
as tight coupling. In order to gain the advantages of SOA in the context of the world wide
web and overcome these problems, Web Services (WS) provide an SOA solution for appli-
cations and services provided in the web. Web services allow applications to interconnect
in an object-model-neutral manner over the internet.
However, large numbers of web applications (WA) already exist that use a monolithic
stand-alone style. These applications are designed without the modularity and indepen-
dence of SOA, making maintaining and adapting them to changing business requirements
a difficult task. Rather than simply beginning over again, providers prefer to migrate these
legacy applications to SOA while preserving their investment in this large set of existing
legacy web applications. Since these dynamic legacy web applications are too important
to be discarded, they must be reused. Strategically, the objective of moving to a service-
oriented architecture is to build a new business architecture that will overcome the mainte-
nance and evolution problems presented by legacy systems.
However, due to the large gap between the traditional monolithic web application style
and SOA, this is a difficult job which is tedious and error-prone to do by hand. The nature
of monolithic dynamic web applications, often with mixed paradigms, and multi-lingual
code makes makes analysis and refactoring of the source code challenging. Automation of
the migration process reduces human intervention, which reduces the time and cost of the
1.2. THESIS STATEMENT 3
migration and increases the consistency of the migrated code.
There are several modernization approaches to new environments in the literature.
However, to our knowledge only a very few research studies have addressed the problem
of adapting monolithic legacy dynamic web applications to SOA. Most of the work done in
this area [73] [60] [25] is very abstract and general, focussing on discussing the benefits of
using Web Services to leverage web applications, without introducing a plan or framework
for addressing the problem.
In this thesis, we present a detailed framework for migrating existing monolithic web
applications to SOA, and a tool set that largely automates this process.
1.2 Thesis Statement
Software design recovery and transformation techniques can be used to assist in automating
the migration from legacy web applications to service-oriented web services.
The result can be considered to be a service-oriented web application that implements
the endpoints of a Web Service. The framework can also be used to combine different sets
of services from two or more different web applications to construct a new web service
application which behaves like the two original applications together.
1.3 Contributions
The contributions of the thesis are:
• We present a general migration framework based on an iterative process of several
discrete steps to analyze and reprogram existing web applications to web services
based on IBM’s widely used SCA web services standard. The process consists of
three main steps: refactor an identified business feature to an object-oriented class,
1.3. CONTRIBUTIONS 4
infer parameter value types for the class, and repackage the class as an SCA service
component.
• We introduce a new automatic process for extracting a set of identified code frag-
ments in a dynamic web application as an independent object-oriented class. As part
of this process, the necessary parameters and result values for the methods of the
class are inferred from the context of the code fragments.
• We introduce a new automatic type inference method for dynamically typed lan-
guages based on run-time instrumentation and coverage testing. The method accu-
rately infers the types of the parameters of a given function from its actual use.
• We introduce a new automatic transformation from an object-oriented class to an
independent Service Component Architecture (SCA) service component, including
adaptation of the original application to use the service.
• We provide a set of tools using source analysis and transformation implementations
of the methods above to automate the reprogramming of PHP-based web applications
to extract and separate web services. The result is a new web application using
these extracted services, and the services themselves, which can be reused by other
applications.
• We demonstrate the use of our framework and tool set in the extraction and migration
of business features in two legacy web applications to web services. These include
Moodle, a production monolithic web application for course and student manage-
ment, and SCARF, a monolithic web application designed to help researchers and
conference administrators to create and maintain discussion forums for research pa-
pers.
1.4. ORGANIZATION OF THE DISSERTATION 5
1.4 Organization of the dissertation
This thesis is structured as follows. In Chapter 2 we review the history of SOA and other
work in SOA migration, noting that little has been done in automating the migration of
web applications to SOA. Chapter 3 presents our framework for migration and the steps of
our proposed automated process. In Chapter 4 we present the first step of our automation,
the refactoring of identified business logic to a separate class, and introduce a running
example application used to demonstrate each step in the remainder of the thesis. Chapter 5
presents the instrumentation-based dynamic type inference analysis used in our framework
to determine service message types. Chapter 6 describes the conversion of the separated
and typed business class to an SCA service component, and the separation of the service
database. In Chapter 7 we demonstrate our framework and automation on two production
web applications, Moodle and SCARF. Finally, in Chapter 8 we summarize, discuss our
conclusions and outline the limitations of our implementation and future work still to be
done.
In the next chapter, we set the stage by introducing the concepts of SOA, reviewing
existing work, and introducing the technologies used in our solution, the TXL source trans-
formation system, and IBM’s Service Component Architecture.
6
Chapter 2
Background
Although Service-Oriented Architecture (SOA) has become popular in recent years, the
majority of legacy systems are still not SOA enabled. The increase in the amount of infor-
mation that companies must handle has resulted in a considerable increase in the complex-
ity of the legacy systems that store this information. While moving to a service-oriented
architecture platform can help in handling this increase, at the same time it is important
to preserve the investment of many years of tuning and debugging of the legacy assets as
much as possible. Several techniques have been proposed for modernizing legacy systems
towards service-oriented architecture.
Approaches to migrating web applications to web services are lacking [2]. Many legacy
web applications are implemented using scripting languages such as PHP [3] or Python
[33]. These languages are dynamically typed, reflexive and support dynamic changes to
the code. In addition, PHP only fully supported object oriented programming in version
5 [56]. The continuing evolution of these applications has resulted in implementations in
mixed programming paradigms. This combination of highly dynamic applications,mixed
paradigms, and the multilingual code bring the challenge to the analysis and refactoring
of legacy web application systems for the purpose of migrating them to SOA. While our
framework is applied to transforms components of a PHP application to web services in an
2.1. SERVICE-ORIENTED ARCHITECTURE 7
SOA environment,it can be extended to support other languages.
In this chapter we introduce the basic ideas of Service-Oriented Architecture (SOA),
review other recent work in the migration of legacy systems to SOA, highlighting the
strengths and weaknesses of the various techniques, and identifying the need for automa-
tion. We end the chapter by briefly introducing the automation technology used in our
automated migration approach, the TXL transformation system [20].
2.1 Service-Oriented Architecture
Service-oriented architecture (SOA) [32] can be viewed as an architectural construct for
flexible connection of separate components in response to changes in business. SOA
focuses on the exchange of information among major software components and on the
reusability of the components by separating the interface from the internal implementation.
There are several features of SOA that make legacy system modernization appealing in to-
day’s world, including loose coupling, abstraction of underlying logic, agility, flexibility,
reusability, autonomy, statelessness, discoverability and reduced costs. The primary pur-
pose for the adoption of SOA is to improve business communication so that the goals of
the enterprise can be more readily realized.
2.2 Legacy Systems
Legacy software can be written in COBOL, HTML, Perl, or even C and Java. These ap-
plications, while in active use, experience modifications and updates over a period of time.
This will result in functional changes such as changes to the business rules that direct the
execution of these applications. In almost every instance the application documentation
does not keep up with every modification and over time this embedded knowledge gets
forgotten. Such applications become legacy as they represent a significant investment in
resources and repository of knowledge [41].
2.3. COMPARISON CRITERIA 8
Legacy systems outline the core of many enterprise’s business processes; they are mis-
sion critical elements of an organization’s infrastructure. However they can cause several
problems: legacy systems may run on obsolete hardware that is slow and expensive to
maintain and they are difficult to extend. In addition, software maintenance can also be ex-
pensive, because documentation and understanding of system details is often absent; trac-
ing faults is costly and time consuming; and a lack of clean interfaces makes integrating
legacy systems with other systems difficult.
Legacy systems are too important to be discarded and thus must be reused. Strategi-
cally, the objective of moving to a service-oriented architecture is to build a new architec-
ture that will overcome the problems presented by legacy systems. However, legacy assets
must be leveraged and incorporated with modern technologies and applications. Migration
legacy systems to new environment is indeed an important subject, however, it is still not
fully understood or dealt with. The migration of legacy systems’ data is crucial for orga-
nizations spending too much to maintain the business value of their outdated information
systems and thus it is an important area of research. The characteristics of service-oriented
architecture present the promise of enabling existing legacy systems to expose their func-
tionality as services, without making major modifications to the legacy systems.
Service-oriented architecture migration is an architectural migration from any non-SOA
system to a system that follows the service-oriented architecture principles, in order to
achieve service-oriented architecture. The major benefits of adopting service oriented ar-
chitecture as a design framework is the ability to realize rapid and low-cost system de-
velopment and to improve total system quality. There has been no successful practical
experience report from projects using a comprehensive modernization approach.
2.3 Comparison Criteria
We compare the approaches with respect to the following eight criteria:
2.4. REPLACEMENT OF LEGACY SYSTEMS 9
• Modernization Strategy. The strategy behind the proposed approach: one of replace-
ment, redevelopment, wrapping or migration.
• Legacy System Type. The kind of system to which the technique applies.
• Degree of Complexity. Time/cost complexity of the method (if reported).
• Analysis Depth. The strategy used to analyze the legacy system to understand its con-
cepts and locate the important functions to be exposed as part of SOA architecture.
The analysis could be shallow or deep depending on the strategy used. Minimal de-
pendency on the existing legacy system components in achieving SOA architecture
can provide more flexibility.
• Process Adaptability. How well the process adapts to the legacy system to minimize
the extent of the required modifications.
• Tool Support. To what degree is the process automated, and if automated, whether
the approach is supported by a proposed tool or an existing tool.
• Degree of Coverage. Does the proposed approach present a complete strategy for
moving to SOA, or only a specific part of the modernization.
• Maturity Level. Has the proposed approach been applied and validated. We clas-
sify the proposed approach as an idea, a method demonstrated by a case study, or a
commercially proven technique.
2.4 Replacement of Legacy Systems
Replacement can be extremely disrupting to the entire organization. If the business rules
that run the legacy application are well understood in the organization and the legacy system
involves obsolete or difficult to maintain technologies, then it may make sense to retire the
2.4. REPLACEMENT OF LEGACY SYSTEMS 10
application and replace it entirely with an off-the-shelf package or a complete rewrite of
the legacy system from scratch.
An organization may choose the replacement strategy if wrapping, redevelopment, and
migration will impose costs that cannot be justified. However, rewriting the application
from scratch is expensive, risky and time consuming. This approach delivers a customized
solution that can be built exactly to meet the organization’s needs.
Commercial off-the-shelf (COTS)[37] systems are ready-made, commercially available
software products. Replacing the application with a COTS component, while less risky and
time consuming than rewriting, can also be expensive since future modifications may be
difficult and expensive to perform.
There are some cases where a COTS solution may not be a good option: important busi-
ness are embedded in the legacy system, modification of the COTS package is expensive,
or the loss of control of the software code base by the organization.
Replacement can take place either by using a big-bang strategy or incrementally. If the
legacy system has a well defined structure, then it makes most sense to replace it incremen-
tally.
Comella-Dorda et al.[19] state that the replacement strategy has two significant risks
that should be taken into consideration: the maintenance of the new system,which will not
be as familiar as the old system; and the lack of a guarantee that the new system will be
as functional as the old legacy system. Since service-oriented architectures are designed
to support reuse of existing infrastructure, resources and code within some particularly
defined concepts, we consider the replacement strategy for legacy code to be the least
desirable solution for migration to SOA.
2.5. WRAPPING STRATEGIES 11
2.5 Wrapping Strategies
Wrapping provides a new SOA interface (e.g. WSDL) [31] to a legacy component, making
it easily accessible by other software components. It is a black-box modernization tech-
nique, since it concentrates on the interface of the legacy system, hiding the complexity of
its internals. Wrapping is used when the legacy code is too expensive to re-write, is rela-
tively small, can be reused, and a fast, cost-effective solution is needed. Wrapping gives
legacy systems the benefits of service oriented architecture in a quick and a simple manner.
If the legacy system has a high business value and good quality code, wrapping can be a
good option.
The main problem is that this strategy does not change the fundamental characteristics
of the legacy applications that are being integrated. Wrapping will not solve problems al-
ready present, such as problems in maintenance and upgrading. In many cases, studying the
internals of the legacy system is important and white-box modernization tools are required.
2.5.1 Overview of wrapping techniques
Sneed[68, 67] discusses a tool-supported method for maintaining legacy code within an
SOA environment. Legacy code is wrapped in an XML shell which allows individual func-
tions in the programs to be offered as web services. The code segments that perform a
desired service or data modification are identified using clustering tools and data flow,are
extracted,and a new component is built using them. The new component is given a WSDL
interface, and a SOAP framework is used to package the component[48]. Finally, a proxy
is made to link the new services into the SOA architecture. The technique has been illus-
trated by wrapping a COBOL calendar function extracted from the legacy software of a
Swiss bank, and the approach has been applied successfully to the SOA integration of both
COBOL and C++ programs. It is most suitable for smaller programs since identifying and
exposing business functions can be time consuming.
2.5. WRAPPING STRATEGIES 12
Canfora et al.[11] propose a method to make the interactive functionalities of legacy
systems accessible as Web Services by wrapping them in an SOA interface. The method
provides the legacy system with a request/response interface, where a client invokes a ser-
vice using a request message and the provider responds with the required results. The wrap-
per interprets a Finite State Automaton which models the interaction between the client and
the legacy system. They generate a wrapper for the email client Pine, which provides an
SOA interface to the get message functionality. In more recent work[12], this wrapping
technique is used as a part of a complete migration process consisting of the selection of
the desired services, wrapping of the selected use cases and deployment and validation of
the wrapped use cases. The main problem with the technique is that most of the work is
done manually, making it difficult to use in industrial solutions.
Stroulia et al.[71, 70] outline an overall process of legacy migration using the CelLEST
method. The user’s interactions with a legacy system are reverse engineered and the task-
specific segments of this interaction are wrapped in new web-accessible front-ends. The
process consists of three steps:
1. Collect system-user interaction traces using specially instrumented, non-intrusive
middleware.
2. Reverse engineer the dynamic behavior of the system interface in terms of the screens
it presents to the user and user navigation through them.
3. Analyze the task-specific navigation paths to extract a model of the user’s task of
interest, in terms of the interface navigation and the information exchange it implies.
CelLEST has been demonstrated on infoMcGill, a legacy application of McGill Uni-
versity.
The case study was done by a single person familiar with the legacy system. This is a
disadvantage of the approach, since a person familiar with the legacy code cannot always
2.6. REDEVELOPMENT STRATEGIES 13
be found. CelLEST does not require any understanding of legacy code, modeling instead
the tasks accomplished by legacy application users based on traces of their interactions.
Although this code-independence is an advantage, it can be complicated to use the approach
when the number of interactions between the users and the legacy application is large.
In Sneed and Sneed[69], an interface is constructed wrapping the navigation and execu-
tion of a legacy system for a standard web browser. Individual blocks of code are wrapped
and reused as web services using a seven step process: Function Mining, Function Wrap-
ping, XML Schema Creation, Server Stub Generation, Client Class Generation, Server
Linking, and Web Service Binding.
Functions of the legacy code are extracted based on information provided by the Soft-
Wrap tool, however there must be a study done before choosing the functions.
2.5.2 Comparison of the techniques
Table 2.1 summarizes the wrapping approaches according to our comparison criteria. All
the techniques have advantages and disadvantages. However, the approach presented in
[11] is largely manual, which makes it the least preferred approach. It is difficult to evaluate
the complexity of the approaches, since all techniques depend a great deal on the size of
the legacy system. In general however the complexity of the wrapping techniques is low,
since there is no deep analysis of the legacy system and only the interface is exposed as
web services.
2.6 Redevelopment Strategies
In this study we use the term redevelopment to refer to reengineering approaches. Reengi-
neering is the analysis and adjustment of an application in order to represent it in a new
2.6. REDEVELOPMENT STRATEGIES 14
Ref. Legacy System Type
Degree of complexity
Analysis Depth Process Adaptability
Tool support
Degree of coverage
Maturity Level
Sne
ed
[12,
13]
Legacy programs
NA Depends on the business rules in the
legacy code
Uses Code Stripping
Automated Complete Case
Study
Str
ouli
a et
al.
[15,
16]
Code independent
Depends on the legacy
application
-users’ interactions with the legacy
application - legacy code independet
a model of the interface
behaviour of the legacy system and
users
Semi-automated
Complete Case Study
Can
fora
et a
l. [1
7]
Interactive, legacy system
NA use cases within legacy appliaction
NA Manual Complete Case Study on Pine System
H. M
Sne
ed
and
S. H
. S
need
[14
]
individual blocks of
code
NA NA NA Automated Complete Case
Study
Table 2.1: Summary of Wrapping Techniques
form. Reengineering can include activities such as reverse engineering, restructuring, re-
designing, and re-implementing software. The following approaches use reverse engineer-
ing and reengineering to add new SOA functionality to existing legacy systems.
There are three main issues in service-oriented reengineering: service identification,
service packaging, and service deployment. Identification of services from a legacy system
is not an easy task. Software reengineering can play an important role in migration to
the service-oriented environment. It is especially applicable to legacy systems with the
following characteristics:
1. The legacy system needs to be migrated to a distributed environment and can be
wrapped and exposed as a Web Service.
2. The legacy system has embedded reusable and reliable functionality with valuable
business logic.
3. Several components in the legacy system are more maintainable than the whole
legacy system.
2.6. REDEVELOPMENT STRATEGIES 15
4. The embedded functionality is useful to be exposed as independent services.
5. Components of the target system run on different platforms or vendor products.
6. Some of the legacy components can be replaced gradually without affecting the ser-
vice consumer.
2.6.1 Overview of redevelopment techniques
Chung et al. (2005)[18] describe a project in which a legacy theorem proof checking and
derivation tool called Bertie3 is reengineered to service-oriented architecture, resulting in
a new tool called Service-Oriented Bertie (SoBertie) that provides the core capabilities of
Bertie3 as web services.
Chung et al. (2007)[17] present a service-oriented software reengineering (SoSR)
methodology designed for applying SOA to legacy systems. The SoSR methodology, a syn-
thesis of best practices, is architecture-centric, service-oriented, role-specific, and model-
driven. It is conceptualized from a three service-participants model, a 4+1 view model, and
RACI charts. Although there are no full examples using SoSR as yet, a case study of the
purchasing department of a retail store legacy inventory system called GMPO is presented.
Distante et al.[29] present a holistic approach to redesigning legacy applications for the
Web using the Ubiquitous Web Applications Design Framework (UWA) and an extended
version of its Transaction Design Model (UWAT+). It consists of design recovery technolo-
gies for the legacy application and forward design methods for Web-based systems. The
process used to produce the UWA/UWAT+ conceptual design of the new application con-
sists of three steps: requirements elicitation, reverse engineering, and forward engineering.
Chen et al.[15] use feature analysis to support service-oriented reengineering. Feature
analysis includes identifying system features, constructing a feature model to organize the
2.6. REDEVELOPMENT STRATEGIES 16
identified features, and identifying their implementation in the legacy system through fea-
ture location techniques.
The authors used a library management information system (MIS) in a digital campus
as a case study. The MIS is analyzed using a top-down technique of domain decomposition
and feature analysis. Several services are identified along with their features. The imple-
mentation of the identified services is then generated by a web services wrapper tool. The
tool is able to generate the glue code for Web Services and the related source code of Web
Service methods.
Cuadrado et al.[23] propose a process for recovering legacy system architecture in order
to identify the plan to be carried out in modernizing the legacy system. Theirs is a white-
box approach based on modifying the existing legacy code. It uses a three step process
consisting of legacy architecture recovery, creating an evolution plan, and executing the
plan. The architecture recovery supports the creation of proper documentation. The evolu-
tion plan consists of four sequential phases: architecture selection, definition of evolution
cycles, planning of evolution cycles, and a preliminary feasibility check. The process is
completed by execution of the plan.
2.6.2 Comparison of the techniques
Table 2.2 summarizes the characteristics of the redevelopment approaches using our com-
parison criteria. For these techniques it was difficult to identify the degree of process adapt-
ability. While each technique uses a different approach to identifying the legacy code with
business value, all of them provide tool support to help. All of the techniques except Chung
et al. (2005) [18] provide a case study.
2.7. MIGRATION STRATEGIES 17
21
the plan, which depends on the legacy system at hand thus phases can be process will
vary from executed either sequentially or in parallel.
7.3 Comparison of the techniques
Comparison of the discussed approaches above according to the selected characteristics is summarized in the following table.
When comparing the above techniques, we noticed that it was hard to identify the degree of
process adaptability. Each technique used a different approach to identify the legacy code with a
business value. In addition, all the techniques have tool support. While all the techniques used a
case study to prove their validation, the work done in [20] did not provide a case study to show
the effectiveness of their technique.
Ref. Strategy Legacy System Type
Degree of complexity
Analysis Depth Process Adaptabili
ty
Tool suppor
t
Degree of coverage
Maturity Level
Chu
ng e
t al
(200
5) [2
0] RE logic
derivation program
Moderate Dependent NA Yes Complete Proposed Idea
Chu
ng e
t al.
(200
7) [2
1] RE Interactive
legacy system
Moderate Reverse software engineering and service-oriented forward software
engineering
Reverse Software
Engineering (RSE)
Yes Complete Case study
Dis
tant
e et
al
[22]
RE Windows stand-alone
application
Time consuming
Based on design recovery &
forward design methods
Web transaction &
navigation Mode
Yes Complete Case study
Che
n et
al.
[23]
RE Technical environ.
Dependent Source code identification
NA Yes Complete Case study On library
Management Inf.
System
Cua
drad
o
Et a
l. [2
4]
RE Dependent Dependent Detail description of the legacy
system
NA Eclipse TPTP
Omondo UML
Complete Case study on a
medical imaging system
Table 2.2: Summary of Redevelopment Techniques
2.7 Migration Strategies
In these methods, the entire legacy application and its core framework is migrated to SOA.
Legacy code is identified, decoupled, and extracted using approaches similar to those used
in wrapping and redevelopment. User interfaces are then reengineered to be compatible
with an SOA structure. Migration strategies incorporate both redevelopment and wrapping
and aim to produce a system with an improved SOA-compatible design. It is not always
obvious how to distinguish migration approaches from wrapping and redevelopment tech-
niques. Here we use the term migration when referring to any approach which moves the
entire legacy system and its core framework to the new environment.
2.7. MIGRATION STRATEGIES 18
Ref. Legacy System Type
Degree of complexity
Analysis Depth Process Adaptability Tool support
Degree of coverage
Maturity Level
Ave
rsan
et
al.[
26] COBOL
Program
N\A Static analysis
The running legacy programs are
essentially unchanged
Yes Complete Pilot project
O'B
rien
et a
l. [2
7]
System Independent
N\A Architecture Reconstruction
Information on legacy system are gathered/
the legacy code is unchanged
Yes Concentrate on identification and reuse of
legacy components as
services
Case Study
On C++
Code
Lew
is e
t al.
[28,
29,3
0]
Program
Independent
Depend on the legacy
system
Architecture reconstruction &
Detail analysis of the target SOA
information on legacy system characteristics,
architecture, and code characteristics are
gathered
Yes Complete Set of Guidelines
Zha
ng e
t al
. [31
]
Object-oriented program
NA Hierarchical clustering method to
identify potential services
Domain analysis is used to identify the
business logic
Yes Complete Case Study
Zha
ng e
t al.
[32]
Legacy e-Payment
systems
NA The original legacy system integrated within the target
system
NA NA Complete Case Study
Cet
in e
t al
. [33
] Program
Independent
NA Legacy system is analyzed
If change is needed, legacy component are modified or replaced
Yes Complete Case Study
Table 2.3: Summary of migration techniques
2.7.1 Overview of migration techniques
Aversano et al.[8] present a case study in which a COBOL system is migrated to a web-
based service oriented architecture. The legacy system is divided into user interface and
server (application logic and database). The user interface has been migrated into a Web
browser shell using Microsoft Active Server Pages and the VBScript scripting language
and the MORPH approach has been used to map the components of the existing interface
onto the new Web based interface. While the server has been wrapped and integrated into
the new web-enabled system with dynamic load libraries written in Microfocus Object
COBOL, loaded into Microsoft Internet Information Server (IIS), and accessed by the ASP
2.7. MIGRATION STRATEGIES 19
pages.
O’Brien et al.[53] present a strategy that identifies and uses legacy components as ser-
vices. Architecture reconstruction is used to identify dependencies between components
for migration to services and thus provide an organization with a better understanding for
their decision-making process.
Lewis et al.[44, 45]and Smith [65] discuss a migration technique called the Service-
Oriented Migration and Reuse Technique (SMART) that helps organizations analyze legacy
systems to decide whether their functionality can reasonably be exposed as services in a
Service-Oriented Architecture (SOA). SMART considers the specific interactions that will
be required by the target SOA and any changes that must be made to the legacy compo-
nents. It gathers a wide range of information about legacy components, the target SOA,
and potential services to produce a service migration strategy as its primary artifact.
Z. Zhang et al.[81] propose a reengineering approach that applies a hierarchical cluster-
ing algorithm to understand the legacy code in order to extract it for web service construc-
tion. The clustering technique is used to extract independent services from legacy code.
The technique supports service identification and packaging, providing functional legacy
code as web services.
J. Zhang et al.[80] discuss a current project on the design and development of pass-
through authentication (PTA) web-services for on-line electronic payment applications.
The application is an on-line synchronous/asynchronous payment processing application
that can perform real-time or batched payment transactions. Although this approach is han-
dling exposing business logic in legacy code as services, the main concern is not to achieve
SOA architecture, rather to expose the legacy system’s functionality as web services.
Cetin et al.[13] propose a mashup migration strategy, addressing both the behavioural
and the architectural aspects of the migration process. Their method consists of six steps:
model the target enterprise business requirements; analyze the existing legacy system; map
2.8. CHOOSING A STRATEGY 20
the target enterprise model to legacy components and identify services; design a concrete
mashup server architecture; define service level agreements; and implement and deploy
services.
The main idea is the integration of the the legacy system at the presentation layer, which
requires re-inventing the popular mashup technology of Web 2.0 at the enterprise level.
2.7.2 Comparison of the techniques
Comparison of the discussed approaches above according to the selected characteristics is
summarized in Table 2.3
As a summary, the above techniques have different approaches to perform their func-
tionality. All the techniques show a case study to support their claims except the work done
in [44, 45]and [65] where SMART is introduced as a set of guidelines to direct the process
of migration. We noticed that since SMART is a legacy system independent, it could be
used in any of the other techniques to evaluate the legacy system involved in the migration.
From the work done in the area of migration techniques towards SOA, the benefit of the
strategy is well understood however there is still no general migration technique that can
be applied that solves all the problems that a developer may face in this area.
2.8 Choosing A Strategy
Given the different strategies for modernization a legacy system to SOA, the question is
how to choose between them. There are several aspects that should be taken into account
when choosing among these different strategies. Table 2.4 summarizes the strengths and
weaknesses of each.
It is possible to combine two or more modernization strategies to achieve the required
goal depending on the advantages and disadvantages of each strategy in the context. It is
not always easy to reuse legacy system components and expose them as services. In some
2.9. WEB SERVICES 21
Strategy Advantages Disadvantages
ReplacementReduce maintenance Time consuming
Improve business functions ExpensiveExperienced resources needed
WrappingFast Inflexible
Difficult maintenance
RedevelopmentIncrease agility Source code needed
Flexibility Original requirements neededReduced cost
MigrationStable environment Time consumingTools availability Experienced resources needed
Source code needed
Table 2.4: Summary of modernization strategies
situations, exposing legacy systems as services will have a higher risk and a higher cost
than replacing them entirely with a new SOA architecture. There is no perfect solution to
the problem of modernizing a legacy system. The choice of strategy depends entirely on
the goals for the SOA architecture, the available budget and resources and the time needed
to complete the project.
2.9 Web Services
Web Services by themselves do not equal Service-Oriented Architecture (SOA) [79]. Web
services are a collection of technologies which provide the ability to build programming
solutions for specific messaging and application integration problems. XML [58], provides
a language that can be used between different platforms and programming languages and
still express complex messages. Simple Object Access Protocol (SOAP) [48], Web Ser-
vices Description Language (WSDL) [31],and Universal Description, Discover and Inte-
gration (UDDI) [52]. By using Web Services, web applications can publish their functions
or messages to the rest of the world. Web Services use XML in order to code and to decode
data, and use SOAP to transport the data. At the moment, these existing technologies are
2.10. THE NEED FOR AUTOMATION 22
adequate to build an SOA. There are several technologies that offer extensions for develop-
ing web services in PHP web applications. In this thesis we are using Service component
Architecture (SCA) technology, that will be discussed further in Chapter 6.
2.10 The Need for Automation
The process of migrating to SOA can be a tedious and error-prone task. Even after poten-
tial service boundaries have been identified, the actual process of refactoring to separable
classes, converting those classes to services, separating the services from the original ap-
plication and refactoring databases and other external data stores is challenging and fraught
with technical pitfalls that can cause the project to fail.
In this thesis we propose a framework and reusable method based on source transfor-
mations to automate virtually all of this process, largely eliminating the need for hand work
and avoiding the technical pitfalls. The resulting automated process has the potential to in-
crease the speed and accuracy of web application migration to SOA by a large factor by
eliminating most of the handwork and potential for error.
2.11 Source Transformation
Our framework uses formal source transformations to automate the steps of a migration
framework for World Wide Web applications from traditional monolithic form to one based
on Web Services. Source transformation is a programming technique based on rules that
generically specify the relationship between the original code and the refactored or repro-
grammed code and automatically apply the rules to input code to perform the changes.
While there are many source transformation systems that could be used to implement
our framework , in this thesis we have used the TXL source transformation language [21] to
2.12. SUMMARY 23
encode and implement our transformation rules. TXL is a programming language specif-
ically designed to support source transformation and for manipulating and experimenting
with programming language notations and features. TXL has been used in many production
applications with transformations involving many of lines of source code.
The TXL transformation process mainly involves three steps:
• a context-free (base)grammar for the source language to be manipulated .
• a set of context-free grammatical changes to the base grammar.
• a set of source transformation rules to implement transformation of the extensions to
the base language. [21]
The TXL processer parses the source program and converts it into a parse tree, then
recursively applies the set of transformation rules, beginning with a main rule, until there
is no match encountered in the parse tree. TXL finalizes the process by unparsing the
transformed parse tree into the target program.
2.12 Summary
In this chapter we have introduced the basic ideas of Service-Oriented Architecture (SOA)
and reviewed the state of the art in migration from legacy applications to SOA. We have
identified the need for automation to avoid the tedious and error-prone process of hand
implementing such migrations, and our plan to automate the majority of them using a
framework based on source transformations. Finally, we reviewed the basics of TXL, the
source transformation system we will use as the basis of our automation.
In the next chapter we introduce the meat of our work, a framework for migration of
legacy monolithic World Wide Web applications to SOA that automates virtually all of the
2.12. SUMMARY 24
code refactoring and reprogramming to yield a service-oriented web application based on
reusable web services.
25
Chapter 3
Web Application to SOA Migration Framework
In this chapter, we introduce our framework for semi-automatically migrating monolithic
legacy web applications to SOA by separating potentially reusable features as web services,
using source transformations to automatically analyze and reprogram web application code
to turn these into web-based business system to more complex inter-business services and
interactions. We also describe each of our proposed automated steps in our framework.
Such modernization helps make web applications more flexible, allowing them to more
easily integrate functionality with other systems and respond to rapidly changing business
needs and competition. While the problem of migrating various kinds of legacy software
systems to a service oriented architecture (SOA) environment has been well studied in the
literature, approaches to migrate web applications to web services are lacking.
3.1 A Migration Framework
The proposed framework uses a new approach to the problem of legacy system migration to
service-oriented architecture. It is one of the first approaches to explore the area of moving
a monolithic web application to SOA with significant levels of automation. The result can
be considered as a service-oriented web application that implements the endpoints of a Web
Service. The framework can also be used to combine different sets of services from two or
3.1. A MIGRATION FRAMEWORK 26
!!
!!
!!
!!
!! !
!
!!
Dynamic Web application
"#$%&%#'()*(+,&-()).%($/0-#/1$)
"#$%&%#'()*(+,&-())*(2#+#/1$)3)4&5+#/1$))
Adapted Web application Using Services
)
!!
!!
!!
"#$!%&'(!%)*&$!+,!-#./($&!0!
Figure 3.1: A Migration Framework
more different web applications to construct a new web service application which behaves
like the two original applications together.
The proposed framework (Figure 3.1) consists of two main steps, Service Identification
and Service Migration, to produce a new application using web services.
3.1.1 Service Identification
One of the main challenges in modernizing a web legacy system is the identification of
the suitable set of services in the legacy code that have business value. It is an essential
step in any migration process towards SOA. While many approaches in this area aims at
automating the identification process, it is still widely done manually.
Our approach does not attempt to solve the identification of services within the ap-
plication. Rather we intend to leverage other research such as the work done by Asun-
cion et al.[6]. Asuncion et al. propose goal-based, model-driven and service-oriented
approaches in order to separate the business rules within the business process. In [45]
Lewis et al. present The Service Migration and Reuse Technique (SMART)used to discover
which legacy systems can be used as services in a Service Oriented Architecture(SOA). The
SMART process provides set of guidelines to document the status of a given legacy system
in order to identify the context, the current system capabilities, describe the target SOA sys-
tem state, analyze gaps between the current and target state and describes the steps needed
3.1. A MIGRATION FRAMEWORK 27
in order to create a migration strategy.
Other approaches include Chen et al. [16] and Aversano et al. [9].
O’Brien et al. [53] present a strategy for architecture reconstruction in legacy systems
modernization by Identifying and reusing legacy components as services. Zhang and Yang
introduce the use of cluster analysis in [81], and in [30] Dwivedi and Kulkarni present
a model-driven approach towards service identification which utilizes process maps and
service hierarchies.
In our framework, the output of the service identification step is an identified candidate
service with the desired business functionalities. This identified candidate is then the input
to our automated migration process. In our experiments, we carried the identification pro-
cess manually. Based on the functionalities that we wanted to extract from the adapted web
application to be included in the web services, we identified each the candidate services
using XML [58] markup of the application source.
In our identification notation, each candidate service operation is marked up using a
<service function = function-name> tag, where function-name is the user-suggested name
for the candidate service operation (Figure 3.2).
3.1.2 Service Separation & Migration
Candidate service migration is the process of separating each identified candidate service
into a separate class , extracting it from the original application code, converting the created
<?php....HTML Code....$x = checkdate();<service function = given function name>
$name = strrev ($fname);< /service >.....
Figure 3.2: Service identification Tagging Using XML
3.2. AUTOMATING SERVICE MIGRATION 28
class into a separate independent service and adapting the original application code to use
the separated service. Once extracted and migrated to a separate service, the extracted
service is used by the adapted original application as a client, and can also be easily used
by other web applications.
Legacy web applications are generally implemented using scripting languages such as
PHP [3] or Python [33]. These languages are dynamically typed, reflexive and support
dynamic changes to the code. The nature of monolithic dynamic web applications, often
with mixed programming paradigms, makes the analysis and refactoring of web application
source code challenging. Thus the process of separation & migration of candidate services
is time consuming, technically complex and error-prone.
While are a number of different approaches to migrating various kinds of legacy soft-
ware systems to a service oriented architecture in the literature [64, 43, 42, 66, 7], ap-
proaches to migrating web applications to web services are lacking [2].
This lack of other approaches, and the clear need for automation to assist in web ap-
plication migration, is the focus of the work of this thesis. The goal of our research is to
to automate the separation and migration of the identified candidate services in PHP-based
web applications to web services using IBM’s Service Component Architecture (SCA)
standard. While our work concentrates on PHP in this thesis, the same process and strategy
can be easily adapted to other web application languages and technologies.
3.2 Automating Service Migration
Our process for automating service separation and migration consists of several steps, each
implemented using source transformation of the PHP web application code. The five steps
of our process (Figure 3.3) are:
1. Candidate Service Refactoring
3.2. AUTOMATING SERVICE MIGRATION 29
2. Candidate Service Separation
3. Parameter Type Inference
4. Service Component Conversion
5. Database Refactoring
In the following sections we describe each of these steps in detail.
3.2.1 Candidate Service Refactoring
The first step takes in the source code of the web application marked up to identify PHP
code sections as a candidate service. For example, in Figure 3.4 a simple PHP code section
is marked as part of the candidate service "Reverse".
The refactoring step creates a function for each of the marked up candidate code sec-
tions, and wraps them in a new class for the candidate service. Parameters of the functions
are inferred from the dependencies of the code sections on their context, and the original
Candidate Services
Refactoring
Candidate Services Separate
Service Migration
User Marked Web Application
!!"#!!!
!!
!!
"#!
!!!!!!
!!
"#!
!!!!
!!
$%&!'()*&+,(-!./)0&1!
Type Inference
.2!
DB Refactoring !!
!!!!
!!
!!
"#!"#!
!!
!!!
!
"#!
SCA Service Class
SCA Adapted Web Application
!!
"#!
!!!!
!!
$2!
$3!
$2!
$4!$5!
Figure 3.3: Steps of our Automated Process for Service Migration
3.2. AUTOMATING SERVICE MIGRATION 30
code sections are replaced by parameterized calls to the functions of the new candidate
service class.
When this step is complete, the application has been refactored to separate the original
marked code sections into functions of the separate class (Figure 3.5). The user provides a
name for the new class, in this case "Example".
3.2.2 Candidate Service Separation
In the next step, we separate the candidate service class into a separate PHP class file and
generate the appropriate PHP code necessary for the original program to use it, including
include directives for the separated class file and creation of an instance object for use in
the original code.
As part of the separation, we create a constructor class for each of the operations
wrapped in class, called the return class, which acts as a dictionary to contain the return
values of the operation. The results of the candidate service separation step on our simple
<?php
include ("welcomeT.html");
$fname = "John";
<service function = Reverse>$name = strrev ($fname);
< /service >
echo "My name is".$name;?>
Figure 3.4: Example Tagged Candidate Service Operation
class Example{
function Reverse ($name, $fname){
$name = strrev ($fname);return new Reverse_return ($name);
}}
Figure 3.5: Example Class Generated by the Refactoring Step
3.2. AUTOMATING SERVICE MIGRATION 31
<?php.......include_once "Example_return.php";include_once "Example.php";$Example_obj = new Example ();......$Reverse_return_obj = $Example_obj -> Reverse ($name, $fname);$name = $Reverse_return_obj -> name;.........?>
(a) Refactored Original Code after Candidate Service Class Separation
<?php
include_once "Example_return.php";
class Example{
function Reverse ($name, $fname){
$name = strrev ($fname);return new Reverse_return ($name);
}}?>
(b) Separated Candidate Service Class
<?phpclass Reverse_return{
public $name;public function __construct ($name){
$this -> name = $name;}
}?>
(c) Return Value Constructor Class for Reverse Operation of Separated Candidate Service Class
Figure 3.6: Example Refactored and Separated Candidate Service Class
example candidate class are shown in Figure 3.6.
3.2.3 Parameter Type Inference
Like most web application languages, PHP is a dynamically typed language, and types of
function parameters are not normally specified. A parameter simply has whatever type it
takes on at run time.
Parameters to service operations, by contrast, must be specified as part of the service
description. Thus in this step we first instrument each function of the refactored and sepa-
rated candidate service class to dynamically capture parameter types , and store in a file a
3.2. AUTOMATING SERVICE MIGRATION 32
<?phpinclude_once "Example_return.php";
class Example{
function Reverse (NULL $name, string $fname){
$name = strrev ($fname);return new Reverse_return($name);
}}?>
Figure 3.7: Example Refactored and Separated Service Class after Type Inference
table of each function annotated with the types of the parameters it receives when actually
run. In some cases, parameters end up with a NULL type, if the corresponding variable has
not been set when the function is called. In this case we delete the NULL values as they do
not affect the output.
This file is then merged with the original candidate service class, so it can be used
to explicitly annotate the parameters of the service operation functions of the candidate
service class with their expected types. These parameter types are required in the Service
Component Conversion step (Section 3.2.4) both for creating the Web Services Description
Language (WSDL) service description of the new service, and for creating Service Com-
ponent Architecture (SCA) parameter annotations for the operations of the new service.
The result of the parameter type inference step is a fully typed version of the separated
candidate class file (Figure 3.7).
3.2.4 Service Component Conversion
After inferring parameter types of the separated candidate service class operation functions,
we are ready to reprogram the class into a real service component. in this step we convert
the separated candidate service class file into an SCA (Service Component Architecture)
service component, by adding the required SCA annotations to the class and each of its op-
eration functions specifying the name, number and types of the expected service operation
3.3. SUMMARY 33
message parameters. As part of this conversion, the Web Service Description Language
(WSDL) service description file is created automatically by the SCA technology.
In order to create an SCA component several steps are required. SCA service type an-
notations must be added to each of the service operation functions of the candidate service
class to specify the types of parameters and return values of the operation. The SCA in-
terface and SCA service annotations must be generated for the candidate service class to
specify the service and its service binding (in the case of our conversions, the SOAP mes-
saging protocol). And finally, the original adapted web application must be converted to a
service client of the WSDL service description and SCA protocol.
Figure 3.8 shows the result of applying these transformations to the candidate service
class file and refactored original application to create an SCA-based client/server relation-
ship using the new web service.
3.2.5 Database Refactoring
In the final step of our migration the original application database is refactored to separate
those tables used only by the new separated service into a separate database, and remove
them from the original application database.
This allows the new web service to be used by other applications independently of the
original. In our current implementation of the framework, this final step is done manually.
3.3 Summary
In this chapter we have introduced a general framework for migration of legacy monolithic
web applications to web services, and the steps of an automated process to assist in the
migration. While we have aimed our automated process at PHP applications and the SCA
web services platform, the framework can be adapted to other languages and platforms
3.3. SUMMARY 34
<?php.....include_once "Example_return.php";include_once ("SCA/SCA.php");$Example_obj = SCA :: getService ("Example.wsdl");..........$Reverse_return_objStr = $Example_obj -> Reverse ($name, $fname);$Reverse_return_obj = unserialize ($Reverse_return_objStr);$name = $Reverse_return_obj -> name;echo "My name is".$name;?>
(a) Converted Original Application as SCA Client
<?php
include_once "Example_return.php";include "SCA/SCA.php";/**
* @service* @binding.soap*/
class Example{
/*** @param string $fname* @return string*/
function Reverse (string $fname){
$name = strrev ($fname);return serialize (new Reverse_return ($name));
}}?>
(b) Converted Candidate Service Class as SCA Service
Figure 3.8: Example Converted to SCA Web Service
using the same basic process.
In the following chapters we detail the implementation of each of the steps of our au-
tomation, demonstrating each step using a simple running example. In Chapter 7 we apply
the entire process to two real production PHP web applications, the Moodle course man-
agement system and the SCARF conference and research paper discussion forum.
35
Chapter 4
Service Refactoring
We present in this chapter the first step in our migration process, which is the automatic
refactoring and separation of candidate services identified in a web application. The refac-
toring is done in two steps: refactoring to collect potential service operations into a class,
and the separation of that class into a separate class file.
The refactoring process is shown in Figure 4.1. We begin with the Web Application
source, with candidate service operations for the service business functionality either auto-
matically or manually identified using XML markup. Our automated refactoring analyzes
the marked application and refactors it to collect and isolate the candidate service using
three refactoring transformations: Service class construction, Parameter identification, and
Return value class creation.
Refactoring refers to the technique of restructuring an existing body of code, by altering
its internal structure without changing its external behavior [47]. The goal of our refactor-
ing is to collect and completely separate the candidate service and its operations from the
rest of the application. The target of refactoring is not to enhance the performance of the
code, but to restructure the code in order to make it more readable or to achieve certain
goals (in our case, the collection of candidate service functionality into a separate class).
In order to be converted to a service, the refactored potential class must be separated
4.1. CANDIDATE SERVICE IDENTIFICATION 36
!"#
User Marked Web Application
!"#$%&'()*$"'+*),,'-%")./&'
'0"%(1-"'2)%)3"#"%,'
14"&.5-)./&''
0"%(1-"'-*),,'-/&,#%$-./&'
$%&'()*+,-.#
Service Class
6#/0#!!
!!
!!
Figure 4.1: Candidate Service Refactoring Process
Tagged Web Application
Adapted Web Application
!"#
Service Class Extraction
!#$%#!!
!!
!!
$%#
!!!!!!
"#$%&''()*+,-.%%&/+'0+,-.%
Service Class
!&'()(*+,#
Figure 4.2: The Candidate Service Separation Step
into a separate class file. The separation process is shown in Figure 4.2. We extract the
refactored candidate service class and adapt it to become a reusable separate class, and
adapt the original web application to use the separated class file.
4.1 Candidate Service Identification
The first step in migrating any legacy application to service oriented architecture is to un-
derstand the source code and its dependencies in order to identify potential services in the
application. In any given code there are business operations that may be turned into ser-
vices, user interface code that should not be included in services, and other business logic
4.2. A RUNNING EXAMPLE 37
that is not user interface but is not part of the potential service,however may be turned into
another service later.
In our work we are not addressing the identification of services, but rather are assuming
that the user has already identified candidate services as input to our process. We do not
attempt to solve the identification of services within the application. Instead we leverage
other research such as the work done by Asuncion et al.[6]. Asuncion et al. propose goal-
based, model-driven and service-oriented approaches in order to separate the business rules
within the business process. Other approaches to identification include Chen et al. [16] and
Aversano et al. [9].
Some authors provide tools that can be used as a front end to our process. O’Brien et al.
[53] present a strategy for architecture reconstruction in legacy systems modernization by
Identifying and reusing legacy components as services. There is also the use of cluster anal-
ysis by Zhang et al. [81], and Dwivedi and Kulkarni [30] present a model-driven approach
towards service identification which utilizes process maps and service hierarchies.
The input to our automated process is the web application source code with a markup
that identifies the code to be refactored and separated into services. Service identification
can be done either manually, as in our case study, or using tools such as those above.
4.2 A Running Example
In order to make the explanation of the steps of our process concrete, will be using a simple
PHP web application as a running example through the rest of the thesis to demonstrate
each of the stages of our migration automation. Figure 4.3 shows the example we will be
using.
The example is a simplified version of the login process (user management portion) of
a real example web application. In it, the user supplies a username and password, and upon
4.2. A RUNNING EXAMPLE 38
<?phpinclude ("config.php");include ("library.php");
if ($_SERVER[’REQUEST_METHOD’] === ’GET’) {include ("login_form.html");
}
if ($_SERVER[’REQUEST_METHOD’] === ’POST’){
if (!empty($SESSION -> has_timed_out)) {$session_has_timed_out = true;$SESSION->has_timed_out = false;
} else {$session_has_timed_out = false;
}
$user = $_POST[’username’];$pwrd = $_POST[’password’];
$id = getUserId($user,$pwrd);$USER = getUserData($id);
if($USER){
$_SESSION[’username’] = $USER;
$lastLogin = getLastLogin($USER);updateLastLogin($USER);
// HTML code//welcome and print user nameinclude ("welcome.html");
$Time = date("m-d-Y", $lastLogin);echo "Date of last login is $Time\n";
}
else {
include("login_fail.html");
}}?>
Figure 4.3: A Running Example Web Application
successful entry, a welcome message and the date of the the user last login is displayed.
When a wrong username and password are supplied, a login fail message is displayed.
In the example, all database operations are isolated in a library file called from the main
code. While this is the norm for most real PHP applications, in practice, refactoring of
inline database code may be necessary in the worst case.
We assume that, after the service identification process, the user has identified a candi-
date user authentication service, with two sections of code for candidate service operations.
1. The username and password is verified against a user table in the database using an
4.3. CANDIDATE SERVICE MARKUP 39
<service function=get_user>$id = getUserId($user,$pwrd);$USER = getUserData($id);
</service>
Figure 4.4: Marked Candidate Service Operation
SQL query, returning a USER object with information about the user.
$id = getUserId($user,$pwrd); $USER = getUserData($id);
2. The date of the last login is retrieved from the database based on the id of the USER
and then updated.
$lastLogin = getLastLogin($USER); updateLastLogin($USER);
The example is representative in that it presents all of the challenges of real applications.
The potential service operations have variables with different types. The supplied username
and passwords are strings. The USER is an object that consists of three fields, the id, the
username, and the user city. There is also an id variable which is an integer that is passed
between two calls in the first candidate operation.
4.3 Candidate Service Markup
We chose to use standard Extensible Markup Language (XML) tags for user markup of
candidate code sections. The proposed function name for the candidate operation is sup-
plied in the markup, and the candidate service class name is supplied as an input to the
refactoring process by the user.
Figure 4.4 shows an example candidate service operation code section markup, with
the proposed name “get_user” for the candidate service operation.
It is also important to mark the location of include files in the web application source,
since in the SCA service conversion process, SCA include files must be placed after all
4.3. CANDIDATE SERVICE MARKUP 40
<?phpinclude ("config.php");include ("library.php");<markinclude/>
if ($_SERVER[’REQUEST_METHOD’] === ’GET’) {include ("login_form.html");
}
if ($_SERVER[’REQUEST_METHOD’] === ’POST’){
if (!empty($SESSION -> has_timed_out)) {$session_has_timed_out = true;$SESSION->has_timed_out = false;
} else {$session_has_timed_out = false;
}
$user = $_POST[’username’];$pwrd = $_POST[’password’];
<service function = get_user>$id = getUserId($user,$pwrd);$USER = getUserData($id);</service>
if($USER){
$_SESSION[’username’] = $USER;
<service function = get_date>$lastLogin = getLastLogin($USER);updateLastLogin($USER);</service>
// HTML code//welcome and print user nameinclude ("welcome.html");
$Time = date("m-d-Y", $lastLogin);echo "Date of last login is $Time\n";
}
else {
include("login_fail.html");
}}?>
Figure 4.5: Running Example with Potential Service Operation Markup
the original includes in the input PHP code. If there are includes after the include for
SCA.php, they will not have been processed when the SCA runtime runs the service class.
This placement process is not easily done automatically, especially in case of other includes
embedded in the body of the code, so we leave it to the user to mark as part of potential
service markup.
Figure 4.5 shows the running example with the code sections corresponding to our
potential service operations marked up using XML < service > tags.
4.4. REFACTORING PROCESS 41
4.4 Refactoring Process
The refactoring and separation process is implemented using two separate TXL [20] source
transformations, each of which takes in the tagged original web application source code
with potential service operations marked up. In the first transformation, the candidate ser-
vice operations are extracted and gathered into a new PHP class function, and the new class
is separated into a class file. The output of this transformation is the new candidate service
class shown in Figure 4.2.
As part of the transformation, return type dependencies of the candidate service opera-
tion are analyzed, and a new return value class is generated for the returned result of each
candidate service operation. This is necessary because, when the candidate service class
becomes a true service later, a type will be needed for the result message from the service
operation.
Figure 4.6 shows the result of this first part of the refactoring on the running example
of Figure 4.5. The name of the new service class, in this case “login”, is chosen by the user
and passed to the transformation as a command line argument. The names of the candidate
operation functions (“get_date”, “get_user”) come from the candidate service operation
markup tags.
The candidate service class file created retains the include files of the original PHP ap-
plication, and adds an include for the operation return value classes (“include_once($login_return.php)
in the example). The original code segment for each tagged candidate service operation has
been turned into a method function of the new class.
For each of these new methods , the input variables and the return values are determined
as follows: all the variables used in an expression or otherwise used in the marked candidate
service operation code segment including the left hand side, are turned into parameters
of the new operation function. if the variable has not been used before, its type will be
4.4. REFACTORING PROCESS 42
<?phpinclude ("config.php");include ("library.php");include_once "login_return.php";class login{
function get_date ($lastLogin, $USER){
$lastLogin = getLastLogin ($USER);updateLastLogin ($USER);return new get_date_return ($lastLogin);
}function get_user ($id, $user, $pwrd){
$id = getUserId ($user, $pwrd);$USER = getUserData ($id);return new get_user_return ($USER, $id);
}}?>
<?phpclass get_date_return{
public $lastLogin;public function __construct ($lastLogin){
$this -> lastLogin = $lastLogin;}
}class get_user_return{
public $id;public $USER;public function __construct ($USER, $id){
$this -> id = $id;$this -> USER = $USER;
}}?>
Figure 4.6: Result of the Candidate Service Class Refactoring and Separation Transforma-tion for the Running Example
NULL and therefore will be deleted. Similarly, all variables appearing on the left side of
assignments in the marked code segment are turned into return values.
For each candidate service operation function in the service class, a return class is
generated that serves as a dictionary for the returned values of the service function. This is
important in the case when variables are modified by the code and yet referenced outside
the scope of the service. A simple constructor is created so that an instance of the return
class can be created and initialized as part of the return statement of the candidate service
operation. All variables modified in the candidate service code must be returned as part of
this return value instance.
The second part of the refactoring TXL source transformation modifies the original
4.4. REFACTORING PROCESS 43
<?phpinclude ("config.php");include ("library.php");
include_once "login_return.php";include_once "login.php";$login_obj = new "login";
if ($_SERVER[’REQUEST_METHOD’] === ’GET’) {include ("login_form.html");
}
if ($_SERVER [’REQUEST_METHOD’] === ’POST’){
if (! empty ($SESSION -> has_timed_out)){
$session_has_timed_out = true;$SESSION -> has_timed_out = false;
}else{
$session_has_timed_out = false;}$user = $_POST [’username’];$pwrd = $_POST [’password’];
$get_user_return_obj = $login_obj -> get_user ($id, $user, $pwrd);$id = $get_user_return_obj -> id;$USER = $get_user_return_obj -> USER;
if ($USER){
$_SESSION [’username’] = $USER;
$get_date_return_obj = $login_obj -> get_date ($lastLogin, $USER);$lastLogin = $get_date_return_obj -> lastLogin;
include ("welcome.html");$Time = date ("m-d-Y", $lastLogin);echo "Date of last login is $Time\n";
}else{
include ("login_fail.html");}
}?>
Figure 4.7: Result of the Candidate Service Client Side Refactoring for the Running Ex-ample
tagged web application to be a client of the new candidate service class. This transforma-
tion again takes the entire original tagged web application as input, but this time transforms
it into a client of the new separated candidate service class. The original PHP code after
refactoring is updated to be a client of the class as follows:
• Include files for the new candidate service class and the return value constructor
classes are added. The order of inclusion is important, since in the service conversion
step these will be turned into the SCA library and a reference to the new service
4.5. SUMMARY 44
WSDL file respectively.
• Creation of a new instance of the candidate service class (“login” in the running
example) is created and stored it into a local object variable (“$login_obj” in the
example).
• Each of the tagged candidate service operation code segments is replaced with a
method call to the corresponding new candidate service class function. The candidate
service class function returns and instance of the appropriate return class from which
the values of any variables modified within the service class are recovered.
Figure 4.7 shows the result of the second part of the refactoring on the running example
of Figure 4.5. Again, the name of the new service class, in this case “login”, is chosen by
the user and passed to the transformation as a command line argument.
4.5 Summary
In this chapter we have introduced the first step in our framework, the automatic refac-
toring and separation of the candidate services . We use source transformation in TXL to
automatically refactor and separate the web application into a candidate service class with
parameterized method functions for operations and a return value class that serves to pass
back values of modified variables that are outside the scope of the service. The original web
application is transformed into a client of the new candidate service class. We demonstrate
these transformations on a small running example web application. In the following chap-
ter, we present the type inference stage of our framework, which uses code instrumentation
to infer the types of the parameters and return values created as part of our refactoring. The
types of these candidate service operation function parameters and return values must be
known before the candidate service class can be converted to a web service.
45
Chapter 5
Type Inference
Once we have refactored and separated the candidate service into a separate class, we would
like to convert that separated class into an SCA service component. In order to do so, we
must specify the types of the service parameters and results. However, PHP, Python and
other similar web scripting languages are dynamically typed - variables simply take on the
type of their assigned values, and while a type may be declared for them, it is merely a hint
of what type they might be, not a requirement. In this chapter we use instrumentation and
test exercising of our candidate service classes to determine the types of candidate service
operation parameters directly from their use. The result is a new version of the candidate
service class with explicit type annotations for operation function parameters and results.
5.1 Background
The Service Component Architecture (SCA) service protocols were originally developed
for strongly typed languages such as Java and C++. Thus the Web Service Description
Language (WSDL) description files used to describe services identify both the types of the
parameters and the types of the results of the operations. WSDL is “an XML format for
describing network services as a set of endpoints operating on messages containing either
document-oriented or procedure-oriented information. The operations and messages are
5.2. OVERVIEW 46
described abstractly, and then bound to a concrete network protocol and message format to
define an endpoint” [31]. The types of these messages must be known if services and their
clients are to communicate meaningfully.
However, PHP, Python, Ruby and other scripting languages commonly used to imple-
ment web applications are dynamically typed languages, in which any variable can take on
a value of any type, for example a number, a string or an object type. Thus as part of our
automated migration, the types of the parameters and return values of candidate services
must be inferred in order to convert them to SCA service components (Chapter 6).
5.2 Overview
In type inference, explicit types are inferred from information extracted from the program.
There has been a lot of work done in the area of type inference in the literature, and there
are several approaches to inferring the types of variables in dynamically typed languages
[10] [55] [57] [40].
The process of type inference may take place either at compile time (statically) or at
run time (dynamically). Static analysis uses flow graph information to attempt to infer
how types flow through the variables, in order to determine those variables which have
a consistent type. Because of uncertainties in execution that cannot be inferred from the
source code, static analysis is often incomplete [50].
Dynamic analysis by contrast observes the actual behavior of the running program, and
gathers information directly from the variables themselves as they are used. Using code
coverage in testing, dynamic analysis can often infer more accurately and completely than
static analysis.
In our migration framework, the return types of the operations are already known, since
they are automatically generated as part of the refactoring step described in Chapter 4.
5.2. OVERVIEW 47
Candidate Service Class
!""#$%&'#()*+,-.')+/01)#
23',45*'#6/)"5"/+'#7',854'#1&',/01)*#
Instrumented Candidate Service Class
Dynamic Type Information
!))1+/+'#$%&'*##
!"#$
Typed Candidate Service Class
Merged Type Information
Figure 5.1: Dynamic Type Inference Using Candidate Service Class Instrumentation
Thus the remaining problem is to infer the types of the parameters of the service operation
methods of the generated candidate service class.
It is important to note that the types of other variables, either in the service operations
or in the remainder of the code, are unimportant since they are not involved in the service
communication and thus simply take on their dynamic PHP types as always. Thus, rather
than attempt a full static analysis, we chose to use a much simpler targeted dynamic in-
strumentation approach , which simply samples the types of parameters of our candidate
service class methods as they are invoked in running the refactored web application (Figure
5.1).
Our type inference begins by inserting instrumentation code into each of the operation
methods of the candidate service class to capture the types of parameters each time the
method is invoked, and write the information to a file. After exercising the application to
5.3. INSTRUMENTATION 48
<?phpinclude ("config.php");include ("library.php");include_once "login_return.php";
class login{
function get_date ($lastLogin, $USER){
$lastLogin = getLastLogin ($USER);updateLastLogin ($USER);return new get_date_return ($lastLogin);
}function get_user ($id, $user, $pwrd){
$id = getUserId ($user, $pwrd);$USER = getUserData ($id);return new get_user_return ($USER, $id);
}}?>
Figure 5.2: Original Generated Candidate Service Class
invoke all of the operation methods, the instrumentation will have provided the types of
values given for all of the parameters. This type information is then merged back into the
service class file as PHP type hints for the service operation function parameters.
5.3 Instrumentation
Figure 5.2 shows the candidate service class as generated by the refactoring step of Chapter
4 for the running example application. We use a TXL source transformation to insert
instrumentation code at the beginning of each operation function of the candidate service
class as shown in Figure 5.3.
At the beginning of the code for each candidate service operation function, the instru-
mentation code opens a file in the temporary (/tmp) directory, and writes a class header
for the service class in order to associate the information with the class. It then writes a
function header for the current operation function, including the type and name of each
parameter, a closing parenthesis and braces as shown in Fig 5.3.
For example, in the instrumented version of the generated candidate service class for
our running example (Figure 5.3), the instrumentation for the get_date function writes the
5.4. EXERCISING THE INSTRUMENTED CODE 49
<?phpinclude ("config.php");include_once "library.php";include_once "login_return.php";
class login{
function get_date ($lastLogin, $USER){
$FileHandle = fopen ("login.php", ’a’);fwrite ($FileHandle, "class login{\n function get_date(");fwrite ($FileHandle, gettype ($lastLogin).’ $lastLogin’);fwrite ($FileHandle, ", ");fwrite ($FileHandle, gettype ($USER).’ $USER’);fwrite ($FileHandle, ") {\n");fwrite ($FileHandle, "}\n}\n");fclose ($FileHandle);$lastLogin = getLastLogin ($USER);updateLastLogin ($USER);return new get_date_return ($lastLogin);
}function get_user ($id, $user, $pwrd){
$FileHandle = fopen ("login.php", ’a’);fwrite ($FileHandle, "class login{\n function get_user(");fwrite ($FileHandle, gettype ($id).’ $id’);fwrite ($FileHandle, ", ");fwrite ($FileHandle, gettype ($user).’ $user’);fwrite ($FileHandle, ", ");fwrite ($FileHandle, gettype ($pwrd).’ $pwrd’);fwrite ($FileHandle, ") {\n");fwrite ($FileHandle, "}\n}\n");fclose ($FileHandle);$id = getUserId ($user, $pwrd);$USER = getUserData ($id);return new get_user_return ($USER, $id);
}}?>
Figure 5.3: Instrumented Version of the Generated Candidate Service Class
type and name of the $lastLogin and $USER parameters to the instrumentation output file.
Thus each time any of the operation functions of the candidate service class is executed,
the instrumentation will append a class definition containing an empty function declaration
with explicit type annotations for each parameter to the instrumentation output file.
5.4 Exercising the Instrumented Code
The instrumented candidate service class must next be exercised to gather parameter type
information and write it to the instrumentation output file. The refactored web application is
run using the instrumented version of the candidate service class. The application is tested
sufficiently to generate type output for all of the candidate service operation functions,
yielding an instrumentation output file.
5.4. EXERCISING THE INSTRUMENTED CODE 50
<?php
class login {function get_user(NULL $id , string $user, string $pwrd ) {}
}class login {
function get_date(NULL $lastLogin, object $USER ) {}
}?>
Figure 5.4: Merged Instrumentation Output File
We exercise our instrumented candidate service from within the refactored web appli-
cation using the web application’s test suite (if available), or manually to ensure coverage.
When operations cannot be covered and types are not determined for a particular operation
function, the operation is considered dead code and therefore can be ignored or eliminated.
Following the instrumented test runs, the instrumentation output file may contain du-
plicate instances for operation functions. These duplicates are merged and checked to see
that the types of the parameters for each invocation are the same. The order of the function
operations in the output file is the order of the execution of the code
However, in the case of having different types for the same variable, it will be due to
the fact that there is an inconsistency in the application that has to be resolved manually.
The refactoring step (chapter 4) may identify variables used by the candidate service
operation code that do not yet have a value when passed as a parameter. These parameters
will have the inferred type NULL.
Figure 5.4 shows the output of the testing and merging phase for our running example
application.
In the example, the inferred type for the id and lastLogin parameters is the NULL type,
while both the $user and $pwrd parameters have been inferred to be of type string. $USER
in an instance of an object type.
5.5. ADDING INFERRED PARAMETER TYPES 51
<?phpinclude ("config.php");include ("library.php");include_once "login_return.php";
class login{
function get_date (NULL $lastLogin, object $USER){
$lastLogin = getLastLogin ($USER);updateLastLogin ($USER);return new get_date_return ($lastLogin);
}function get_user (NULL $id, string $user, string $pwrd){
$id = getUserId ($user, $pwrd);$USER = getUserData ($id);return new get_user_return ($USER, $id);
}}?>
Figure 5.5: Typed Generated Candidate Service Class
5.5 Adding Inferred Parameter Types
Once type inference is complete, another TXL source transformation integrates the inferred
parameter type information into the original candidate service class by replacing the func-
tion headers of each candidate service operation method with the corresponding header in
the merged instrumentation output file. The result is a fully typed version of the candidate
service class ready for conversion to a service.
Figure 5.5 shows the results of merging the inferred type information into the candidate
service class generated for our running example.
5.6 Summary
In this chapter we have introduced the type inference stage of our framework. In this stage
we determine the types of the parameters of the candidate service operations required for
conversion to a service. Our type inference process uses dynamic instrumentation and ex-
ercising of the application to gather the types of values passed to the parameters at run time.
5.6. SUMMARY 52
We automate the instrumentation process using source transformation technology, and ex-
ercise the application using tests sufficient to invoke every candidate service operation.
In the next chapter use the inferred type information in the next step of our framework,
conversion of the service classes to an SCA service component.
53
Chapter 6
Service Component Conversion and Database Refactoring
After type inference, the refactored, separated and typed candidate service class is ready
to become an independent service, and the original web application a client of the new
service. In this chapter, we describe the last step of our automated migration, the transfor-
mation of the candidate service class to a Service Component Architecture (SCA) service
component. We begin by outlining the basics of the SCA platform, and then present the
final source transformations to migrate our candidate service classes to SCA services. Fi-
nally, we outline the need for database refactoring, where the database is separated into the
portion used by the original client, and the portion used by the new service.
6.1 Service Component Architecture
There are several technologies that offer extensions for developing web services in PHP
web applications, all based on the SOAP [48] service messaging protocol.
• NuSOAP is a set of PHP classes that allow developers to create and consume SOAP
web services [62].
• PEAR is a SOAP client/server implementation for PHP [76].
6.1. SERVICE COMPONENT ARCHITECTURE 54
Figure 6.1: Service Component Architecture (adapted from [54])
• Service Component Architecture (SCA) is a general approach to enabling service-
oriented architecture for web applications. They work together with several program-
ming languages, including Java, C++, and PHP. The SCA web services platform was
originally created by a group of vendors, including BEA, IBM, Oracle, SAP, and
others and is now owned by OASIS [24].
In our framework we chose to use SCA because it is largely language independent and
easy to install, adopt and understand. In addition, the SCA platform provides the ability
to automatically generate WSDL service description files describing the implemented web
services, saving us the necessity of creating them ourselves. By using the SCA extension
we can also more easily implement reuse using configurable components and offer reusable
services using composite references.
While in our present conversion we use SOAP messaging for service communication,
SCA is also more general than the alternatives, providing bindings other than SOAP, such as
XML-RPC, JSON-RPC, and REST-RPC [63], making our migration results more flexible.
6.2. SCA FOR PHP 55
Service Component Architecture (SCA) for PHP makes it possible for a PHP program-
mer to write reusable components, which can be called in a variety of ways, either locally
or remotely via web services using an identical interface. The latest release of SCA be
downloaded at http : //pecl.php.net/get/SCA_SDO. SCA components export a service
interface that can be used by other service components. These components in turn can be
wrapped together to provide composite service components, which can be accessed in the
same way as individual components [34].
6.2 SCA for PHP
Conversion of a PHP class file to an SCA service involves a number of steps. Including the
standard SCA interface ′′SCA/SCA.php′′ in the class causes the PHP SCA extension to
recognize an annotated PHP class as a Web service. In order for SCA to find the service
class, the PHP filename of the class file must match the service class name.
SCA annotations in the service class file specify the operations, types and bindings of
the intended service. These annotations are encoded as specially formatted PHP comments,
which must be placed directly preceding the class and each method definition.
The first and most important annotation is @service, which designates the class as a
web service. The @binding.soap annotation tells the PHP SCA extension to use SOAP
bindings for the service. In order to deploy this new PHP web service, the only other
requirement is a running web server.
The second set of annotations specify the operations of the service, as annotations on
each of the PHP functions of the service class. Each method function of the service class
must be preceded by an SCA annotation comment specifying the parameters and return
value of the operation and their types.
6.2. SCA FOR PHP 56
<?phpinclude "SCA/SCA.php"
/*** @service* @binding.soap*/class addition {
/*** @parameter a int* @parameter b int* @result int*/function add(a,b) {
return a+b;}
}?>
Figure 6.2: Simple Example PHP SCA Service Class
Figure 6.2 shows the SCA annotations necessary to turn a simple PHP class that calcu-
lates the result of adding two integers into an SCA service with the operation “add”.
Before a PHP client application can call an SCA service, it must first load the Web
Services Description Language (WSDL) description of the service. The SCA for PHP
framework provides an automated means of generating the WSDL service description for a
service from the annotations in the service class file. Invoking the service using the special
URL http : //hostname/path/serviceclassfile.php?wsdl will automatically generate
the WSDL file for the service, which can then be stored in a service registry or loaded by a
client.
The client uses the WSDL file to instantiate a PHP proxy object for the web service,
from which the operations of the service can be invoked. Loading a WSDL service for use
in a client simply involves using the SCA getService operation (Figure 6.3), after which the
client application can use the operations of the service as if they were simply methods of
an object of a local PHP class.
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 57
<?phpinclude "SCA/SCA.php";
$addition_obj = SCA :: getService ("addition.wsdl");
......$x = $addition_obj.add ($y, $z);
......?>
Figure 6.3: Loading a WSDL Service in a PHP Client
6.3 Converting a Candidate Service Class to SCA
Converting our separated typed candidate service class to an SCA service requires three
steps:
• Serialization of the service-side service class operations,
• Serialization of client-side service calls and SCA adaptation of the original web ap-
plication, and
• Generation of the SCA service class annotations.
Figure 6.4 shows these three final steps in our automated migration framework. As in
the other stages of our process, each step is implemented as a TXL source transformation
of the PHP source code.
The first transformation identifies the object and array parameters of service opera-
tion functions of the typed service class generates de-serialization code for each of them.
Parameters of inferred type NULL are removed, and de-serialization code for parameters
that are of type object or array is added, as well as serialization of the result object of the
operation.
The second transformation matches arguments of calls to the service operations in the
adapted web application to the formal parameters of the typed service class and adds serial-
ization code for corresponding arguments and result values in the adapted web application.
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 58
Adapted Web Application
!"#$%#
!!!!!!
Typed Candidate Service Class
&'(#!"#$%&"'()"#*+(,-'
-"#%*.%/*+(,'!01'&.*--'*,,(2*+(,'
SCA Service Class
3#
$%#!!!!
!!!"#$%&"'0*..'
-"#%*.%/*+(,'
SCA Adapted Web Application
!)*#)+,-./0#
Figure 6.4: Candidate Service Class Conversion to SCA
As part of this transformation, the web application is converted to a client of the WSDL
service, and all uses of the candidate service class operations are converted to service object
calls.
Finally, the third transformation infers and inserts the required SCA annotation com-
ments for the service class and the parameters and return values of all service operations.
The result of this transformation is an SCA service component.
The following sections detail each of these steps, using our running example to demon-
strate the resulting changes.
6.3.1 Service Data Objects
Because a service accessed through an SCA call may be located on a separate or remote
machine, parameter and result types of primitive types such as integer or string must be
encoded in a machine-independent manner when passed to and from service operations.
The reason for this is that other types, such as objects and arrays, may contain pointers
(implemented as machine memory addresses) or depend on the layout of memory on the
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 59
client machine.
There are a number of methods for encoding data passed to and from services. One
such mechanism is provided by Service Data Objects (SDO) [14]. Two versions of SDO
are available for programs written in PHP:
1. SDO-DAS-Relational: Implements a persistent storage model in which objects are
represented as rows in a shared relational database. Objects are instantiated, fetched
and updated by both clients and the service using queries to the database.
2. SDO-DAS-XML : Objects are described using an XML schema and are converted to
and from XML text representation when passed between clients and services.
In a migration to services situation, the choice between the two is dependent on the
plans for database refactoring (Section 6.3.7). If the web application’s original database is
to remain shared between the service and the web application, then the relational approach
might be most appropriate. However, if the database is to be split with the new service as
part of migration in order to allow new clients independent of the original application, then
the XML-based approach may be better.
The XML-based method has the advantage that the types of parameters and return val-
ues are described using an XML DTD schema independent of the original application. The
XML representation is then used to transport parameter and result values to and from the
service.
Figure 6.5 shows a simple example DTD schema for a user class with two elements,
a username (string) and an id (integer). This XML description can be used to create PHP
objects, and can be used in a WSDL service description to define the types of the parameters
and results that are exchanged. PHP objects can be created using the XML DTD, and fields
of the objects can be read and modified like other PHP objects.
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 60
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:user="http://userSchema" targetNamespace="http://userSchema">
<xsd:element name="user" type="user:UserRecord"/><xsd:complexType name="UserRecord" mixed="true">
<xsd:sequence><xsd:element name="username" minOccurs="1" maxOccurs="1" type="xsd:string"/><xsd:element name="id" minOccurs="1" maxOccurs="1" type="integer"/>
</xsd:sequence></xsd:complexType>
</xsd:schema>
Figure 6.5: Simple Example XML DTD Class Schema
Complete conversion to XML schemas requires that all uses of objects throughout the
application be converted to use the XML representation, not just when passed to or from the
service. The decision between relational and XML use of SDO is a manual decision, and
complete migration to either is a substantial transformation with significant implications
for the entire application.
6.3.2 Object Serialization
An alternative machine-independent method for passing PHP objects between local and
remote machines is object serialization, in which parameters and results can be passed
between PHP-based clients and services in encoded text form. This is similar to using SDO
XML representation, but uses PHP types directly rather than XML schemas, and requires
parameter and result value conversion only at calls to the service, rather than globally in
the application. In our prototype migration framework we have chosen to use this simpler
alternative, reserving the SDO alternative for future work.
PHP object serialization is provided by two built-in functions, serialize() and unseri-
alize(). The first takes as a parameter a PHP value of any type and converts it to a string
representation. The second converts the serialized string representation back to a PHP
value. Values can be of any type, including complex objects and arrays. The type and
structure of the values is encoded into their serialization, allowing us to pass structured
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 61
<?phpinclude ("config.php");include ("library.php");include_once "login_return.php";
class login{
function get_date (NULL $lastLogin, object $USER){
$lastLogin = getLastLogin ($USER);updateLastLogin ($USER);return new get_date_return ($lastLogin);
}function get_user (NULL $id, string $user, string $pwrd){
$id = getUserId ($user, $pwrd);$USER = getUserData ($id);return new get_user_return ($USER, $id);
}}?>
Figure 6.6: Typed Candidate Service Class
PHP values between programs without the need for external schemas.
In our automated migration, we use these functions to pass complex data types across
SCA service calls. Parameter objects are serialized into a string prior to calling the service
and unserialized in the service operation functions. Similarly, return objects created by the
refactoring process are serialized in the service operation functions and unserialized when
the service call returns.
6.3.3 Serialization of Service Operations
The first transformation in our final migration to SCA is the conversion of the generated
candidate service class to use serialized parameters and result values. The input to this first
step is the generated candidate service class following type inference, in which the service
operation functions have been annotated with PHP type hints. Figure 6.6 shows the typed
candidate service class generated for our running example.
The serialization conversion of candidate service classes is a TXL source transforma-
tion that inserts code to unserialize parameters that have complex types, that is, objects and
arrays, on entry to each operation function, and to serialize the result object before return.
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 62
<?phpinclude ("config.php");include_once "library.php";include_once "login_return.php";
class login{
function get_date (string $USERStr){
$USER = unserialize ($USERStr);$lastLogin = getLastLogin ($USER);updateLastLogin ($USER);return serialize (new get_date_return ($lastLogin));
}
function get_user (string $user, string $pwrd){
$id = getUserId ($user, $pwrd);$USER = getUserData ($id);return serialize (new get_user_return ($USER, $id));
}}?>
Figure 6.7: Serialized Candidate Service Class
As part of this transformation, the formal parameters of the operation function must be
converted to string type in order to receive the serialized value from the client.
In some cases, parameters may represent variables that do not have a value prior to the
call to the service function. Following type inference, these have a type hint of NULL. The
transformation removes these valueless parameters since they do not pass any information
into the operation.
In the running example of Figure 6.6, the only parameter that is not either NULL or
a simple string type is the $USER parameter of get_date, which is an object. Figure 6.7
shows the running example after service operation serialization. The name of the $USER
parameter has been converted to the string parameter $USERStr, and a statement has been
inserted to unserialize the contents of $USERStr into the variable $USER. In both func-
tions the return statement has been modified to serialize the instantiation of the result value
returned to the client.
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 63
6.3.4 Serialization of Service Calls
A corresponding second TXL source transformation processes the adapted web application
to use corresponding serialization and unserialization of candidate service call parameters
and result values (Figure 6.4). This second transformation transforms each candidate ser-
vice operation call in the adapted web application to serialize complex argument values
and unserialize the result object of the operation. It inserts code to serialize arguments that
have complex types, that is, objects and arrays, on entry to each operation function, and to
unserialize the service operation’s result object upon return.
In order to decide which service call arguments are to be serialized, the transformation
needs to know the types of the parameters of the operation, which are not available in the
dynamically-typed PHP source code of the application. Thus the transformation takes a
second input, reading the typed candidate service class to use as a reference (Figure 6.4).
By matching the order of arguments in candidate service operation calls to the correspond-
ing formal parameter types in the candidate service class, the transformation can identify
which arguments must be serialized.
As part of the transformation, arguments corresponding to parameters of type NULL
are removed to correspond to the removal of NULL formal parameters in the serialization
transformation of the candidate service class.
Figure 6.8 shows the source of the adapted web application of our running example
following refactoring as input to the service call serialization transformation. Calls to the
candidate service operations get_user and get_date are highlighted.
Following the service call serialization transformation, several changes have been made
(Figure 6.9). In the call to get_user, the $id argument has been removed since it was
inferred to be of type NULL, and the result value object has been replaced by a serialized
result string which is unserialized to get the result object. The call to get_date has been
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 64
<?phpinclude ("config.php");include ("library.php");
include_once "login_return.php";include_once "login.php";$login_obj = new "login";
if ($_SERVER[’REQUEST_METHOD’] === ’GET’) {include ("login_form.html");
}
if ($_SERVER [’REQUEST_METHOD’] === ’POST’){
if (! empty ($SESSION -> has_timed_out)){
$session_has_timed_out = true;$SESSION -> has_timed_out = false;
}else{
$session_has_timed_out = false;}$user = $_POST [’username’];$pwrd = $_POST [’password’];
$get_user_return_obj = $login_obj -> get_user ($id, $user, $pwrd);$id = $get_user_return_obj -> id;$USER = $get_user_return_obj -> USER;
if ($USER){
$_SESSION [’username’] = $USER;
$get_date_return_obj = $login_obj -> get_date ($lastLogin, $USER);$lastLogin = $get_date_return_obj -> lastLogin;
include ("welcome.html");$Time = date ("m-d-Y", $lastLogin);echo "Date of last login is $Time\n";
}else{
include ("login_fail.html");}
}?>
Figure 6.8: Refactored Web Application Client Side Before Serialization
transformed to serialize the $USER object before passing it as argument, to accept the
serialized result string to unserialize back to the result object of the operation.
6.3.5 Service Class Conversion to SCA
Once the serialization transformations are complete, we are ready to turn the candidate
service class into an SCA service component and the adapted web application into a client
of the SCA service. In both cases, this requires addition of appropriate SCA annotations
that can be processed by the SCA platform to implement the service layer.
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 65
<?phpinclude ("config.php");include ("library.php");
include_once "login_return.php";include_once "login.php";$login_obj = new "login";
if ($_SERVER[’REQUEST_METHOD’] === ’GET’) {include ("login_form.html");
}
if ($_SERVER [’REQUEST_METHOD’] === ’POST’){
if (! empty ($SESSION -> has_timed_out)){
$session_has_timed_out = true;$SESSION -> has_timed_out = false;
}else{
$session_has_timed_out = false;}$user = $_POST [’username’];$pwrd = $_POST [’password’];
$get_user_return_objStr = $login_obj -> get_user ($user, $pwrd);$get_user_return_obj = unserialize ($get_user_return_objStr);$id = $get_user_return_obj -> id;$USER = $get_user_return_obj -> USER;
if ($USER){
$_SESSION [’username’] = $USER;
$USERStr = serialize ($USER);$get_date_return_objStr = $login_obj -> get_date ($USERStr);$get_date_return_obj = unserialize ($get_date_return_objStr);$lastLogin = $get_date_return_obj -> lastLogin;
include ("welcome.html");$Time = date ("m-d-Y", $lastLogin);echo "Date of last login is $Time\n";
}else{
include ("login_fail.html");}
}?>
Figure 6.9: Refactored Web Application Client Side After Serialization
The first part of this change is the addition of SCA service and operation annotations to
the serialized candidate service class. Two kinds of changes are required: the conversion of
the class to an SCA service using service annotations, and the conversion of each operation
function to an SCA service operation using parameter and result annotations.
As usual, these changes are implemented using a TXL source transformation of the
serialized service class. Figure 6.10 shows the result of applying this transformation to the
serialized service class of our running example. SCA annotations are represented in PHP
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 66
<?phpinclude ("config.php");include_once "library.php";include_once "login_return.php";
include "SCA/SCA.php";
/*** @service* @binding.soap*/
class login{
/*** @param string $USERStr* @return string*/
function get_date (string $USERStr){
$USER = unserialize ($USERStr);$lastLogin = getLastLogin ($USER);updateLastLogin ($USER);return serialize (new get_date_return ($lastLogin));
}
/*** @param string $user* @param string $pwrd* @return string*/
function get_user (string $user, string $pwrd){
$id = getUserId ($user, $pwrd);$USER = getUserData ($id);return serialize (new get_user_return ($USER, $id));
}}?>
Figure 6.10: Final SCA Annotated Service Class for the Running Example
as special comments inserted before the class or operation.
The service annotation consists simply of the @service and @binding.soap annotations,
at the beginning of the example result. The @binding.soap annotation tells the PHP SCA
to use SOAP bindings for the web service.
The operation function annotations specify the order and types of the parameters and
result value of the SCA service operation. Each @param annotations specify the type
and name of each parameter of the service operation. For example, the @param string
$user annotation of function get_user in Figure 6.10 specifies that the first parameter of the
operation should be a text string.
These type annotations are the reason that we required the type inference of Chapter 5.
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 67
Web services and their clients must agree on the order, type and representation of param-
eters, and thus use static types for parameters and results in the web service description.
Since PHP is a dynamically typed language, it has no such requirement, and so the types
of parameters must be inferred from their use in the code.
The return value annotation @return specifies the type of the returned result of a service
operation function. Because we are using seralization, the result type of all of our extracted
candidate service operations is string.
The SCA platform uses the annotations to automatically generate a WSDL service de-
scription for use by the original web application and other clients of the service. Because
we have specified SOAP binding, arguments to service calls will be packaged by SCA into
SOAP messages with argument values in the order specified in the parameter annotations
for the service operation.
Before we can use the new service, we use the SCA WSDL generator to create the
WSDL specification of the service. Given the annotated PHP service class file, SCA
platform produces this automatically in response to an HTTP request of the form http :
//hostname/path/serviceclassfile.php?wsdl The generated WSDL service description
for the final SCA annotated service class of our running example in Figure 6.10 is shown
in Figure 6.11.
6.3.6 Web Application Conversion to SCA
The final step in our migration is the conversion of the adapted web application to be a
client of the new SCA service. This transformation consists simply of replacing the include
file for the candidate service class to an include for the SCA platform, and converting the
creation of the candidate service class object to creation of a WSDL service object.
Figure 6.12 shows the final result for our running example, converting the adapted web
application to a client of the new SCA service.
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 68
<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions xmlns:tns2="http://login" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"targetNamespace="http://login">
<wsdl:types><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://login" elementFormDefault="qualified"><xs:element name="get_date">
<xs:complexType><xs:sequence><xs:element name="USERStr" type="xs:string"/>
</xs:sequence></xs:complexType>
</xs:element><xs:element name="get_dateResponse"><xs:complexType><xs:sequence><xs:element name="get_dateReturn" type="xs:string"/>
</xs:sequence></xs:complexType>
</xs:element><xs:element name="get_user">
<xs:complexType><xs:sequence><xs:element name="user" type="xs:string"/><xs:element name="pwrd" type="xs:string"/>
</xs:sequence></xs:complexType>
</xs:element><xs:element name="get_userResponse">
<xs:complexType><xs:sequence><xs:element name="get_userReturn" type="xs:string"/>
</xs:sequence></xs:complexType>
</xs:element></xs:schema>
</wsdl:types>
<wsdl:message name="get_dateRequest"><wsdl:part name="get_dateRequest" element="tns2:get_date"/>
</wsdl:message><wsdl:message name="get_dateResponse"><wsdl:part name="return" element="tns2:get_dateResponse"/>
</wsdl:message><wsdl:message name="get_userRequest">
<wsdl:part name="get_userRequest" element="tns2:get_user"/></wsdl:message><wsdl:message name="get_userResponse"><wsdl:part name="return" element="tns2:get_userResponse"/>
</wsdl:message><wsdl:portType name="loginPortType"><wsdl:operation name="get_date"><wsdl:input message="tns2:get_dateRequest"/><wsdl:output message="tns2:get_dateResponse"/>
</wsdl:operation><wsdl:operation name="get_user"><wsdl:input message="tns2:get_userRequest"/><wsdl:output message="tns2:get_userResponse"/>
</wsdl:operation></wsdl:portType>
<wsdl:binding name="loginBinding" type="tns2:loginPortType"><soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/><wsdl:operation name="get_date"><soap:operation soapAction=""/><wsdl:input><soap:body use="literal"/>
</wsdl:input><wsdl:output><soap:body use="literal"/>
</wsdl:output></wsdl:operation><wsdl:operation name="get_user"><soap:operation soapAction=""/><wsdl:input><soap:body use="literal"/>
</wsdl:input><wsdl:output><soap:body use="literal"/>
</wsdl:output></wsdl:operation>
</wsdl:binding>
<wsdl:service name="loginService"><wsdl:port name="loginPort" binding="tns2:loginBinding"><soap:address location="http://draco.ee.queensu.ca/login.php"/>
</wsdl:port></wsdl:service>
</wsdl:definitions><!-- this line identifies this file as WSDL generated by SCA for PHP. Do not remove -->
Figure 6.11: Generated WSDL Service Description for the Running Example
6.3. CONVERTING A CANDIDATE SERVICE CLASS TO SCA 69
<?phpinclude ("config.php");include ("library.php");
include_once "login_return.php";
include "SCA/SCA.php";$login_obj = SCA :: getService (’login.wsdl’);
if ($_SERVER[’REQUEST_METHOD’] === ’GET’) {include ("login_form.html");
}
if ($_SERVER [’REQUEST_METHOD’] === ’POST’){
if (! empty ($SESSION -> has_timed_out)){
$session_has_timed_out = true;$SESSION -> has_timed_out = false;
}else{
$session_has_timed_out = false;}$user = $_POST [’username’];$pwrd = $_POST [’password’];
$get_user_return_objStr = $login_obj -> get_user ($user, $pwrd);$get_user_return_obj = unserialize ($get_user_return_objStr);$id = $get_user_return_obj -> id;$USER = $get_user_return_obj -> USER;
if ($USER){
$_SESSION [’username’] = $USER;
$USERStr = serialize ($USER);$get_date_return_objStr = $login_obj -> get_date ($USERStr);$get_date_return_obj = unserialize ($get_date_return_objStr);$lastLogin = $get_date_return_obj -> lastLogin;
include ("welcome.html");$Time = date ("m-d-Y", $lastLogin);echo "Date of last login is $Time\n";
}else{
include ("login_fail.html");}
}?>
Figure 6.12: Final Adapted Wep Application as SCA Service Client
6.3.7 Database Refactoring
If the separated service resulting from the candidate service migration involves database
access, as can often be the case, then a remaining decision in the migration to a service
is whether the database itself should be refactored to separate the parts used only by the
migrated web application and the parts used by only the new service. Because the database
is itself already a service that can be moved to other servers as required, this is often not a
necessary step in moving to SOA.
6.4. SUMMARY 70
If the splitting of the database is desired, database refactoring requires a global analysis
of all clients of the database, not just the migrated web application and its new separated
service. While database refactoring is intended to be a part of our overall framework, in
this prototype it is left to manual intervention and we have not attempted to automate it.
6.4 Summary
In this chapter we have presented the final step in our automated migration process, the
final conversion of the candidate service class and its adapted web application client to web
services. Using a sequence of TXL source transformations, the typed candidate service
class and the adapted web application are converted to a Service Component Architecture
(SCA) service component and service client respectively. The final result is a fully migrated
web application with WSDL-based reusable service functionality.
In the next chapter we demonstrate our entire automated migration process on two pro-
duction web applications, the Moodle course management system and the SCARF research
paper discussion forum.
71
Chapter 7
Case Studies
In the previous chapters we have outlined our framework for automatic migration of web
applications to Service-Oriented Architecture (SOA) using a sequence of source transfor-
mations that take identified potential service operations in the application code to separate
reusable SCA web services. Our running example has demonstrated the application of the
process to a small but representative toy web application. In this chapter we demonstrate
the use of our framework on two real web applications, the Moodle course management
system, a large production web application used by thousands of students and instructors
worldwide, and the SCARF, the Stanford conference and research forum, a discussion fo-
rum application.
7.1 Case Study 1: Moodle
Moodle [51] is a popular production open source Course Management System (CMS).
Moodle stands for "Modular Object-Oriented Dynamic Learning Environment". It allows
instructors to create online course content and students to access it. The Moodle home page
includes a list of participants (instructors and students), a calendar with a course schedule,
and a list of pending assignments. Other interesting features include: online quizzes and
forums, where students can post comments and questions, glossaries of terms, and links
7.1. CASE STUDY 1: MOODLE 72
to other web resources. Moodle users have four primary roles: administrator, instructor,
student, and guest.
We chose Moodle for our web application migration case study because it is a large
(950,000 lines of code) production monolithic PHP web application that is used widely
internationally, has open source with good documentation, and has a strong supporting de-
veloper community. While Moodle is designed to have a plug-in architecture, components
are accomplished using include files, classes and method calls in a monolithic architecture.
It is typical of large PHP web applications in this respect.
In this first experiment, we demonstrate our framework by migrating some interesting
internal functionalities of Moodle to web services. We began by manually analyzing Moo-
dle in a top-down manner, dividing basic functionalities into sub-functionalities in order
to gain insight into the application, and as a result we identified a number of potential
candidate services.
Given its strong security requirements and multiple distinct user roles, user authentica-
tion functionality is a key aspect of Moodle. However, user authentication, including login
functionality, is intermingled with user interface and other application code, making ex-
traction of user authentication a challenging task. In this experiment, we use our process to
extract a web service that manages user login and role management, and to convert Moodle
into a client of the new service.
7.1.1 The Moodle Login Process
Moodle provides a single login page to all its users (administrator, teacher, student and
guest), where a user name and password are required (administrator, teacher, student) and
their information validated before the user is allowed to continue. The code that generates
and processes the login page is in login/index.php, relative to the Moodle base directory. As
a front page requirement, login is the first functionality we identified as a potential service
7.1. CASE STUDY 1: MOODLE 73
in Moodle.
Moodle’s login functionality is structured into multiple plugins which are provided us-
ing a PHP factory routine that chooses the correct login method based on configuration
information. However the code to manage the plugins is itself spread throughout the code.
Indeed, some sections of the login management code are specific to one of the plugins
(ldap). This variation and mix of different authentication code makes login management
an excellent candidate to be a service, because once it is separated, authentication methods
could be changed or added simply by binding Moodle to different versions of the service.
We have identified several authentication plugins used in Moodle:
• Manual authentication : accounts are created manually by an administrator.
• Email authentication: accounts are created manually by the users.
• LDAP authentication: account information is stored on an external Lightweight Di-
rectory Access Protocol server.
• Nologin authentication: accounts are suspended.
The login management functionality is spread out over several PHP dynamic web
pages:
• login/index.php : the default login page.
• lib/moodlelib.php: contains the function authenticate_user_login() called by index.php
which provides the list of all enabled authentication plugins.
• lib/auth/manual/auth.php: contains the code for manual authentication.
• lib/authlib.php: contains the authentication plugins for all other types.
7.1. CASE STUDY 1: MOODLE 74
7.1.2 Step 1: Login Service Identification
We begin by hand analyzing the Moodle source code to identify the potential candidate ser-
vice operations needed for a login management service. Beginning with the Moodle login
page (login/index.php) which is responsible for displaying the form that allows the Moodle
users to enter their login information, we identify sections of code related to the login au-
thentication and mark them as potential service operations. We tagged login authentication
code sequences in the Moodle code as candidate login service operations. Figures 7.1 and
7.2 show some of the result of hand tagging the Moodle login/index.php code for input to
our migration process.
7.1. CASE STUDY 1: MOODLE 75
<?php // $Id: index.php,v 1.129.2.10 2010/01/11 22:05:47 mjollnir_ Exp $
require_once("../config.php");<markIncludes/>
// check if major upgrade needed - also present in /index.phpif ((int)$CFG->version < 2006101100) { //1.7 or older
require_logout();redirect("$CFG->wwwroot/$CFG->admin/");
}
$loginguest = optional_param(’loginguest’, 0, PARAM_BOOL); // determines whether visitors are logged in as guestautomatically
$testcookies = optional_param(’testcookies’, 0, PARAM_BOOL); // request cookie test
// initialize variables$errormsg = ’’;$errorcode = 0;
/// Check for timed out sessionsif (!empty($SESSION->has_timed_out)) {
$session_has_timed_out = true;$SESSION->has_timed_out = false;
} else {$session_has_timed_out = false;
}
/// Check if the guest user exists. If not, create one.<service function = moodle_guest>
if (! record_exists(’user’, ’username’, ’guest’, ’mnethostid’, $CFG->mnet_localhost_id)) {if (! $guest = create_guest_record()) {
notify(’Could not create guest user record !!!’);}
}</service>
// setup and verify auth settings
<service function = moodle_authplugin>if (!isset($CFG->registerauth)) {
set_config(’registerauth’, ’’);}
if (!isset($CFG->auth_instructions)) {set_config(’auth_instructions’, ’’);
}
// auth plugins may override these - SSO anyone?$frm = false;$user = false;
$authsequence = get_enabled_auth_plugins(true); // auths, in sequenceforeach($authsequence as $authname) {
$authplugin = get_auth_plugin($authname);$authplugin->loginpage_hook();
}</service>
// HTTPS is potentially required in this pagehttpsrequired();
/// Define variables used in pageif (!$site = get_site()) {
error("No site found!");}
////////// (... 40 lines elided ...) //////////
/// Check if the user has actually submitted login data to us
if (empty($CFG->usesid) and $testcookies and (get_moodle_cookie() == ’’)) { // Login without cookie when testrequested
////////// (... 10 lines elided ...) //////////
}
Figure 7.1: Moodle login/index.php with Potential Service Operation Markup (Part 1 of 2)
7.1. CASE STUDY 1: MOODLE 76
<service function = moodle_authUser >if ($user) {
//user already supplied by aut plugin prelogin hook} else if (($frm->username == ’guest’) and empty($CFG->guestloginbutton)) {
$user = false; /// Can’t log in as guest if guest button is disabled$frm = false;
} else {if (empty($errormsg)) {
$user = authenticate_user_login($frm->username, $frm->password);}
}</service>
<service function = moodle_restored >// Intercept ’restored’ users to provide them with info & reset passwordif (!$user and $frm and is_restored_user($frm->username)) {
print_header("$site->fullname: $loginsite", $site->fullname, $navigation, ’’,’’, true, ’<div class="langmenu">’.$langmenu.’</div>’);
print_heading(get_string(’restoredaccount’));print_simple_box(get_string(’restoredaccountinfo’), ’center’, ’70%’);require_once(’restored_password_form.php’); // Use our "supplanter" login_forgot_password_form. MDL-20846$form = new login_forgot_password_form(’forgot_password.php’, array(’username’ => $frm->username));$form->display();print_footer();die;
}</service>
update_login_count();
if ($user) {
////////// (... 20 lines elided ...) //////////
/// Let’s get them all set up.<service function = moodle_complete >
add_to_log(SITEID, ’user’, ’login’, "view.php?id=$USER->id&course=".SITEID,$user->id, 0, $user->id);
$USER = complete_user_login($user);</service>
/// Prepare redirectionif (user_not_fully_set_up($USER)) {
$urltogo = $CFG->wwwroot.’/user/edit.php’;// We don’t delete $SESSION->wantsurl yet, so we get there later
////////// ( ... 20 lines elided ...) //////////
}
/// check if user password has expired/// Currently supported only for ldap-authentication module
<service function = moodle_ldap >$userauth = get_auth_plugin($USER->auth);if (!empty($userauth->config->expiration) and $userauth->config->expiration == 1) {
if ($userauth->can_change_password()) {$passwordchangeurl = $userauth->change_password_url();if(!$passwordchangeurl) {
$passwordchangeurl = $CFG->httpswwwroot.’/login/change_password.php’;}
} else {$passwordchangeurl = $CFG->httpswwwroot.’/login/change_password.php’;
}$days2expire = $userauth->password_expire($USER->username);if (intval($days2expire) > 0 && intval($days2expire) < intval($userauth->config->expiration_warning)) {
print_header("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno(get_string(’auth_passwordwillexpire’, ’auth’, $days2expire), $passwordchangeurl, $urltogo);print_footer();exit;
} elseif (intval($days2expire) < 0 ) {print_header("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"
langmenu\">$langmenu</div>");notice_yesno(get_string(’auth_passwordisexpired’, ’auth’), $passwordchangeurl, $urltogo);print_footer();exit;
}}
</service>
////////// ( ... 110 lines elided ...) //////////
include("index_form.html");print_footer();
?>
Figure 7.2: Moodle login/index.php with Potential Service Operation Markup (Part 2 of 2)
7.1. CASE STUDY 1: MOODLE 77
7.1.3 Step 2: Refactoring
From this point on the steps of the migration of are automated (which is the purpose of
our work). Once we have identified and marked the potential operations of our candidate
service class, the refactoring process of Chapter 4 separates and creates the new service
class for us. The result of this process for our proposed Moodle login service is shown in
Figures 7.3 and 7.4. The original Moodle application is automatically modified to call the
methods of this class in place of the original inline code as described in Chapter 4.
<?phprequire_once ("../config.php");include_once "login_return.php";
class login{
function moodle_ldap ($userauth, $USER, $passwordchangeurl, $CFG, $days2expire, $navigation, $urltogo){
$userauth = get_auth_plugin ($USER -> auth);if (! empty ($userauth -> config -> expiration) and $userauth -> config -> expiration == 1){
if ($userauth -> can_change_password ()){
$passwordchangeurl = $userauth -> change_password_url ();if (! $passwordchangeurl){
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}
}else{
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}$days2expire = $userauth -> password_expire ($USER -> username);if (intval ($days2expire) > 0 && intval ($days2expire) < intval ($userauth -> config -> expiration_warning)){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordwillexpire’, ’auth’, $days2expire), $passwordchangeurl, $urltogo);print_footer ();exit;
}elseif (intval ($days2expire) < 0){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordisexpired’, ’auth’), $passwordchangeurl, $urltogo);print_footer ();exit;
}}return new moodle_ldap_return ($days2expire, $passwordchangeurl, $userauth);
}
function moodle_complete ($user){
add_to_log (SITEID, ’user’, ’login’, "view.php?id=$USER->id&course=".SITEID, $user -> id, 0, $user -> id);$USER = complete_user_login ($user);return new moodle_complete_return ($USER);
}
Figure 7.3: Refactored Moodle Candidate Service Class (Part 1)
7.1. CASE STUDY 1: MOODLE 78
function moodle_restored ($user, $frm, $site, $navigation, $langmenu, $form){
if (! $user and $frm and is_restored_user ($frm -> username)){
print_header ("$site->fullname: $loginsite", $site -> fullname, $navigation, ’’, ’’, true, ’<div class="langmenu">’.$langmenu.’</div>’);
print_heading (get_string (’restoredaccount’));print_simple_box (get_string (’restoredaccountinfo’), ’center’, ’70%’);require_once (’restored_password_form.php’);$form = new login_forgot_password_form (’forgot_password.php’, array (
’username’ => $frm -> username));$form -> display ();print_footer ();die;
}return new moodle_restored_return ($form);
}
function moodle_authUser ($user, $frm, $CFG, $errormsg){
if ($user){}elseif (($frm -> username == ’guest’) and empty ($CFG -> guestloginbutton)){
$user = false;$frm = false;
}else{
if (empty ($errormsg)){
$user = authenticate_user_login ($frm -> username, $frm -> password);}
}return new moodle_authUser_return ($user, $frm);
}
function moodle_authplug ($CFG, $frm, $user, $authsequence, $authplugin, $authname){
if (! isset ($CFG -> registerauth)){
set_config (’registerauth’, ’’);}if (! isset ($CFG -> auth_instructions)){
set_config (’auth_instructions’, ’’);}$frm = false;$user = false;$authsequence = get_enabled_auth_plugins (true);foreach ($authsequence as $authname){
$authplugin = get_auth_plugin ($authname);$authplugin -> loginpage_hook ();
}return new moodle_authplug_return ($authplugin, $authsequence, $user, $frm);
}
function moodle_guest (object $CFG, NULL $guest){
if (! record_exists (’user’, ’username’, ’guest’, ’mnethostid’, $CFG -> mnet_localhost_id)){
if (! $guest = create_guest_record ()){
notify (’Could not create guest user record !!!’);}
}return new moodle_guest_return ($guest);
}}?>
Figure 7.4: Refactored Moodle Candidate Service Class (Part 2)
7.1. CASE STUDY 1: MOODLE 79
As part of the refactoring, the results required from the new candidate service class
methods are analyzed, and a result value class for the results of each of the candidate ser-
vice operations is generated. The generated result value classes for our Moodle candidate
service class are shown in Figure 7.5.
<?php
class moodle_ldap_return{
public $userauth;public $passwordchangeurl;public $days2expire;public function __construct($days2expire, $passwordchangeurl, $userauth){
$this -> userauth = $userauth;$this -> passwordchangeurl = $passwordchangeurl;$this -> days2expire = $days2expire;
}}class moodle_complete_return{
public $USER;public function __construct($USER){
$this -> USER = $USER;}
}class moodle_restored_return{
public $form;public function __construct($form){
$this -> form = $form;}
}class moodle_authUser_return{
public $frm;public $user;public function __construct($user, $frm){
$this -> frm = $frm;$this -> user = $user;
}}class moodle_authplug_return{
public $frm;public $user;public $authsequence;public $authplugin;public function __construct($authplugin, $authsequence, $user, $frm){
$this -> frm = $frm;$this -> user = $user;$this -> authsequence = $authsequence;$this -> authplugin = $authplugin;
}}class moodle_guest_return{
public $guest;public function __construct($guest){
$this -> guest = $guest;}
}?>
Figure 7.5: Generated Result Value Classes for the Moodle Candidate Service
7.1. CASE STUDY 1: MOODLE 80
7.1.4 Step 3: Type Inference
Once the candidate service class has been generated and separated by the refactoring pro-
cess, we have a version of Moodle that separates and encapsulates login functionality as a
set of candidate service operation, but we still do not know what the types of the parameters
of those operations are, so the candidate service class cannot yet become a separate service.
Each previously marked candidate service operation has been turned into a function
operation whose parameters are the PHP variables used in the original tagged candidate
service operation code. All the variables on the right hand side of an assignment or other-
wise used in the marked candidate service are turned into parameters in the new operation,
while all variables on the left side of an assignment are turned into return values.
Because PHP is a dynamically typed language, without other information we cannot
know the types of these variables and results without running the application. The next
step therefore is to use the type inference process described in Chapter 5 to dynamically
exercise Moodle to gather the run-time types of variables passed as parameters to each of
the candidate service operation functions.
The result of applying the instrumentation transformation described in Chapter 5 to the
generated Moodle candidate service class of Figures 7.3 and 7.4 is shown in Figure 7.6.
Using this instrumented version of the refactored candidate service class and the adapted
original Moodle web application, the instrumented Moodle was exercised by exploring all
of the login-related links accessible from the Moodle login page until all candidate service
operation functions had been called. The result was an instrumentation file containing type
signatures for all of the parameters of the candidate service operation functions (Figure
7.7).
Because we did not have a configured LDAP server available to test with, our ability
to completely exercise the instrumented Moodle candidate service class was limited. As a
7.1. CASE STUDY 1: MOODLE 81
require_once ("../config.php");include_once "login_return.php";
class login{
function moodle_ldap ($userauth, $USER, $passwordchangeurl, $CFG, $days2expire, $navigation, $urltogo){
$FileHandle = fopen ("login.php", ’a’);fwrite ($FileHandle, "function moodle_ldap(");fwrite ($FileHandle, gettype ($userauth).’ $userauth’);fwrite ($FileHandle, ", ");fwrite ($FileHandle, gettype ($USER).’ $USER’);fwrite ($FileHandle, ", ");fwrite ($FileHandle, gettype ($passwordchangeurl).’ $passwordchangeurl’);fwrite ($FileHandle, ", ");fwrite ($FileHandle, gettype ($CFG).’ $CFG’);fwrite ($FileHandle, ", ");fwrite ($FileHandle, gettype ($days2expire).’ $days2expire’);fwrite ($FileHandle, ", ");fwrite ($FileHandle, gettype ($navigation).’ $navigation’);fwrite ($FileHandle, ", ");fwrite ($FileHandle, gettype ($urltogo).’ $urltogo’);fwrite ($FileHandle, ") {\n");fwrite ($FileHandle, "}\n}\n");fclose ($FileHandle);$userauth = get_auth_plugin ($USER -> auth);if (! empty ($userauth -> config -> expiration) and $userauth -> config -> expiration == 1){
if ($userauth -> can_change_password ()){
$passwordchangeurl = $userauth -> change_password_url ();if (! $passwordchangeurl){
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}
}else{
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}$days2expire = $userauth -> password_expire ($USER -> username);if (intval ($days2expire) > 0 && intval ($days2expire) < intval ($userauth -> config -> expiration_warning)){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordwillexpire’, ’auth’, $days2expire), $passwordchangeurl, $urltogo);print_footer ();exit;
}elseif (intval ($days2expire) < 0){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordisexpired’, ’auth’), $passwordchangeurl, $urltogo);print_footer ();exit;
}}return new moodle_ldap_return ($days2expire, $passwordchangeurl, $userauth);
}
////////// (... 5 other functions elided ...) //////////
}?>
Figure 7.6: Moodle Candidate Service Class with Type Instrumentation
result, several parameters that otherwise would have been inferred had null values, and their
inferred type hints are NULL. An example is the $userauth parameter of the moodle_ldap
candidate service operation function in Figure 7.7.
7.1. CASE STUDY 1: MOODLE 82
<?php
class login {function moodle_ldap(NULL $userauth, object $USER, NULL $passwordchangeurl, object $CFG,
NULL $days2expire, array $navigation, string $urltogo){}function moodle_complete(object $user){}function moodle_restored(object $user, object $frm, object $site, array $navigation, string $langmenu, NULL $form){}function moodle_authUser(boolean $user, object $frm, object $CFG, string $errormsg){}function moodle_authplug(object $CFG, NULL $frm, NULL $user, NULL $authsequence, NULL $authplugin, NULL $authname){}function moodle_guest(object $CFG, NULL $guest){}
}?>
Figure 7.7: Merged Instrumentation Type Information Output for the Moodle CandidateService Class
Using the typing transformation of Chapter 5, the inferred types from the instrumenta-
tion shown in Figure 7.7 are automatically merged into the the generated Moodle candidate
service class to yield a fully typed candidate service class shown in Figures 7.8 and 7.9.
We are now ready to turn this class into a true SCA web service.
7.1. CASE STUDY 1: MOODLE 83
<?phprequire_once ("../config.php");include_once "login_return.php";
class login{
function moodle_ldap (NULL $userauth, object $USER, NULL $passwordchangeurl, object $CFG, NULL $days2expire, array $navigation, string $urltogo)
{$userauth = get_auth_plugin ($USER -> auth);if (! empty ($userauth -> config -> expiration) and $userauth -> config -> expiration == 1){
if ($userauth -> can_change_password ()){
$passwordchangeurl = $userauth -> change_password_url ();if (! $passwordchangeurl){
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}
}else{
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}$days2expire = $userauth -> password_expire ($USER -> username);if (intval ($days2expire) > 0 && intval ($days2expire) < intval ($userauth -> config -> expiration_warning)){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordwillexpire’, ’auth’, $days2expire), $passwordchangeurl, $urltogo);print_footer ();exit;
}elseif (intval ($days2expire) < 0){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordisexpired’, ’auth’), $passwordchangeurl, $urltogo);print_footer ();exit;
}}return new moodle_ldap_return ($days2expire, $passwordchangeurl, $userauth);
}function moodle_complete (object $user){
add_to_log (SITEID, ’user’, ’login’, "view.php?id=$USER->id&course=".SITEID, $user -> id, 0, $user -> id);$USER = complete_user_login ($user);return new moodle_complete_return ($USER);
}
function moodle_restored (object $user, object $frm, object $site, array $navigation, string $langmenu, NULL $form){
if (! $user and $frm and is_restored_user ($frm -> username)){
print_header ("$site->fullname: $loginsite", $site -> fullname, $navigation, ’’, ’’, true, ’<div class="langmenu">’.$langmenu.’</div>’);
print_heading (get_string (’restoredaccount’));print_simple_box (get_string (’restoredaccountinfo’), ’center’, ’70%’);require_once (’restored_password_form.php’);$form = new login_forgot_password_form (’forgot_password.php’, array (
’username’ => $frm -> username));$form -> display ();print_footer ();die;
}return new moodle_restored_return ($form);
}function moodle_authUser (boolean $user, object $frm, object $CFG, string $errormsg){
if ($user){}elseif (($frm -> username == ’guest’) and empty ($CFG -> guestloginbutton)){
$user = false;$frm = false;
}else{
if (empty ($errormsg)){
$user = authenticate_user_login ($frm -> username, $frm -> password);}
}return new moodle_authUser_return ($user, $frm);
}
Figure 7.8: Typed Moodle Candidate Service Class after Type Inference (Part 1)
7.1. CASE STUDY 1: MOODLE 84
function moodle_authplug (object $CFG, NULL $frm, NULL $user, NULL $authsequence, NULL $authplugin, NULL $authname){
if (! isset ($CFG -> registerauth)){
set_config (’registerauth’, ’’);}if (! isset ($CFG -> auth_instructions)){
set_config (’auth_instructions’, ’’);}$frm = false;$user = false;$authsequence = get_enabled_auth_plugins (true);foreach ($authsequence as $authname){
$authplugin = get_auth_plugin ($authname);$authplugin -> loginpage_hook ();
}return new moodle_authplug_return ($authplugin, $authsequence, $user, $frm);
}function moodle_guest (object $CFG, NULL $guest){
if (! record_exists (’user’, ’username’, ’guest’, ’mnethostid’, $CFG -> mnet_localhost_id)){
if (! $guest = create_guest_record ()){
notify (’Could not create guest user record !!!’);}
}return new moodle_guest_return ($guest);
}}?>
Figure 7.9: Typed Moodle Candidate Service Class after Type Inference (Part 2)
7.1.5 Step 4: Conversion to SCA
In the final stage of the automated migration, we use the transformations of Chapter 6 to
turn the Moodle candidate service class into an SCA-based web service, and modify the
adapted Moodle web application to use the service as a client.
In the first serialization transformation of the conversion, the typed candidate service
class is automatically transformed to remove parameters with a type hint of NULL, and to
insert code to undo the serialization of parameters that are of type object or array in each
operation. Code to serialize the result object before return is also added. The result of this
transformation on the typed Moodle candidate service class is shown in Figures 7.10 and
7.11.
Finally, the SCA annotation transformation of Chapter 6 is applied to the serialized
candidate service class to yield an SCA service component. We add the include statement
7.1. CASE STUDY 1: MOODLE 85
<?phprequire_once ("../config.php");include_once "login_return.php";
class login{
function moodle_ldap (string $USERStr, string $CFGStr, string $navigationStrStr, string $urltogo){
$navigationStr = unserialize ($navigationStrStr);$CFG = unserialize ($CFGStr);$USER = unserialize ($USERStr);$userauth = get_auth_plugin ($USER -> auth);if (! empty ($userauth -> config -> expiration) and $userauth -> config -> expiration == 1){
if ($userauth -> can_change_password ()){
$passwordchangeurl = $userauth -> change_password_url ();if (! $passwordchangeurl){
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}
}else{
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}$days2expire = $userauth -> password_expire ($USER -> username);if (intval ($days2expire) > 0 && intval ($days2expire) < intval ($userauth -> config -> expiration_warning)){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordwillexpire’, ’auth’, $days2expire), $passwordchangeurl, $urltogo);print_footer ();exit;
}elseif (intval ($days2expire) < 0){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordisexpired’, ’auth’), $passwordchangeurl, $urltogo);print_footer ();exit;
}}return serialize (new moodle_ldap_return ($days2expire, $passwordchangeurl, $userauth));
}
function moodle_complete (string $userStr){
$user = unserialize ($userStr);add_to_log (SITEID, ’user’, ’login’, "view.php?id=$USER->id&course=".SITEID, $user -> id, 0, $user -> id);$USER = complete_user_login ($user);return serialize (new moodle_complete_return ($USER));
}
function moodle_restored (string $userStr, string $frmStr, string $siteStr, string $navigationStrStr, string $langmenu)
{$navigationStr = unserialize ($navigationStrStr);$site = unserialize ($siteStr);$frm = unserialize ($frmStr);$user = unserialize ($userStr);if (! $user and $frm and is_restored_user ($frm -> username)){
print_header ("$site->fullname: $loginsite", $site -> fullname, $navigation, ’’, ’’, true, ’<div class="langmenu">’.$langmenu.’</div>’);
print_heading (get_string (’restoredaccount’));print_simple_box (get_string (’restoredaccountinfo’), ’center’, ’70%’);require_once (’restored_password_form.php’);$form = new login_forgot_password_form (’forgot_password.php’, array (
’username’ => $frm -> username));$form -> display ();print_footer ();die;
}return serialize (new moodle_restored_return ($form));
}
Figure 7.10: Serialized Moodle Candidate Service Class (Part 1)
7.1. CASE STUDY 1: MOODLE 86
function moodle_authUser (boolean $user, string $frmStr, string $CFGStr, string $errormsg){
$CFG = unserialize ($CFGStr);$frm = unserialize ($frmStr);if ($user){}elseif (($frm -> username == ’guest’) and empty ($CFG -> guestloginbutton)){
$user = false;$frm = false;
}else{
if (empty ($errormsg)){
$user = authenticate_user_login ($frm -> username, $frm -> password);}
}return serialize (new moodle_authUser_return ($user, $frm));
}
function moodle_authplug (string $CFGStr){
$CFG = unserialize ($CFGStr);if (! isset ($CFG -> registerauth)){
set_config (’registerauth’, ’’);}if (! isset ($CFG -> auth_instructions)){
set_config (’auth_instructions’, ’’);}$frm = false;$user = false;$authsequence = get_enabled_auth_plugins (true);foreach ($authsequence as $authname){
$authplugin = get_auth_plugin ($authname);$authplugin -> loginpage_hook ();
}return serialize (new moodle_authplug_return ($authplugin, $authsequence, $user, $frm));
}
function moodle_guest (string $CFGStr){
$CFG = unserialize ($CFGStr);if (! record_exists (’user’, ’username’, ’guest’, ’mnethostid’, $CFG -> mnet_localhost_id)){
if (! $guest = create_guest_record ()){
notify (’Could not create guest user record !!!’);}
}return serialize (new moodle_guest_return ($guest));
}}?>
Figure 7.11: Serialized Moodle Candidate Service Class (Part 2)
for the SCA library, and SCA annotations for the class and each method. This includes
the @service and @binding.soap annotations for the class, and the parameter and result
type annotations for each operation function. This enables the class as a remote service, as
shown in Figures 7.12, 7.13 and 7.14.
Visiting the converted service class using the special SCA WSDL generation URL
7.1. CASE STUDY 1: MOODLE 87
<?phprequire_once ("../config.php");include_once "login_return.php";
require "SCA/SCA.php";
/*** @service* @binding.soap*/
class login{
/*** @param string $USERStr* @param string $CFGStr* @param string $navigationStrStr* @param string $urltogo* @return string*/function moodle_ldap (string $USERStr, string $CFGStr, string $navigationStrStr, string $urltogo){
$navigationStr = unserialize ($navigationStrStr);$CFG = unserialize ($CFGStr);$USER = unserialize ($USERStr);$userauth = get_auth_plugin ($USER -> auth);if (! empty ($userauth -> config -> expiration) and $userauth -> config -> expiration == 1){
if ($userauth -> can_change_password ()){
$passwordchangeurl = $userauth -> change_password_url ();if (! $passwordchangeurl){
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}
}else{
$passwordchangeurl = $CFG -> httpswwwroot.’/login/change_password.php’;}$days2expire = $userauth -> password_expire ($USER -> username);if (intval ($days2expire) > 0 && intval ($days2expire) < intval ($userauth -> config -> expiration_warning)){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordwillexpire’, ’auth’, $days2expire), $passwordchangeurl, $urltogo);print_footer ();exit;
}elseif (intval ($days2expire) < 0){
print_header ("$site->fullname: $loginsite", "$site->fullname", $navigation, ’’, ’’, true, "<div class=\"langmenu\">$langmenu</div>");
notice_yesno (get_string (’auth_passwordisexpired’, ’auth’), $passwordchangeurl, $urltogo);print_footer ();exit;
}}return serialize (new moodle_ldap_return ($days2expire, $passwordchangeurl, $userauth));
}
/*** @param string $userStr* @return string*/function moodle_complete (string $userStr){
$user = unserialize ($userStr);add_to_log (SITEID, ’user’, ’login’, "view.php?id=$USER->id&course=".SITEID, $user -> id, 0, $user -> id);$USER = complete_user_login ($user);return serialize (new moodle_complete_return ($USER));
}
Figure 7.12: Final SCA-annotated Service Class (Part 1 of 3)
7.1. CASE STUDY 1: MOODLE 88
/*** @param string $userStr* @param string $frmStr* @param string $siteStr* @param string $navigationStrStr* @param string $langmenu* @return string*/
function moodle_restored (string $userStr, string $frmStr, string $siteStr, string $navigationStrStr, string $langmenu)
{$navigationStr = unserialize ($navigationStrStr);$site = unserialize ($siteStr);$frm = unserialize ($frmStr);$user = unserialize ($userStr);if (! $user and $frm and is_restored_user ($frm -> username)){
print_header ("$site->fullname: $loginsite", $site -> fullname, $navigation, ’’, ’’, true, ’<div class="langmenu">’.$langmenu.’</div>’);
print_heading (get_string (’restoredaccount’));print_simple_box (get_string (’restoredaccountinfo’), ’center’, ’70%’);require_once (’restored_password_form.php’);$form = new login_forgot_password_form (’forgot_password.php’, array (
’username’ => $frm -> username));$form -> display ();print_footer ();die;
}return serialize (new moodle_restored_return ($form));
}
/*** @param boolean $user* @param string $frmStr* @param string $CFGStr* @param string $errormsg* @return string*/function moodle_authUser (boolean $user, string $frmStr, string $CFGStr, string $errormsg){
$CFG = unserialize ($CFGStr);$frm = unserialize ($frmStr);if ($user){}elseif (($frm -> username == ’guest’) and empty ($CFG -> guestloginbutton)){
$user = false;$frm = false;
}else{
if (empty ($errormsg)){
$user = authenticate_user_login ($frm -> username, $frm -> password);}
}return serialize (new moodle_authUser_return ($user, $frm));
}
/*** @param string $CFGStr* @return string*/function moodle_authplug (string $CFGStr){
$CFG = unserialize ($CFGStr);if (! isset ($CFG -> registerauth)){
set_config (’registerauth’, ’’);}if (! isset ($CFG -> auth_instructions)){
set_config (’auth_instructions’, ’’);}$frm = false;$user = false;$authsequence = get_enabled_auth_plugins (true);foreach ($authsequence as $authname){
$authplugin = get_auth_plugin ($authname);$authplugin -> loginpage_hook ();
}return serialize (new moodle_authplug_return ($authplugin, $authsequence, $user, $frm));
}
Figure 7.13: Final SCA-annotated Service Class (Part 2 of 3)
7.1. CASE STUDY 1: MOODLE 89
/*** @param string $CFGStr* @return string*/function moodle_guest (string $CFGStr){
$CFG = unserialize ($CFGStr);if (! record_exists (’user’, ’username’, ’guest’, ’mnethostid’, $CFG -> mnet_localhost_id)){
if (! $guest = create_guest_record ()){
notify (’Could not create guest user record !!!’);}
}return serialize (new moodle_guest_return ($guest));
}
/*** @param string $CFGStr* @return string*/
function moodle_authplug (string $CFGStr){
$CFG = unserialize ($CFGStr);if (! isset ($CFG -> registerauth)){
set_config (’registerauth’, ’’);}if (! isset ($CFG -> auth_instructions)){
set_config (’auth_instructions’, ’’);}$frm = false;$user = false;$authsequence = get_enabled_auth_plugins (true);foreach ($authsequence as $authname){
$authplugin = get_auth_plugin ($authname);$authplugin -> loginpage_hook ();
}return serialize (new moodle_authplug_return ($authplugin, $authsequence, $user, $frm));
}
/*** @param string $CFGStr* @return string*/
function moodle_guest (string $CFGStr){
$CFG = unserialize ($CFGStr);if (! record_exists (’user’, ’username’, ’guest’, ’mnethostid’, $CFG -> mnet_localhost_id)){
if (! $guest = create_guest_record ()){
notify (’Could not create guest user record !!!’);}
}return serialize (new moodle_guest_return ($guest));
}}?>
Figure 7.14: Final SCA-annotated Service Class (Part 3 of 3)
http : //hostname/path/login.php?wsdl causes the SCA platform to automatically gen-
erate the Web Services Description Language (WSDL) service description for the new
service from the SCA annotations, and we are now ready to convert the adapted Moodle
web application to be a client.
7.1. CASE STUDY 1: MOODLE 90
As described in Chapter 6, a second serialization transformation is first applied to the
adapted Moodle web application to serialize parameter values and unserialize the result
object of each candidate service operation call.
In the final transformation, the adapted Moodle web application is converted to an SCA
client of the new web service. We add the include statement for the SCA library, create
an instance of the proxy object for the service, and update each service operation call to
use it. The affected parts of the resulting final client Moodle web application code for the
login/index.php file is shown in Figures 7.15, 7.16 and 7.15.
7.1.6 Moodle / SOA: Testing the Result
We validated the conversion of the Moodle login management system to a web service in
two different ways.
First, because we had to invoke all of the operations of the candidate service class from
the web application in the type inference instrumentation step, we already knew how to
cover all of the new web service operations from the Moodle browser interface.
Thus we exercised the SOA-converted Moodle in the same way, by logging in as guest,
as user and a administrator to exercise all of the service class operations. We further ex-
plored user capabilities in the various roles, by adding and editing courses as administrator,
by viewing the resources available to guests as guest, and by checking that guest users were
not allowed to view private course materials. In all cases the behaviour of the web service
converted application was identical to the behaviour of the original monolithic Moodle
application.
In the second validation we logged the values of all of the PHP variables before and
after the identified sections of code, both in the original version of the code and in the
transformed web services version of the code, covering all originally tagged code sections
(i.e., or equivalently after conversion, all operations of the new service). We then checked
7.1. CASE STUDY 1: MOODLE 91
<?phprequire_once ("../config.php");include_once "login_return.php";
require ’SCA/SCA.php’;$login_obj= SCA::getService(’login.wsdl’);
if ((int) $CFG -> version < 2006101100){
require_logout ();redirect ("$CFG->wwwroot/$CFG->admin/");
}
$loginguest = optional_param (’loginguest’, 0, PARAM_BOOL);$testcookies = optional_param (’testcookies’, 0, PARAM_BOOL);
$errormsg = ’’;$errorcode = 0;
if (! empty ($SESSION -> has_timed_out)){
$session_has_timed_out = true;$SESSION -> has_timed_out = false;
}else{
$session_has_timed_out = false;}
$CFGStr = serialize ($CFG);$moodle_guest_return_objStr = $login_obj -> moodle_guest ($CFGStr);$moodle_guest_return_obj = unserialize ($moodle_guest_return_objStr);$guest = $moodle_guest_return_obj -> guest;
$CFGStr = serialize ($CFG);$moodle_authplug_return_objStr = $login_obj -> moodle_authplug ($CFGStr);$moodle_authplug_return_obj = unserialize ($moodle_authplug_return_objStr);$frm = $moodle_authplug_return_obj -> frm;$user = $moodle_authplug_return_obj -> user;$authsequence = $moodle_authplug_return_obj -> authsequence;$authplugin = $moodle_authplug_return_obj -> authplugin;
httpsrequired ();
if (! $site = get_site ()){
error ("No site found!");}
if (empty ($CFG -> langmenu)){
$langmenu = "";}else{
$currlang = current_language ();$langs = get_list_of_languages ();$langlabel = get_accesshide (get_string (’language’));$langmenu = popup_form ("$CFG->httpswwwroot/login/index.php?lang=", $langs, "chooselang", $currlang, "", "", "",
true, ’self’, $langlabel);}
$loginsite = get_string ("loginsite");$navlinks = array ( array ( ’name’ => $loginsite, ’link’ => null, ’type’ => ’misc’));$navigation = build_navigation ($navlinks);
if ($user !== false or $frm !== false){}else if ((! empty ($SESSION -> wantsurl) and strstr ($SESSION -> wantsurl, ’username=guest’)) or $loginguest){
$frm -> username = ’guest’;$frm -> password = ’guest’;
}else if (! empty ($SESSION -> wantsurl) && file_exists ($CFG -> dirroot.’/login/weblinkauth.php’)){
include ($CFG -> dirroot.’/login/weblinkauth.php’);if (function_exists (’weblink_auth’)){
$user = weblink_auth ($SESSION -> wantsurl);}if ($user){
$frm -> username = $user -> username;}else{
$frm = data_submitted ();}
}
Figure 7.15: Final Migrated Moodle Web Application (Part 1 of 3)
7.1. CASE STUDY 1: MOODLE 92
else{
$frm = data_submitted ();}
if (empty ($CFG -> usesid) and $testcookies and (get_moodle_cookie () == ’’)){
$errormsg = get_string ("cookiesnotenabled");$errorcode = 1;
}else if ($frm){
$frm -> username = trim (moodle_strtolower ($frm -> username));if (is_enabled_auth (’none’) && empty ($CFG -> extendedusernamechars)){
$string = eregi_replace ("[^(-\.[:alnum:])]", "", $frm -> username);if (strcmp ($frm -> username, $string)){
$errormsg = get_string (’username’).’: ’.get_string ("alphanumerical");$errorcode = 2;$user = null;
}}
$CFGStr = serialize ($CFG);$frmStr = serialize ($frm);$moodle_authUser_return_objStr = $login_obj -> moodle_authUser ($user, $frmStr, $CFGStr, $errormsg);$moodle_authUser_return_obj = unserialize ($moodle_authUser_return_objStr);$frm = $moodle_authUser_return_obj -> frm;$user = $moodle_authUser_return_obj -> user;
$siteStr = serialize ($site);$frmStr = serialize ($frm);$userStr = serialize ($user);$navigationStr = serialize ($navigation);$moodle_restored_return_objStr = $login_obj -> moodle_restored ($userStr, $frmStr, $siteStr, $navigation, $langmenu);$moodle_restored_return_obj = unserialize ($moodle_restored_return_objStr);$form = $moodle_restored_return_obj -> form;
update_login_count ();
if ($user){
if ($user -> username == ’guest’){
unset ($user -> lang);}else if (! empty ($user -> lang)){
unset ($SESSION -> lang);}
if (empty ($user -> confirmed)){
print_header (get_string ("mustconfirm"), get_string ("mustconfirm"));print_heading (get_string ("mustconfirm"));print_simple_box (get_string ("emailconfirmsent", "", $user -> email), "center");print_footer ();die;
}
if ($frm -> password == ’changeme’){
set_user_preference (’auth_forcepasswordchange’, true, $user -> id);}
$userStr = serialize ($user);$moodle_complete_return_objStr = $login_obj -> moodle_complete ($userStr);$moodle_complete_return_obj = unserialize ($moodle_complete_return_objStr);$USER = $moodle_complete_return_obj -> USER;
if (user_not_fully_set_up ($USER)){
$urltogo = $CFG -> wwwroot.’/user/edit.php’;}else if (isset ($SESSION -> wantsurl) and (strpos ($SESSION -> wantsurl, $CFG -> wwwroot) === 0)){
$urltogo = $SESSION -> wantsurl;unset ($SESSION -> wantsurl);
}else{
$urltogo = $CFG -> wwwroot.’/’;unset ($SESSION -> wantsurl);
}
Figure 7.16: Final Migrated Moodle Web Application (Part 2 of 3)
7.1. CASE STUDY 1: MOODLE 93
if (! has_capability (’moodle/site:config’, get_context_instance (CONTEXT_SYSTEM)) and ! empty ($CFG ->mymoodleredirect) and ! isguest ())
{if ($urltogo == $CFG -> wwwroot or $urltogo == $CFG -> wwwroot.’/’ or $urltogo == $CFG -> wwwroot.’/index.
php’){
$urltogo = $CFG -> wwwroot.’/my/’;}
}
$CFGStr = serialize ($CFG);$USERStr = serialize ($USER);$navigationStr = serialize ($navigation);$moodle_ldap_return_objStr = $login_obj -> moodle_ldap ($USERStr, $CFGStr, $navigation, $urltogo);$moodle_ldap_return_obj = unserialize ($moodle_ldap_return_objStr);$userauth = $moodle_ldap_return_obj -> userauth;$passwordchangeurl = $moodle_ldap_return_obj -> passwordchangeurl;$days2expire = $moodle_ldap_return_obj -> days2expire;
reset_login_count ();redirect ($urltogo);exit;
}else{
if (empty ($errormsg)){
$errormsg = get_string ("invalidlogin");$errorcode = 3;
}
if (! empty ($CFG -> mnet_dispatcher_mode) && $CFG -> mnet_dispatcher_mode === ’strict’ && is_enabled_auth (’mnet’) && record_exists_sql ("SELECT h.id FROM {$CFG->prefix}mnet_host h
INNER JOIN {$CFG->prefix}mnet_host2service m ON h.id=m.hostidINNER JOIN {$CFG->prefix}mnet_service s ON s.id=m.serviceidWHERE s.name=’sso_sp’ AND h.deleted=0 AND m.publish = 1") && record_exists_select (’user’, "username =
’{$frm->username}’ AND mnethostid != {$CFG->mnet_localhost_id}")){
$errormsg.= get_string (’loginlinkmnetuser’, ’mnet’, "mnet_email.php?u=$frm->username");}
}}
if ($session_has_timed_out and ! data_submitted ()){
$errormsg = get_string (’sessionerroruser’, ’error’);$errorcode = 4;
}
if (empty ($SESSION -> wantsurl)){
$SESSION -> wantsurl = (array_key_exists (’HTTP_REFERER’, $_SERVER) && $_SERVER ["HTTP_REFERER"] != $CFG ->wwwroot &&
$_SERVER ["HTTP_REFERER"] != $CFG -> wwwroot.’/’ && $_SERVER ["HTTP_REFERER"] != $CFG -> httpswwwroot.’/login/’&&
$_SERVER ["HTTP_REFERER"] != $CFG -> httpswwwroot.’/login/index.php’) ? $_SERVER ["HTTP_REFERER"] : NULL;}
if (! empty ($CFG -> alternateloginurl)){
$loginurl = $CFG -> alternateloginurl;if (strpos ($SESSION -> wantsurl, $loginurl) === 0){
$SESSION -> wantsurl = NULL;}if ($errorcode){
if (strpos ($loginurl, ’?’) === false){
$loginurl.= ’?’;}else{
$loginurl.= ’&’;}$loginurl.= ’errorcode=’.$errorcode;
}redirect ($loginurl);
}
if (get_moodle_cookie () == ’’){
set_moodle_cookie (’nobody’);}
////////// (50 more lines elided)
print_header ("$site->fullname: $loginsite", $site -> fullname, $navigation, $focus, ’’, true, ’<div class="langmenu">’.$langmenu.’</div>’);
include ("index_form.html");print_footer ();
?>
Figure 7.17: Final Migrated Moodle Web Application (Part 3 of 3)
7.1. CASE STUDY 1: MOODLE 94
Figure 7.18: Screenshot of the Login Page of the Converted Moodle Web Application
that the values of the variables were in the same states in both versions of the code. In this
test, the values of all variables, with the exception of date- and time-specific fields, were
identical.
Figure 7.18 shows a screenshot of the final migrated Moodle web application’s login
page using the separated web service.
7.2. CASE STUDY 2: SCARF 95
7.2 Case Study 2: SCARF
SCARF, the Stanford Conference and Research Forum, is a PHP-based web application de-
signed to help researchers and conference administrators to create and maintain discussion
forums for their research papers [72].
7.2.1 The SCARF Paper Management Subsystem
In SCARF, research papers are uploaded and stored in a database where users can view,
comment and edit them, as well as organize them into sessions. SCARF is intended to
support interactive conferences such as SIGCOMM, for which it was originally developed.
7.2.2 Step 1: Paper Management Service Identification
Our plan is to identify and separate a new web service for the research paper management
aspects of SCARF, separating it from the user interface code of the web application so
that it can be accessed and reused by other applications. The paper management system
in SCARF supports several operations. For example, users can download a specific paper,
edit the content of a paper,and add a new paper to the forum. We start by analyzing the
SCARF folder to identify the functionalities related to paper management.
The business logic of the paper management functionality is spread over five PHP
pages:
• editpaper.php: Logic to enable an authenticated user to add a new paper to the forum
or edit the information of existing papers.
• showpaper.php: Logic to access specific paper details, such as name, authors, ab-
stract, comments on paper, to enable adding new comments (calling comments.php)
and to download the paper along with any relevant files (calling getpaper.php and
getfile.php).
7.2. CASE STUDY 2: SCARF 96
• showsession.php: Logic to show all papers available in a specific session with infor-
mation about them.
• getpaper.php: Logic to download a paper.
• getfile.php: Logic to download an auxiliary file associated with a paper.
Each of these pages contains sections of code that provide particular discrete operations
we can identify as part of our candidate paper management service class, interspersed with
user interface code to present and interact with the page. Figures 7.19, 7.20 and 7.21 show
the tagged candidate service operation code sections for the paper management functional-
ity of SCARF, after marking them in each of these files.
7.2.3 Step 2: Refactoring
The SCARF paper management functionality is different from Moodle login management
in that the functionality of the new candidate web service is spread widely over different
PHP source pages of the application. In this case we use our framework in a different way,
generating several different candidate service classes for the operations, one from each PHP
page, and merging the results into a single unified candidate service class (Figure 7.22).
We run our refactoring transformation in turn on each of the five tagged source pages
shown in Figures 7.19 - 7.21, generating a new separate candidate service class for each
one, while adapting the original page to use the new service. By specifying to the refactor-
ing process that the new candidate service classes should each have the same name, in this
case papers, we prepare them for merging.
When the refactoring step is complete, we have five generated candidate service classes,
each with the same name, and each with its own set of candidate service operations. We
then merge the candidate service operation functions from the five different classes into
one single class file containing all of the candidate service operations, as shown in Figure
7.2. CASE STUDY 2: SCARF 97
<?phpinclude_once("functions.php");<markIncludes/>include_once("header.php");
////////// (... 10 lines elided ...) //////////
if (isset($_GET[’paper_id’])) {$id = (int) $_GET[’paper_id’];
<service function=getPaperDetails>$result = query("SELECT title, abstract, session_id, pdf, pdfname FROM papers WHERE paper_id=’".$id."’");$title = $result[0]["title"];$abstract = $result[0]["abstract"];$session_id = $result[0]["session_id"];$pdf = $result[0]["pdf"];$pdfname = $result[0]["pdfname"];
$result = query("SELECT user_id FROM authors WHERE paper_id=’".$id."’ ORDER BY ‘order‘");$authors = Array();if ($result){
foreach($result as $row) {$authors[] = $row;
}}</service>
}
////////// (... 60 lines elided ...) //////////
include("editform3.php");
<service function=getFileEdit>$result = query("SELECT name, data FROM files WHERE paper_id=’".$id."’");</service>
////////// (... 75 lines elided ...) //////////
if (!isset($_POST[’paper_id’])) {// new paper
<service function=addPaper>$row = query ("SELECT MAX( ‘order‘ ) as max FROM ‘papers‘ WHERE session_id = ’".$session."’");$order = (int) $row[0] + 1;query ("INSERT INTO papers (title, abstract, pdf, pdfname, session_id, ‘order‘) VALUES (’".$title."’, ’".$abstract
."’, ’".$pdf."’, ’".$pdfname."’, ’".$session."’, ’".$order."’)");$row = query ("SELECT paper_id FROM papers WHERE title=’".$title."’ AND abstract=’".$abstract."’ AND pdfname=’".$
pdfname."’ AND session_id=’".$session."’ ORDER BY paper_id DESC");
$id = $row[0][’paper_id’];;</service>
} else {// updated paper paper
if (!empty($filename)) {$pdfSetString = "pdf=’$pdf’, pdfname=’$pdfname’,";
} else {$pdfSetString = "";
}<service function=updatePaper>query("UPDATE papers SET title=’".$title."’, abstract=’".$abstract."’, ".$pdfSetString." session_id=’".$session."’
WHERE paper_id=’".$id."’");$id = (int) $_POST[’paper_id’];query("DELETE FROM authors WHERE paper_id=’".$id."’");</service>
}
////////// (... 50 lines elided ...) //////////
$num = 0;<service function=addAuthors>foreach ($_POST[’authors’] as $author) {
if (! empty($author)) {query ("INSERT INTO authors (‘paper_id‘, ‘user_id‘, ‘order‘) VALUES (’".$id."’, ’" . mysql_real_escape_string($
author) . "’, ’".$num."’)");}$num++;
}</service>
if (!isset($_POST[’paper_id’])) {print "Paper added successfully";
} else {print "Paper updated successfully";
}print ". View <a href=’showpaper.php?paper_id=$id’>the paper</a>";
}include_once("footer.php");?>
(a) Page Management Service Operation Markup in editpaper.php
Figure 7.19: SCARF Application Pages with Potential Service Operation Markup (Part 1)
7.2. CASE STUDY 2: SCARF 98
<?php
include_once("functions.php");<markInclude/>include_once("header.php");
<service function=getPaperAttribs>$id = (int) $_GET[’paper_id’];
$result = query("SELECT paper_id, title, abstract FROM papers WHERE paper_id=’".$id."’");if (count($result) == 0) die("I’m sorry, there isn’t any paper with that id");
$id = $result[0][’paper_id’];$title = $result[0][’title’];$abstract = $result[0][’abstract’];</service>
$result = query("SELECT showemail, users.email, CONCAT(firstname, ’ ’, lastname) AS fullname, affiliation FROM authorsLEFT JOIN users ON users.user_id = authors.user_id WHERE paper_id=’".$id."’");
print "<h2>$title</h2><br>\n";
if (is_admin())print "<a href=’editpaper.php?paper_id=$id’>(Edit this paper)</a><br>";
print "<table> <tr><td><a href=’getpaper.php?paper_id=$id’>View Paper</a></td><td><img src=’images/pdf.gif’></td>";
<service function=getFileInfo>$result2 = query("SELECT name, type FROM files WHERE paper_id=’".$id."’");</service>
////////// (... 30 lines elided ...) //////////
$email = getEmail();logToFile("$email viewed paper ’$title’");
include_once("footer.php");?>
(b) Page Management Service Operation Markup in showpaper.php
<?phpinclude_once("functions.php");<markInclude/>
<service function= getfile>$id = (int) $_GET[’paper_id’];$name = mysql_real_escape_string($_GET[’name’]);$result = query("SELECT name, ext, type, data, title FROM files LEFT JOIN papers USING (paper_id) WHERE files.paper_id=’
$id’ AND name=’$name’");</service>
if (count($result) == 0) {print ("I’m sorry, no files with that name exist. Please click this link and send a mail to <a href=\"mailto:scarf
[email protected]?&subject=ConfDB error&body=" . htmlspecialchars($_SERVER["REQUEST_URI"]) . "\">Paul Tarjan</a> containing this message:<br><br>");
print $_SERVER["REQUEST_URI"];} else {
$name = $result[0]["name"];$ext = $result[0]["ext"];$type = $result[0]["type"];$data = $result[0]["data"];$title = $result[0]["title"];
header("Content-type: $type");header("Content-Length: ". strlen($data));header("Content-Disposition: inline; filename=\"$name - $title.$ext\"");
print $data;}?>
(c) Page Management Service Operation Markup in getfile.php
Figure 7.20: SCARF Application Pages with Potential Service Operation Markup (Part 2)
7.2. CASE STUDY 2: SCARF 99
<?phpinclude_once("functions.php");<markInclude/>include_once("header.php");
////////// (... 50 lines elided ...) //////////
print "\n<br>Session Chair: $row[fullname]<br><table width=’100%’>";
<service function = paperTitle>$result2 = query("SELECT paper_id, title FROM papers WHERE session_id=’".$row[session_id]."’ ORDER BY ‘order‘");</service>
if (count($result2) == 0) {print ("Sorry, there aren’t any papers uploaded yet for this session. Please check back soon.");
}
foreach ($result2 as $row2) {print "<tr><td><a href=’showpaper.php?paper_id=$row2[paper_id]’>$row2[title]</a>";if (is_admin()) {
print " <a href=’editpaper.php?paper_id=$row2[paper_id]’>(edit)</a>";}$result3 = query("SELECT COUNT(comment) AS num_comments FROM comments WHERE paper_id=’$row2[paper_id]’ AND
approved=’1’");$row3 = $result3;print "</td><td align=’right’><a href=’showpaper.php?paper_id=$row2[paper_id]’>".$row3[0][’num_comments’]."
comment";if ($row3[0][’num_comments’] != 1) print "s";print "</a></td></tr>\n";<service function = paperAuthor>$result3 = query("SELECT firstname, lastname FROM authors LEFT JOIN users USING (user_id) WHERE paper_id=’".
$row2[paper_id]."’ ORDER BY ‘order‘");</service>print "<tr><td> ";$count = 0;if ($result3){foreach( $result3 as $row3) {
if ($count != 0) print ", ";$count++;$parts = explode(" ", $row3[’firstname’]);foreach ($parts as $value)
print $value[1] . ". ";print $row3[’lastname’];
}}print "</td></tr>\n";
}print "</table><br>\n";
}
include_once("footer.php");?>
(d) Page Management Service Operation Markup in showsession.php
<?phpinclude_once("functions.php");<markInclude />
<service function = getpaper>$id = (int) $_GET[’paper_id’];$result = query("SELECT title, pdf, pdfname FROM papers WHERE paper_id=’".$id."’");</service>
$title = $result[0][’title’];$pdf = $result[0][’pdf’];$pdfname = $result[0][’pdfname’];
$pdfname = $title . ".pdf";
header("Content-type: application/xpdf");header("Content-Length: ". strlen($pdf));header("Content-Disposition: attachement; filename=\"$pdfname\"");
print $pdf;?>
(e) Page Management Service Operation Markup in getpaper.php
Figure 7.21: SCARF Application Pages with Potential Service Operation Markup (Part 3)
7.2. CASE STUDY 2: SCARF 100
!"#$%&'&()*+,&-).)/+-+.0&1231410+-51&6+3*)/+1&
").787)0+&!+,98:+1&
$+;):0<,8./&
").787)0+&&!+,98:+&"=)11+1&
>+,/8./&
+780*)*+,?&*@*&
1@<6*)*+,?&*@*&
/+0*)*+,?&*@*&
/+A8=+?&*@*&
1@<61+118<.?&*@*&
").787)0+&1+,98:+&&:=)11+1&
&&BCD& &&BCD&
&&BCD& &&BCD&&&BCD&
>+,/+7&!+,98:+&"=)11&E()*+,1F&&&&&&&
&
&&&&&&BCD&&
Figure 7.22: Generating and Merging Candidate Service Class Operations from MultipleWeb Application Pages
7.22. If the different generated candidate service classes we have two operations with the
same name and functionality, then we merge them by hand into a single operation function.
If their functionality is different, then we must rename one of them and its corresponding
calls in the adapted page file.
As in the refactoring step for Moodle shown in the previous section, the results required
by each candidate service operation are analyzed and a result value class generated for
each candidate service operation. These classes do not require merging since each is a
unique separate class, but the multiple files containing them are merged into one simply by
concatenating the files.
7.2.4 Step 3: Type Inference
Once the generated candidate service classes for each page have been merged into a single
merged candidate service class, the remaining steps of the automation process simply pro-
ceed as before. We use the dynamic type inference technique of Chapter 5 to infer the types
of all of the operation parameters of the new merged candidate service class by instrument-
ing and running the class with the adapted application pages to gather and store dynamic
type information, and then use the type merging transformation to add the inferred types
to the merged candidate service class operation functions. Figure 7.23 shows the merged
7.2. CASE STUDY 2: SCARF 101
<?phpinclude_once ("functions.php");include_once "papers_return.php";
class papers{
function addAuthors ($_POST, $author, $id, $num){
$FileHandle = fopen ("/tmp/papers.merge.php", ’a’);fwrite ($FileHandle, "class papers{\n function addAuthors(");fwrite ($FileHandle, gettype ($_POST).’ $_POST’);fwrite ($FileHandle, ",");fwrite ($FileHandle, gettype ($author).’ $author’);fwrite ($FileHandle, ",");fwrite ($FileHandle, gettype ($id).’ $id’);fwrite ($FileHandle, ",");fwrite ($FileHandle, gettype ($num).’ $num’);fwrite ($FileHandle, ") {\n");fwrite ($FileHandle, " }\n}\n");fclose ($FileHandle);foreach ($_POST [’authors’] as $author){
if (! empty ($author)){
query ("INSERT INTO authors (‘paper_id‘, ‘user_id‘, ‘order‘) VALUES (’".$id."’, ’".mysql_real_escape_string($author)."’, ’".$num."’)");
}$num ++;
}return new addAuthors_return ();
}
function updateFile ($id, $oldname, $name, $ext, $type, $data){
$FileHandle = fopen ("/tmp/papers.merge.php", ’a’);fwrite ($FileHandle, "class papers{\n function updateFile(");fwrite ($FileHandle, gettype ($id).’ $id’);fwrite ($FileHandle, ",");fwrite ($FileHandle, gettype ($oldname).’ $oldname’);fwrite ($FileHandle, ",");fwrite ($FileHandle, gettype ($name).’ $name’);fwrite ($FileHandle, ",");fwrite ($FileHandle, gettype ($ext).’ $ext’);fwrite ($FileHandle, ",");fwrite ($FileHandle, gettype ($type).’ $type’);fwrite ($FileHandle, ",");fwrite ($FileHandle, gettype ($data).’ $data’);fwrite ($FileHandle, ") {\n");fwrite ($FileHandle, " }\n}\n");fclose ($FileHandle);query ("DELETE FROM files WHERE paper_id=’".$id."’ AND name=’".$oldname."’");query ("INSERT INTO files (paper_id, name, ext, type, data) VALUES (’".$id."$’, ’".$name."’, ’".$ext."’, ’".$type.
"’, ’".$data."’)");return new updateFile_return ();
}
////////// (12 more instrumented candidate service operation functions) //////////
}?>
Figure 7.23: Instrumented Merged Candidate Service Class for SCARF Paper Management
SCARF paper management candidate service after the instrumentation transformation.
The instrumented SCARF candidate service class is then exercised by running the
SCARF application with the adapted application pages and the instrumented merged can-
didate service class shown in Figure 7.23, exploring all of the paper management related
links from the SCARF user interface until all of candidate service operation functions have
7.2. CASE STUDY 2: SCARF 102
<?phpclass papers{function getPaperDetails(array $result,integer $id,string $title,string $abstract,NULL $session_id,string $pdf,string
$pdfname,NULL $authors,array $row) {}
function getFileEdit(array $result,integer $id) {}
function updatePaper2(string $newname,integer $id,string $oldname) {}
function addPaper(array $row,integer $session,NULL $order,string $title,string $abstract,string $pdf,string $pdfname,integer $id) {
}function updateFile(string $id,string $oldname,string $name,string $ext,string $type,string $data) {}
function updatePaper(string $title,string $abstract,string $pdfSetString,integer $session,integer $id,array $_POST) {}
function deletePaper(integer $id,string $oldname) {}
function addAuthors(array $_POST,NULL $author,integer $id,integer $num) {}
function getFile(NULL $id,array $_GET,NULL $name,NULL $result) {}
function getpaper(NULL $id,array $_GET,NULL $result) {}
function getPaperAttribs(integer $id,array $_GET,array $result,NULL $title,NULL $abstract) {}
function getFileInfo(NULL $result2,string $id) {}
function paperTitle(NULL $result2,array $row) {}
function paperAuthor(array $result3,array $row2) {}
}?>
Figure 7.24: Type Instrumentation Output of the SCARF Candidate Service Class
been called at least once.
The output of this step is an instrumentation file containing type signatures for all of the
parameters of all fourteen of the candidate service operation functions (Figure 7.24), which
are then merged into the candidate service class using the typing transformation described
in Chapter 5 to yield the fully typed merged candidate service class.
7.2.5 Step 4: Conversion to SCA
In the final stage of the automated migration, conversion to an SCA service component
proceeds as for Moodle. We use the transformations of Chapter 6 to turn the SCARF
candidate service class into an SCA-based web service, and modify the adapted SCARF
web application to use the service as a client.
The steps are identical to those for the Moodle case study:
7.2. CASE STUDY 2: SCARF 103
1. The typed candidate service class is automatically transformed to remove parameters
with a type hint of NULL, and to insert code to undo the serialization of parameters
that are of type object or array in each operation. Code to serialize the result object
before return is also added.
2. The SCA annotation transformation of Chapter 6 is applied to the serialized candidate
service class to yield an SCA service component. We add the include statement for
the SCA library, and SCA annotations for the class and each method. This includes
the @service and @binding.soap annotations for the class, and the parameter and
result type annotations for each operation function. This enables the class as a remote
service.
3. Invoking the converted service class using the special SCA WSDL generation URL
http : //hostname/path/papers.php?wsdl causes the SCA platform to automati-
cally generate the Web Services Description Language (WSDL) service description
for the new service from the SCA annotations.
4. In the final transformation, the adapted source pages of the SCARF web application
are converted to be an SCA client of the new web service. We add the include state-
ment for the SCA library, create an instance of the proxy object for the service, and
update each service operation call to use it.
Figures 7.25, 7.26 and 7.27 show the final SCARF paper management service after
conversion to an SCA service. Each of the adapted SCARF application pages from which
the service was extracted are converted to SCA WSDL clients of the service using the final
transformation of Chapter 6, and the migration is complete.
7.2. CASE STUDY 2: SCARF 104
<?phpinclude_once ("functions.php");include_once "papers_return.php";include "SCA/SCA.php";/**
* @service* @binding.soap*/
class papers{
/*** @param string $_POSTStr* @param integer $id* @param integer $num* @return string*/
function addAuthors (string $_POSTStr, integer $id, integer $num){
$_POST = unserialize ($_POSTStr);foreach ($_POST [’authors’] as $author){
if (! empty ($author)){
query ("INSERT INTO authors (‘paper_id‘, ‘user_id‘, ‘order‘) VALUES (’".$id."’, ’".mysql_real_escape_string($author)."’, ’".$num."’)");
}$num ++;
}return serialize (new addAuthors_return ());
}/**
* @param string $id* @param string $oldname* @param string $name* @param string $ext* @param string $type* @param string $data* @return string*/
function updateFile (string $id, string $oldname, string $name, string $ext, string $type, string $data){
query ("DELETE FROM files WHERE paper_id=’".$id."’ AND name=’".$oldname."’");query ("INSERT INTO files (paper_id, name, ext, type, data) VALUES (’".$id."$’, ’".$name."’, ’".$ext."’, ’".$type.
"’, ’".$data."’)");return serialize (new updateFile_return ());
}/**
* @param string $newname* @param integer $id* @param string $oldname* @return string*/
function updatePaper2 (string $newname, integer $id, string $oldname){
query ("UPDATE files SET name=’".$newname."’ WHERE paper_id=’".$id."’ AND name=’".$oldname."’");return serialize (new updatePaper2_return ());
}/**
* @param integer $id* @param string $oldname* @return string*/
function deletePaper (integer $id, string $oldname){
query ("DELETE FROM files WHERE paper_id=’".$id."’ AND name=’".$oldname."’");return serialize (new deletePaper_return ());
}/**
* @param string $title* @param string $abstract* @param string $pdfSetString* @param integer $session* @param integer $id* @param string $_POSTStr* @return string*/
function updatePaper (string $title, string $abstract, string $pdfSetString, integer $session, integer $id, string $_POSTStr)
{$_POST = unserialize ($_POSTStr);query ("UPDATE papers SET title=’".$title."’, abstract=’".$abstract."’, ".$pdfSetString." session_id=’".$session."
’ WHERE paper_id=’".$id."’");$id = (int) $_POST [’paper_id’];query ("DELETE FROM authors WHERE paper_id=’".$id."’");return serialize (new updatePaper_return ($id));
}
Figure 7.25: Final Migrated SCARF Paper Management Service Class (Part 1 of 3)
7.2. CASE STUDY 2: SCARF 105
/*** @param string $rowStr* @param integer $session* @param string $title* @param string $abstract* @param string $pdf* @param string $pdfname* @param integer $id* @return string*/
function addPaper (string $rowStr, integer $session, string $title, string $abstract, string $pdf, string $pdfname,integer $id)
{$row = unserialize ($rowStr);$row = query ("SELECT MAX( ‘order‘ ) as max FROM ‘papers‘ WHERE session_id = ’".$session."’");$order = (int) $row [0] + 1;query ("INSERT INTO papers (title, abstract, pdf, pdfname, session_id, ‘order‘) VALUES (’".$title."’, ’".$abstract
."’, ’".$pdf."’, ’".$pdfname."’, ’".$session."’, ’".$order."’)");$row = query ("SELECT paper_id FROM papers WHERE title=’".$title."’ AND abstract=’".$abstract."’ AND pdfname=’".$
pdfname."’ AND session_id=’".$session."’ ORDER BY paper_id DESC");$id = $row [0] [’paper_id’];;return serialize (new addPaper_return ($id, $row, $order));
}/**
* @param string $resultStr* @param integer $id* @return string*/
function getFileEdit (string $resultStr, integer $id){
$result = unserialize ($resultStr);$result = query ("SELECT name, data FROM files WHERE paper_id=’".$id."’");return serialize (new getFileEdit_return ($result));
}/**
* @param string $resultStr* @param integer $id* @param string $title* @param string $abstract* @param string $pdf* @param string $pdfname* @param string $rowStr* @return string*/
function getPaperDetails (string $resultStr, integer $id, string $title, string $abstract, string $pdf, string $pdfname, string $rowStr)
{$row = unserialize ($rowStr);$result = unserialize ($resultStr);$result = query ("SELECT title, abstract, session_id, pdf, pdfname FROM papers WHERE paper_id=’".$id."’");$title = $result [0] ["title"];$abstract = $result [0] ["abstract"];$session_id = $result [0] ["session_id"];$pdf = $result [0] ["pdf"];$pdfname = $result [0] ["pdfname"];$result = query ("SELECT user_id FROM authors WHERE paper_id=’".$id."’ ORDER BY ‘order‘");$authors = Array ();if ($result){
foreach ($result as $row){
$authors [] = $row;}
}return serialize (new getPaperDetails_return ($authors, $result, $pdfname, $pdf, $session_id, $abstract, $title));
}/**
* @param string $_GETStr* @return string*/
function getFile (string $_GETStr){
$_GET = unserialize ($_GETStr);$id = (int) $_GET [’paper_id’];$name = mysql_real_escape_string ($_GET [’name’]);$result = query ("SELECT name, ext, type, data, title FROM files LEFT JOIN papers USING (paper_id) WHERE files.
paper_id=’$id’ AND name=’$name’");return serialize (new getFile_return ($result, $name, $id));
}
Figure 7.26: Final Migrated SCARF Paper Management Service Class (Part 2 of 3)
7.2. CASE STUDY 2: SCARF 106
/*** @param string $_GETStr* @return string*/
function getpaper (string $_GETStr){
$_GET = unserialize ($_GETStr);$id = (int) $_GET [’paper_id’];$result = query ("SELECT title, pdf, pdfname FROM papers WHERE paper_id=’".$id."’");return serialize (new getpaper_return ($result, $id));
}/**
* @param string $id* @return string*/
function getFileInfo (string $id){
$result2 = query ("SELECT name, type FROM files WHERE paper_id=’".$id."’");return serialize (new getFileInfo_return ($result2));
}/**
* @param integer $id* @param string $_GETStr* @param string $resultStr* @return string*/
function getPaperAttribs (integer $id, string $_GETStr, string $resultStr){
$result = unserialize ($resultStr);$_GET = unserialize ($_GETStr);$id = (int) $_GET [’paper_id’];$result = query ("SELECT paper_id, title, abstract FROM papers WHERE paper_id=’".$id."’");if (count ($result) == 0)die ("I’m sorry, there isn’t any paper with that id");$id = $result [0] [’paper_id’];$title = $result [0] [’title’];$abstract = $result [0] [’abstract’];return serialize (new getPaperAttribs_return ($abstract, $title, $id, $result));
}/**
* @param string $result3Str* @param string $row2Str* @return string*/
function paperAuthor (string $result3Str, string $row2Str){
$row2 = unserialize ($row2Str);$result3 = unserialize ($result3Str);$result3 = query ("SELECT firstname, lastname FROM authors LEFT JOIN users USING (user_id) WHERE paper_id=’".$row2
[paper_id]."’ ORDER BY ‘order‘");return serialize (new paperAuthor_return ($result3));
}/**
* @param string $rowStr* @return string*/
function paperTitle (string $rowStr){
$row = unserialize ($rowStr);$result2 = query ("SELECT paper_id, title FROM papers WHERE session_id=’".$row [session_id]."’ ORDER BY ‘order‘");return serialize (new paperTitle_return ($result2));
}}?>
Figure 7.27: Final Migrated SCARF Paper Management Service Class (Part 3 of 3)
7.3. SUMMARY 107
7.2.6 SCARF / SOA: Testing the Result
Figure 7.28 shows a screen shot of one of the paper management pages of the final mi-
grated SCARF web application using the separated paper management web service. As
for the Moodle migration, we validated the conversion of the SCARF paper management
subsystem into a web service by thoroughly testing the migrated SCARF web application
in two ways.
First, we already knew how to cover all of the new web service operations from the
SCARF browser interface, because we had to cover all of the operations of the candidate
service class from the web application as part of the type inference instrumentation step. To
test the migrated SCARF, we exercised all of the same links in the SCARF user interface
to cover all of the operations of the new paper management web service, and verified that
the behaviour and output of each of the pages was the same for these operations.
Second, as for Moodle, we logged the values of PHP variables before and after each
tagged candidate service operation code segment in the original application, and compared
those to the same variables before and after the calls to the corresponding web service
operations of the new extracted SCARF paper management web service.
7.3 Summary
In this chapter we have presented two case studies in the use of our framework to extract
and convert the login management functionality of the production Moodle open-source web
application and the paper management subsystem of the SCARF conference forum to SCA-
based web services. In each case, beginning with a hand-identified set of potential service
operations, we used the steps of our automated migration process to expose and convert
these operations as new reusable web services, and to convert the original web applications
to a clients of the services.
7.3. SUMMARY 108
Figure 7.28: Screenshot of the Edit Paper Page of the Converted SCARF Web Application
In the case of Moodle, the candidate operation code segments were relatively localized,
but in the case of SCARF, tagged candidate operations appeared in several files, requiring
the generation of several different versions of the candidate service class and merging of
their operations into a merged candidate service class. We tested that the behaviour of
the migrated applications matched that of the original by covering the functionalities of
the new services and checking the state of PHP variables against the original monolithic
web applications. In the next chapter we conclude the thesis, highlight limitations of our
prototype process, and outline opportunities for continued future work.
109
Chapter 8
Conclusions and Future Work
In this thesis we have presented a general framework and tool prototype that automates
the migration of monolithic web applications to web services in an SOA environment.
The framework represents a new approach to the problem of migrating legacy systems to
service-oriented architecture. It is one of the first approaches to explore the area of moving
monolithic web applications to SOA, and the first describing a complete detailed process
and significant levels of automation.
8.1 Contributions
The contributions of the thesis are:
• A general framework using an iterative process of incremental steps to analyze and
reprogram existing web applications to web services based on the SCA web services
standard.
• An automatic extraction process to extract and separate identified business features
in dynamically-typed scripting languages as object-oriented classes.
• An automatic process for inferring the dynamic types of parameter values in dynamically-
typed scripting languages using instrumentation and coverage testing.
8.1. CONTRIBUTIONS 110
• An automatic process for converting an object-oriented class into a Service Compo-
nent Architecture (SCA) service component.
• A prototype set of tools using source analysis and transformation to automate the
reprogramming of web applications written in PHP to extract and separate identified
business features as web services.
• A demonstration of the framework and tool set in extracting web services from Moo-
dle, a production monolithic web application for course and student management,
and SCARF, a monolithic web application for a conference and research paper dis-
cussion forum.
Our framework consists of several automated steps: candidate service refactoring, can-
didate service separation, parameter type inference, service component conversion, and
database refactoring. In the candidate service refactoring and separation step we automati-
cally refactor a candidate service class from the web application and generate a return value
class used to transfer information. In the parameter type inference step, we use automati-
cally generated code instrumentation to infer the types of the parameters of the operations.
In service component conversion step, we automatically convert the candidate service class
into an SCA service component. The web application is then automatically transformed to
use the new service class as a WSDL client.
The result of applying our framework is a new web application in which the identified
business operations have been separated into one or more web services that both serve the
original web application and can be reused by other applications.
8.2. LIMITATIONS 111
8.2 Limitations
At present our prototype implementation does not handle every feature of the PHP lan-
guage. In particular, the refactoring step does not always detect all modifications or uses
of variables in the tagged candidate service code fragments, in particular when variables
appear inside strings. As a result the inferred parameters and return classes may in some
unusual cases be incomplete. However, this is a well understood problem and it is relatively
straightforward to extend the implementation.
Due to the use of the TXL source transformation engine and its PHP grammar, at
present our source transformations do not retain PHP comments from the original code.
This is a known difficulty with source transformation tools, and can be addressed using the
techniques described in Malton et al. [46].
8.3 Future Work
There are several future lines of research for our work.
One possible line of future work is to convert the uses of the objects in the application to
use to use the XML Data Access Service for Service Data Objects (SDO-DAS-XML) [14].
While our migration process uses serialization to transfer any non primitive data types,
further analysis of both the client application and the candidate service class could identify
the use of core data structures and provide automated assistance for the migration of core
data structures to SDO.
Currently every candidate segment of feature code in the original application is con-
verted into a separate service operation. Another area of future research is to identify sim-
ilar operations and merge them into a single operation. The invocations of the operations
would also have to be adapted to the new single operation.
While we have illustrated our approach on the PHP language, our framework and its
8.3. FUTURE WORK 112
steps are not specific to any particular language. Extending our prototype automated mi-
gration tools to other web application languages such as Python is another area for future
research.
BIBLIOGRAPHY 113
Bibliography
[1] A. Ajlan and H. Zedan. E-learning (MOODLE) Based on Service Oriented Architec-
ture. In the EADTU’s 20th Anniversary Conference, Lisbon, Portugal, 8-9 November,
pages 62–70, 2007.
[2] A. Almonaies, J.R. Cordy and T.R. Dean. Legacy System Evolution towards Service-
Oriented Architecture. In International Workshop on SOA Migration and Evolution,
pages 53–62, 2010.
[3] Mehdi Achour, Friedhelm Betz, Antony Dovgal, Nuno Loopes, Hannes Mag-
nusson, Georg Richter, Damien Seguy, and Jakub Vrana. PHP Manual,
http://www.php.net/manual/en/index.php, last accessed Aug 2011.
[4] Asil A. Almonaies, Manar H. Alalfi, James R. Cordy, and Thomas R. Dean. Towards a
framework for migrating web applications to web services. In Proceedings of the 2011
Conference of the Center for Advanced Studies on Collaborative Research, CASCON
’11, pages 229–241, Riverton, NJ, USA, 2011. IBM Corp.
[5] A. Arsanjani, S. Ghosh, A. Allam, T. Abdollah, S. Gariapathy, and K. Holley. Soma: a
method for developing service-oriented solutions. IBM Syst. J., 47(3):377–396, 2008.
[6] Camlon H. Asuncion, Maria-Eugenia Iacob, and Marten van Sinderen. Towards a
flexible service integration through separation of business rules. In EDOC, pages
184–193, 2010.
BIBLIOGRAPHY 114
[7] L. Aversano, G. Canfora, A. Cimitile, and A. De Lucia. Migrating legacy systems
to the web: an experience report. In Proceedings of Fifth European Conference on
Software Maintenance and Reengineering, pages 148–157, 2001.
[8] Lerina Aversano, Gerardo Canfora, Aniello Cimitile, and Andrea De Lucia. Migrating
legacy systems to the web: An experience report. In CSMR, pages 148–157, 2001.
[9] Lerina Aversano, Luigi Cerulo, and C. Palumbo. Mining candidate web services from
legacy code. In WSE, pages 37–40, 2008.
[10] Kim B. Bruce. Safe type checking in a statically-typed object-oriented programming
language. In Proceedings of the 20th ACM SIGPLAN-SIGACT symposium on Prin-
ciples of programming languages, POPL ’93, pages 285–298, New York, NY, USA,
1993. ACM.
[11] Gerardo Canfora, Anna Rita Fasolino, Gianni Frattolillo, and Porfirio Tramontana.
Migrating interactive legacy systems to web services. In 10th European Conference
on Software Maintenance and Reengineering (CSMR 2006), 22-24 March 2006, Bari,
Italy, pages 24–36, 2006.
[12] Gerardo Canfora, Anna Rita Fasolino, Gianni Frattolillo, and Porfirio Tramontana. A
wrapping approach for migrating legacy system interactive functionalities to service
oriented architectures. Journal of Systems and Software, 81(4):463–480, 2008.
[13] Semih Cetin, N. Ilker Altintas, Halit Oguztuzun, Ali H. Dogru, Ozgur Tufekci, and
Selma Suloglu. Legacy migration to service-oriented computing with mashups. In
Proceedings of the Second International Conference on Software Engineering Ad-
vances (ICSEA 2007), August 25-31, 2007, Cap Esterel, French Riviera, France,
page 21, 2007.
BIBLIOGRAPHY 115
[14] Graham Charters, Matthew Peters, Caroline Maynard, and Anan-
toju Srinivas. An introduction to Service Data Objects for PHP,
http://www.ibm.com/developerworks/library/os-sdophp/, last accessed July 2011.
[15] Feng Chen, Shaoyun Li, and William Cheng-Chung Chu. Feature analysis for service-
oriented reengineering. In APSEC, pages 201–208, 2005.
[16] Feng Chen, Shaoyun Li, and William Cheng-Chung Chu. Feature analysis for service-
oriented reengineering. In Proceedings of the 12th Asia-Pacific Software Engineering
Conference, APSEC ’05, pages 201–208, Washington, DC, USA, 2005. IEEE Com-
puter Society.
[17] Sam Chung, Joseph Byung Chul An, and Sergio Davalos. Service-oriented software
reengineering: Sosr. In 40th Hawaii International International Conference on Sys-
tems Science (HICSS-40 2007), CD-ROM / Abstracts Proceedings, 3-6 January 2007,
Waikoloa, Big Island, HI, USA, page 172, 2007.
[18] Sam Chung, Peter S. Young, and Jack Nelson. Service-oriented software reengineer-
ing: Bertie3 as web services. In 2005 IEEE International Conference on Web Services
(ICWS 2005), 11-15 July 2005, Orlando, FL, USA, pages 837–838, 2005.
[19] Santiago Comella-Dorda, Kurt C. Wallnau, Robert C. Seacord, and John E. Robert.
A survey of black-box modernization approaches for information systems. In ICSM,
pages 173–183, 2000.
[20] James R. Cordy. The txl source transformation language. Sci. Comput. Program.,
61(3):190–210, August 2006.
[21] James R. Cordy. The txl source transformation language. Sci. Comput. Program.,
61(3):190–210, August 2006.
BIBLIOGRAPHY 116
[22] Joëlle Coutaz. User interface plasticity: Model driven engineering to the limit! In
2nd ACM SIGCHI Symposium on Engineering Interactive Computing Systems, pages
1–8, 2010.
[23] Félix Cuadrado, Boni García, Juan C. Dueñas, and Hugo A. Parada G. A case study on
software evolution towards service-oriented architecture. In 22nd International Con-
ference on Advanced Information Networking and Applications, AINA 2008, Work-
shops Proceedings, GinoWan, Okinawa, Japan, March 25-28, 2008, pages 1399–
1404, 2008.
[24] David Chappell. INTRODUCING SCA, http://tuscany.apache.org/sca-overview.html,
last accessed March 2012.
[25] K. Dezhgosha and S. Angara. Web services for designing small-scale web applica-
tions. In Electro Information Technology, 2005 IEEE International Conference on,
pages 4 pp. –4, may 2005.
[26] Dinakar Dhurjati, Sumant Kowshik, and Vikram Adve. Safecode: enforcing alias
analysis for weakly typed languages. SIGPLAN Not., 41(6):144–157, June 2006.
[27] Dinakar Dhurjati, Sumant Kowshik, and Vikram S. Adve. Safecode: enforcing alias
analysis for weakly typed languages. In PLDI, pages 144–157, 2006.
[28] Dieter Fensel and Christoph Bussler. The Web Service Modeling Framework WSMF.
Electronic Commerce Research and Applications, 1:113–137, 2002.
[29] Damiano Distante, Scott R. Tilley, and Gerardo Canfora. Towards a holistic approach
to redesigning legacy applications for the web with uwat. In 10th European Confer-
ence on Software Maintenance and Reengineering (CSMR 2006), 22-24 March 2006,
Bari, Italy, pages 295–299, 2006.
BIBLIOGRAPHY 117
[30] V. Dwivedi and N. Kulkarni. A model driven service identification approach for pro-
cess centric systems. In Congress on Services Part II, 2008. SERVICES-2. IEEE,
pages 65 –72, sept. 2008.
[31] Erik Christensen, Francisco Curbera, Greg Meredith, Sanjiva Weerawarana. Web
Services Description Language (WSDL) Version 1.1, http://www.w3.org/TR/wsdl,
last accessed September 2010.
[32] Thomas Erl. Service-oriented architecture. Prentice Hall, 2004.
[33] G. Van Rossum. Python programming language, http://www.python.org/.
[34] IBM. SCA Homepage, http://www.ibm.com/developerworks/library/specification/ws-
sca/, last accessed June 2012.
[35] J.Chatarji. Introduction to service-oriented architecture(soa), 2004.
[36] Meena Jha and Piyush Maheshwari. Reusing code for modernization of legacy sys-
tems. In 13th International Workshop on Software Technology and Engineering Prac-
tice (STEP 2005), 24-25 September 2005, Budapest, Hungary, pages 102–114, 2005.
[37] Loh Yong Joo, Tjan Soon Yin, Donald Xu, Ernest Thia, Pei Fen Chia, Christopher
Wee Keong Kuah, and Kong Keng He. A feasibility study using interactive com-
mercial off-the-shelf computer gaming in upper limb rehabilitation in patients after
stroke. Journal of Rehabilitation Medicine, 42(5):437–441, 2010.
[38] K. Dezhgosha and S. Angara. Web services for designing small-scale Web applica-
tions. In the 2005 IEEE International Conference on Electro Information Technology,
4 pages, 2005.
[39] SeongKi Kim and Sang-Yong Han. Performance comparison of dcom, corba and web
service. In Hamid R. Arabnia, editor, Proceedings of the International Conference on
BIBLIOGRAPHY 118
Parallel and Distributed Processing Techniques and Applications, pages 106–112.
CSREA Press, 2006.
[40] Kenneth Knowles and Cormac Flanagan. Hybrid type checking. ACM Trans. Pro-
gram. Lang. Syst., 32(2):6:1–6:34, February 2010.
[41] M.M. Lehman. On understanding laws, evolution, and conservation in the large-
program life cycle. Journal of Systems and Software, 1(0):213 – 221, 1979âAS1980.
[42] G. Lewis, E. Morris, L O’Brien, D. Smith, and L. Wrage. Smart: The service-oriented
migration and reuse technique. In Proceedings of the 13th IEEE International Work-
shop on Software Technology and Engineering Practice, pages 222–229, 2005.
[43] G. Lewis, E. Morris, and D. Smith. Analyzing the reuse potential of migrating legacy
components to a service-oriented architecture. In In Proceedings of the Conference
on Software Maintenance and Reengineering, pages 15–23, 2006.
[44] Grace A. Lewis, Edwin J. Morris, and Dennis B. Smith. Analyzing the reuse potential
of migrating legacy components to a service-oriented architecture. In CSMR, pages
15–23, 2006.
[45] Grace A. Lewis, Edwin J. Morris, Dennis B. Smith, and Liam O’Brien. Service-
oriented migration and reuse technique (smart). In STEP, pages 222–229, 2005.
[46] Andrew J. Malton, Kevin A. Schneider, James R. Cordy, Thomas R. Dean, Darren
Dousineau, and Jason Reynolds. Processing software source text in automated de-
sign recovery and transformation. In IEEE 9th International Workshop on Program
Comprehension (IWPC 2001), May 2001, Toronto, Canada, pages 127–134, 2001.
[47] Martin Fowler. Refactoring: improving the design of existing code. Addison-Wesley
Longman Publishing Co., Inc., Boston, MA, USA, 1999.
BIBLIOGRAPHY 119
[48] Martin Gudgin, Marc Hadley, Noah Mendelsohn, Jean-Jacques Moreau, Henrik
Frystyk Nielsen,Anish Karmarkar,Yves Lafon. Simple Object Access Protocol
(SOAP) Version 1.2, http://www.w3.org/TR/soap12, last accessed September 2010.
[49] Caroline Maynard, Graham Charters, Matthew Peters, and Simon Laws. SCA/SDO
for PHP, http://pecl.php.net/package/SCA_SDO, last accessed Aug 2011.
[50] Robin Milner. A theory of type polymorphism in programming. Journal of Computer
and System Sciences, 17:348–375, 1978.
[51] Moodle Trust. Moodle, http://Moodle.org, last accessed October 2010.
[52] OASIS. UDDI Version 2.03 Data Structure Reference,
http://www.uddi.org/pubs/DataStructure-V2.03-Published-20020719.htm, last
accessed September 2010.
[53] Liam O’Brien, Dennis B. Smith, and Grace A. Lewis. Supporting migration to ser-
vices using software architecture reconstruction. In 13th International Workshop on
Software Technology and Engineering Practice (STEP 2005), 24-25 September 2005,
Budapest, Hungary, pages 81–91, 2005.
[54] Open SOA Collaboration. SOA PHP Homepage,
http://www.osoa.org/display/PHP/SCA+with+PHP, last accessed Aug 2011.
[55] Xinming Ou, Gang Tan, Yitzhak M, and David Walker. Dynamic typing with depen-
dent types. In In IFIP International Conference on Theoretical Computer Science,
pages 437–450, 2004.
[56] Php.net. PHP 5 ChangeLog, http://www.php.net/ChangeLog-5.php, last accessed
Aug 2011.
BIBLIOGRAPHY 120
[57] Benjamin C. Pierce and David N. Turner. Local type inference. ACM Trans. Program.
Lang. Syst., 22(1):1–44, January 2000.
[58] Liam Quin. Extensible Markup Language (XML), http://www.w3.org/XML/, last
accessed Nov 2012.
[59] Amala Vijaya Selvi Rajan and Jim Otieno. Leveraging traditional distributed applica-
tions to web services for e-learning applications. In 15th International Workshop on
Database and Expert Systems Applications, pages 430–435, 2004.
[60] A.V.S. Rajan and J. Otieno. Leveraging traditional distributed applications to web
services for e-learning applications. In Database and Expert Systems Applications,
2004. Proceedings. 15th International Workshop on, pages 430 – 435, aug.-3 sept.
2004.
[61] Margaret Rouse. Service Data Objects (SDO),
http://searchsoa.techtarget.com/definition/Service-Data-Objects, last accessed
Dec 2011.
[62] Scott Nichol. Introduction to NuSOAP, http://www.scottnichol.com/nusoapintro.htm,
last accessed September 2010.
[63] Simon Laws. SCA with PHP, http://www.osoa.org/display/PHP/SCA+with+PHP, last
accessed September 2010.
[64] D. Smith. Migration of legacy assets to service-oriented architecture environments.
In Proceedings of the 29th International Conference on Software Engineering, pages
174–175, 2007.
[65] Dennis B. Smith. Migration of legacy assets to service-oriented architecture environ-
ments. In ICSE Companion, pages 174–175, 2007.
BIBLIOGRAPHY 121
[66] H. M. Sneed and S. H. Sneed. Creating web services from legacy host programs. In
Proceedings of the Fifth IEEE International Workshop on Web Site Evolution, pages
59–65, 2003.
[67] Harry M. Sneed. Wrapping legacy software for reuse in a soa. In Vienna University,
2005.
[68] Harry M. Sneed. Integrating legacy software into a service oriented architecture.
In 10th European Conference on Software Maintenance and Reengineering (CSMR
2006), 22-24 March 2006, Bari, Italy, pages 3–14, 2006.
[69] Harry M. Sneed and Stephan H. Sneed. Creating web services from legacy host
programs. In 5th International Workshop on Web Site Evolution (WSE 2003) - Archi-
tecture, 22 September 2003, Amsterdam, The Netherlands, pages 59–65, 2003.
[70] Eleni Stroulia, Mohammad El-Ramly, and Paul G. Sorenson. From legacy to web
through interaction modeling. In ICSM, pages 320–, 2002.
[71] Eleni Stroulia, Mohammad El-Ramly, Paul G. Sorenson, and Roland Penner. Legacy
systems migration in cellest. In ICSE, page 790, 2000.
[72] Paul Tarjan and Nick McKeown. SCARF: Stanford Conference and Research Forum,
http://scarf.sourceforge.net/index.html, last accessed Feb 2013.
[73] M. Tatsubori and K. Takahashi. Decomposition and abstraction of web applications
for web service extraction and composition. In Web Services, 2006. ICWS ’06. Inter-
national Conference on, pages 859 –868, sept. 2006.
[74] Michiaki Tatsubori and Kenichi Takashi. Decomposition and abstraction of web ap-
plications for web service extraction and composition. In IEEE International Confer-
ence on Web Services, pages 859–868, 2006.
BIBLIOGRAPHY 122
[75] TechGuruLive. What is a hardware load balancer?,
http://techgurulive.com/2011/01/17/what-is-a-hardware-load-balancer/, last ac-
cessed October 2010.
[76] The PHP Group. Package Information: SOAP,
http://pear.php.net/package/SOAP/redirected, last accessed September 2010.
[77] Francesco Trucchia and Jacopo Romei. Pro PHP Refactoring. Apress, Berkely, CA,
USA, 1st edition, 2010.
[78] Mark van den Brand, Jan Heering, Hayco de Jong, Merijn de Jonge, Tobias Kuipers,
Paul Klint, Leon Moonen, Pieter Olivier, Jeroen Scheerder, Jurgen Vinju, Eelco
Visser, and Joost Visser. The asf+sdf meta-environment: a component-based lan-
guage development environment. Electronic Notes in Theoretical Computer Science,
44(2), 2001.
[79] WEBSERVICE. Web Services, http://www.w3.org/2002/ws/Activity, last accessed
September 2010.
[80] Jia Zhang, Jen-Yao Chung, and Carl K. Chang. Migration to web services oriented
architecture: a case study. In Proceedings of the 2004 ACM Symposium on Applied
Computing (SAC), Nicosia, Cyprus, March 14-17, 2004, pages 1624–1628, 2004.
[81] Zhuopeng Zhang and Hongji Yang. Incubating services in legacy systems for archi-
tectural migration. In 11th Asia-Pacific Software Engineering Conference (APSEC
2004), 30 November - 3 December 2004, Busan, Korea, pages 196–203, 2004.