There are many legacy applications written in many programming languages that businesses rely on every day. These applications frequently address unique and complex issues facing a business. But most importantly, these applications have been tested and proven over many years of deployment.
Today, these applications need to work with the internet. That is the reason we created APL+IntegrationServer. Our APL+IS provides a simple point and click interface which makes it possible to publish those existing applications to the internet, without requiring a rewrite of the logic which makes these legacy applications so valuable.
In addition, you do not have to learn any new languages, such as VB, Java, Javascript, C#, ASP or the like, to get your application integrated with the internet.
Simply put you can continue to develop in the language which meets the demands of your business, and still take advantage of the internet. All of the logic remains in your programming language of choice, in the development environment you understand.
Using APL+IS you can publish your functions to the web as WebServices when communicating with other applications, have them return web pages for interaction with browsers, or have the result from your function returned as SOAP or Microsoft Binary. We will look at just how this can work in our example below.
We have chosen APL as the application language in our example, and will demonstrate how to publish functions from an application created using APL. The same methodology will work for any language. APL gives the choice of creating either an ActiveX object or a .Net assembly dll, both of which will work just fine. We are going to choose to create the .Net assembly dll, so that we can do some performance checks against Microsoft’s IIS server using .ASPX pages later on.
In our application we have created three functions, HTTP_hello, ADD, and Calculate.
Let’s look at how we publish these functions to the web.
First we will locate the application we want to use on the hard drive.
We have entered the location of the application, the namespace and the class information for the dll.
This provides the APL+IS the information it needs to associate the application with the name “demows”. Also notice the minpool and maxpool names. By setting these you can manage a pool of applications. The minpool guarantees at least this many copies of the application will be available. So, if your application takes a while to load, because of the need to connect to databases, or other time consuming activities during initialization, you can have a number of them pre-loaded and ready to go at any moment.
In addition, you can specify the maximum number that should be opened, and once those are in use, you can also specify where the request should be sent by entering a url in the busyid field. This could then route the request to another server, or simply return a server busy message. You control what happens.
As the demand is reduced for any application, the number is reduced back down to the minpool amount.
Now that we know about the application we want to use, the next thing we want to do is publish a function in that application.
To do this we will add a new virtual path named /test/hello. This is an arbitrary string, and is what the usr will use to access the function. For instance, if this were being accessed from a web browser the user would enter:
http://www.yourwebsite.com/test/hello
That would take them to your server, and then run the function you have associated with this virtual path. Your configuration would look something like:
The wsid points to the workspace id you associated with your application above. The method references the function:
The params are the input you expect for your function:
In this case we are going to ask for the entire entity-body, there are many choices here and you can set as many parameters as your function requires. We will look at more of these in the examples below.
The result in this case is a document. Again, this has a wide variety of options, and can be more than one thing. Again, we will look at more options below.
That is it, we will call the function HTTP_hello with the entity-body as the parameter and return a document. As we anticipate this being displayed in a web browser we will return an html document. Here is the HTTP_hello function:
response„HTTP_hello INP response„'<html>' response„response,'<head><title>Hello APL+WebService</title></head>' response„response,'<body>' response„response,'<h1>Hello APL+WebService</h1>' response„response,'<br><br>' response„response,'This page was generated by the <b>HTTP_hello</b> function in workspace <b>',ŒWSID,'</b>'response„response,'<br><h2>Entity Body:</h2><br><pre>',INP,'</pre><br>' response„response,'</body>' response„response,'</html>'
This simple function returns the html with any entity-body in a pre tag.
Next, let us look at a function which will add two numbers submitted from a web browser or from a web service. The input in our example will be for web browser, but the server would just as well take an xml submission. In both cases the function see the same input.
What is interesting with this example, is that we are expecting two integers as the input to the ADD function. Below is the ADD function:
r„ADD INP;a;b (a b)„2†INP 'a: 'a 'b: 'b r„a+b
This also returns an integer, which we will need to have the server translate into an xml structure in order to return it. All of this happens automatically. Here is the setting for the input:
Here is the setting for the result:
The user wanting to access this function could enter:
http://www.yourwebsite.com/test/add?a=10&b=20
The function will see two integers, “a” set to 10 and “b” set to 20. If the data came in from a form, xml or whatever, the function would always see the same data with no changes to the setup. The server automatically creates the correct variable and type and then calls the function.
Since the result is just an integer, the server will create the following result.
<?xml version="1.0" ?> - <ADDResponse> <r>30</r> </ADDResponse>
If there were multiple elements in the return, the xml would automatically adapt to the returned data.
The next function we will look at does an amortization. The virtual link is /test/loan and the function name is Calculate. The input has several parts, and we are going to ask for entity-body-decoded:
This creates an n by 2 matrix of the value pairs submitted. Again, the type of submission does not matter, the matrix will automatically be created.
This is the input part of the Calculate function:
HTML„Calculate PARS;ŒTRAP;NAMES;VALUES;LoanAmt;PercentDown;LenMax;LenMin; IntrMax;IntrMin;PAYMENTS;PERIODS;INTEREST;NI;NM;PER;INT; ROWTITLES;COLTITLES;PAY_HTML;NAME;VAL;I;TITLE;X; ERRORFIELDS;ERRORMSGS;NOT_NUMERIC;CRLF;ALIGN; ROW;COLTIT;PAY;PAYVALS;J ŒTRAP„(0 1000)'C' '…ERR' © Calculates loan repayments © LoanAmt Loan amount © LenMax Maximum loan period © LenMin Minimum loan period © IntrMax Maximum interest rate © IntrMin Minimum interest rate © Also uses the following global variable (for illustration) © PeriodType Type of period;1 = years, 2 = months NAMES VALUES„‡[2]PARS PeriodType„1 VALUES„œ,/2œ¨ŒVFI¨VALUES ©VALUES„1000000 20 10 5 8.5 6 LoanAmt PercentDown LenMax LenMin IntrMax IntrMin„VALUES
Looking at the calculation part of the function we find:
LenMin LenMax„LenMin LenMax[“LenMin LenMax] IntrMin IntrMax„IntrMin IntrMax[“IntrMin IntrMax] VALUES„LoanAmt PercentDown LenMax LenMin IntrMax IntrMin PER„PERIODS„¯1+LenMin+¼1+LenMax-LenMin PERIODS„PERIODS×12 1[PeriodType] INT„INTEREST„0.5ׯ1+(2×IntrMin)+¼1+2×IntrMax-IntrMin INTEREST„INTEREST÷100×12 1[PeriodType]
NI„½INTEREST NM„½PERIODS
PAYMENTS„(LoanAmt×1-0.01×PercentDown)×((NI,NM)½NM/INTEREST)÷1-1÷(1+INTEREST)°.*PERIODS
From this we will build an HTML document to return. We could have returned an array, a matrix, the server could have then created either an xml document, a SOAP document or even Microsoft Binary to return to the client
The overall concept is that you can continue to work in your language and development environment and the APL+IntegrationServer will publish your function to the web.
There are a wealth of options both for input and for returns, which can be found in the APLDN Library.
One of the important questions that often arises is: “If I continue to use my language will I be as fast as IIS and ASPX?” The answer is that you will be faster! The following example runs the Calculate function above. The test was run using the Microsoft Application Center Test tool.
In the Microsoft case we called the above assembly dll from an ASPX page using C# as the language. In our case we used the configuration shown above. We selected 8 users in the Test tool.
The results of the test show that the APLWS server was approximately 160% faster than the IIS server and .ASPX. In addition the IIS server had approximately a 1% failure rate. This is quite significant, as the user would be left with a “server busy” page every 99 pages. When the pages are part of an application, this can be disastrous as the user could end up losing significant work and data.
Application Center Test
Overview: Summary
(1) |
Test Name: |
test: APLWS |
|
Test Run Name: |
report-APLWS-Apr 20, 2004 17-43-36 |
|
Test Started: |
4/20/2004 5:42:34 PM |
|
Test Duration: |
00:00:01:00 |
|
Test Iterations: |
3,816 |
|
Test Notes: |
- |
(2) |
Test Name: |
test: IIS |
|
Test Run Name: |
report-IIS-Apr 20, 2004 17-44-54 |
|
Test Started: |
4/20/2004 5:43:52 PM |
|
Test Duration: |
00:00:01:00 |
|
Test Iterations: |
2,435 |
|
Test Notes: |
- |
Test Run Graph
Properties |
|
|
|
|
(1) |
(2) |
|
Test type: |
Dynamic |
Dynamic |
|
Simultaneous browser connections: |
8 |
8 |
|
Warm up time (secs): |
0 |
0 |
|
Test duration: |
00:00:01:00 |
00:00:01:00 |
|
Test iterations: |
3,816 |
2,435 |
|
Detailed test results generated: |
Yes |
Yes |
|
|
|
|
|
Summary |
|
|
|
|
|
(1) |
(2) |
|
Total number of requests: |
3,819 |
2,417 |
|
Total number of connections: |
3,816 |
2,435 |
|
|
|
|
|
|
Average requests per second: |
63.65 |
40.28 |
|
Average time to first byte (msecs): |
88.67 |
174.08 |
|
Average time to last byte (msecs): |
88.72 |
174.30 |
|
Average time to last byte per iteration (msecs): |
88.79 |
173.01 |
|
|
|
|
|
|
Number of unique requests made in test: |
1 |
1 |
|
Number of unique response codes: |
1 |
2 |
|
|
|
|
|
Errors Counts |
|
|
|
|
|
(1) |
(2) |
|
HTTP: |
0 |
1 |
|
DNS: |
0 |
0 |
|
Socket: |
0 |
19 |
|
|
|
|
|
Additional Network Statistics |
|
|
|
|
|
(1) |
(2) |
|
Average bandwidth (bytes/sec): |
803,135.70 |
546,174.02 |
|
|
|
|
|
|
Number of bytes sent (bytes): |
1,519,962 |
1,113,505 |
|
Number of bytes received (bytes): |
46,668,180 |
31,656,936 |
|
|
|
|
|
|
Average rate of sent bytes (bytes/sec): |
25,332.70 |
18,558.42 |
|
Average rate of received bytes (bytes/sec): |
777,803.00 |
527,615.60 |
|
|
|
|
|
|
Number of connection errors: |
0 |
0 |
|
Number of send errors: |
0 |
12 |
|
Number of receive errors: |
0 |
7 |
|
Number of timeout errors: |
0 |
0 |
|
|
|
|
|
Response Codes |
|
|
|
|
|
(1) |
(2) |
|
Response Code: 403 - The server understood the request, but is refusing to fulfill it. |
|
|
Count: |
- |
1 |
|
|
|
Percent (%): |
- |
0.04 |
|
|
|
|
|
|
|
|
Response Code: 200 - The request completed successfully. |
|
|
Count: |
3,819 |
2,416 |
|
|
|
Percent (%): |
100.00 |
99.96 |
|
|
|
|
|
|
|
Overall, the APL+IS makes it possible to not only continue to work in your preferred language and development environment, but also to have a faster and more importantly consistent result. |