1

On our as/400 we have a test environment and a productive environment. Once we tested our programs are working, we can put them in the productive environment. Both environments contain a similiar set of libraries.

The basic mechanism to tell our programs, in which environment they work, are liblists used for the jobs they run in. That works great, for some things, but for others it doesn't. Therefore we often have a parameter passed to the programs on job submission, that tells the program to work in either test or productive environment. That annoys the hell out of me, since my programs always have to carry this parameter throughout their whole execution time, and often even pass it on to other programs. Sometimes the initial program does not even need the information itself, but still has to take it as a parameter, because it calls a program that does need it.

To present the specific problem I am faced with: Communication between individual parts of a bigger process is often done via dataqueues throughout our sytem. Reading a specific DTAQ according to the liblist works like a charm, simply call RCVDTAQ on the DTAQ's name, the liblist takes care of choosing the right lib. Same goes for writing into DTAQs.

But sometimes the program has to create a new DTAQ before listening or writing to it. Now that does not work with our layout and the liblists. Think of it like this:

PROD-liblist:

PPGMLIB1
PPGMLIB2
PDFILELIB1
PDTAQLIB1
P...
...

TEST-liblist

TPGMLIB1
TPGMLIB2
TDFILELIB1
TDTAQLIB1
T...
...

Now my program should create the DTAQ in ?DTAQLIB1, where ? should be either P or T.

My first idea would be to go through the liblist and look for the entries PDTAQLIB or TDTAQLIB, and take whichever comes first -- but than I couldn't figure out how to to that (hence my connected question: How can I read the liblist from within an ILE-Program? (preferably RPG or CL)).

I know I could possibly achieve my goal by checking, which user owns the current job, but that would break our logic of selecting the libs by liblists (like our current workaround does).

Is there anything I'm missing? Some special way to to call CRTDTAQ maybe, or some special api to do this liblist comparison, that I'm trying to write?

Community
  • 1
  • 1
kratenko
  • 7,354
  • 4
  • 36
  • 61
  • Is the program called out of either PPGMLIBn or TPGMLIBn? And does that always correlate with either PDTAQLIBn or TDTAQLIBn? If so, then the program simply uses the correlated DTAQ library based on where it was called from. Pull the program library from the Program Status DS in RPG. – user2338816 Apr 30 '14 at 14:24
  • @user2338816 I guess that would work in most cases, but not if you wanted to use a program from PPGMLIBn to access a DTAQ from TDTAQLIBn (why ever someone wanted that). The problem I see there, is that it would give you different mechanisms for creating a DTAQ and reading it. You could end up creating a DTAQ outside of your LIBLIST and dumping when trying to read from it with 'object not found'. – kratenko Apr 30 '14 at 14:53
  • Agreed for potential odd cases. That's why I asked for the clarification on the program library and the correlation, and it could make a difference for such cases. Are you looking for "DTAQ" as a substring in any library in *LIBL? – user2338816 Apr 30 '14 at 18:11

3 Answers3

2

Warren's configuration file idea is a good one, but sounds like it would be a lot more than you need. How about just using a data area?

For example, ensure there is always a data area called MODE in your ?DFILELIB1 library. It would have just a single character, "P" or "T", for the mode.

Or even simpler (though perhaps less clear): you could test for the presence or absence of a TESTMODE data area, and proceed accordingly.

Martin McCallion
  • 743
  • 1
  • 4
  • 22
  • Yes, the general configuration data store is probably more than is needed for this particular project. We have this as general infrastructure for use by all our applications. Squeezing it in as Maybe its a good candidate for an open source project ;-) The data queue service information table was put into a recent project, because we recognized that this was a design Pattern that we use repeatedly. These services have some common configuration needs, so a table with a row for each service was deemed more appropriate, at least for us. – WarrenT Jul 17 '12 at 14:39
  • I really like the idea of the `MODE` dataarea. Sure, there is something new created, but in a way that does not anything existant to be changed. It integrates well with the concept of liblist control, and it is cleaner and more flexible than parsing the liblist for special libs. Also, there is no loop included, but only one clean call to `rtvdtaara` without any lib. You could even extend it to adding a dtaara `DTAQLIB` for direct control over where libs are created. – kratenko Nov 06 '12 at 11:18
  • Sure a data area is a fine way to store small amounts of configuration data. But keep it simple. Store the entire library name in the data area. Retrieve it. One line of CL. Simple. Yes, you could have a "neat trick" that works here, in the current scenario, by adding just a little bit more unnecessary code. But really, why? But everytime you hardcore things, or build in arbitrary limitations, you help lock in the status quo, making it harder to change environments down the line. – WarrenT Nov 06 '12 at 23:55
1

To read the library list in CL, use RTVJOBA. To read it in ILE RPG, I'd suggest the QUSRJOBI API, format JOBI0700. http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=%2Fapis%2Fqusrjobi.htm
I think your idea of scanning the library list is probably the best one for your environment.

Buck Calabro
  • 7,558
  • 22
  • 25
  • I still think, this is the only one, where I don't have to introduce something new. But I still think, I will head for @martin's answer (see there for reasons). – kratenko Nov 06 '12 at 11:13
1

I generally try to avoid hard-coding library names anywhere in my programs. If you are scanning for specific names or name patterns, this may work fine for now, but what happens down the line when new environments are created, perhaps with a new naming scheme. Therefore I would store environmental setup as configuration data.

I have two approaches for this.

You can set up a general configuration values table, which can be used by all sorts of programs to look up all sorts of configuration values. In our shop, we call this our Generic Values file. It has to main key fields, the first is often used for a program name, and the second for the name of the value being configured. We also frequently put a table name as the first key, and a column name as the second, each record defining a valid value for the column and a description of it.

Where I am implementing SOA services with Data Queues, I have a table specifically to define information about the service. This includes information such as library and data queue names, as well as other information used by the client interface, by the job performing the service, or by the job managing my servicing jobs.

In either case, configuration files are in the environment-specific data libraries, with values appropriate for that particular environment. I have commented SQL script members that contain the INSERTS for all the configuration records, so that a source scan can easily find library or object name references. I recommend segregating environment specific configuration from other application configuration data that will be tested and moved over to production.

WarrenT
  • 4,502
  • 19
  • 27
  • This is a good approach in general, espacially if you create something new. In my scenario, it does not really fit, since I had to restructure everything, and I don't like forcing collegues to change everything, if not necessarry. – kratenko Nov 06 '12 at 11:10