troubleshooting Question

Running AS/400 Program Remotely w/return Params - Hangs!

Avatar of krtarwood
krtarwood asked on
.NET Programming
21 Comments1 Solution4011 ViewsLast Modified:
Hi Experts!

I am kind of new to interacting with the 400 and so far loathe dealing with it, however I have to complete this project soon so hopefully you can help!
 
I am using VB.Net to connect, run an RPG program which takes two input parameters and returns a float and a data structure to my application. I haven't tried going back to the ODBC/ADO method yet but I am not above giving that a shot. Initially my application was hanging while trying to connect to the 400, but I've fixed that. Now it hangs up when attempting to call the program itself. No exception is returned - it just sits there. I have no real knowledge of the 400 side of things so I don't know how to log user activity to see what is going wrong or anything.

Below is my code:
[code]
Imports ADODB
Imports System
Imports System.IO
Imports System.Configuration

Namespace InfoWebCore

    Public Class GetItemData

        Dim sServerName As String
        Dim sUserID As String
        Dim sPassword As String
        Dim sLibrary As String
        Dim sProgram As String
        Dim bUseSSL As Boolean = False

#Region "Properties"
        Public Property HostName() As String
            Get
                Return sServerName
            End Get
            Set(ByVal Value As String)
                sServerName = Value
            End Set
        End Property

        Public Property UserID() As String
            Get
                Return sUserID
            End Get
            Set(ByVal Value As String)
                sUserID = Value
            End Set
        End Property

        Public Property Password() As String
            Get
                Return sPassword
            End Get
            Set(ByVal Value As String)
                sPassword = Value
            End Set
        End Property

        Public Property Library() As String
            Get
                Return sLibrary
            End Get
            Set(ByVal Value As String)
                sLibrary = Value
            End Set
        End Property

        Public Property Program() As String
            Get
                Return sProgram
            End Get
            Set(ByVal Value As String)
                sProgram = Value
            End Set
        End Property

        Public Property UseSSL() As Boolean
            Get
                Return bUseSSL
            End Get
            Set(ByVal Value As Boolean)
                bUseSSL = Value
            End Set
        End Property
#End Region

#Region "Methods"
        Public Function RunProgram(ByVal itemId As String, ByVal customerId As Integer) As Array
            ' Check that required properties have been set
            If sServerName Is Nothing Then
                Throw New Exception("HostName property must be set to AS/400 IP or hostname prior to calling this method.")
            End If
            If sUserID Is Nothing Then
                Throw New Exception("UserID property must be set to AS/400 username prior to calling this method.")
            End If
            If sPassword Is Nothing Then
                Throw New Exception("Password property must be set to AS/400 user's password prior to calling this method.")
            End If
            If sLibrary Is Nothing Then
                Throw New Exception("Library property must be set to AS/400 library prior to calling this method.")
            End If
            If sProgram Is Nothing Then
                Throw New Exception("Program property must be set to AS/400 program to call prior to calling this method.")
            End If

            Dim as400 As cwbx.AS400System = New cwbx.AS400SystemClass
            Dim program As cwbx.Program = New cwbx.Program

            ' Grab the library, username, password, etc from the properties
            Try
                as400.Define(sServerName)
                program.system = as400
                program.system.UserID = sUserID
                program.system.Password = sPassword
                program.system.PromptMode = cwbx.cwbcoPromptModeEnum.cwbcoPromptNever
                program.system.DefaultUserMode = cwbx.cwbcoDefaultUserModeEnum.cwbcoDefaultUserIgnore
                program.LibraryName = sLibrary
                program.ProgramName = sProgram
                program.system.UseSecureSockets = bUseSSL

                as400.Signon()
            Catch g As Exception
                Throw New Exception("Failed to set AS/400 properties.", g)
            End Try

            ' Try to connect to 400
            Try
                as400.Connect(cwbx.cwbcoServiceEnum.cwbcoServiceRemoteCmd)
            Catch j As Exception
                Throw New Exception("Failed to connect with AS/400 - Please try again later.", j)
            End Try

            Dim stringConverter As cwbx.StringConverter = New cwbx.StringConverterClass
            Dim packedConverter As cwbx.PackedConverter = New cwbx.PackedConverterClass
packedConverter.DecimalPosition = 0
            packedConverter.Digits = 8
           
Dim floatConverter As cwbx.FloatConverter = New cwbx.FloatConverterClass
           
            Dim parameters As cwbx.ProgramParameters = New cwbx.ProgramParametersClass

            ' // ********************************************************
            ' // P55ADVP Program Parameters
            ' // ********************************************************

            ' // Parameter list for P55ADVP:
            ' //
            ' // Name   Size    Desc
            ' //
            ' // PSLITM 25,0    (Input) Alpha - Long Item Number
            ' // PSSHAN 8,0     (Input) Numeric - Customer Shipping ID
            ' // PSUPRC 15,4    (Output) Numeric - Adjusted Price
            ' // PSITM          (Output) Data Structure - Item Attributes

            ' Input Parameters
            parameters.Append("PSLITM", cwbx.cwbrcParameterTypeEnum.cwbrcInput, 25)
            stringConverter.Length = 25
            parameters("PSLITM").Value = stringConverter.ToBytes(itemId.PadRight(25, " "c))
           
            parameters.Append("PSSHAN", cwbx.cwbrcParameterTypeEnum.cwbrcInput, 8)
            parameters("PSSHAN").Value = packedConverter.ToBytes(customerId)

            'Output Parameters
            parameters.Append("PSUPRC", cwbx.cwbrcParameterTypeEnum.cwbrcOutput, 15)
            ' I tried passing a zero value here because the RPG guy told me it might work - it didn't
            'parameters("PSUPRC").Value = floatConverter.ToBytes(0)

            parameters.Append("PSITM", cwbx.cwbrcParameterTypeEnum.cwbrcOutput, 195)
            ' Same here - passed empty
            'parameters("PSITM").Value = stringConverter.ToBytes("")

            Try
                    ' Hangs here!
                    program.Call(parameters)
            Catch ex As Exception
                If as400.Errors.Count > 0 Then
                    Dim error400 As cwbx.Error
                    For Each error400 In as400.Errors
                        Throw New Exception("An error occured while attempting to call the program " & sProgram & " on the AS/400 - see stack trace for details.", ex)
                    Next
                End If

                If program.Errors.Count > 0 Then
                    Dim errorPgm As cwbx.Error
                    For Each errorPgm In program.Errors
                        Throw New Exception("An execution error occured while attempting to execute the program " & sProgram & " on the AS/400 - see stack trace for details.", ex)
                    Next
                End If
            End Try

            ' Lets return values from the 400 in the order they appear in the catalog, shall we?
            Dim itemStruc As New cwbx.Structure
            Dim i As Integer

            itemStruc.Bytes = parameters("PSITM").Value

            Dim byteLength As Integer
            byteLength = itemStruc.Length

            itemStruc.Fields.Append("SIITM", 8)
            itemStruc.Fields.Append("SILITM", 25)
            itemStruc.Fields.Append("SIITSZ", 15)
            itemStruc.Fields.Append("SIITUN", 15)
            itemStruc.Fields.Append("SIUNWT", 15)
            itemStruc.Fields.Append("SIUNPL", 15)
            itemStruc.Fields.Append("SIPLWT", 15)
            itemStruc.Fields.Append("SIGCLR", 25)
            itemStruc.Fields.Append("SIIUPC", 20)
            itemStruc.Fields.Append("SICUPC", 20)
            itemStruc.Fields.Append("SIPUPC", 20)
            itemStruc.Fields.Append("SIAMCR", 1)
            itemStruc.Fields.Append("SIGRGD", 1)

            ' Eventually I will return everything in an array but I am just testing a couple values below.
            Dim returnArr() As String

            ReDim returnArr(2)

            stringConverter.Length = 15
            returnArr(0) = stringConverter.FromBytes(itemStruc("SIITSZ").Value)

            packedConverter.DecimalPosition = 4
            packedConverter.Digits = 15
            returnArr(1) = packedConverter.FromBytes(parameters("PSUPRC").Value)
            returnArr(2) = byteLength.ToString

            ' Finally, disconnect
            as400.Disconnect(cwbx.cwbcoServiceEnum.cwbcoServiceAll)

            Return returnArr
        End Function
#End Region
    End Class

End Namespace

--
' The call to the class looks like this:

        Dim talkTo400 As New InfoWebCore.GetItemData
        talkTo400.HostName = ConfigurationSettings.AppSettings("priceBookServer").ToString
        talkTo400.Library = ConfigurationSettings.AppSettings("priceBookLibrary").ToString
        talkTo400.UserID = ConfigurationSettings.AppSettings("priceBookUser").ToString
        talkTo400.Password = ConfigurationSettings.AppSettings("priceBookPassword").ToString
        talkTo400.Program = ConfigurationSettings.AppSettings("priceBookProgram").ToString
        talkTo400.UseSSL = False

        Dim outArray() As String
        Dim tidbit As String
        Try
            outArray = talkTo400.RunProgram("0253-0050-21", 100845)
            For Each tidbit In outArray
                lblTestOut.Text &= tidbit & ";"
            Next
        Catch f As Exception
            lblTestOut.Text = "An error has occured while attempting to gather necessary data. Error was: " & f.ToString
        End Try

[/code]

Firstly our RPG programmer tells me there is no such thing as an input or output parameter, they are always both. This is interesting considering the cwbx.cwbrcParameterTypeEnum types can be input, output or both. Either way, I've tried them all different ways to no avail - still hangs. Even the test program that took no input params hung, so I'm assuming this has something to do with the call itself, the setup or the output parameters (maybe).

Perhaps you can suggest some reasons as to why the call would hang? I've tried testing the process by calling a program that our RPG guy wrote with hard coded input params just to see if I was malformatting them. Evidently I have no messages waiting on the 400 either so I don't think this is the problem.

I'm using V5R1M0 version of Client Access and .Net v1 in case that matters.

Thanks for the help!
ASKER CERTIFIED SOLUTION
iboutchkine

Our community of experts have been thoroughly vetted for their expertise and industry experience.

Join our community to see this answer!
Unlock 1 Answer and 21 Comments.
Start Free Trial
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 21 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros