Use Case: Migrating Legacy Software to Web
For legacy software that's been maintained for years, it's daunting to pick new technologies to migrate to - especially new technologies that may require another software development in five years. MAE provides an environment to minimize the code changes required to modernize your software.
You have modernized your infrastructure, but you're being held back by dependence on legacy software or equpment that is not going away anytime soon:
All of these examples are problems because programs are hard to modify, so you must minimize legacy maintenance. But you want them accessible via a web interface. Perhaps with a very different look.
How do you modernize these legacy programs?
MAE has a number of capabilities for running legacy software and displaying it in real-time.
If your software is terminal based, see Use Case: Web-Enabling Legacy Text-Based Software.
If your software was not originally designed for a terminal (so it has no escape sequences to control cursor location, text color, etc), MAE contains components for you to run your software, receive program output, and send program input. To complete the solution, you will need to develop a MAE component that processes the received program output and determines what program input to send. To output to a web browser, you can choose to keep a text-based interface (and perhaps use TermGW to handle web page details) or you can use MAE's single page app (SPA) support libraries. Aside from a few HTML assets (one for your SPA layout and others for filling in detail in the page plus images), you can draw on MAE's UserDevice class for screen updates and UI interaction; to render generated images, use MAE's Image class.
If you have held off migrating your software to a modern technology platform until you can be assured that the migration will hold longer than technology fads, now is the time to migrate to MAE. MAE has abstracted user interaction, database access, abstracted user notification, virtualized the file system, and source language independence. As these areas evolve with technology, changes may be as simple as updating a configuration, updating an interface script, or upgrading a MAE component. If you have a MAE developers license, you will have the MAE source code, so there's no concern about escrowing the software with HanoverSoft.
When you migrate your legacy app, you may wish to preserve the screen layout. Or you may wish to revise it. When you perserve the screen layout, you will save the time of designing the new interface and the extra time needed for developing it, testing it, and re-training users. When you revise the screen layout, you provide users with clearer input controls and display organization.
Does this solution look like a fit for your organization? Reach out to HanoverSoft at +1 (919) 270-6712 or info@hanoversoft.net to discuss.
When you need to run software to capture its output and/or send it it input, you need to configure IoGW to manage it as a resource. If the program requires a terminal, the configure it as a ptty, otherwise configure it as a pipe. If your command is /usr/bin/reportgen with parameters "-r 500" and you want to configure the resource name to Report500, then use tioreg like this:
tioreg -add Report500 pipe:/?exec=/usr/bin/reportgen+-r+500
for a pipe or
tioreg -add Report500 ptty:/?exec=/usr/bin/reportgen+-r+500
for a ptty. If your ptty program outputs terminal escape sequences based upon the TERM environment variable, you can set that for vt100 using
tioreg -add Report500 ptty:/?exec=/usr/bin/reportgen+-r+500&TERM=vt100
If you're also using TermGW, you'll need to tell it to expect vt100 escape codes, either via MaeTerm configuration or TermAPI::setTerminalType().
Regardless of the details of running your program, your program is now available to run. By simply opening the Report500 resource, the program will start running and its output will be captured to the input stream.
Access to MAE through the web interface requires a login. The default login screen is served by UserGW from /usr/mae/html/pub/login.html, which should be customized per your site. The user must successfully authenticate before advancing to maeterm.
Authorized users are maintained in the MAE User database table. Manipulate that using tuser. To add user Jan Smith with e-mail jan@abc.com and password changeme, use
tuser add -n "Jan Smith" -e jan@abc.com -p changeme
(Note that the password is encrypted in the database table.)
If your users will only be accessing maeterm, you can make it the default app that displays when the user logs in using
tpset usergw firstapp=maeterm
Before migrating your software, assess your source code for
MAE has already abstracted points, but you'll need to compare your legacy software's needs against MAE's offerings. Where MAE falls short, you'll need additional MAE components (legacy resources); either you can engage HanoverSoft Professional Services or you can develop them yourself. For new development of legacy resources, abstract the functionality and encapsulate it within a new MAE component where you can. This will simplify testing. This is a particularly prudent strategy if you have multiple applications that have the same dependencies - you can reuse your new MAE component for other apps.
Before undertaking your migration endeavor, it is wise to devise a plan. What needs to be developed? What resources (people, time, assets) will be needed? What is the timeline for how the project progresses? What can be done simultaneously versus what depends upon other prior step completion?
Do you want to preserve the screen layout or do you want to revise it? Each has pros and cons.
When you perserve the screen layout, you will save a lot of time. For a user who is familiar with the application, take various screenshots of the application and carve up the display into functional areas. If status always appears in an area, call that the status area; if record data always appears in another area, call that the record area; and so on. Even though these areas may overlap at different points when the program is running, it identifies where text is displayed. This is critical for a MAE migration because your migrated app will output text to target regions, not to specific screen locations. A region name is an identifier - a case sensitive series of letters and numbers without spaces or punctuation. Create descriptive region names, such as AppStatus, OpStatus, UserData, NavPane, Results, etc.
You can design a web page based upon the regions you have identified. Consider an HTML table if your interface has adjacent block regions. It's OK for regions to overlap - when you clear a region, and output to an overlapping region, the old text disappears and the new text appears in the same spot.
When output follows a standard format with variations here and there, consider using a record. Here, a record is a HTML snippet (stored in /usr/mae/html/record) with named blanks that can be filled in with your data. You can have usergw fill in the data as it renders it in the browser or you can fill in the data after the record is rendered. To have usergw fill in the record simple.html in a region called greeting using the key/value pairs of name=Jane and age=22, create /usr/mae/html/record/simple.html:
Good day, <div id=simple_name > </div >! <br >Your age is <div id=simple_age > </div >.
and display it with something like this:
void drawUserGreeting(UserDevice & device, const string & name, int age)
{
HashArray data;
data.set("name", name);
data.set("age", age);
device.record("simple", data, "greeting");
}
When you revise the screen layout, you provide users with clearer input controls and display organization. You can take advantage of UI controls such as buttons, pull-downs, click hotspots, data uploads, collapsable regions, and links to other web-accessible resources. UI controls are typically displayed as a group; when using UI controls, you will need to ensure all inputs are answered (as input validation) before taking action when the user clicks on a button to process the inputs; also keep in mind that values for inputs arrive asynchronously, so an input at the bottom of the form may be answered before an input at the top; if you need to control that flow, then don't display inputs until you're ready for the user to respond to them.
Note that you can use records (described in previous section) to great effect: Each record can have empty, named regions which may in turn be used to display another record. And when a parent record is cleared from the display, all sub-records are cleared as well. This unleashes the power of the single page app; you don't need to keep switching web pages when you can update regions of your starting page so easily.
When assessing your software (above), you identified legacy resources that can be encapsulated separately from your legacy software, yet accessible by your legacy software. Create a MAE component for each legacy resource (see Developing a New App). In your MAE registration file (.mreg), define the API for accessing your new component. This becomes your new interface to the legacy resource.
To test your new MAE component legacy resource, you can use the MsgPlayer tool to generate messages and send them to your legacy resource to ensure they respond correctly to a given sequence of messages.
If your legacy resource needs a text-based monitor to allow administrator access, you can use tmon to send monitor commands to your legacy resource and see the responses. You will need to configure an RPC service with the name module.monitor; see tmon.
If you have the test plan for the original legacy software, that is ideal. If not, based upon all critical paths of the legacy software, make sure your test plan includes each new critical path in your new MAE app.
You will need your single page app's start page with the filename /usr/mae/html/channel.html.
For sub-page content that will end up in /usr/mae/html/record/, create .ui files which readily convert to .html files using genmae. When our .ui file includes user controls that send messages back to your app, genmae will generate the appropriate HTML and ensure the message is received and your app's callback is called; otherwise, it could be ignored.
If you have any static images, you can store them in the ImageLib database table or put them in /usr/mae/html/images. For sub-page HTML content that refers to images in the filesystem, consider the URL document root to start at /usr/mae/html. Use the ImageLib class to reference the image, pull it into the Image class, and render it using the UserDevice class.
Given all your assessment, planning, and design, migrate your software to MAE. See Developing a New App.
You will need updated documentation and training for your users.
If you choose to recreate your documentation to make it web-accessible, consider creating wiki pages in /usr/mae/html/doc/ which can be converted to HTML (a future release will allow conversion to PDF and possibly other formats), which can be displayed to the user. See Simple Text Formatting to review wiki formatting; see wiki2doc for details about conversion to HTML or other formats.