SOAP Services in Barracuda

This tutorial assumes you have read the introduction to the Barracuda SOAP plugin.

Barracuda SOAP services are defined and written in Lua in a simple text format.

These service definitions would normally be embedded in your server, but can be loaded
dynamically or uploaded remotely if required without rebuilding the server. This process
can drastically reduce service development times and allows new services or patches to
be easily deployed to existing devices.

Barracuda SOAP will dynamically generate and publish the appropriate WSDL (Web Service
Description Language) document from your installed sevice definitions. This dynamic
generation means that the WSDL always reflects the currently installed services : there
is no possibility of a mismatched service and WSDL.

It also means that the all complexities of WSDL and SOAP syntax are handled by Barracuda SOAP,
leaving implementers to concentrate on writing services,in contrast to the usual approach
of parsing a user-supplied WSDL file, and constructing a set of skeleton C handlers which
then have to be coded, compiled, and linked to the server.

Simple service definition

The following is all that is required
to define a SOAP service called Info, with an operation called Date that
returns the server's date:

soap_services = {
  Info = {
    Date = {
      output = {name = "return", type = "date"},
      call = function() return os.date("!%Y-%m-%d") end,
    },
  }
}

Note the type="date" declaration;
Barracuda SOAP supports all XML Schema simple
data types, with automatic conversion of double, string, decimal, and
integer.

Here is a vbscript program that accesses the service defined above, assuming that
Barracuda SOAP is configured to publish SOAP services on localhost/soap :

dim SOAPClient
set SOAPClient = createobject("MSSOAP.SOAPClient")

SOAPClient.mssoapinit("http://localhost/soap/info.wsdl")

wscript.echo "SOAP Server date is :", SOAPClient.Date()

Service Definitions in Detail

Barracuda SOAP services are defined as a Lua table called soap_services. This
table defines one or more services; each service can support any number of
operations.

An operation is a single remote procedure call (rpc).

Each named element in the soap_services table is a SOAP service definition, and must
contain a list of operations supported by this service.

note: SOAP service, operation and parameter names
must be valid XML names, as per the W3C XML
spec
.

Each operation is a table with the following defined members : input,
output, call, and lifetime

input (optional)
If specified, input is a table (list) defining any input parameters to be passed
to the call function.

Each parameter definition is a table with the following members:

 

name (mandatory)
a string definining the name of this parameter;
type (optional)
the data type, which defaults to "string". type can be one of :

 

  • A string defining an XML schema type, ie "integer",
  • A string defining an array of simple elements, defined by appending the word
    "Array" to a simple type, ie "stringArray",
  • A table defining a structured type.
  • Structured types are defined as a list (table) of members,
    each with a name and type element.

    They can contain simple types and arrays, but not sub-structures.

For convenience, if only a single input parameter is specified, it need not be
wrapped in a list, ie.

input={name="x", type="double"} is equivalent to input={{name="x",
type="double"}}

output (optional)
If specified, output is a table (list) defining any parameters returned by the
call function.

The structure of output parameters are identical to input, but since most
client applications only support a single return value, multiple values are usually
returned as a structure or array.
call (mandatory)
The call member is the Lua rpc function.

It will be called with the parameters defined by input, and is expected to return
values as defined by output. Failure to return the results specified will result
in an error message being sent to the client.

As a special case, if the call function returns nil followed by an error
message, the server will return a SOAP error to the caller, with the error message
supplied.
lifetime (optional)
a number defining the number of seconds the response remains valid. This value is
used for cache control headers.

(The default value for response lifetimes is configured in the
server).

Example service definitions

note : two dashes (--) indicates a comment in
Lua; strings are enclosed with quotes (" "); tables are enclosed in a pair of
braces ({ }); and table entries are seperated by a comma (,). (trailing
commas are permitted). For the full Lua syntax, see the Lua documentation

client & server info :

 

soap_services = {

  Info = {

    HTTPVersion = {   -- returns the HTTP request version as a string.
      output = {name = "return",type = "string"},
      lifetime = 0, -- never cache
      call = function() return request:version() end,
    },

    Header = { -- returns a string with the value of the named HTTP header.
      input = {name = "name",type = "string"},
      output = {name = "value",type = "string"},
      lifetime = 0, -- never cache
      -- return empty string if no header
      call = function(s) return request:header(s) or "" end,
    },

    Date = { -- returns the current server date, in UTC
      lifetime = 5, -- date is valid for 5 seconds
      output = {name = "return",type = "date"},
      call = function() return os.date("!%Y-%m-%d") end,
    },

   }
}

a simple calculator :

 

soap_services = {

  Math = { -- service definition

    Add = { -- operation
      input = {{name = "x", type = "double"},{name = "y", type = "double"}},
      output = {name = "return",type = "double"},
      call = function(x,y) return x+y end
    }

    Subtract = { -- operation
      input = {{name = "x", type = "double"},{name = "y", type = "double"}},
      output = {name = "return",type = "double"},
      call = function(x,y) return x-y end
    }

    Multiply = { -- operation
      input = {{name = "x", type = "double"},{name = "y", type = "double"}},
      output = {name = "return",type = "double"},
      call = function(x,y) return x*y end
    }

    Divide = { -- operation
      input = {{name = "x", type = "double"},{name = "y", type = "double"}},
      output = {name = "return",type = "double"},
      call = function(x,y) return x/y end
    }

    Sum = { -- operation to sum an array of doubles
      input = {name = "t", type = "doubleArray"},
      output = {name = "return",type = "double"},
      call = function(t)
             local tot = 0
             for i,v in ipairs(t) do tot = tot+v end
             return tot
           end
    }

    RandomInt = { -- return random integer in the range 0-n
      input = {name = "range", type = "integer"},
      output = {name = "return",type = "integer"},
      call = function(range) return rnd(0,range) end,
    },

  } -- end of Math service definition
} -- end of soap_services definition

 

Download SOAP Examples

The combined Barracuda Embedded Web Server demo and tutorial includes the SOAP demo. Download and unpack the demo. Read the included readme file for more information on how to run the SOAP demo.

When you have tested the SOAP demo, you can unpack and modify the demo.

Note: If you modify the .preload script, the SOAP application must be restarted.

Tip: You can instrument the code with the Lua function trace("your message"). The trace() function accepts multiple arguments and Lua types. The data is sent to the Barracuda trace.

Related Article:
Lua Fast-Tracks Embedded Web Application Development


Complex Circuitry Got You Stumped?

Navigate the world of embedded web servers and IoT effortlessly with our comprehensive tutorials. But if time isn't on your side or you need a deeper dive, don't fret! Our seasoned experts are just a call away, ready to assist with all your networking, security, and device management needs. Whether you're a DIY enthusiast or seeking expert support, we're here to champion your vision.



OPC-UA

OPC-UA Client & Server

An easy to use OPC UA stack that enables bridging of OPC-UA enabled industrial products with cloud services, IT, and HTML5 user interfaces.

Edge Controller

Edge Controller

Use our user programmable Edge-Controller as a tool to accelerate development of the next generation industrial edge products and to facilitate rapid IoT and IIoT development.

On-Premises IoT

On-Premises IoT Platform

Learn how to use the Barracuda App Server as your On-Premises IoT Foundation.

Embedded Web Server

Barracuda Embedded Web Server

The compact Web Server C library is included in the Barracuda App Server protocol suite but can also be used standalone.

WebSocket Server

Microcontroller Friendly

The tiny Minnow Server enables modern web server user interfaces to be used as the graphical front end for tiny microcontrollers. Make sure to check out the reference design and the Minnow Server design guide.

WebDAV Server

Network File System

Why use FTP when you can use your device as a secure network drive.

HTTP Client

Secure HTTP Client Library

PikeHTTP is a compact and secure HTTP client C library that greatly simplifies the design of HTTP/REST style apps in C or C++.

WebSocket Client

Microcontroller Friendly

The embedded WebSocket C library lets developers design tiny and secure IoT applications based on the WebSocket protocol.

SMTP Client

Secure Embedded SMTP Library

Send alarms and other notifications from any microcontroller powered product.

Crypto Library

RayCrypto C Library

The RayCrypto engine is an extremely small and fast embedded crypto library designed specifically for embedded resource-constrained devices.

Embedded PKI Service

Automatic SSL Certificate Management for Devices

Real Time Logic's SharkTrust™ service is an automatic Public Key Infrastructure (PKI) solution for products containing an Embedded Web Server.

Modbus

Modbus TCP client

The Modbus client enables bridging of Modbus enabled industrial products with modern IoT devices and HTML5 powered HMIs.

Posted in Whitepapers