Jun 25

Shield to distribute EasyCom Server in North America


We have agreed to distribute the EasyCom Server in North America and provide 1st level support. Its early days yet but we are very eager to get things going. Our testing so far has shown that this is a very good way to keep the IBM i in the solution without burdening it with tasks other systems can do better at.

If you would like to try out the EasyCom server or have a live demonstartion of it running in our envirnemnt let us know and we will gladly oblidge. Pricing can be supplied on request, the client side is free with the server side (IBM i) attracting a small annual fee for use and support..

Chris…

Jun 24

IBM i data being served through to a ZendServer CE edition install on Windows 7


We now have a fully functioning DR4i interface running on the laptop with the data being pulled from the IBM i via the EasyCom server!

Took a couple to tries due to a small issue with one of the EasyCom dll’s and our downlevel ZendServer CE install, but it is all working and we can use it for demo’s to prospective customers to show the power of our solution working in conjunction with the EasyCom server.

We can take our webserver with us and access any IBM i which is running the EasyCom server and our product. Everyone should be taking a look at this technology, it removes a lot of the headaches of installing on the IBM i such as making sure you have all of the pre-requisites like 5761SS1 etc.. We are hoping others will see the benefits of having the great processing capabilities of the IBM i with the http services being run elsewhere..

Chris…

Jun 23

PHP extension running on Windows 7 ZendServer


I have a a Zend Community Edition install on my laptop and was wondering if I could use it as the source for my IBM i PHP scripts. Not that it is a suitable solution for many others but I can take my laptop to any customer, set up DR4i and run the PHP interface directly from my laptop to the IBM i. If the customer is already running Zend on the IBM i I can install a temporary key to access the EasyCom server or install the EasyCom server directly on the IBM i (takes about 5 minutes) and remove it when I am finished! I could also install a Linux setup but this is a much simpler option.

The first challenge was how to get the extension loaded to my laptop installation, going through the Zend control interfaces did show a list of extensions and would allow me to manipulate them but I could not find any method of installing additional extensions. The obvious answer would be to edit the php.ini file directly and add the new extension, but I was unsure what effect this would have. So I contacted EasyCom and asked for details on how this could be achieved, they sent me a link to a download that would install the correct DLL and set up the php.ini file automatically.

The install seemed to go well but when I started the ZendServer interface it told me the extension did not install correctly! Another call to EasyCom and they shipped me an updated dll to replace the one previously downloaded.

This is the error it generated:

[23-Jun-2010 12:15:31] PHP Warning: PHP Startup: Easycom For PHP v3: Unable to initialize module
Module compiled with build ID=API20090626,NTS,VC9
PHP compiled with build ID=API20090626,NTS,VC8
These options need to match
in Unknown on line 0

After I installed the updated dll it did load and it now successfully connects to the IBM i EasyCom server and builds the pages. It did leave a couple of lines in the display which need to be removed (I need to work that out) but overall it is working correctly except for one small issue which I know about, EasyCom needs to update the client to support long long variables. Once they fix that I am ready for the road and can demonstrate the new PHP basedDR4i interface on demand (well with a bit of additional configuration on the IBM i).

We have just agreed to be a distribution and support representative for Aura Equipments for North America, so if you wish to discuss the possibilities for running PHP in your IBM i environment without the complexity of setting up the IBM i HTTP server and ZendServer let us know, we will be more than willing to share our experiences.

Chris…

Jun 15

HA4i under development


The Receiver Apply Program (RAP) is being updated and we are adding a number of new features. As part of this update we will release the product under a new name of HA4i to fall in line with the naming convention we have already started with DR4i.

HA4i will be aimed at the customer who needs more than just Journal replication but needs to run it with limited staff skills. We have seen far too many HA installations fall by the way side simply because the project grew to large and complex to be effectively managed. DR4i is seeing some success due to its low complexity approach, something we want to continue with HA4i.

Any RAP installation that is current on maintenance will be entitled to a free upgrade to the new product.

Chris…

Jun 11

Passing PHP structures in i5_toolkit program_prepare.


I have added this into the comments section of the last post about PHP structures but thought it might also be appropriate to add a new entry just in case..

The use of the “CountRef” parameter on the program call is saying look at one of the variables that I have passed within this array. “Count” can also be used which also allows you to use a php variable from your script to do this. If you are only passing in a single structure you do not need to pass in this parameter at all.

The following examples should explain what I am saying?? The first example shows how to use the “CountRef” parameter, you can see that ‘numjrn’ (a string) is passed as part of the array so “CountRef” can use this parameter as a count for the number of structures.

     array("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT),
     array("name" => "numjrn", "io" => I5_IN, "type" => I5_TYPE_INT),
     array("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10"),
      array("DSName" => "jrninfo", "CountRef" => 'numjrn', "DSParm" => array(...

This is also correct and will pass in what ever value you set $numjrn to.

     $numjrn = 1;
     array("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT),
     array("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10"),
      array("DSName" => "jrninfo", "Count" => $numjrn, "DSParm" => array(....

As we are only passing in a single structure the following code segments will also work.

     array("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT),
     array("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10"),
      array("DSName" => "jrninfo", "Count" => 1, "DSParm" => array(....

and finally

     array("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT),
     array("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10"),
      array("DSName" => "jrninfo", "DSParm" => array(....

This has certainly cleared up the confusion for us, passing in multiple structures is simply adding them to the array and using the correct method for setting the count variable for each structure array..

Chris…

Jun 10

New Status Screens for DR4i


We have continued to develop the status screens for DR4i and now have a brand new process flow for delivering an easy to use interface for monitoring the activities of the product.

The first screen which is displayed is the sign on screen, it requires a valid iOS user profile and password to continue and helps restrict access to the IBM i data. If the sign on fails the user will not see any status.

Sign-On screen

Sign On screen presented before access to DR4i Status

Once a valid user and password has been entered the current status of DR4i will be shown, in the example we have supplied there are a number of issues we have generated to show the additional pages available. The additional pages cannot be accessed unless data is available to be displayed. The logout button will log the user out, end the communication connection for this specific instance to the IBM i and destroy any stored session variables before returning the user to the sign on screen.

DR4i status

Main Status screen for DR4i

If there are any errors as can be seen by the red highlighted field a click on the field will display the following screen which lists any errors that are logged by DR4i. The errors are logged by receiver name so you can interrogate the issues by receiver.

List of errors logged by DR4i

List of errors logged by DR4i

The above screen provides links to an additional screen where more information can be seen about the error and the object affected.

Details of error

Error Details display

Another problem can be where an apply process is in the suspend mode and is not processing receiver changes as they occur, this can cause a build up of the receivers in the waiting queue which can be identified by clicking the “waiting” link. In the example we have 6 waiting receivers, clicking the link will result in the following display.

receiver list

A list of the receivers waiting to be applied

Another list you may be interested in viewing is the list of email messages that have been sent by DR4i, these messages can be helpful when reviewing what DR4i has process and what if any problems have been flagged. The following screens show the detail which is available by selecting the appropriate links.

List of email messages sent

List of sent emails


Email entry display

Content of email log entry

There is also a list of messages available from this interface, it can only display the message text but is a useful tool to verify what messages are in the DR4i messages queue. A nice feature we have included is the message queue is display with the last message on the top and it has the date and time the message was sent.

message list

List of messages in the DR4i message queue

Thats the new interface, we have been getting some good responses to the product and particularly the new interface. This interface and some of the newer apply processing will be implemented into the next version of the RAP product which is due out at the end of this year.

Let us know if you have any comments about the new screens or wish to know more about the product and where it fits into an availability solution.

Chris…

Jun 10

i5_ToolKit Passing Structures part II


While playing around with the passing of structures into our Service Program via the i5_toolkit functions we came across the need to pass in more than one structure to the service program.

Having spent sometime playing with how to correctly pass in variables we thought passing in a number of structures should be easy, unfortunately we stumbled across a problem. We have a service program which reads the messages from a data queue using the QMHRDQM API which have a number of messages in related to the DR4i requests for receiver changes. The message consists of a number of fields some of which are the same for every message (the journal information) and others which are different every time (the receiver names and library).

We could have simply copied the data from each message back and just ignored the fact that the journal information would be the same every time. Its only 30 bytes so even for 100 messages its a small amount of data. But as we always do, we want to make this as slick as possible so we only want to return the information which does not change once. Our first attempts at building the structure failed and resulted in the IBM i program ending mysteriously with no output as to why (Its a known bug which is now fixed in the latest extension we were shipped). So we sent of a message to EasyCom asking what we were doing wrong and asked for their support.

In the meantime, (they are 6 hours ahead of us so they would have not seen the message until the next day) we decided to change the service program slightly and pass in three additional character strings for the journal information. This is the resulting array setup for the program prepare.

$desc = array(
      array("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT),
      array("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10"),
      array("name" => "jrn", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("name" => "jrnlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("name" => "jrniasp", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("DSName" => "ents", "CountRef" => 'numents', "DSParm" => array(
            array("name" => "rcvr", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ),
            array("name" => "rcvrlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'))));

This is what the service program was set up to use.

int get_dq_ents(int *num, char *DQ, char *Jrn, char *JrnLib, char *JrniASP, DQ_Ent_t ents[])

This worked perfectly but we wanted to find out how to pass in the multiple structures. EasyCom came back with the reply and the following code.

$desc = array (
      array ("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT ), 
      array ("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10" ), 
      array ("DsName" => "jrninf", "count" => 1, "DSParm" => array (
      array ("name" => "jrn", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ), 
      array ("name" => "jrnlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ), 
      array ("name" => "jrniasp", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ) ) ), 
      array ("DSName" => "ents", "CountRef" => 'numents', "DSParm" => array (
      array ("name" => "rcvr", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ), 
      array ("name" => "rcvrlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ) ) ) );

The problem was we were using CountRef for each structure as shown below.

$desc = array(
array("name" => "numents", "io" => I5_IN, "type" => I5_TYPE_INT),
array("name" => "dtaq", "io" => I5_IN, "type" => I5_TYPE_CHAR, "length" => "10"),
array("DsName" => "jrninf", "CountRef" => 1, "DSParm" => array (
      array("name" => "jrn", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("name" => "jrnlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'),
      array("name" => "jrniasp", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'))),
array("DSName" => "ents", "CountRef" => 'numents', "DSParm" => array(
      array("name" => "rcvr", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10' ),
      array("name" => "rcvrlib", "io" => I5_OUT, "type" => I5_TYPE_CHAR, "length" => '10'))));

EasyCom support explained that we should not use the CountRef variable more than once and that Count should be used for the first structure quantity (probably would work for all but CountRef was appropriate for the setting of the second array of structures?). The service program was updated to accept the additional structure and the process now works flawlessly!

We had tried a number of the examples from the manuals all of which failed for various reasons, so if you are like us struggling to get the structure and array technology clear in you mind maybe this will help?

Chris…

Jun 08

Ending a persistent connection in PHP


One of the questions we had when running persistent connections was how do you end them? We had been trying to use the i5_pclose() function but for some reason it did not seem to work.

We had assumed that calling the function without a connection resource would end the last connection, that it appears is wrong! You should always call the function by passing in the $conn resource you want to close. Because of the way the connection is created and managed we knew that the job which would be running any requests we made would always be the same one. Testing also showed us that even if we used the same user id to connect from multiple browsers on the same system the connection ID would be different for each bowser session.

When the sessions did not end we started to look at alternatives to the i5_pclose() function. One idea we came up with was to use the endjob *immed command, as it would be running in the same job the connection was using, we knew we could issue the command with JOB(*) as that is the current job. The following code worked and closed the job as expected.


include('functions.php');
// send a request to end the job on the target system
$conn = 0;
if(connect($conn)) {
	i5_command("ENDJOB JOB(*) OPTION(*IMMED)",$conn);
	}
$ret_url = $_SESSION['ret_url'];
session_destroy();
header('Location: ' .$ret_url);
exit(0);

We include the functions.php script as it has the connect() function in it which returns the correct connection. The ENDJOB command simply ends the current job, we then destroy any session variables which forces the user to resign in and push the user back to a sign on page.

Then the light went on, maybe the reason the i5_pclose() function was not working (it did once but we figure that was a fluke) was because we needed to pass in the connection id. As it turned out this was correct so the following code also ends the correct persistent connection.


include('functions.php');
// send a request to end the job on the target system
$conn = 0;
if(connect($conn)) {
	i5_pclose($conn);
	}
$ret_url = $_SESSION['ret_url'];
session_destroy();
header('Location: ' .$ret_url);
exit(0);

This is probably a better way to close the connection as the EasyCom server may do some clean up as it removes the connection.

Hope it helps others understand a bit more about persistent connections.

Chris…

Jun 07

Strange behavior with structures!


We have been playing with the passing of structures into the message queue listing service program and came across what seems to be a strange side effect.

The code for the PHP and service program has been published before so no need to do it again, the problem appeared when we were fixing up an issue where no messages of the required severity were left in the message queue. We wanted to simply return *NONE / *NONE for the message ID and message data. We coded up the change in the service program and tried to display the results in the web browser, for some reason the page would not show the *NONE / *NONE (it built an empty array) but as soon as we added more messages everything would start to show up!

We did some digging and found that when a single structure is returned to the PHP program it is not returned as an array of one, it is returned as a single structure. This meant our code which was trying to address the array of structures came up empty and no errors were identified!

The fix is pretty simple although I am not sure if this is a bug or a feature?? Here is the code we added to the PHP page to overcome the problems.

if($nbr == 1) {
		echo('' .$messages[msgid] .'' .wordwrap($messages[dta],$wrap,"
") .''); } else { for($i = 0; $i < $nbr; $i++) { echo('' .$messages[$i][msgid] .'' .wordwrap($messages[$i][dta],$wrap,"
") .''); } }

All we did was check if the number returned was 1 and if it was we addressed it as a structure as opposed to an array of structures.. We will pass this onto Aura Equipments for clarification but thought we would post the findings in case anyone else had seen similar behavior. This same behavior would be exhibited if a single message of the required severity was actually contained in the message queue so it is important to fix…

Chris…