| 1 |
\chapter{The stub-generator}\label{chap:stubgen} |
| 2 |
\index{stub-generator} |
| 3 |
\section{Introduction} |
| 4 |
We discussed the {\tt h\_in} in chapter \ref{chap:h-in}, and we saw that there |
| 5 |
is quite some work involved in creating a simple {\em hello-world} |
| 6 |
example. Much care is needed to be taken to manually marshal and unmarshal the |
| 7 |
data and call the right handler functions. This is error-prone and |
| 8 |
makes it hard to focus on the business logic of your system. |
| 9 |
|
| 10 |
To alleviate that problem, there is the stub-generator or {\tt stubgen}. The |
| 11 |
stub-generator generates the 'plumbing\index{plumbing} code' needed for |
| 12 |
writing ANs\index{application node} and SNs\index{service node}, similar to |
| 13 |
what an IDL\index{interface definition language}-compiler does in the world of |
| 14 |
CORBA\index{Common Request Broker Architecture}. The language that the stub |
| 15 |
generator uses for describing services, is WSDL\index{Web Services Description |
| 16 |
Language} or {\em Web Services Description Language} |
| 17 |
~\cite{Booth:07:WSD}. WSDL is used on the internet to specify the interface |
| 18 |
that web services offer, and is (with some restrictions) a good match for NoTA |
| 19 |
services as well. |
| 20 |
|
| 21 |
In this chapter, we discuss the backgrounds of service definition files and |
| 22 |
the stub-generator; you can find a practical example in the next chapter. |
| 23 |
|
| 24 |
\section{Writing a service definition} |
| 25 |
The starting point for using the stub-generator is to define the service |
| 26 |
definition. You should start with doing some deep thinking about what your |
| 27 |
service should do, and how it should do that. Designing good interfaces is an |
| 28 |
art in itself - see chapter~\ref{chap:development} for some guidelines and |
| 29 |
some pointers to other material. |
| 30 |
|
| 31 |
In chapter~\ref{chap:h-in}, we mentioned that the {\tt H\_IN}-API is inspired |
| 32 |
by the BSD-sockets API, but that you should be careful \emph{not} to make too |
| 33 |
many assumptions about the {\tt H\_IN}-API based on knowledge of BSD-API. The |
| 34 |
same is true for the WSDL; reading the WSDL specifications and applying all |
| 35 |
that to your NoTA-WSDL files will generally not work. NoTA supports a subset |
| 36 |
of WSDL 1.1. However, this chapter should give you enough information to work |
| 37 |
with NoTA-flavor of WSDL. |
| 38 |
|
| 39 |
\subsection{Contracts}\index{contract} |
| 40 |
One, somewhat surprising feature of the NoTA service definitions, is that they |
| 41 |
describe \emph{both} the client-side and the server-side. That is, the service |
| 42 |
definition file describes all the messages the server will accept, but also |
| 43 |
those for the client. In other words: {\bf a service definition is a contract |
| 44 |
between a Service Node and an application node}. It stipulates the |
| 45 |
obligations of {\bf both} parties. |
| 46 |
|
| 47 |
We emphasize this, because it is different from systems like CORBA or |
| 48 |
COM\index{Component Object Model}, where the service (or interface) |
| 49 |
definitions {\em only} describe the behavior of the 'server'. |
| 50 |
|
| 51 |
\subsection{Using WSDL} |
| 52 |
The NoTA {\tt stubgen} uses a WSDL\index{Web Services Description |
| 53 |
Language}-based format for describing services. WSDL uses XML\index{extensible |
| 54 |
markup language} as its substrate, which makes it a rather verbose format. On |
| 55 |
the other hand, it can easily be processed with automated tools. |
| 56 |
|
| 57 |
A service-description file looks something like this: |
| 58 |
\begin{lstlisting}[language=XML,numbers=none] |
| 59 |
<?xml version=¨1.0¨ encoding=¨UTF-8¨> |
| 60 |
|
| 61 |
<definitions .....> |
| 62 |
|
| 63 |
<types> |
| 64 |
..... some user-defined types .... |
| 65 |
</types> |
| 66 |
|
| 67 |
<message .... > |
| 68 |
.... message 1 details .... |
| 69 |
</message> |
| 70 |
|
| 71 |
<message .... > |
| 72 |
.... message 2 details .... |
| 73 |
</message> |
| 74 |
|
| 75 |
</definitions> |
| 76 |
\end{lstlisting} |
| 77 |
Let's go through these section shortly, and discuss them in more detail after |
| 78 |
that. |
| 79 |
\begin{itemize} |
| 80 |
\item {\tt definitions} - this section includes meta-information about |
| 81 |
this service definition file, and may refer to outside resources; |
| 82 |
\item {\tt types} - this (optional) section defines types specific for |
| 83 |
this service definitions; |
| 84 |
\item {\tt messages} - this section defines the actual messages that we |
| 85 |
can send or receive. This is the most interesting section of the service |
| 86 |
description. |
| 87 |
\end{itemize} |
| 88 |
|
| 89 |
\subsubsection{Definitions} |
| 90 |
The {\tt definitions} part specifies meta-information about the service |
| 91 |
definition. These are currently \textbf{ignored} by the stub-generator, so |
| 92 |
let's no go into them here. |
| 93 |
|
| 94 |
\subsubsection{Types} |
| 95 |
The \texttt{types} defines additional types for use in the service |
| 96 |
definitions. It may include simple types (think: {\tt typedef}), complex types |
| 97 |
(think: {\tt struct}) and enumerations (think: {\tt enum}). Obviously, you are |
| 98 |
not {\bf required} to define your own types. |
| 99 |
|
| 100 |
For an example of this, we can look at the service definition for the Resource |
| 101 |
Manager (we'll discuss the Resource Manager in chapter~\ref{chap:stubgen}); |
| 102 |
you can find the full service definition for the Resource Manager in |
| 103 |
appendix~\ref{chap:rm-sis}. Here is the \texttt{types}-part (edited for |
| 104 |
readability): |
| 105 |
|
| 106 |
\begin{lstlisting}[language=XML] |
| 107 |
<types> |
| 108 |
<!-- Status options. --> |
| 109 |
<simpleType name="sid_t"> |
| 110 |
<restriction base="nota:uns16" /> |
| 111 |
</simpleType> |
| 112 |
|
| 113 |
<simpleType name="status_t"> |
| 114 |
<restriction base="nota:uns32"> |
| 115 |
<!-- Operation completed successfully. --> |
| 116 |
<enumeration value="0x0000">S_OK</enumeration> |
| 117 |
|
| 118 |
<!-- Errors: --> |
| 119 |
<enumeration value="0x1000">E_GENERAL_ERROR</enumeration> |
| 120 |
<enumeration value="0x1010">E_SERVICE_NOT_FOUND</enumeration> |
| 121 |
<enumeration value="0x1020">E_UNKNOWN_EVENT</enumeration> |
| 122 |
<enumeration value="0x2000">E_INSUFFICIENT_RIGHTS</enumeration> |
| 123 |
</restriction> |
| 124 |
</simpleType> |
| 125 |
|
| 126 |
<!-- Service list type. --> |
| 127 |
<complexType name="servicelist_t"> |
| 128 |
<sequence> |
| 129 |
<element name="service_desc" type="nota:bdata" minOccurs="0" |
| 130 |
maxOccurs="unbounded" nillable="true"/> |
| 131 |
</sequence> |
| 132 |
</complexType> |
| 133 |
</types> |
| 134 |
\end{lstlisting} |
| 135 |
|
| 136 |
Looking through this example: |
| 137 |
\begin{itemize} |
| 138 |
\item lines 2-5 specify a {\tt simpleType}: {\tt sid\_t} is a '{\tt |
| 139 |
typedef}' for a {\tt nota:uns16}-type. We listed the NoTA-types in |
| 140 |
table~\ref{table:service-signals}; the corresponding name in the service |
| 141 |
definition is that name in small letters, namespaced with {\tt nota:}. So, |
| 142 |
in this case, we get {\tt nota:uns16}. |
| 143 |
|
| 144 |
In the WSDL way notation, we say that |
| 145 |
the {\em base restriction} on the {\tt sid\_t}-type is that its values must |
| 146 |
be in the range of a {\tt nota:uns16}; |
| 147 |
|
| 148 |
\item lines 7-18 specify another {\tt simpleType}: {\tt status\_t} is an |
| 149 |
´{\tt enum}'. Line 8 says that the base-type here is a {\tt |
| 150 |
nota:uns32}\footnote{apparently, the designer was expecting {\em many} |
| 151 |
event codes...}. |
| 152 |
|
| 153 |
After that, some the {\tt enumeration}-element defines |
| 154 |
named values for various states. Note that that they are all part of the |
| 155 |
{\tt restriction}; |
| 156 |
|
| 157 |
\item Finally, lines 21-26 define a {\tt complexType}, a named type that |
| 158 |
consist of {\tt element}s and {\tt sequence}s of elements. Think {\tt |
| 159 |
struct}. |
| 160 |
|
| 161 |
An {\tt element} is a named value with a certain type; in this case a {\tt |
| 162 |
service\_desc} of type {\tt nota:bdata}. The astute reader will note that |
| 163 |
that type is not defined; indeed. {\tt nota:bdata} can mean either {\tt |
| 164 |
BDAT1} or {\tt BDAT2}, and both AN an SN must support {\bf both}; |
| 165 |
stubgen-generated code does this automatically. |
| 166 |
|
| 167 |
You can also specify attributes such as {\tt minOccurs}, {\tt maxOccurs} and |
| 168 |
{\tt nillable}; these attributes can be useful for descriptive purposes, but |
| 169 |
they are currently ignored by the stub-generator. |
| 170 |
|
| 171 |
The {\tt sequence}-tag tells us we have a {\em sequence} of $0~\ldots~n$ |
| 172 |
of such {\tt |
| 173 |
service\_desc}-elements. |
| 174 |
\end{itemize} |
| 175 |
|
| 176 |
\subsubsection{Messages} |
| 177 |
We continue with a discussion of \emph{messages}. The service definition |
| 178 |
describe all messages that nodes can sent each other. As we already mentioned, |
| 179 |
the service definition is like a two-party contract, and it describes the |
| 180 |
messages of \textbf{both sides}, service node and application node. |
| 181 |
|
| 182 |
We turn to the service definition of \emph{resource manager} (to be discussed |
| 183 |
in chapter~\ref{chap:rm}) once more for an example; we look at some messages |
| 184 |
dealing with \emph{registration}. As we said before, there's no need to |
| 185 |
understand what the RM does, we just want to look at the messages. |
| 186 |
|
| 187 |
\begin{lstlisting}[language=XML] |
| 188 |
<!-- Service message interface --> |
| 189 |
<!-- Registration --> |
| 190 |
<message name="Register_req" code="0x0001" direction="in"> |
| 191 |
<documentation> |
| 192 |
Message for registering a service. |
| 193 |
</documentation> |
| 194 |
<part name="ontology_name" type="nota:bdata"> |
| 195 |
<documentation> |
| 196 |
Name for the used service ontology (e.f. "NoTA"). |
| 197 |
</documentation> |
| 198 |
</part> |
| 199 |
<part name="service_desc" type="nota:bdata"> |
| 200 |
<documentation> |
| 201 |
Service description following the defined ontology |
| 202 |
(e.g. "NoTA_ServiceName_R01_01_v02"). |
| 203 |
</documentation> |
| 204 |
</part> |
| 205 |
<part name="cert_reg" type="nota:bdata"> |
| 206 |
<documentation> |
| 207 |
Service registration certificate. |
| 208 |
</documentation> |
| 209 |
</part> |
| 210 |
</message> |
| 211 |
|
| 212 |
<message name="Register_cnf" code="0x0002" direction="out"> |
| 213 |
<documentation> |
| 214 |
Returns SID and status for the registration request. |
| 215 |
</documentation> |
| 216 |
<part name="status" type="tns:status_t"> |
| 217 |
<documentation> |
| 218 |
Error code (S_OK, E_GENERAL_ERROR, E_INSUFFICIENT_RIGHTS). |
| 219 |
</documentation> |
| 220 |
</part> |
| 221 |
<part name="sid" type="nota:sid_t"> |
| 222 |
<documentation> |
| 223 |
Device context unique Service Identifier (SID). |
| 224 |
</documentation> |
| 225 |
</part> |
| 226 |
<part name="cert_dereg" type="nota:bdata"> |
| 227 |
<documentation> |
| 228 |
Certificate needed for deregistering the service |
| 229 |
(NULL string = no certificate needed). |
| 230 |
</documentation> |
| 231 |
</part> |
| 232 |
<part name="cert_act" type="nota:bdata"> |
| 233 |
<documentation> |
| 234 |
Certificate for activating the service |
| 235 |
(NULL string = no certificate needed). |
| 236 |
</documentation> |
| 237 |
</part> |
| 238 |
</message> |
| 239 |
\end{lstlisting} |
| 240 |
|
| 241 |
The example show two messages. The first is \texttt{Register\_req}, sent by |
| 242 |
the application node to the Service Node (the RM, in this case). The second |
| 243 |
message is \texttt{Register\_cnf}, which is a confirmation message sent by |
| 244 |
the Service Node back to the Application node, to report of the |
| 245 |
success/failure of the \texttt{Register\_req}-message. |
| 246 |
|
| 247 |
Let's go through the example. First, \texttt{Register\_req}. |
| 248 |
|
| 249 |
\begin{itemize} |
| 250 |
\item lines 3-22 define the \texttt{Register\_req}-message. In line 3 the |
| 251 |
\texttt{message}-element is opened with 3 important elements: |
| 252 |
\begin{itemize} |
| 253 |
\item \texttt{name=''Register\_req''}: unsurprisingly, this defines the |
| 254 |
message name; note that the message name is only there for it's |
| 255 |
informational value; it's not used on the protocol-level; |
| 256 |
\item \texttt{code=''0x0001''}: this defines the signal-id; nodes use the |
| 257 |
signal-id (not the \texttt{name}) to identify messages. The signal-id must |
| 258 |
be unique for a service definition; Note that the \texttt{code}-attribute |
| 259 |
is NoTA-specific and \textbf{not} part of WSDL; |
| 260 |
\item \texttt{direction=''in''}: the \texttt{in} value means that this |
| 261 |
is an \emph{incoming message} for the \textbf{service node}. The |
| 262 |
\texttt{direction} is always from the SNs perspective. |
| 263 |
\end{itemize} |
| 264 |
\item After that there is the aptly-named \texttt{documentation}; this |
| 265 |
contains some information for human consumption, and ignored for anything |
| 266 |
else. |
| 267 |
\item Then follow some \texttt{part}-elements. Each of these describe a |
| 268 |
parameter, with \texttt{name} and \texttt{type} attributes describing |
| 269 |
respectively the parameter name and its type. As before, the |
| 270 |
\texttt{name}-attribute is only there for informational purposes. The |
| 271 |
\texttt{type}-attribute determines what kind of data the message contains; |
| 272 |
the type can be one of the basic NoTA types, or one of the types we defined |
| 273 |
before in the \texttt{types}-section discussed before. \texttt{part}s can |
| 274 |
also contain \texttt{documentation}. |
| 275 |
\end{itemize} |
| 276 |
|
| 277 |
Without the XML-verbosity, the message looks something like: |
| 278 |
\begin{verbatim} |
| 279 |
in: [0x0001] Register_req (nota:bdata ontology_name, |
| 280 |
nota:bdata service_desc, |
| 281 |
nota:bdata cert_reg); |
| 282 |
\end{verbatim} |
| 283 |
|
| 284 |
Now, let's look at the second message, \texttt{Register\_cnf} (line 24-48) |
| 285 |
Most of the above also applies there, but let's focus on the differences. |
| 286 |
|
| 287 |
\begin{itemize} |
| 288 |
\item In line 24, we give \texttt{Register\_cnf} its unique signal-id, |
| 289 |
and, importantly, we define the \texttt{direction} to be \texttt{out}. That |
| 290 |
means that is a message for the \emph{application node} - the AN must accept |
| 291 |
it; |
| 292 |
\item The other parts of the message are similar to what we have seen |
| 293 |
before. |
| 294 |
\end{itemize} |
| 295 |
|
| 296 |
Using our made-up notation, the function looks something like: |
| 297 |
\begin{verbatim} |
| 298 |
out: [0x0002] Register_cnf (tns:status_t status, |
| 299 |
nota:sid_t sid, |
| 300 |
nota:bdata cert_dereg, |
| 301 |
nota:bdata cert_act); |
| 302 |
\end{verbatim} |
| 303 |
|
| 304 |
\subsubsection{WSDL: concluding} |
| 305 |
This concludes our initial discussion of service definition files (they will |
| 306 |
be back!). One important thing we did not explicitly mention is the importance |
| 307 |
of {\em comments}; in XML\index{extensible markup language}, comments look |
| 308 |
like {\tt <!-- comment -->} and they priceless when trying to comprehend the |
| 309 |
thoughts of others when they designed the service - or even to comprehend your |
| 310 |
own thoughts, a few months later. |
| 311 |
|
| 312 |
The information in this section should be sufficient for you to write your own |
| 313 |
service definitions. We can recommend the guidelines in |
| 314 |
chapter~\ref{chap:development}. As said, designing interfaces is a kind of |
| 315 |
{\em art} - it's always good to think of the poor {\em other} programmers that |
| 316 |
will have to use your interfaces\ldots. |
| 317 |
|
| 318 |
\section{The stub-generator} |
| 319 |
We went through the details of service definition files. Service definitions |
| 320 |
are an important communication tool for describing your services to others, |
| 321 |
and reason about them on a functional rather than implementation |
| 322 |
level. However, and even more important reason for having the service |
| 323 |
definition files if for using the \textbf{stub-generator}. |
| 324 |
|
| 325 |
The stub-generator is a tool that reads service definition files and generates |
| 326 |
the 'plumbing' code for both application nodes and service nodes. As we've |
| 327 |
seen in chapters~\ref{chap:h-in}~and~\ref{chap:h-in-example}, programming |
| 328 |
nodes \emph{by hand} can be quite tedious. The stubgen can ease the burden |
| 329 |
significantly. |
| 330 |
|
| 331 |
The best way to find out what the stubgenerator actually generates, is to go |
| 332 |
through the generated files of some simple example. But in short, the stub |
| 333 |
generator takes the NoTA messages and transfers those in functions; so, |
| 334 |
instead of determining the bytes to send, you call a generated function. This |
| 335 |
function will then take care of the actual conversion of its arguments into |
| 336 |
sequences of bytes. The stubgenerator makes message passing (to some extent) |
| 337 |
seem like ordinary function calls. |
| 338 |
|
| 339 |
\subsection{\texttt{nota-stubgen3.pl}} |
| 340 |
If you have installed NoTA on your system (if needed, see |
| 341 |
appendix~\ref{chap:installation}), there will be a tool called |
| 342 |
\texttt{nota-stubgen3.pl}. |
| 343 |
|
| 344 |
When we run it without any arguments, it prints the following: |
| 345 |
\begin{verbatim} |
| 346 |
Usage: |
| 347 |
nota-stubgen3.pl {-option value} path wsdl_file {xsd_file} [output_file] |
| 348 |
|
| 349 |
Options may be |
| 350 |
-platform name the name of the platform for which the files |
| 351 |
will be generated |
| 352 |
Valid platform names are symbian, posix |
| 353 |
Arguments |
| 354 |
path path where the generated files will be created |
| 355 |
wsdl_file name of the wsdl file of which the stub code is to be |
| 356 |
generated |
| 357 |
xsd_file optional; name of the xsd files with additional type |
| 358 |
definitions |
| 359 |
The file extension must be xsd, because they are |
| 360 |
recognised as xsd files based on the extension |
| 361 |
output_file optional; name for the output files |
| 362 |
|
| 363 |
Example: |
| 364 |
nota-stubgen3.pl -platform posix OutputDir file.wsdl typedef.xsd outname |
| 365 |
giving minimum number of parameters: |
| 366 |
nota-stubgen3.pl -platform posix . file.wsdl |
| 367 |
\end{verbatim} |
| 368 |
|
| 369 |
We're assuming we are on a \texttt{posix}-platform here. Suppose we have a |
| 370 |
service definition file \texttt{myservice.xml} in the current directory. We |
| 371 |
can simply run: |
| 372 |
\begin{verbatim} |
| 373 |
$ nota-stubgen3.pl -platform posix . myservice.xml |
| 374 |
\end{verbatim} |
| 375 |
Except for the somewhat unexpected '\texttt{.}'-parameter (the current |
| 376 |
directory), it is quite straightforward. Running this will create: |
| 377 |
\begin{itemize} |
| 378 |
\item \texttt{myservice\_service.c} and \texttt{myservice\_service.h}: |
| 379 |
these are the \emph{stubs} for the Service Node implementation; |
| 380 |
\item \texttt{myservice\_user.c} and \texttt{myservice\_user.h}: |
| 381 |
these are the stubs for the application node implementation; |
| 382 |
\item \texttt{myservice\_common.h}: contains common definitions for use by |
| 383 |
both the AN and SN implementations. |
| 384 |
\end{itemize} |
| 385 |
|
| 386 |
You will need to combine these stub-files with your own implementation of the |
| 387 |
functions, and compile them to get working programs. We feel that is best |
| 388 |
explained with an example: in the next chapter we will revisit the |
| 389 |
Caesar-example of chapter\ref{chap:h-in-example} and re-implement it using the stub-generator. |
| 390 |
|
| 391 |
\section{Questions} |
| 392 |
\begin{enumerate} |
| 393 |
\item What are the advantages of using the stub-generator compared to |
| 394 |
writing the code 'by hand'? Are there any disadvantages? |
| 395 |
\item Are the NoTA service definitions compatible with WSDL? If not, |
| 396 |
what's the difference? |
| 397 |
\end{enumerate} |