Nov 26

New Partners and sales representatives required

The Receiver Apply Program is now a fully fledged Availability product for the IBM i. We are looking for Partners and Sales Representatives to help us sell and implement the product in the customer base. If you are an IBM i Business Partner, Sales Representative or simply have customers running IBM i boxes and you are looking for a product which allows you to compete with other Partners and Sales Representatives when Availability is required we will want to hear from you.

The product is capable of meeting the most important requirement of Availability, the protection of data and the ability to bring that data up to a state which is within a reasonable number of transactions of the originating system. RAP Uses Remote Journals protect your data so the only other requirement is to be able to apply that data within a reasonable time frame, allowing users to access that data in the knowledge that it is in a state that ensures its integrity. We provide tools to allow journal changes to be carried out on a regular basis without the need for a complex scheduling product, it uses the IBM supplied scheduler to carry out the task and supports changes in the minute range if required.

A new feature allows the content of Job Queues to be replicated to a remote system, using this information you can ensure the integrity of the data by identifying any data which has been partially completed due to job issues. If a job ends abnormally on the source or the systems is lost before a job completes you need to know what data if any has to be removed before reloading the job on the target with the same parameters as those used on the source. Jobs which failed to run because they were still sat on the job queue will also be identified making it easy to reload the job queues with the required job strings.

Even though Object coverage has been improved for journalling, there are still objects which are required to be in-sync on the target system before an application can be successfully restarted. The latest release of RAP provides technology which captures object changes as they occur and submits a request to replicate that change to the target object. The process has been developed to use a filtering technique which allows the request to be done by command or a save and restore process. Any problems found will be logged back on the source system and a re-submit is possible.

The economic climate is preventing many companies from making purchasing decisions, the installation cost alone can put a lot of customers off. RAP is simple to install and configure, you do not need highly trained specialist to install and configure it. Many of the features provided by other Availability products require very detailed configurations to be created, we have taken the approach that if the object is not journalled or the library configured for object replication it is not replicated. This has greatly reduced the configuration and management complexity for the product. Profile replication simply needs to know if you want System Profiles replicated or not and if you want passwords to be replicated.

The market is not as vibrant as we would expect in this quarter, so any leverage you have to help make a sale should be useful. RAP can help, it is priced for the current economic climate and beyond.

If you are interested in becoming a Partner or simply want to sell the product let us know, we will happily discuss how we can work together to improve each others business.

Chris…

Nov 23

New Active Job Snapshot for recovery process

As part of the next release for RAP we have developed a snapshot tool which can capture the active jobs on source system and store the information on the target. This will allow the user to see the active job information for the source system after a failure. The snapshots can be taken from 60-3600 second intervals which allows the data to be between 0 and 3600 seconds old after a failure. The data collection is very efficient and uses little network bandwidth to transfer the data between systems (about 120 bytes per job). Testing on our system shows approximately an elapsed CPU time of 0.7 seconds after over an hour of data collection at 1 minute intervals.

We will be linking the batch data which is stored in the job data files captured using a new job queue data capture engine and again stored on the target system real time as it is collected. Using this data you will be able to determine a recovery point for RAP much easier and have a better recovery position after a failure.

The new version of RAP will be made available in the 1st Qtr of 2009.

Chris…

Nov 20

Job Queue Monitoring and replication in RAP

We have created a new collection engine for Job Queue data which has been integrated into the next version of RAP. This will allow the users of RAP to start data collection on a source system for the job queues attached to a particular subsystem and see the job information on the target system. The data is replicated automatically to the remote system using our new data apply process which works in the same manner as the other HA products you see out there today. Using this technology allows you to see how the job is progressing through its life cycle plus the information about how the job was loaded ran and ended.

You may ask yourself why this is important? Well the HA products have always been based around the replication of data and objects on a time sensitive basis, they have no way of tying up the data and the application. So if your system fails and you have to do a role swap you will be left on your own to determine exactly what state your data is in and if any jobs will need re-submitting to bring you data into a usable state. Don’t be fooled by things like Cross System Mirroring or other IBM technologies either, none of them today support the replication of job queue data to allow you to see the state of your job queues at system failure time.

The some of the features provided in the JobQGenie Product are also available in this version of RAP, so if you need to recover you can take a few simple options to review the data which has been added by the apply process and remove any orphan data before resubmitting the jobs automatically. Eventually we can use the data stored within the RAP product to automatically determine and set up a recovery point to a known state for the application.

Another feature we are working on is the capture of active jobs on a regular basis and storing that data on the remote system for review during a fail over, this will give you added information about exactly what was going on when the system failed.

We are going to be adding the new data capture engine to the JobQGenie product in the next version. JobQGenie provides a more flexible approach to job queue data replication due to its filtering capabilities plus other recovery features which are not going to be added to RAP. This product is also suitable for HA installations of the other ISV’s products such as *NoMax, QuickEDD, MiMiX, Orion, Echo2 and others. It is the only product which provides the job queue monitoring capabilities without the need to change your application at all!

The next version of RAP will probably be ready for shipment in early 2009 with JobQGenie following shortly afterwards. if your interested in a trial or want discuss how either product can be used please call us to discuss.

Chris…

Nov 16

Using API’s to gather Information QUSRJOBI

We have been usin API’s to gather information for sometime in our products so we have had to work out how to use quite a number with some interesting results! To say the manuals are hard to understand is only part of the problem, even reading through the header files trying to determin exactly how to address the resturned information can be difficult! So as we write test code for our systems which we feel could be of interst we will post it here. Its obviously not production code and is written with a lot of information gathered from the systems before we run the request and will not be able to recover from errors as we would hope the production code will! But if its helps others its not a bad thing to put it up (is it?).

Here is the code we have used to gather the library lists from the API QUSRJOBI, we wrote 2 samples because the first one didnt seem to work (long days make for stupid mistakes). Both sets of code now work aainst the test system and produce the expected results. This code is for info only and we cannot be responsible for it use.

First sample uses the JOBI0700 format which returns only the library names.

#include 
#include 
#include 
#include 
#include 

typedef _Packed struct Job_Inf_x {
                Qwc_JOBI0700_t JobInf;
                Qwc_Lib_List_t Lib[25];
                }Job_Inf_t;

int main(int argc, char **argv) {
int i = 0;
int Num_Libs = 0;
int JobInf_Len = 0;
char *ptr;
char JFmt[8] = "JOBI0700";                  /* Job Inf Fmt  */
char IntJobId[16];

Job_Inf_t JobDets;
Qus_EC_t Error_Code = {0};

Error_Code.Bytes_Provided = sizeof(Error_Code);

JobInf_Len = sizeof(struct Job_Inf_x);
memset(IntJobId,' ',16);

QUSRJOBI(&JobDets,
         JobInf_Len,
         JFmt,
         argv[1],
         IntJobId,
         &Error_Code);
if(Error_Code.Bytes_Available) {
   printf("%.7s\n",Error_Code.Exception_Id);
   exit(-1);
   }
printf("Buffer size = %d\n",sizeof(JobDets));
printf("Bytes returned %d\n",JobDets.JobInf.Bytes_Return);
printf("Job Status %.10s\n",JobDets.JobInf.Job_Status);
printf("Bytes Available %d\n",JobDets.JobInf.Bytes_Avail);
printf("Number of System Libs %d\n",JobDets.JobInf.Libs_In_Syslibl);
printf("Number of Product Libs %d\n",JobDets.JobInf.Prod_Libs);
printf("Number of Current Libs %d\n",JobDets.JobInf.Curr_Libs);
printf("Number of User Libs %d\n",JobDets.JobInf.Libs_In_Usrlibl);
Num_Libs += JobDets.JobInf.Libs_In_Syslibl;
Num_Libs += JobDets.JobInf.Prod_Libs;
Num_Libs += JobDets.JobInf.Curr_Libs;
Num_Libs += JobDets.JobInf.Libs_In_Usrlibl;
for(i = 0; i < Num_Libs; i++) {
   printf(" Library[%d] = %.11s\n",i,JobDets.Lib[i].Lib_Name);
   }
exit(0);

} 

This is a sample of the output

Buffer size = 355
Bytes returned 135
Job Status *ACTIVE
Bytes Available 135
Number of System Libs 4
Number of Product Libs 0
Number of Current Libs 0
Number of User Libs 1
Library[0] = QSYS
Library[1] = QSYS2
Library[2] = QHLPSYS
Library[3] = QUSRSYS
Library[4] = JQG400
Press ENTER to end terminal session.

The next sample used the JOBI0750 format which returns more information about the libraries.

#include 
#include 
#include 
#include 
#include 

typedef _Packed struct Lib_Info{
     char Lib_Name[10];
     char Lib_Text_Description[50];
     int  Lib_ASP_Number;
     char Lib_ASP_Name[10];
     char Reserved[2];
     } Lib_Info_t;


int main(int argc, char **argv) {
int i = 0;
int JobInf_Len = 0;
char *tmp;
char *ptr;
char JFmt[8] = "JOBI0750";                  /* Job Inf Fmt  */
char IntJobId[16];
char Buf[2500];
Qwc_JOBI0750_t *JobDets;
Lib_Info_t *Libptr;
Qus_EC_t Error_Code = {0};

Error_Code.Bytes_Provided = sizeof(Error_Code);

JobInf_Len = 2500;
memset(IntJobId,' ',16);

QUSRJOBI(Buf,
         JobInf_Len,
         JFmt,
         argv[1],
         IntJobId,
         &Error_Code);
if(Error_Code.Bytes_Available) {
   printf("%.7s\n",Error_Code.Exception_Id);
   exit(-1);
   }

JobDets = (Qwc_JOBI0750_t *)Buf;
tmp = Buf;

printf("Bytes returned %d\n",JobDets->Bytes_Return);
printf("Job Status %.10s\n",JobDets->Job_Status);
printf("Bytes Available %d\n",JobDets->Bytes_Avail);
printf("Number of System Libs %d\n",JobDets->Number_Sys_Libs);
printf("Number of Product Libs %d\n",JobDets->Number_Prod_Libs);
printf("Number of Current Libs %d\n",JobDets->Number_Curr_Libs);
printf("Number of User Libs %d\n",JobDets->Number_User_Libs);
printf("Offset Sys %d\n",JobDets->Offset_Sys_Libs);
printf("Offset Prod %d\n",JobDets->Offset_Prod_Libs);
printf("Offset Curr %d\n",JobDets->Offset_Curr_Libs);
printf("Offset User %d\n",JobDets->Offset_User_Libs);
if(JobDets->Number_Sys_Libs > 0) {
   ptr = tmp + JobDets->Offset_Sys_Libs;
   Libptr = (Lib_Info_t *)ptr;
   for(i = 0; i < JobDets->Number_Sys_Libs; i++) {
      printf("Sys Library[%d] = %.10s\n",i,Libptr->Lib_Name);
      printf("Text %.50s\n",Libptr->Lib_Text_Description);
      printf("ASP Number %d\n",Libptr->Lib_ASP_Number);
      printf("ASP Name %.10s\n",Libptr->Lib_ASP_Name);
      Libptr++;
      }
   }
if(JobDets->Number_Prod_Libs > 0) {
   ptr = tmp + JobDets->Offset_Prod_Libs;
   Libptr = (Lib_Info_t *)ptr;
   for(i = 0; i < JobDets->Number_Prod_Libs; i++) {
      printf("Prod Library[%d] = %.10s\n",i,Libptr->Lib_Name);
      printf("Text %.50s\n",Libptr->Lib_Text_Description);
      printf("ASP Number %d\n",Libptr->Lib_ASP_Number);
      printf("ASP Name %.10s\n",Libptr->Lib_ASP_Name);
      Libptr++;
      }
   }
if(JobDets->Number_Curr_Libs > 0) {
   ptr = tmp + JobDets->Offset_Curr_Libs;
   Libptr = (Lib_Info_t *)ptr;
   for(i = 0; i < JobDets->Number_Curr_Libs; i++) {
      printf("Curr Library[%d] = %.10s\n",i,Libptr->Lib_Name);
      printf("Text %.50s\n",Libptr->Lib_Text_Description);
      printf("ASP Number %d\n",Libptr->Lib_ASP_Number);
      printf("ASP Name %.10s\n",Libptr->Lib_ASP_Name);
      Libptr++;
      }
   }
if(JobDets->Number_User_Libs > 0) {
   ptr = tmp + JobDets->Offset_User_Libs;
   Libptr = (Lib_Info_t *)ptr;
   for(i = 0; i < JobDets->Number_User_Libs; i++) {
      printf("User Library[%d] = %.10s\n",i,Libptr->Lib_Name);
      printf("Text %.50s\n",Libptr->Lib_Text_Description);
      printf("ASP Number %d\n",Libptr->Lib_ASP_Number);
      printf("ASP Name %.10s\n",Libptr->Lib_ASP_Name);
      Libptr++;
      }
   }
exit(0);

}

The output from this code is much longer so we have just provided a shortened version.

Bytes returned 480
Job Status *ACTIVE
Bytes Available 480
Number of System Libs 4
Number of Product Libs 0
Number of Current Libs 0
Number of User Libs 1
Offset Sys 100
Offset Prod 0
Offset Curr 0
Offset User 404
Sys Library[0] = QSYS
Text System Library
ASP Number 1
ASP Name *SYSBAS
Sys Library[1] = QSYS2
Text System Library for CPI's
ASP Number 1
ASP Name *SYSBAS
Sys Library[2] = QHLPSYS
Text
ASP Number 1
ASP Name *SYSBAS
Sys Library[3] = QUSRSYS
Text System Library for Users
ASP Number 1
ASP Name *SYSBAS
User Library[0] = JQG400
Text
ASP Number 1
ASP Name *SYSBAS

We hope the code is useful to others.

Chris...

Nov 10

New redpaper on using the APYJRNCHG(X) commands

Our RAP uses the IBM APYJRNCHG command to apply the data on the target system every time a receiver is changed. The technology has been around for many years and IBM has been announcing changes to supported objects for the past couple of years. The latest change in V6R1 is the merge of the APYJRNCHG and APYJRNCHGX functionality into the APYJRNCHG command.

If you want to understand a bit more about the technology here is a new technote issued by the redbooks people.

Chris…