Presentation is loading. Please wait.

Presentation is loading. Please wait.

Step-by-Step Legacy Migration with Aranea Jevgeni Kabanov R&D lead, Aranea project lead Webmedia, Ltd.

Similar presentations


Presentation on theme: "Step-by-Step Legacy Migration with Aranea Jevgeni Kabanov R&D lead, Aranea project lead Webmedia, Ltd."— Presentation transcript:

1 Step-by-Step Legacy Migration with Aranea Jevgeni Kabanov R&D lead, Aranea project lead Webmedia, Ltd. ekabanov@webmedia.ee

2 Motivating scenario “Stakeholders have a large web application written in Struts. They consider Struts legacy and want to continue development in JSF. However rewriting all of the code would take too much time, effort and money and would halt the ongoing development.“

3 Our solution 1.Use Aranea web integration layer to run different technologies side-by-side 2.Refactor the application into independent coarse-grained components 3.Start new development immediately and change old code only when requirements change – step-by-step migration

4

5

6

7

8 Goal Get rid of legacy and custom web frameworks in your application

9 Aranea Aranea began as an Object-Oriented MVC Web Framework From the onset we had plans to build web integration on the same platform Aranea Integration has been released to public yesterday :)

10 Disclaimer Aranea MVC is stable and used in production Aranea Integration is beta and used in pilot migration projects Everything is Open-Source with documentation and support available for free from araneaframework.org Commercial support/training/consulting is provided at araneaframework.com

11 Organization Aranea Component Model Widgets Flow navigation Aranea Integration Layer Struts, JSF, GWT Step-by-step migration Principles Case study

12 Aranea Component Model Every component is a first-class object Objects are created by the programmer No (XML) mappings State is in the object (no scopes) Components, pages and flows are represented by first-class widgets

13 Hello World! NameWidget name.jsp Reads the name from requests and passes it to HelloWidget HelloWidget hello.jsp Renders the “Hello ${name}!” greeting, where name is given by the caller.

14 NameWidget public class NameWidget extends BaseUIWidget { //Called on “hello” event public void handleEventHello() { String name = //reads “name” from request parameters (String) getScopedData().get("name"); getFlowCtx().replace(new HelloWidget(name)); } Insert your name: name.jsp:

15 HelloWidget public class HelloWidget extends BaseUIWidget { private String name; //Widget state is in its fields public HelloWidget(String name) { this.name = name; //We could pass any Java object here } public String getName() { return this.name; } public void handleEventBack() { getFlowCtx().replace(new NameWidget()); } Hello ${widget.name}! hello.jsp:

16 web.xml... araneaServlet AraneaSpringDispatcherServlet araneaApplicationStart example.NameWidget 1 araneaServlet /main/*...

17 Flows Currently we use replace() which means: A new instance is created every time We know where to return Flow1

18 Flows What we would want is to preserve the instance and nest the new flow Flow1 Flow2

19 Flows start() and finish() do exactly that: public class NameWidget extends BaseUIWidget {... public void handleEventHello() {... getFlowCtx().start(new HelloWidget(name)); } public class HelloWidget extends BaseUIWidget {... public void handleEventBack() { getFlowCtx().finish(null); }

20 Including widgets Widgets can be included, let’s try to use HelloWidget inside NameWidget like this handleEventHello() HelloWidget We assume that the “back” button was removed from HelloWidget

21 Including widgets First let’s modify the HelloWidget: public class HelloWidget extends BaseUIWidget { private String name; public HelloWidget(String name) { this.name = name; } public String getName() { return this.name; } public void setName(String name) { this.name = name; }

22 Including widgets Now let’s add a HelloWidget instance public class NameWidget extends BaseUIWidget { private HelloWidget helloWidget; protected void init() { helloWidget = new HelloWidget("Stranger"); addWidget("hello", helloWidget); } public void handleEventHello() { String name = (String) getScopedData().get("name"); helloWidget.setName(name); }

23 Including widgets Insert your name: And finally we include the widget in the JSP

24 Including widgets So this is what we get: helloWidget.setName(“Jevgeni”) HelloWidget, helloWidget

25 Widgets are objects We can include several widgets of same class on one page public class RootWidget extends BaseUIWidget { protected void init() { addWidget("hello1", new NameWidget()); addWidget("hello2", new NameWidget()); addWidget("hello3", new NameWidget()); }

26 Flows are objects public class RootWidget extends BaseUIWidget { protected void init() { addWidget("flowContainer1", new StandardFlowContainerWidget(new NameWidget())); addWidget("flowContainer2", new StandardFlowContainerWidget(new NameWidget())); addWidget("flowContainer3", new StandardFlowContainerWidget(new NameWidget())); } We can also include several flow containers on one page

27 Goal Get rid of legacy and custom web frameworks in your application

28 Our Solution 1.Use Aranea web integration layer to run different technologies side-by-side 2.Refactor the application into coarse-grained integration components 3.Start new development immediately and change old code only when requirements change – step-by-step migration

29 Requirements We want to implement widgets using any framework/technology available This can mean running a whole application in one widget and another application in its sibling Without any changes to the technology In fact we want to do that retroactively, reusing existing applications

30 Aranea Integration Layer Integration Layer API is based around widgets: StrutsWidget, JsfWidget, GwtWidget Widgets receive the URI of the starting point of the subapplication E.g. new StrutsWidget(“/Welcome.do”); AraneaUtil gives access to all of the Aranea API from embedded applications

31 Struts Integration Problems 1.Session and request attributes share the same namespace and can clash 2.Request parameter names will clash already during form submission 3.Struts navigates between pages by changing the actual URL 4.HTML limits usage of some tags

32 Problem 1: Attributes We can make request attributes local, by wrapping HttpServletRequest and saving them in a local map Since HttpSession can only be accessed via HttpServletRequest we can do the same thing to session attributes

33 Problem 2: Parameters Since parameter names clash already during the submission of request we need to solve the problem in HTML We can do it by introducing prefixes to each field name referring to the containing widget The request wrapper restores the original names

34 Problem 3: Navigation We put a filter over the Struts servlet that will include the Aranea servlet While Aranea renders the particular StrutsWidget, it will include the according action Therefore it will render in correct place as will everything else

35 Problem 3: Navigation However we need to include some information that is used to render Aranea Servlet path Window id Current widget id We do that by overriding encodeURL() in request wrapper

36 Problem 4: HTML There are two main things we need to change in Struts HTML output: Forms cannot be nested and must be escaped Field names must be prefixed These are easy to change using a lexer (not even a parser) on the output stream To escape forms we construct a JavaScript object with the same properties/methods

37 name.jsp & hello.jsp <form method="get" action=" "> Hello ${param.name}! ">Back

38 HelloNameWidget & RootWidget public class HelloNameWidget extends StrutsWidget { public HelloNameWidget() { super("/name.jsp"); } public class RootWidget extends BaseUIWidget { protected void init() { addWidget("hello1", new HelloNameWidget()); setViewSelector("root"); } <input type="submit" onclick=“new Aranea.Struts.Form(…).submit()" value="Say hello!"> Output:

39 What will happen? public class RootWidget extends BaseUIWidget { protected void init() { addWidget("hello1", new HelloNameWidget()); addWidget("hello2", new HelloNameWidget()); addWidget("hello3", new HelloNameWidget()); setViewSelector("root"); }

40 DEMO

41 Generalizing Integration The approach taken with Struts can be easily extended to any action-based framework Including custom ones In fact most of it is applicable to component- based frameworks as well However component-based frameworks will usually allow us to solve these problems simpler

42 JSF Integration We use the same approach to encapsulate request and session attributes Form fields can be prefixed by overriding the naming container (form) Navigation can be solved by overridding the view handler No postprocessing necessary!

43 DEMO

44 GWT Integration Essentially the simplest, as almost everything happens on the client side Two problems Using RPC to call widget methods Restoring client-side state after a full request Not solved yet!

45 Our Vision

46 Goal Get rid of legacy and custom web frameworks in your application

47 Our Solution 1.Use Aranea web integration layer to run different technologies side-by-side 2.Refactor the application into coarse-grained integration components 3.Start new development immediately and change old code only when requirements change – step-by-step migration

48 Refactoring 1.Enable Aranea Integration and sanitize HTML (produces working application) 2.Extract layout, menu and login 3.Split application into coarse-grained components

49 Case Study Estonian Tax Inspection application module Connected with Forestry and European Union directives Part of a large application family based on common architecture that manage all tax and customs needs

50 Technologies MVC web framework is Struts Presentation done using Velocity and Tiles A lot of custom extensions to all of them SSO using Weblogic API

51 Step 1: Integration & HTML Application started running after initial configuration HTML tags were used in some places, which means encodeURL() was not applied Some scripts accessed form fields by name Added a widget prefix before the name

52 Step 2: Layout, menu and login Since login was done using SSO we left it be We extended the Aranea MenuWidget to implement the menu from scratch, reusing all the old privileges After lifting header, footer and menu to the RootWidget turned out that Tiles were not doing anything useful anymore and could be eliminated

53 Step 3: How to split? First we extract the widgets pointing to the relevant parts of the application Next we change all navigation/inclusion between those parts to use Aranea API: Sending events to the hosting widget AraneaUtil.getFlowCtx(), AraneaUtil.addWidget(), used from the embedded applications

54 Step 3: Analyze and split After some research we decided that the best way to split the application would be vertically – by functionality We ended up with five different functionality types and about ten different widgets (some widgets were multipurpose)

55 Step 3: Analyze and split Some widgets were used only as flows while others were included as components By extracting and abstracting several included widgets we eliminated a lot of copy-paste While we could further refine our components it was good enough for starting migration

56 Results Five main functionality parts which could be rewritten one by one without affecting the others No more Tiles Less copy-paste If we needed to add a sixth functionality part we could start using JSF immediately

57 Goal Get rid of legacy and custom web frameworks in your application

58 Our solution 1.Use Aranea web integration layer to run different technologies side-by-side 2.Refactor the application into coarse-grained integration components 3.Start new development immediately and change old code only when requirements change – step-by-step migration

59 Step-by-step migration After refactoring every component is a Java class with a particular interface/contract The rest of the components can only interact with it via that contract Therefore we can just rewrite it using any other implementation as long as the contract is preserved

60 Case study: migration In the case study we wanted to use Aranea, so there was no need for further migration Eventually we would like to lift the whole Tax and Customs application to Aranea using other framework features when needed However we also have clients who prefer JSF and Tapestry, so in those cases we would continue

61 The Next Step Aranea Integration solves the problem of mashing up Java web applications A lot of legacy applications are written in Perl, PHP, Oracle Forms, etc You’d also want to integrate with.NET web applications Aranea Remote Integration will support that!

62 Webmedia Webmedia (www.webmedia.eu) is a Baltic company employing over 300 people that sponsors Aranea developmentwww.webmedia.eu Webmedia offers complete commercial support for Aranea MVC & Integration In fact we now also offer support for migrating your legacy web applications to a platform of your choice :)

63 Final Words Using Aranea Integration is easy Problems might come up requiring better understanding of Integration works Migration is not completely painless, but it is cheap next to the alternative Migrated Struts Mailreader application in the distribution is a good starting point

64 Questions www.araneaframework.com www.araneaframework.org


Download ppt "Step-by-Step Legacy Migration with Aranea Jevgeni Kabanov R&D lead, Aranea project lead Webmedia, Ltd."

Similar presentations


Ads by Google