Wednesday, June 3, 2009

Program call: a practical example

In this post, I will show a practical example of using the jtopen plugin to call a program on the AS/400.

We will create a grails service to execute commands on the AS/400.

We assume we have a grails application with the jtopen plugin installed.

We first have to set the AS/400 host, user and password. We will edit the grails-app/conf/Config.groovy file and add the three following lines:
jtopen.as400 = 'as400'
jtopen.user = 'user'
jtopen.password = 'password'
Of course, you should customize the values to your environment. As they are typically per-environement values, we will set them with the grails.serverURL variable.

We then create a new service:
grails create-service Command

This will create the file grails-app/services/CommandService.groovy, we will change it to:
import org.codehaus.groovy.grails.plugins.jtopen.types.*
class CommandService {
boolean transactional = false
def ibmI

def executeCommand(String command) {
def cr = ibmI.call('QCMDEXC',[
new IChar(command),
new IPacked(command.length(),15,5)] as Type[])
cr.success?:cr.messageList
}
}
And that's it!
Let's have a closer look.

import org.codehaus.groovy.grails.plugins.jtopen.types.*
We import the parameter types used to call the program.

def ibmI
This line creates a property named ibmI. It will automatically be injected with an IbmI object.

def cr = ibmI.call('QCMDEXC',[
new IChar(command),
new IPacked(command.length(),15,5)] as Type[])
Here is the heart of the service. This will call the QCMDEXC API with the two parameters it expects:
  • The command to execute as a CHAR variable
  • The command length as a (15,5) packed decimal
You can see that the QCMDEXC parameters are surrounded by [ and ] as Type[]. This is necessary because of a bug in groovy. This bug has been fixed in the groovy trunk and this circumvention shouldn't be necessary in future grails releases.

cr.success?:cr.messageList
This line makes the service return true if the command execution is successful or the array of messages returned by the command will be returned.

Now let's create a controller using this service:
grails create-controller DataArea

This will create the file grails-app/controllers/DataAreaController.groovy, change it to:
class DataAreaController {
def commandService
def create = {
def result = commandService.executeCommand("CRTDTAARA ${params.name} TYPE(*CHAR) LEN(10)")
render result==true?"Data area ${params.name} created":result.inspect()
}
}
We now start the application:
grails run-app

Now point your browser to:
http://localhost:8080/yourAppName/dataArea/create?name=grails

You should see the message "Data area grails created". On your AS/400, you should have a data area named grails in the jtopen.user user current library (or QGPL).

That's all for this example.

4 comments:

  1. Just wondering, why did you not use something like this?

    cc = new CommandCall(AS400_obj)
    cc.run("CRTDTAARA ${params.name}")

    ReplyDelete
  2. Never mind. I see that it a program call. Nothing to do with a command call.

    ReplyDelete
  3. Hi Damien.
    What about a plugin that convert DDS records like IBM webfacing Tool, do you know?
    It will be a very good open-source project to web-enabled RPG with Grails.
    Are you interested in?

    ReplyDelete
  4. Hi Damien.
    Can you give me some example to call a program with input and output parameter?
    There are other doc/example resources about this plugin?
    How can i convert for example a IPacked to BigDecimal for print it?

    ReplyDelete