FglWsdl详解

The fglwsdl tool (WSDL and XSD)

Topics

To access a remote Web Service, you first must get the WSDL information from the service provider. Sample services can be found through UDDI registries(http://www.uddi.org), or on other sites such as XMethods (http://www.xmethods.net).


Using fglwsdl

The fglwsdl tool, provided as part of the Genero Web Services (GWS), allows you to get the WSDL description of any Web Service that will be accessed by a GWS Client application, or to use a WSDL description when you are creating a corresponding GWS Server application. It also allows you to generate 4GL data types from XML schemas (also known as XSD).

Syntax:

  fglwsdl [-command] <filename | url | regex value>

     where:

  • command is one of the command-line options
  • filename is the name of a WSDL description file for a Web Service or a XML schema file
                 or
    url  is the web location of a WSDL description for a published Web Service or the location of an XSD schema resource on the web. For example, provide the host server and the name of the service: http://<host-server>/<name-of-the-service>?WSDL

Note:

As fglwsdl does not support https, to generate a stub from a https url, you have to save the WSDL file locally and create the stub from this local file.

Command Line Options:

 Command

  Description

-V

Display version information

-h

Display this help

-l

List services from a WSDL or variables from a XSD

-c [options]

Generate client stub (default) to be used in a GWS Client application

-s [options]

Generate server stub to be used in a GWS Server application

-x [options]

Generate data types from a XML schema (XSD)

The options for the generation of the client or server stub are listed below in the specific WSDL options and in the Common options. These options can also be used without  -c, if you are generating a client stub (the default).

The options for the generation of data types are listed below in the specific XSD options and in the Common options. The -x option cannot be used with -c or -s.

There is also an extra command to validate a regular expression against a value as described in the specific Extra command.

 Extra command

  Description

-regex

Validate the value against the regex regular expression described in XML Schema specification

 

 WSDL Options

  Description

-o file

Specify a Base name for the output files.

-n service port

Generate only for the given service name and portType.

-b binding

Generate only for the given binding.

-prefix name

Add name as the prefix of the generated web service functions, variables and types. (name can contain %s for servicename, %p for portname and %f for filename)

-compatibility

Generate a Genero 1.xx compatibility client stub.

-fRPC

Force RPC convention; use RPC Convention to generate the code, regardless of what the WSDL information contains.

-disk

Save WSDL and all dependencies from an URL on the disk. 
Note:
 To generate code at the same time, you must use the option -c, -s, or both. Otherwise, no code is generated.

-domHandler

Generates the use of DOM in the client stub and calls to callback handlers.

 

 XSD Options

  Description

-o file

Name of the output file. If file has no extension, .inc is added.

-n name [ns]

Generate only for the given variable name and namespace (if there is one).

-prefix name

Add name as the prefix of the generated data types.

-disk

Save XSD and all dependencies from an URL on the disk. 
Note:
 No code is generated.

 

Common Options

  Description

-comment

Add XML comments to the generation.

-fArray

Force XML array generation instead of XML list when possible. If the WSDL contains an XML definition of a 4GL list, generate a 4GL array matching the same definition.

-fInheritance

Force generation of XML choice records for all inheritance types found in the schemas, otherwise only for abstract types and elements.

-noFacets

Don't generate facet constraints restricting the value-space of simple datatype.

-legacyTypes

Don't generate BIGINT, TINYINT and BOOLEAN data types.

-ignoreMixed

Ignore attribute mixed="true" in XML schemas when generating code.

-ext schema

Add an external schema. External schemas for dependencies won't be included in the WSDL description or in the XSD schema if their location attributes are missing. Use this option to add a missing external schema for a WSDL or XSD dependency.

-noValidation

Disable XML schema validation warnings.

-autoNsPrefix nb

Automatic prefix generation for variables and types using a substring of the namespace by removing the nb first elements (-1 means only the last element). 
For example:
 if a variable belongs to the namespace http://www.4js.com/Global/Service, a value of -1 will giveService as a prefix, and a value of 1 will give Global_Service as a prefix.

-nsPrefix ns value

Add value as prefix of the generated variables and types belonging to namespace ns (supersede the -prefix and the -autoNsPrefix option, and can be called several times).

Network Options

  Description

-noHTTP

Disable HTTP - search for the WSDL description or the XML schema and its dependencies on the client instead of the internet. Useful, for example, if a company has restricted access to the internet.

-proxy location

Connect via proxy where location is host[:port] or ip[:port].

-pAuth login pass

Proxy authentication login and password.

-hAuth login pass

HTTP authentication login and password.

-cert cert

File of the X509 PEM-encoded certificate for HTTPS purpose.

-key key

File of the PEM-encoded private key for HTTPS purpose.

-wCert cert

Certificate name in the Windows keystore for HTTPS purpose (Windows only).

Back to the top


Generating files for a GWS Client

Using the fglwsdl tool, you can obtain the WSDL information for a GWS Client application. The following example requests the Calculator Web Service information from the specified URL, and the output files will have the base name ws_calculator:

     fglwsdl -o ws_calculator http://localhost:8090/Calculator?WSDL

For a client application, fglwsdl generates two output files, which should not be modified:

  • <filename>.inc - the globals file, containing declarations of global variables that can be used as input or output for functions accessing Web Service operations,  and the global wsError record. In our example, the file is ws_calculator.inc.

This file must be listed in a GLOBALS statement at the top of any .4gl modules that you write for your GWS Client application.

  • <filename>.4gl - containing the definitions of the functions that can be used in your GWS client application to perform the requested Web Service operation, and the code that manages the Web Service request. In our example, the file is ws_calculator.4gl.

This file must be compiled and linked into your GWS Client application.

The Web Service error structure

Check this structure, defined in the globals .inc file,  for a detailed error description when a Web Service function returns with a non-zero status. 
Notice that even if status is -2 due to asynchronous calls, the record contains a description.

DEFINE wsError RECORD

   code STRING,         -- short description of the error

   codeNS STRING,       -- the namespace of the error code

   description STRING,  -- description of the error

   action STRING        -- internal "SOAP action"

END RECORD

The generated functions

Genero Web Services client functions have the following requirements:

  • The function cannot have input parameters.
  • The function cannot have return values.
  • The function's input message must be defined as a global or module RECORD.
  • The function's output message must be defined as a global or module RECORD.

As a result, two types of GWS functions are generated for the Web Service operation that you requested:

  • One function type uses global records for the input and output. The names of these functions end in "_g". Before calling the function in your GWS Client application, you must set the values in the global input record. After the function call,  the status of the request is returned from the server, and the output message is stored in the global output record. In addition to performing the desired operation, this function handles the communication for the SOAP request and response, and sets the values in the wsError record as needed.
  • The other function type serves as a "wrapper" for the "_g" function. It passes the values of input parameters to the "_g" function, and returns the output values and status received from the "_g" function.  Your client application does not need to directly access the global records. This function can only be used if the parameters are simple variables (no records or arrays). 

The generated .inc globals file contains comments that list the prototypes of the functions for the GWS operation, and the definitions of the global INPUT and OUTPUT records.

The generated callback handlers

More and more Web Services provide support of the different WS-* specifications. To enable a better interoperability with such services, the fglwsdl tool allows the programmer to modify the SOAP request before it is sent, and to perform additional verifications of the SOAP response before it is returned from the 4GL function.

When option -domHandler is used, the fglwsdl tool performs the following two operations at once:

  • It generates the client stub based entirely on the DOM API to ease the manipulation of the XML requests and responses.
  • It generates additional calls for each operation of a service to execute one of the three callback handlers the programmer has to implement. These three callback handlers are described in the next section.

Handler definition

There are three kind of callbacks you must implement for each service generated with the -domHandler option.

  • The request handler that allows the modification of the entire SOAP request before it is send over the net.
    It must be named ServiceName_HandleRequest, where ServiceName is the name of the service according to the different prefix options used during generation. It must return TRUE if you want the caller function to continue normally or FALSE to return from the caller function with a SOAP error you can define via the wsError record.

·                      FUNCTION ServiceName_HandleRequest(operation,doc,header,body)

·                        DEFINE operation STRING          -- Operation name of the request to be modified.

·                        DEFINE doc       xml.DomDocument -- Entire XML document of the request

·                        DEFINE header    xml.DomNode     -- XML node of the SOAP header of the request

·                        DEFINE body      xml.DomNode     -- XML node of the SOAP body of the request

·                        CASE operation

·                          WHEN "Add"

·                            ...                          -- Use the DOM APIs to modify the request of the Add operation

·                          WHEN "Sub"

·                            ...                          -- Use the DOM APIs to modify the request of the Sub operation

·                          OTHERWISE

·                            DISPLAY "No modification for operation :",operation

·                        END CASE

·                        RETURN TRUE                      -- Continue normally in Add_g() or Sub_g()

·                      END FUNCTION

  • The response handler that allows the validation of the entire SOAP response before it is de-serialized into the corresponding record.
    It must be named ServiceName_HandleResponse, where ServiceName is the name of the service according to the different prefix options used during generation. It must return TRUE if you want the caller function to continue normally or FALSE to return from the caller function with a SOAP error you can define via the wsError record.

·                      FUNCTION ServiceName_HandleResponse(operation,doc,header,body) RETURNING BOOLEAN

·                        DEFINE operation STRING          -- Operation name of the response to be checked.

·                        DEFINE doc       xml.DomDocument -- Entire XML document of the response

·                        DEFINE header    xml.DomNode     -- XML node of the SOAP header of the response

·                        DEFINE body      xml.DomNode     -- XML node of the SOAP body of the response

·                        CASE operation

·                          WHEN "Add"

·                            ...                          -- Use the DOM APIs to check the response of the Add operation

·                          WHEN "Sub"

·                            ...                          -- Use the DOM APIs to check the response of the Sub operation

·                          OTHERWISE

·                            DISPLAY "No verification for operation :",operation

·                        END CASE

·                        RETURN TRUE                      -- Continue normally in Add_g() or Sub_g()

·                      END FUNCTION

  • The fault response handler that allows the verification of the entire SOAP fault response before it is de-serialized into the wsError record.
    It must be named ServiceName_HandleResponseFault, where ServiceName is the name of the service according to the different prefix options used during generation. It must return TRUE if you want the caller function to continue normally or FALSE to return from the caller function with a SOAP error you can define via the wsError record.

·                      FUNCTION ServiceName_HandleResponseFault(operation,doc,header,body) RETURNING BOOLEAN

·                        DEFINE operation STRING          -- Operation name of the fault response to be checked.

·                        DEFINE doc       xml.DomDocument -- Entire XML document of the fault response

·                        DEFINE header    xml.DomNode     -- XML node of the SOAP header of the fault response

·                        DEFINE body      xml.DomNode     -- XML node of the SOAP body of the fault response

·                        CASE operation

·                          WHEN "Add"

·                            ...                          -- Use the DOM APIs to verify the SOAP fault response of the Add operation

·                          WHEN "Sub"

·                            ...                          -- Use the DOM APIs to verify the SOAP fault response of the Sub operation

·                          OTHERWISE

·                            DISPLAY "No verification for operation :",operation

·                        END CASE

·                        RETURN TRUE                      -- Continue normally in Add_g() or Sub_g()

·                      END FUNCTION

Example output

The example Web Service for which the WSDL information was requested, Calculator, has an Add operation that returns the sum of two integers. 

The generated file ws_calculator.inc lists the prototype for the Add and Add_g functions, the asynchronous AddRequest_g and AddResponse_g functions, as well as the definitions of the global variables Add and AddResponse:

# Operation: Add
#
# FUNCTION: Add_g()             -- Function that uses the global input and output records

#   RETURNING: soapStatus       -- An integer where 0 represents success

#   INPUT: GLOBAL Add

#   OUTPUT: GLOBAL AddResponse

#

# FUNCTION: Add(p_a, p_b)       -- Function with input parameters that correspond

#  RETURNING: soapStatus ,p_r   -- to the a and b variables of the global 
                                -- INPUT record
                                -- Return values are the status integer and the value
                                -- in the r variable of the global OUTPUT record

#                                

# FUNCTION: AddRequest_g()      -- Asynchronous function that uses the global input record

#  RETURNING: soapStatus        -- An integer where 0 represents success, -1 error

#   INPUT: GLOBAL Add           --  and -2 means that a previous request was sent and that a response is in progress.

#

# FUNCTION: AddResponse_g()     -- Asynchronous function that uses the global output record

#  RETURNING: soapStatus        -- An integer where 0 represents success, -1 error

#   OUTPUT: GLOBAL AddResponse  --  and -2 means that the response was not yet received, and that a new call should be done later.

#VARIABLE : Add                 -- defines the global INPUT record

DEFINE Add RECORD ATTRIBUTE(XMLName="Add",
                            XMLNamespace="http://tempuri.org/")
         a INTEGER ATTRIBUTE(XMLName="a",XMLNamespace=""),
         b INTEGER ATTRIBUTE(XMLName="b",XMLNamespace="")
       END RECORD

# VARIABLE : AddResponse       -- defines the global OUTPUT record

DEFINE AddResponse RECORD ATTRIBUTE(XMLName="AddResponse",
                                    XMLNamespace="http://tempuri.org/")
         r INTEGER ATTRIBUTE(XMLName="r",XMLNamespace="")
       END RECORD

Using the generated functions

The information obtained from the ws_calculator.inc file allows you to write code in your own .4gl module as part of the Client application, using the Web Service operation Add.

  • Using parameters and return values

Since the input variables for our example are simple integers, you can call the Add function in your Client application, defining variables for the parameters and return values.

FUNCTION myWScall()
  DEFINE op1        INTEGER

  DEFINE op2        INTEGER

  DEFINE result     INTEGER

  DEFINE wsstatus   INTEGER

  ...

  LET op1 = 6
  LET op2 = 8
  CALL Add(op1, op2) RETURNING wsstatus, result
  ...
  DISPLAY result

  • Using global records

You could choose to call the Add_g function instead, using the global  records Add and AddResponse directly. If the input variables are complex structures like records or arrays, you are required to use this function.

FUNCTION myWScall()
  DEFINE wsstatus INTEGER
  ...
  LET Add.a = 6
  LET Add.b = 8
  LET wsstatus = Add_g()
  ...
  DISPLAY AddResponse.r

In this case, the status is returned by the function, which has also put the result  in the AddResponse global record.

See Tutorial: Writing a Client Application for more information. The demo/WebServices subdirectory of your Genero installation directory contains complete examples of Client Applications.

  • Using asynchronous calls

If you don't want your application to be blocked when waiting for the response to a request, you should first call AddRequest_g; this will send the request using the global Add record to the server. It returns a status of 0 (zero) if everything goes well, -1 in case of error, or -2 if you tried to resend a new request before the previous response was retrieved.

FUNCTION sendMyWScall()
  DEFINE wsstatus INTEGER
  ...
  LET Add.a = 6
  LET Add.b = 8
  LET wsstatus = AddRequest_g()
  IF wstatus <> 0 THEN

    DISPLAY "ERROR :", wsError.code
  END IF 
  ...

You can then call AddResponse_g to retrieve the response in the AddResponse global record of the previous request. If returned status is 0 (zero) the response was successfully received, -1 means that there was an error, and -2 means that the response was not yet received and that the function should be called later.

FUNCTION retrieveMyWScall()
  DEFINE wsstatus INTEGER
  ...
  LET wsstatus = AddResponse_g()
  CASE wstatus
    WHEN -2
      DISPLAY "No response available, try later"
    WHEN 0
      DISPLAY "Response is :",AddResponse.r
    OTHERWISE

      DISPLAY "ERROR :", wsError.code
  END CASE

  ...

You can mix the asynchronous call with the synchronous one as they are using two different requests. In other words, you can perform an asynchronous request with AddRequest_g, then a synchronous call with Add_g, and then retrieve the response of the previous asynchronous request with AddResponse_g.

Warning: In development mode, a single 4GL Web Service server can only handle one request at a time, and several asynchronous requests in a row without retrieving the corresponding response will lead to a deadlock. To support several asynchronous requests in a row, it is recommended that you are in deploymentmode with a GAS as the front end.

Back to the top


Generating files for a GWS Server

You can write a GWS Server application for a Web Service that you have created; see Tutorial: Writing a Server Application. However, if you want to make sure your Web Service is compatible with that of a third-party (an accounting application vendor, for example), you can use the fglwsdl tool  to obtain the WSDL information that complies with that vendor's standards, and to generate corresponding files that can be used in your GWS Server application.

The following example requests the Calculator Web Service information from the specified URL, and the output files will have the base name "ws_calculator".

     fglwsdl -s -o ws_calculator http://localhost:8090/Calculator?WSDL

For a server application, fglwsdl generates two files, which should not be modified:

  • <filename>.inc - the globals file, containing declarations of global variables that can be used as input or output to functions accessing the Web Service operations. In our example, the file is ws_calculatorService.inc.

This file must be listed in a GLOBALS statement at the top of any .4gl modules that you write for your GWS Server application.

  • <filename>.4gl - containing a function that creates the service described in the WSDL, publishes the operations of the service, and registers the service. In our example, the file is ws_calculatorService.4gl.

This file must be compiled and linked into your GWS Server application.

Example output

In the generated file ws_calculatorService.inc, the definitions of the variables for the input and output record are the same as those generated for the Web Service Client application:

#VARIABLE : Add                  -- defines the global INPUT record

DEFINE Add RECORD ATTRIBUTE(XMLName="Add",
                            XMLNamespace="http://tempuri.org/")
         a INTEGER ATTRIBUTE(XMLName="a",XMLNamespace=""),
         b INTEGER ATTRIBUTE(XMLName="b",XMLNamespace="")
       END RECORD

# VARIABLE : AddResponse        -- defines the global OUTPUT record

DEFINE AddResponse RECORD ATTRIBUTE(XMLName="AddResponse",
                                    XMLNamespace="http://tempuri.org/")
         r INTEGER ATTRIBUTE(XMLName="r",XMLNamespace="")
       END RECORD

The generated file ws_calculatorService.4gl contains a single function that creates the Calculator service, creates and publishes the service operations, and registers the Calculator service:

FUNCTION Createws_calculatorService()
  DEFINE service com.WebService
  DEFINE operation com.WebOperation
...
# Create Web Service
  LET service = com.WebService.CreateWebService("Calculator","http://tempuri.org/")

# Publish Operation : Add
  LET operation = com.WebOperation.CreateRPCStyle("Add","Add",Add,AddResponse)
  CALL service.publishOperation(operation,"")
...
# Register Service
  CALL com.WebServiceEngine.RegisterService(service)
  RETURN 0
...
END FUNCTION

Writing your functions

The ws_calculator.inc file provides you with the global input and output records and function names that allow you to write your own code implementing the Add operation. Your new code should not be written in the generated modules. For example, do not add your own version of the Add function to the generated ws_calculator.4gl module; it can be included in your module containing the MAIN program block, or in a separate module to be included as part of the Web server application. The function must use the generated definitions for the global input and output records.

In your version of the operation, this function adds 100 to the sum of the variables in the input record:

FUNCTION Add()
    LET AddResponse.r = (Add.a + Add.b) + 100
END FUNCTION

See Tutorial: Writing a Server application for more information. The demo/WebServices subdirectory of your Genero installation directory contains complete examples of Server Applications.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值