Open Source on IBM i

Dynamic Configuration with ILEastic

My last post was about sharing configuration in an ILEastic web service. This is especially handy when you split your web service application into multiple modules. This is not necessary but may be a good idea if you have many end points / routes so that your modules don't grow too big.

But sometimes the configuration is dynamic and you can't put it manually into a table which is later read from the web service application.

Use case: You want to dynamically start new web service instances depending on the utilization. So beforehand you don't know how many instances/jobs you will start and each instance needs at least another port.

Solution: You define a port range. You provide a configuration web service which among other attributes contains a free port number from the port range. All provisioned configurations are persisted somehow/somewhere so that you know which ports are already in use.

So we don't push the configuration to the web service instance f. e. by passing it as a program parameter (which is not easy or even possible if you have a big configuration structure) but we let the web service ask for the configuration when it is ready to do so.

How will the web service know where to ask for the configuration?

This can be achieved by setting an environment variable to the url the web service instance will query. Keep in mind that the url also needs to be dynamic and unique so that no other web service instance fetches the "wrong" configuration.

Note: Don't forget to add the CPYENVVAR(*YES) parameter to the submit job command.

So the code for loading the configuration in the web service may look something like this:

dcl-proc loadConfig;
  dcl-pi *n pointer end-pi;

  dcl-pr getenv pointer extproc('getenv');
    name pointer value options(*string:*trim);
  end-pr;

  dcl-s config pointer;
  dcl-s data varchar(1000);
  dcl-s url varchar(1000);
  dcl-s sqlString varchar(10000);

  // get the configuration url from the environment variable
  url = %str(getenv('CONFIG_URL'));
  if (url = *blank);
    message_escape('No config url provided.');
  endif;

  // get the configuration (in json format) from the previously retrieved url
  sqlString = 'SELECT * FROM ( Values( SYSTOOLS.HTTPGETCLOB( ? ,'''') ) )';
  EXEC SQL PREPARE statement FROM :sqlString;
  EXEC SQL DECLARE c CURSOR FOR statement;
  EXEC SQL OPEN c USING :url;
  EXEC SQL FETCH FROM c INTO :data;
  if (sqlcode = 0);
    config = json_parseString(data);
  endif;

  return config;

  on-exit;
    EXEC SQL CLOSE c;
end-proc;

Note: This is only a prototype! Please add error handling where needed and keep in mind that this will start a Java VM for every job because of the usage of the SYSTOOLS HTTP SQL function.

Happy provisioning!

Mihael

Tags : RPG