0

我想从某个外部 API 或 REST 端点调用 AS400 上的 IBM 命令。IBM i / AS400 是否提供类似的功能?

4

4 回答 4

2

有一个名为 XMLSERVICE 的服务程序,它包含在任何相当新的 IBM i 中,它是任何客户端与 i 通信的一种相当简单的方式,包括发出 IBM i 命令和从 IBM i 程序接收参数。它接受多种“传输”方法,包括 HTTP 和 ODBC。

在各种编程语言中都有 XMLSERVICE 的包装器,例如PythonJavaScript (Node.js)PHPRuby。如果您对这些语言中的任何一种感到满意,或者可以找到适合您选择的语言的 itoolkit 版本,那么它非常易于使用。

如果您无法选择将在客户端使用的方法,并且希望在 IBM i 上设置一些非常标准化的东西,例如 RESTful HTTP 接口,那么您可以使用众多可用选项之一轻松完成此操作,包括再次Python 和 Node.js 均已由 IBM 打包并免费提供,安装方便。

于 2020-02-05T20:20:26.150 回答
1

他们有API和sourceforge 上的jtOpen。您可能还想看看Ublu

于 2020-02-05T19:30:09.367 回答
1

IBM 上的 FTP 服务器除了 http,还知道一个rcmd命令。

于 2020-02-06T09:12:52.743 回答
1

如果您从 Windows 服务器进行此远程调用,IBM System i Access ActiveX 对象库 ( cwdx.dll) 可能是调用内置 IBM i 命令以及用 RPG、CL、C 或C++。

下面的示例代码是用 VB6/VBA 编写的,但同样的技术可以用于任何与 COM 兼容的 Windows 语言(C++、C#、VB.Net、Delphi)。有趣的是,这个 ActiveX 调用有时可以允许 SQL 在阻止其他远程 SQL 调用的系统上运行。例如,如果我尝试DELETE通过 ODBC、OLE DB 或 JDBC (IBM Data Studio) 运行如下所示的 SQL 命令;它将被阻止,因为关联的服务器作业使用“RMTFIL”和“RMTOBJ”(Enforcive Objects Ver 8.3.0.0)来控制 SQL 访问。与远程 ActiveX 命令关联的服务器作业没有这些限制,并且可以运行用户有权执行的任何命令,就像在命令行上一样。

Option Explicit

Sub Test_Run_RPG_Program()

    On Error Resume Next
    Dim system As AS400System
    Set system = ConnectToSystem
    If Err Then
        MsgBox "Could not connect to system." & vbCrLf & Err.Description
        Exit Sub
    End If

    Dim prog As Program
    Set prog = New Program
    prog.LibraryName = "MYLIB"
    prog.ProgramName = "MYPROG"
    Set prog.system = system

    On Error Resume Next
    prog.Call
    If Err Then
        MsgBox Err.Description
    End If
    system.Disconnect cwbcoServiceRemoteCmd

End Sub


Sub Test_Run_RPG_Program_Fail()

    On Error Resume Next
    Dim system As AS400System
    Set system = ConnectToSystem
    If Err Then
        MsgBox "Could not connect to system." & vbCrLf & Err.Description
        Exit Sub
    End If

    Dim prog As Program
    Set prog = New Program
    prog.LibraryName = "MYLIB"
    prog.ProgramName = "MYPROGXXX"
    Set prog.system = system

    On Error Resume Next
    prog.Call
    If Err Then
        '-2147467259  &H80004005        "MCH3401 - Cannot resolve to object MYPROGXXX. Type and Subtype X'0201' Authority X'0000'."
        MsgBox Err.Description
    End If
    system.Disconnect cwbcoServiceRemoteCmd

End Sub


Sub Test_Run_Command()

    On Error Resume Next
    Dim system As AS400System
    Set system = ConnectToSystem
    If Err Then
        MsgBox "Could not connect to system." & vbCrLf & Err.Description
        Exit Sub
    End If

    Dim comm As cwbx.Command
    Set comm = New cwbx.Command
    Set comm.system = system
    comm.Run "DSPLIB MYLIB"       'prints output file like in batch mode
    If Err Then
        MsgBox comm.errors.Count
        MsgBox Err.Description
    End If
    system.Disconnect cwbcoServiceRemoteCmd     'Does disconnect do anything?  Active Job remains until AS400System destructor runs

End Sub


Sub Test_Run_Command_Fail()

    On Error Resume Next
    Dim system As AS400System
    Set system = ConnectToSystem
    If Err Then
        MsgBox "Could not connect to system." & vbCrLf & Err.Description
        Exit Sub
    End If

    Dim comm As cwbx.Command
    Set comm = New cwbx.Command
    Set comm.system = system
    comm.Run "DSPF"
    If Err Then
       MsgBox Err.Description & vbCrLf & vbCrLf & FormatError(comm.errors)
        'Error occurred in IBM i Access Library. Command failed.
        'CPF0001 - Error found on DSPF command.
        'CPD0031 - Command DSPF not allowed in this setting.
    End If
    system.Disconnect cwbcoServiceRemoteCmd     'Does disconnect do anything?  Active Job remains until AS400System destructor runs

End Sub



Sub Test_Run_RUNSQL_Delete()           'Succeeded, no Err

    On Error Resume Next
    Dim system As AS400System
    Set system = ConnectToSystem
    If Err Then
        MsgBox "Could not connect to system." & vbCrLf & Err.Description
        Exit Sub
    End If

    Dim comm As cwbx.Command
    Set comm = New cwbx.Command
    Set comm.system = system
    Dim commandStr As String
    commandStr = "RUNSQL SQL('DELETE FROM MYLIB.MYFILE WHERE MYFIELD = ''ABCDEFG''') COMMIT(*NONE) NAMING(*SQL)"
    comm.Run commandStr
    If Err Then
       MsgBox Err.Description & vbCrLf & vbCrLf & FormatError(comm.errors)
    End If
    system.Disconnect cwbcoServiceRemoteCmd     'Does disconnect do anything?  Active Job remains until AS400System destructor runs
End Sub

Sub Test_Run_RUNSQL_Insert()           'Succeeded, no Err

    On Error Resume Next
    Dim system As AS400System
    Set system = ConnectToSystem
    If Err Then
        MsgBox "Could not connect to system." & vbCrLf & Err.Description
        Exit Sub
    End If

    Dim comm As cwbx.Command
    Set comm = New cwbx.Command
    Set comm.system = system
    Dim commandStr As String
    commandStr = "RUNSQL SQL('INSERT INTO MYLIB.MYFILE (FIELD1, FIELD2, FIELD3) VALUES (''ABCDEFG'', 6000, 10.34)') COMMIT(*NONE) NAMING(*SQL)"
    comm.Run commandStr
    If Err Then
       MsgBox Err.Description & vbCrLf & vbCrLf & FormatError(comm.errors)
    End If
    system.Disconnect cwbcoServiceRemoteCmd
End Sub


Sub Test_Run_RUNSQL_SELECT_Fail()

'Fails because SELECT statement not supported by RUNSQL.
'Would fail on command line too with status message of 'RUNSQLSTM or RUNSQL command failed.'

    On Error Resume Next
    Dim system As AS400System
    Set system = ConnectToSystem
    If Err Then
        MsgBox "Could not connect to system." & vbCrLf & Err.Description
        Exit Sub
    End If

    Dim comm As cwbx.Command
    Set comm = New cwbx.Command
    Set comm.system = system
    Dim commandStr As String
    commandStr = "RUNSQL SQL('SELECT REGEXP_MATCH_COUNT(S,''^([F][W])|([L][F])[0-9]{4}[Y,N]$'') FROM (SELECT ''LF7002N'' AS S FROM SYSIBM.SYSDUMMY1) AS A') COMMIT(*NONE) NAMING(*SQL)"
    comm.Run commandStr
    If Err Then
       MsgBox Err.Description & vbCrLf & vbCrLf & FormatError(comm.errors)
    End If
    system.Disconnect cwbcoServiceRemoteCmd     'Does disconnect do anything?  Active Job remains until AS400System destructor runs
End Sub


Private Function ConnectToSystem() As AS400System

    On Error Resume Next
    Dim system As AS400System
    Set system = New AS400System
    system.Define "xxx.xxx.xxx.xxx"    'an IP address usually goes here
    system.Connect cwbcoServiceRemoteCmd
    Set ConnectToSystem = system
End Function



Private Function FormatError(ByVal errorList As cwbx.errors) As String

    If errorList Is Nothing Then
        FormatError = ""
        Exit Function
    End If

    Dim errItem As cwbx.Error
    Dim errMsg As String

    errMsg = Build_ProgramCommand_ReturnCode_Message(errorList.ReturnCode) & vbCrLf
    For Each errItem In errorList
        errMsg = errMsg & errItem.Text & vbCrLf
    Next
    'Debug.Print Mid$(errMsg, 1, Len(errMsg) - 2)
    FormatError = Mid$(errMsg, 1, Len(errMsg) - 2)
End Function



Private Function Build_ProgramCommand_ReturnCode_Message(ByVal return_code As Long)

    'Program and Command Return Code Constants

    Dim errMsg As String
    errMsg = "Error occurred in IBM i Access Library. "
    Select Case return_code
        Case Is = cwbrcInvalidSystemHandle: Build_ProgramCommand_ReturnCode_Message = errMsg & "Invalid system handle."      '6000
        Case Is = cwbrcInvalidProgram:      Build_ProgramCommand_ReturnCode_Message = errMsg & "Invalid program."            '6001
        Case Is = cwbrcSystemName:          Build_ProgramCommand_ReturnCode_Message = errMsg & "Bad System Name."            '6002
        Case Is = cwbrcCommandString:       Build_ProgramCommand_ReturnCode_Message = errMsg & "Bad command string."         '6003
        Case Is = cwbrcProgramName:         Build_ProgramCommand_ReturnCode_Message = errMsg & "Bad program name."           '6004
        Case Is = cwbrcLibraryName:         Build_ProgramCommand_ReturnCode_Message = errMsg & "Bad library name."           '6005
        Case Is = cwbrcInvalidType:         Build_ProgramCommand_ReturnCode_Message = errMsg & "Invalid data type"           '6006
        Case Is = cwbrcInvalidParmLength:   Build_ProgramCommand_ReturnCode_Message = errMsg & "Invalid parameter length."   '6007
        Case Is = cwbrcInvalidParm:         Build_ProgramCommand_ReturnCode_Message = errMsg & "Invalid parameter."          '6008
        Case Is = cwbrcTooManyParms:        Build_ProgramCommand_ReturnCode_Message = errMsg & "Too many parameters."        '6009
        Case Is = cwbrcIndexRangeError:     Build_ProgramCommand_ReturnCode_Message = errMsg & "Index out of range."         '6010
        Case Is = cwbrcRejectedUserExit:    Build_ProgramCommand_ReturnCode_Message = errMsg & "User rejected."              '6011
        Case Is = cwbrcUserExitError:       Build_ProgramCommand_ReturnCode_Message = errMsg & "User error."                 '6012
        Case Is = cwbrcCommandFailed:       Build_ProgramCommand_ReturnCode_Message = errMsg & "Command failed."             '6013
        Case Is = cwbrcProgramNotFound:     Build_ProgramCommand_ReturnCode_Message = errMsg & "Program not found."          '6014
        Case Is = cwbrcProgramError:        Build_ProgramCommand_ReturnCode_Message = errMsg & "Program error."              '6015
        Case Is = cwbrcCommandTooLong:      Build_ProgramCommand_ReturnCode_Message = errMsg & "Command too long."           '6016
        Case Is = cwbrcUnexpectedError:     Build_ProgramCommand_ReturnCode_Message = errMsg & "Unexpected error."           '6099
        Case Else:                          Build_ProgramCommand_ReturnCode_Message = errMsg & "Unrecognised error."
    End Select
End Function



'    Dim hostMessageLibraryName As Variant   'Upon successful completion, contains the name of the library containing the system message file.
'    Dim hostMessageFileName As Variant      'Upon successful completion, contains the name of the system message file.
'    Dim hostSubstitutionText As Variant     'Upon successful completion, contains the message substitution text.
'                                            'The substitution text is the data inserted into the substitution variable fields defined for the message.
'                                            'This information is returned in the host code page. This is the format required by the QMHRTVM API.
'
'    errItem.GetHostMessageInfo hostMessageLibraryName, hostMessageFileName, hostSubstitutionText
于 2020-02-07T21:28:05.967 回答