a framework for migrating web applications to web services sil a

136
AF RAMEWORK FOR MIGRATING WEB A PPLICATIONS TO WEB S ERVICES 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

Upload: others

Post on 03-Feb-2022

1 views

Category:

Documents


0 download

TRANSCRIPT

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

Dedication

To my father and best friend Abdullah Almonaies.

iii

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

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>&nbsp;&nbsp;";$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.