Embedding Micro Service Workflows in Web Content #5

Hello,
I’ve managed to complete the plugin with all the described features (and some minor drawbacks) so this is gonna be my last post on this topic I guess.
My last post was mainly about defining and assigning values to variables via the abbr-design-pattern.
I also explained that only primitive variables can be defined this way, well, I was wrong. ;)
By the time I had finished the plugin with all the relevant data structures to hand over resp. receive complex variables to/from web services I realized that it isn’t much effort to also define such variables in the definition tag and assign the complex data later on.
So if you want to define a complex variable, you just have to write the keyword “struct” in front of its name:

null

So here i, j and k are primitive variables and person2 is a complex variable (like a struct in C but without having defined the structure of the content yet).

But how are complex data structures actually defined now? Let’s have a look. It’s pretty straight forward actually: They are gonna be defined inside the input tag. Remembering the grammar from posting 1, an invocation instance has 3 ways to receive input – the static tag where all the content can also be seen by the user (the actual idea of microformats), the user tag where values can be inserted via a popup, and the ws tag where the output of the previous invoked web service is stored.
Complex variables can now be defined either inside the static or the user tag:

null

In this example, we have defined the input for the web service with category, x and y as primitive variables and person as complex variable (since it consists of sub elements). All these values can be accessed with the $-syntax, so $x would evaluate in ’2′ and $person.name.nname would result in ‘Doe’. So here you’ve seen how you can access values inside a complex variable – just separate the structure with “.” like in ordinary programming languages.

You might have seen a bit of redundancy when it comes to the values of the variables. This is one of the drawbacks I’ve mentioned before. As you can see, “human” is defined inside the abbr-tag _and_ also inside the title attribute, with the only difference that it is surrounded with quotes. I’m going to explain this a bit:

By default, the plugin takes the value which is defined in the title attribute (since you can write it in a user hidden and machine understandable format and the user will still see a “friendly value” on the html page; like the value of y which is 3.1415… and the user only sees Pi as actual visible content of the html page – all such constants are btw a good example for default values which can be defined once and reused later on).
If the title attribute is omitted, then the value inside the abbr-tag is taken (which the user can see).
So now you may be wondering: I can take the value “human” just as it is form the abbr-tag, why do I have to write it inside title-attribute when there’s no difference at all? Well, the reason is, that all these assignments are going to be evaluated by the eval()-function (so you could also write 2+1.1415… inside the Pi-title and it wouldn’t make a difference). Since I don’t know whether the value of the abbr-tag shall be treated as number or string, I have to surround strings with quotes in order to make it understandable for the eval()-function which whould treat “human” as an (undefined) variable and therefore throws an exception. As you can see, the value of x doesn’t need to be also inserted in the title-attribute, since it’s a number.
So now you migh continue thinking: Just parse the content of the abbr-tag to determine whether it’s a number or not, but look at this:
0660/1234567 is a (phone) number. I don’t want it to be part of some calculation- especially not 660 divided by 1234567 which eval() would insist on, therefore I would have to surround it with quotes.
Well, there would be of course certain ways to manage this problem without this redundancy, but then I would have to analyze each value specifically and since this is (again) a prototype, I decided to just stick with the quotes which makes my life simpler.

I hope I could explain this issue to you appropriately, so let’s continue with more interesting stuff:

I changed the semantic of the input tag a little bit.
Before introducing variables, all the data that was inside the input tag (the static, user and ws tags) was automatically also the input for the web service which is bound to the invocation instance. So first of all you couldn’t just hand over values which are not meant to be seen by the user (since the static values are also shown on the web page and user values are inserted via a popup by the user).
Furthermore, the order of all this data had to be the same order as the web service wants it (when thinking about the parameter sequence), which is more than unflexible.
So I changed the semantic of the input tag in such a way, that it is more used to define (also complex) variables rather than directly say: This is the input of the web service. Period.

The parameter sequence can now be defined independently via the invoke-tag:

null

Pretty self explaining, the title attribute defines the order of the parameters which shall be handed over to the web service and the class attribute defines in which variable the result of the web service shall be stored to become accessible later on.
Inside the title attribute no eval()uation takes place (so you cannot hand over 2+2 for example; to do this, you first have to define a variable, assign 2+2 to it and write the name of the variable inside the title attribute). The reason for this is simple: The plugin is designed in such a static way (again a drawback but think about the keyword prototype) that it doesn’t know anything about the invoked web service except it’s name and where to find it. It has no clue about its interface, the WSDL file, so the name of the parameters which need to be mentioned inside the transfered SOAP message must be those of the invoke-tag’s title attribute. So now you know why handing over 2+2 directly would result in an error.

As you can see in the example, primitive and compex variables can now be handed over to the web service. In this case, also a complex structure is returned and stored in person2.

Omitting the whole invoke-tag results in not invoking the web service which is bound to the invocation instance at all. This can be useful when you just want to split up the workflow in 2 parts (via the if-then-else tag) and do not need any additional invocation of a web service.

Before introducing variables, only the return value of the invocated web service could be compared inside the condition of the if-then-else tag; and only with some static values without combinations of logical operators.
Now the condition can be of arbitrary complexity, as long as the eval() function understands it. So you can use your defined variables in any logical meaningful combination.

For example:

null

The popup-tag is also more flexible now: Arbitrary information can now be shown to the user.

The code snippet

null

would result in “John Johnson’s SVNR is 1234010101.”

A few words about passing values between invocation services. It is now possible to hand over several values to other invocation instances rather than only the result value of the invocated web service.

A little example:

null

Invocation instance A calls invocation instance B and hands over 3 parameters: The SVNR from person2, some calculation which gets evaluted before transmission, and also a complex variable (remember, person2.name consists of vname and nname).

These 3 values get stored as “local variables” (“instance variables” would be the better terminology since they are stored inside the instance scope) of invocation instance B which are named a,b and c (the last one is automatically also a complex variable) and don’t need to be defined separately. Again, like you are used to.

Let’s finally talk about the time when to initialize and reset variables.

On browser startup every scope is empty of course. When a user opens an html page, an additional and also empty page scope will be created (identified by the page’s URL).
Since it is possible to create and initialize variables outside of any invocation instance (–> global and page scope variables), I had to decide when these variables are going to be set: either when the page loads or when the first invocation instance is actually executed on this page. I’ve chosen the latter due the following reason: Let’s say page A defines and sets a global variable which is also used on another page B inside an invocation instance. If I had chosen to set variables which are outside of any invocation instance on page load, then the invocation instance on page B would instantly work with another value of the global variable even when page A reloads. Reloading a page shouldn’t actually change any global variables in my mind, only actual executions of invocation instances. So it would be possible to set up a page with some global variables which can get reset when invoking the page’s “reset”-invocation instance, for example.

Since it is possible to have serveral pages open at the same time, there can also exist several different page scopes (but only 1 is active of course).
Closing a tab doesn’t reset its page scope though, since the same page could be open in another tab which still needs those page scope variables. On the other hand, refreshing a page resets all page scope variables.
Since all types of variables aren’t persistent (except the special $context variable), closing the whole browser results in losing all variable values, even those in global scope.

Keep in mind that the plugin was not developed to show friendly error messages when the workflow doesn’t match its grammar and there are also some more additional restrictions concerning variables (which I won’t desdribe in detail here).

Finally I want to say that it was fun creating this plugin because there weren’t any detailed guidlines on how to actually do it – just a “simple” and maybe fuzzy requirment: “introduce variables, and all the things you can do with them” which offered me a lot of liberties how the workflow should look like – with all it’s features and restrictions.

If you are interested in this topic, my bachelor thesis will surely describe the whole idea in more detail, including the full grammar of the new workflow.

Thanks for reading this bunch of updates.
Tom

, , , , ,
  • Delicious
  • Facebook
  • Digg
  • Reddit
  • StumbleUpon
  • Twitter

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>