swirl
Guide to OmniMark 7   OmniMark home
docs home 
IndexConceptsTasksSyntaxLibrariesLegacy LibrariesErrors
 
Functions       Platforms  
 

Net, Web Services Broker (OMWSB)

 
 

Net, Web Services Broker (OMWSB) is packaged separately from OmniMark. The following describes version 1.0 of Net, Web Services Broker (OMWSB).

WSB provides a set of functions that enable you to create a server application that acts as a host and broker for web service requests sent from client applications and processed by service applications. Note the distinction between the roles of the client application, the server application and the service application:

Note: The WSB library is supplied separately from OmniMark and is installed, by default, in its own directory. To use the WSB library therefore, you will need to ensure that the function library and include paths for the WSB library are set approriately for your environment. See the documentation for your development and runtime environments for information on setting the paths correctly.

Note: The WSB library will not run with OmniMark Desktop Engine or with the OmniMark Fast VM under OmniMark Studio or OmniMark Studio for Eclipse (the "Execute Project" option).

The WSB library provides functions that can be used by the server application to host services, route requests, and process requests for which no service exists. It also provides functions that can be used by service applications to implement a service and to receive and interpret a request. The WSB library does not provide functions for use in web service clients. However, the functions required by clients to communicate with servers and to interpret responses are provided by OmniMark's TCP/IP library and by OmniMark's built in XML processing capability.

The WSB library runs service applications in threads, allowing the WSB server to handle multiple simultaneous requests.

Web services may use a variety of communication protocols (SOAP, XML-RPC, etc) and a variety of transport mechanisms (HTTP, Mail, etc.). The current version of the Web Services Broker library supports SOAP 1.1, XML-RPC, and user-defined protocols over HTTP.

A WSB example

Here is an example of a WSB application using the SOAP protocol. It consists of four programs, the server, the service, a client, and a "die" client, designed to shut down the server remotely. The example implements a time service.

This example, as well as examples using XML-RPC and a user-defined protocol, are included with your OMWSB installation. Please note that these samples are designed to illustrate the operation of the Web Service Broker and should not be taken as complete or robust implementation of the SOAP or XML-RPC protocols.

A WSB server

This is the code for the server.

  import 'omwsb.xmd' prefixed by wsb.

  process
     local wsb.server server

     ; set up the server
     set server to wsb.create-server on 3556 of-type wsb.soap-service
     ; build the service map
     wsb.add-service to server named "http://omnimark.com/time"
      handled-by "times.xvc"
     ; start the server
     wsb.start-servicing-requests on server

     put #error "omwsb Server started on port 3556%n"
     repeat
        local wsb.request request

        ; Wait for requests. Requests not in map handled here.
        set request to wsb.wait-for-request on server

        do when (wsb.request-name of request) = "http://omnimark.com/die"
           local stream responder
           open responder as wsb.writer of request
           put responder "http/1.0 200 ok%13#%10#"
            || "Content-Type: text/xml; charset=%"utf-8%"%13#%10#"
            || "Content-Length: 0"
            || "%13#%10#%13#%10#"
           close responder
           log-message "die action received. Shutting down.%n"
           exit
        else
           ;else report bad request
           log-message "Unknown request received."
           log-message "Header: " || wsb.request-header of request
           log-message "Body: " || wsb.reader of request
        done

        catch #external-exception
              identity catch-id
              message catch-msg
              location catch-loc
           log-message '%g(catch-id) : %g(catch-msg)%n%g(catch-loc)'
           ; exit if server has fatal error
           rethrow when catch-id = "OMWSB000"
     again

A WSB service

Here is an example of a WSB service application. It implements a time service. The server program above is designed to act as host and broker for this service. Note that this program must be compiled to create "times.xvc" and that the "times.xvc" file must be in the current working directory of the server program.

  ; times.xom
  ; a time service

  import 'omwsb.xmd' prefixed by wsb.
  include 'omdate.xin'
  global stream the-time

  declare catch parse-error
   reason value stream message

  process
     repeat
        local wsb.request request
        local stream responder
        local stream response

        ; Parse the request
        set request to wsb.wait-for-request
        using group process-soap
        do xml-parse scan wsb.reader of request
           suppress
        catch parse-error reason message
           open responder as wsb.writer of request
           put responder "http/1.1 404 Invalid request%13#%10#%13#%10#"
           put responder "xml error in request:%n" || message || "%n"
           close responder
           exit
        done

        ; Build the response      
        set response
         to "<soap-env:Envelope%13#%10#"
         || "  xmlns:soap-env=%"http://schemas.xmlsoap.org/soap/envelope/%"%13#%10#"
         || "  soap-env:encodingStyle=%"http://schemas.xmlsoap.org/soap/encoding/%"%13#%10#"
         || "  xmlns:time=%"http://schemas.omnimark.com/time%">%13#%10#"
         || "   <soap-env:Body>%13#%10#"
         || "     <time:current-time>%13#%10#"
         || the-time
         || "     </time:current-time>%13#%10#"
         || "   </soap-env:Body>%13#%10#"
         || "</soap-env:Envelope>%13#%10#"

        open responder as wsb.writer of request
        put responder "http/1.0 200 ok%13#%10#"
         || "Content-Type: text/xml; charset=%"utf-8%"%13#%10#"
         || "Content-Length: "
         || "d" % length of response
         || "%13#%10#%13#%10#"
         || response
        close responder

        catch #external-exception identity catch-id
           rethrow when catch-id = "OMWSB000"
     again

  ;ensure a clean exit
  catch #program-error
   code error-code
   message error-message
   location error-location
     log-message ('An error occurred in the time service:%n'
                || '%d(error-code): %g(error-message)%n%g(error-location)%n')

  ;rules for processing the SOAP packet
  group process-soap

  element #base "Envelope"
     suppress

  element #base "Body"
     suppress

  element #base "request"
     suppress

  element #base "zone"
     local stream zone initial {"%c"}
     set the-time
      to ymdhms-to-arpadate ymdhms-adjust-time-zone
          now-as-ymdhms to-be zone

  markup-error
     throw parse-error
      reason (#message || " At line %d(#line-number)")

  group #implied

A WSB Client

Here is a client that uses the time service.

  import 'omtcp.xmd' prefixed by tcp.
  include "omdate.xin"

  global integer port initial {3556}
  global stream  hostname initial {"localhost"}
  define input function my-time-zone as output now-as-ymdhms drop any{14}

  ;default to local time zone
  global stream zone initial {my-time-zone};{now-as-ymdhms drop any{14}}

  define input function generate-soap-request
   action value stream soap-action
   as
     local stream contents

     set contents
      to "<soap-env:Envelope%13#%10#"
      || " xmlns:soap-env=%"http://schemas.xmlsoap.org/soap/envelope/%"%13#%10#"
      || " soap-env:encodingStyle=%"http://schemas.xmlsoap.org/soap/encoding/%"%13#%10#"
      || " xmlns:time=%"http://schemas.omnimark.com/time%">%13#%10#"
      || "  <soap-env:Body>%13#%10#"
      || "   <time:request>%13#%10#"
      || "    <time:zone>" || zone || "</time:zone>%13#%10#"
      || "   </time:request>%13#%10#"
      || "  </soap-env:Body>%13#%10#"
      || "</soap-env:Envelope>%13#%10#"

     output "post /SOAPServer http/1.0%13#%10#"
         || "Host: www.soapserver.com%13#%10#"
         || "Content-Type: text/xml; charset=%"utf-8%"%13#%10#"
         || "SOAPAction: " || soap-action || "%13#%10#"
         || "Content-Length: "
         || "d" % length of contents
         || "%13#%10#%13#%10#"
         || contents

  process
     local tcp.connection conn

     ;check for valid time zone format
     do unless zone matches (["+-"] digit{4})
        log-message ('Incorrect time zone format "' || #args[1] || '"%n'
                  || "Use '-'/'+' hhmm format. E.g. +0200")
        halt with 1
     done

     set conn to tcp.connect to hostname on port
     tcp.put-string to conn from
      (generate-soap-request action "http://omnimark.com/time")

     ; receive response   
     do scan tcp.reader of conn
        ; See if valid response. If so, decode data. Otherwise, report error
        match (any** "http/" digit+ "." digit+ blank+ digit{3} => response-code)
              (any** "Content-Type:" blank+ [\ " ;"]+ => content-type)?
              (any** 'charset="' any++ => charset '"')?
              (any** "Content-Length:" blank* digit+ => content-length)?
              (any** "%13#%10#%13#%10#")?
           do when response-code = "200"
              do xml-parse scan #current-input
                 suppress
              done
           else
              log-message ("http error. Code=" || response-code)
           done
        match lookahead any
           log-message ("Invalid response received:%n" || #current-input)
           halt with 1
     done

  ;-------------------------------------------------------
  ; SOAP Processing rules
  ;
  element #base "Envelope"
     suppress

  element #base "Body"
     suppress

  element #base "current-time"
     log-message "%nThe time is: " || "%sc" drop white-space* || "%n"

Shutting down a WSB server

It is important that you shut down a WSB server by sending it a message telling it to shut down. If you shut it down by killing the server process, (for example by typing Ctrl-C on the command line) the service programs hosted by the server will not have an opportunity to clean up any resources they are using. Here is a client that will send a shutdown command to the server application shown above.

  import 'omtcp.xmd' prefixed by tcp.

  global integer port initial {3556}
  global stream  hostname initial {"localhost"}

  define input function generate-soap-request
   action value stream soap-action
   as
     output "post /SOAPServer http/1.0%13#%10#"
         || "Host: www.soapserver.com%13#%10#"
         || "Content-Type: text/xml; charset=%"utf-8%"%13#%10#"
         || "SOAPAction: " || soap-action || "%13#%10#"
         || "Content-Length: 0"
         || "%13#%10#%13#%10#"

  process
     local tcp.connection conn

     set conn to tcp.connect to hostname on port
     tcp.put-string to conn from
      (generate-soap-request action "http://omnimark.com/die")

Functions
   wsb.add-service
   wsb.clear-all-services
   wsb.create-server
   wsb.dispatch-request
   wsb.has-known-request-type
   wsb.reader
   wsb.remove-service
   wsb.request
   wsb.request-header
   wsb.request-name
   wsb.request-type
   wsb.server
   wsb.service-exists
   wsb.start-servicing-requests
   wsb.wait-for-request
   wsb.writer
 
Platforms
   HP/UX
   IBM AIX
   Linux (Intel)
   MS Windows 98/ME
   MS Windows NT/2000/XP
   Sun Solaris
 
 

Top [ INDEX ] [ CONCEPTS ] [ TASKS ] [ SYNTAX ] [ LIBRARIES ] [ LEGACYLIBRARIES ] [ ERRORS ]

OmniMark 7.1.2 Documentation Generated: June 28, 2005 at 5:46:17 pm
If you have any comments about this section of the documentation, send email to [email protected]

Copyright © Stilo Corporation, 1988-2005.