Leveraging off of web services

Posted by Thomas Mercer-Hursh on 28-May-2008 13:56

Recently on PEG we had another round of discussions about encapsulating TTs and PDS in objects versus various ideas for how to make them available outside the object.

One of the themes of that discussion, which relates back to the recent one here on OO versus the relational features in ABL, ... well, at least my themes ... is that in many cases, particularly within a session, the right answer for what one passes when the result of a method is complex is not a TT or PDS, but another object. E.g., if one has a Set object containing a TT and there is a method to return a row, then it should return an entity object for that row, not a buffer. Or, if one is returning a subset of the total set, then one returns another set object, not a TT or PDS.

A second theme is that there are times when the results are likely to need to go across a wire, whether simply to a client or on an ESB, and in those cases the indicated from for passing such data seems to me to be XML, since it is technology neutral and can be used with any technology on the other end and with any transport mechanism.

After this morning's webinar on web services, I was impressed with what PSC has done to make for seamless transparent connections between familiar ABL structures on the inside and web services modes on the outside. I wonder if there is a way that we could leverage this capability even when there was no web service involved, thus making this mapping in and out of familiar and useful ABL structures transparent and easy.

This is a bit vague, I realize, but maybe if we talk about it a bit it will either crystalize into something specific or be revealed as pointless musing!

All Replies

Posted by Admin on 28-May-2008 19:57

A simple solution could be;



1) To mark the class as Serializable (similar to .Net/Java
concept),



2) Enhance the compiler to warn/error on an attempt to pass a
non-Serializable class across the appserver boundary [strongly
named reference @ compile, handle reference @
runtime/optional]]>

]]>

3) The developer of the class to provide methods within the

class to return a string representation of the

serialized class AND accept a string an deserialize it into the

existing class.The WebServices are could also then used these 'developer built'

methods to provide a means of passed complex data types to/from

soap messages that was not seen as a proprietary psc format - often

the soap message takes on a different form that the underlying TT

.

Posted by Thomas Mercer-Hursh on 28-May-2008 20:55

You seems to get just how powerful this concept could be!

FWIW, since 10.1B I have architected my business entity classes with three overloaded constructors. One takes no arguments and is use when creating a new one of something. One takes a list of parameters corresponding to all properties of the class for us in instantiating either from the database or a data source which which has already collected all the necessary values. And the third takes an XML input with all of the values for instantiation over the wire. Minimal program generation is needed to do this with no enhancements in the language and the serialize part is pretty easy too, even with out a WRITE-XML method for objects.

But, I think this needs to extend to methods, i.e., a way for the method to use a native Progress mode locally, but to use a serializable form over the wire ... or, at least that might be the appearance. If one had automated, behind the scenes generation of XML for a TT output ... which appears to exist now for the web service functionality, whose to say that this shouldn't be the normal mode even with another ABL object. Yes, one would want a special keyword to indicate this, but just think about it ... the two could actually have different signatures, but exchange the same message!

Posted by Admin on 28-May-2008 22:29

The reason I moved away from the constructor style was to enable me to use this on 3rd party class/objects ... following on from using the same concept on .Net objects you could inherit the base [non PSC serializable away class/object] add these methods and have a compliant class/object. I guess you could also use this to cover your case examples of different signatures - base class to do the BL work, but inherited under different guises with appropriate serialization methods.

The second reason for the methods would be used in cases of static classes. By 'static' I refer to a class which contains BL but data comes from a TT handle supplied during invokations - rather than have the load lag times seen with a 'class per row', having only a single instance [static] class being loaded once. In these cases I could not use a constructor, but could serialize/deserialize a collection of rows from an external TT (supplied via a handle reference prior to the serialization call).

From PSC view the coding effort would be minimal (well, compared to other alternatives) - plus it would work in XMLNode insertion, soap encoding (for anything other than simple types), appserver calls and inter VM calls (eg between embedded .Net objects and Eclipse calls within the IDE itself). To top it off it would place the control in the developers hands to manage the serialization - rather than a default rule engine (albeit requiring more coding effort by the developer). Using the C# concept of a [Serializable] attribute for compile/runtime checking would also help bring the concept into an existing understood concept (and make its adoption easier).

Have PSC internally move anywhere on using a class as a datasource to .Net visual elements within the New UI structure? Has the Progress.Data.BindingSource structure been expanded to handle any of the class interaction? From the NewUI/.Net interaction this could become as simple as;

UIForm = NEW Progress.WinUI.Form( ).
UIXml = NEW System.Xml.XmlReader().
UIXml:Value = MyClass:Serialize(Format:XML).
UIData = NEW System.Data.DataTable().
UIData:ReadXML(UIXml).
UIGrid = NEW System.Windows.Forms.DataGridView( ).
UIGrid:DataSource = UIData.
UIForm:Controls:Add(UIGrid).

the MyClass:Serialize would understand the XML format and return a string containing the appropriately formatted XML ... even to the point of translating enum & null type conversions (as it is developer custom code).

Posted by Thomas Mercer-Hursh on 29-May-2008 11:19

If you are talking about subclassing .NET objects with ABL objects, I think there is a rather bigger problem to solve than anything I am talking about. It seems to me that all the operations which I am discussing already exist and it is simply a question of putting the functionality in the right place. This is not to say that I don't wish one could subclass a non-ABL object, I'm just being realistic about whether it is likely to happen.

Indeed, given the desirability of UI and BL separation, I am a lot more concerned about upping the functionality of the ABL, e.g., multi-threading or some imitation thereof, than I am in trying to mix in non-ABL objects. I still like the idea of writing the whole application in ABL, except perhaps the UI.

I'm not sure that your notion of static BL with a handle to a non-static data instance is the way I would go. Possible, but I am more inclined to solve the problem of large collections of entity objects by creating a set object and inside the set object using the TT and PDS. Then, one has one set of BL for the set and one instance for any entity object which is in play, but no reason for large numbers of entity objects to be in play at the same time.

And, couldn't you do this with 10.1C as is?

In re serializing the objects, I think this is already quite simple in most cases and the sort of thing I would expect to have generated, even from very early stages in the development of generation. What I was raising here was more the idea of automatically serializing the results of individual methods. Still not hard to do by hand, but the web services stuff made me wonder if it couldn't be done transparently.

Posted by Admin on 29-May-2008 20:21

Agree ... can all be done now. I just think it would be great if a common standard (ie PSC driven) way of doing this was announced/proposed - rather than everyone going down a similar [ but not the same] path, rolling it out and only then have the core functionality released (and odd looks as to why the new features are not adopted).

I would also hope that the common method could be applied across a number of situations, including WebServices, xmlnodes, appserver and NewUI [hey, need a name for this]. It can all be done, but more often in a non standard and more code intensive manner.

The reason I keep raising the NewUI side is that .Net requires binding to ABL data - for both mixed [abl/clr] client and pure .Net client [and other non abl environments], and it forms a good test bed as it is a mix of environments where only one side can be influenced. Data interchange should be a common layer, below the communications layer (appserver/wsa/clrhost/eclipse/sockets).

Thinks we are on the same page. I will keep silent and await the rush of other voices

Posted by Admin on 30-May-2008 01:37

> if one has a Set object containing a TT and there is a method to
> return a row, then it should return an entity object for that row,
> not a buffer.

The tricky part from the 4GL engine part of view would be scoping this buffer to the entity object. Since the 4GL has no such thing as a "row object", it's always connected to a buffer. So you have an entity wrapping the temp-table and handing out related child entity objects wrapping a particular row. How are you managing the scope/lifetime of these objects? Once you delete the temp-table/PDS, the entities will reference a stale buffer.

Posted by Admin on 30-May-2008 01:47

> After this morning's webinar on web services, I was impressed
> with what PSC has done to make for seamless transparent
> connections between familiar ABL structures on the inside and
> web services modes on the outside.

The 4GL AppServer does that very well for (persistent) procedures. The trap here is not to expose a persistent procedure in a unbound stateless AppServer. After all every call to this AppServer could mean a call to another AppServer instance.

This shows the potential problem with exposing classes. It will be the EJB deja vu of Java: remotely chatting with too fine grained objects. This has two problems:
- you're binding yourself to an (App)Server (on the other hand, that's what we do all the time with databases ;-)

- you have no control over the object graph in memory, because that can grow and grow.

- you might not be aware of the marshalling taking place. And there might be an incredible amount of "remoted object", living on the server, but accessed from the client

On the other hand if you're only talking about an easy way to marshall 4GL "data transfer objects", so classes without behavior just state, than you could ask yourself why not use a PDS.

Posted by Admin on 30-May-2008 02:00

> FWIW, since 10.1B I have architected my business entity classes
> with three overloaded constructors.

I hope you still carefully design the public API in case you want to support a remoted scenario. I mean how would a typical use case like entering a customer look like in your architecture when the entities are running inside an AppServer and your UI is running remotely from the AppServer? What do you want to expose to the UI? You probably don't want to expose/marshall the (internal) CustomerEntity, since that object potentially requires database access and potentially other objects when you manipulate it.

In .Net I have designed some proxy classes, but here I explicitly control access to the remote object.

Posted by Thomas Mercer-Hursh on 30-May-2008 11:51

I just think it would be great if a common standard (ie PSC driven) way of doing this was announced/proposed - rather than everyone going down a similar path, rolling it out and only then have the core functionality released (and odd looks as to why the new features are not adopted).

Unfortunately, that would require a different attitude toward discussing product plans than PSC has display in the past.

NewUI .

There is one. Officially it is the Advanced UI.

In the ABL info exchange last year there was a lot of interest in going beyond the current Advanced UI coupling of .NET UI with ABL data to support other kinds of non-UI coupling and other languages than .NET, specifically Java. The response lead me to think that, while such ideas had occurred to PSC, any realization was far enough off to be off the radar.

I think that the business case we need to build up here is how is all of this going to get used. To me, the Advanced UI is based on the premise that there are a substantial number of sites which have existing ABL GUI clients who could benefit from selective upgrading of individual windows with .NET controls. I have no doubt that is a real use case and one of the things that is especially notable about it is that this solution allows substantial upgrade to be done selectively without the need to change the entire application nor to do any significant re-architecting. I.e., compared with other sites which need UI and BL separation in order to put on a new UI, it is CHEAP!

Now, there are some who feel that they want to mix .NET or Java with ABL on the same platform for non-UI purposes. Certainly there are specialized cases where that would be desirable, but I'm not sure how broadly applicable the use case is.

The much larger use case, I think, is the one of unlike technologies which are not one the same platform. And, of course, we have this with both Open Client and Sonic. What we don't have is a technology which allows tightly coupled sessions to interoperate closely, i.e., an alternative to true multi-threading, but there I would be happy to have the sessions all be ABL.

My stimulus for starting this topic has a lot to do with trying to encourage people to think in OO terms, i.e., real encapsulation, instead of passing complex data structures all over the place, albeit in increasingly efficient ways with recent releases. While efficient, this blurring of encapsulation seems wrong to me and so I look to find patterns and technologies which will help people to see how to preserve the encapsulation and yet achieve the functionality they need. And, of course, one of the motivators there is the potential for distributing things across multiple platforms or sessions where the native data structure is either not sharable or may not be the optimum way of sharing in any case.

So, one of the questions I am raising here is if we can't leverage the web services technology more generally in order to allow people to more effortlessly and transparently achieve a technology neutral communication between components.

Thinks we are on the same page

Same book, at least.

I will keep silent and await the rush of other voices

A good way to achieve overall silence ... deadly silence. Speak out and stimulate!

Posted by Thomas Mercer-Hursh on 30-May-2008 11:56

handing out related child entity objects wrapping a particular row.

Well, in my case I wouldn't design the entity object to contain a "row". After all, the whole notion of row is a part of the relational way of looking at data. TT and PDS are very efficient ways of dealing with sets of data and so I have proposed using them on the inside of set objects as a storage mechanism, but that doesn't mean that I think even that set object should present itself as a relational entity to its consumers. And, when one is focused on the individual entity object, there is no reason to be thinking in terms of rows at all. The entity object merely has properties and an identity. It is only internal to the set object that we do any mapping of that to a relational structure.

Posted by Thomas Mercer-Hursh on 30-May-2008 12:06

While we have AppServer and Sonic, and both do very useful things, it seems to me that we are missing a couple of core capabilities. One of these is a mechanism for creating service objects which are persistent and shared, but which are coupled at a higher performance level than one can achieve by having to get on and off the "bus". While a state free operation is clearly the right thing to do for having multiple agents serve a pool, that doesn't necessarily mean that it is optimum for everything to be state free since one then ends up paying the penalty for instantiation of something that is going to be predictably needed over and over.

On the other hand if you're only talking about an easy way to marshall 4GL "data transfer objects", so classes without behavior just state, than you could ask yourself why not use a PDS.

1. Using a PDS means having to have a definition of the PDS on both ends of the wire, i.e., not encapsulated.

2. A PDS has behavior and some of that behavior is actually inappropriate in the client.

3. A PDS is a relatively heavyweight object and at least some experiments suggest that one can achieve better performance by serializing.

4. A PDS implies a limited range of potential consumers rather than a design which is flexible in the choice of technology for the consumer.

Posted by Thomas Mercer-Hursh on 30-May-2008 12:12

Well, I suspect we are thinking about rather different architectures.

First, I have a strong WUI bias these days so there isn't much running on the client at all.

Second, an entity object would have no database connection or understanding. It would be created by the data access layer object which had those connections or by the set object which had a surrogate ... the set object also not having any database connection, but having something database-like inside of it.

Indeed, I can imagine cases where one would have entity objects and set objects for things that were never persisted. One example of which might be session context.

Posted by Admin on 01-Jun-2008 05:54

> Well, in my case I wouldn't design the entity object to contain a "row".
> After all, the whole notion of row is a part of the relational way of looking at
> data. TT and PDS are very efficient ways of dealing with sets of data and so I
> have proposed using them on the inside of set objects as a storage
> mechanism, but that doesn't mean that I think even that set object should
> present itself as a relational entity to its consumers

I didn't say that your class would impersonate a temp-table buffer, I was referering to the technical difficulty of tracking references and stale data. If your set object encapsulates a PDS/TT it has a snapshot of some data. Since you need to enumerate the internal set, it means the set object has currency (just as a TT-buffer has currency). You could also expose an index based API that translates internally to some TT lookup based on that index. There are at least two options to implement this:

- order.GetOrderline(1).OrderDate
This means that you now exposed a new object, "Orderline" through "GetOrderline(1)", which either points to a TT-row/buffer, back into the order object or has a clone of the TT-buffer data (Orderline has no notion of the TT since it merely has properties). In either case you can't guarantee the lifetime of the Orderline object, since the caller can refererence it as long as it wants/needs.

- order.GetOrderDate(1)
In this case you present an unnatural API, since you ask for the date on orderline 1. This means that "order" will now expose all orderline properties/behavior.

Posted by Admin on 01-Jun-2008 06:03

> 1. Using a PDS means having to have a definition of the PDS on both ends of
> the wire, i.e., not encapsulated.

The same is true if you want to share an ABL OO instance: both ends need the definition.


> 2. A PDS has behavior and some of that behavior is actually inappropriate in
> the client.

You don't have to use it. Code reuse is about reusing existing code. You can define your own simple PDS contract that doesn't use the before image of the PDS at all.

> 3. A PDS is a relatively heavyweight object and at least some experiments
> suggest that one can achieve better performance by serializing.

Sure, a PDS comes with all the transactional stuff and buffer capabilities of standard database tables. But the good thing is that they stream to disk transparantly when needed. That is a very powerfull feature.

> 4. A PDS implies a limited range of potential consumers rather than a design
> which is flexible in the choice of technology for the consumer.

XML isn't the best performing serialization technology if you want raw power. Than there are lots of things to consider with XML as well like the location of the schema, how to serialize dates/amounts, etc. Using XML as a transport protocal means that you probably need some wrapping at the client (code generated XML-adapters), unless you want to use the raw XML.

Posted by Thomas Mercer-Hursh on 01-Jun-2008 11:08

I was referering to the technical difficulty of tracking references and stale data. If your set object encapsulates a PDS/TT it has a snapshot of some data. Since you need to enumerate the internal set, it means the set object has currency (just as a TT-buffer has currency).

I'm obviously missing something. If I extract a set from the DB and hold it in whatever form and I pay attention to individual elements from that set in whatever form, it seems to me the same issues apply. I see nothing about the PDS/TT Set object and the property based entity object which are in any way different here. Nor do I see any way in which the technology by which sets are transmitted has any impact on the issue.

Posted by Thomas Mercer-Hursh on 01-Jun-2008 11:19

The same is true if you want to share an ABL OO instance: both ends need the definition.

Not really. All they need is a common agreement on signature. The one on the client end could be read only and might only expose a fraction of the data provided to it, for example.

BTW, I suppose it is true that the PDS on the receiving end can be dynamic, but I tend to forget that option since it sound like such a painful way to get what one needs.

E.g., imagine a source which is Item data. The receiving end only wants to show a browser of part number, description, price, and on hand quantity out of 50 fields in the item record. Yes, one option is to define a custom source for just this data, but one could also use a generic source which provides all of the data. A dynamic PDS could pick out just the desired data, but would be fragile if there were changes in the data structure. An XML solution could extract only the desired data and be robust as long as the desired portion was unaltered.

You don't have to use it.

No, but you are sending it across the wire and doing so in both directions.

But the good thing is that they stream to disk transparantly when needed.

I like temp-tables and that is one of the reasons. It is a property which is valuable during its life in a session. It is, however, not relevant during transmission.

XML isn't the best performing serialization technology if you want raw power.

Of course not ... but anything more powerful is also more proprietary. The whole point of wanting to use XML is to remove coupling between producer and consumer to the minimum level.

Posted by Admin on 02-Jun-2008 20:20

XML isn't the best performing serialization technology if you want raw power

I would hope that any serialization layer would allow for the encoding method to be stated, even to the level of xml - for example data & schema (for example to build an .Net DataTable) or simple data (for inclusion within soap/larger xml document). If you need raw power define your own encoding type which returns a 'raw-transfer' style image or csv string. Given the class will have both the serialize/deserialize methods (and provide for a default/unnamed format) you should have the best of both worlds. Plus PSC has a minimal effort of providing compile/runtime checks on classes level of serialization support (a simple internal procedure scan of the .r code would suffice).

Provide the solution in layers and allow developers to use based on the need. This should be no different to the way PDS was supplied as a layer over a collection of TT's - great solution. You have PDS level population/extraction plus maintain the original TT access.

Advanced UI - didn't know the name had stuck, understood that a new name was in the wings as it kind of implies that the existing UI was 'vintage'. In PSC's shoes I would be pushing this a lot harder and the existing OpenClient direction. Existing OpenClient projects that I have been involved in tend to end up being moved completely off the PSC platform and into 100% Java/.Net solutions. AUI is somewhat like ActiveX - in that it plugs into the existing UI framework and can be treated as a gradual migration. The OpenClient model opens the box on a whole range of 'Open' platform discussions which can move quickly into Open database and server technologies - which then leads to 100% Java/.Net (which also adds to the debate regarding Progress coders [resources] availability, and maintaining a single team/training etc).

Bit this last paragraph is a whole other discussion.

Posted by Admin on 02-Jun-2008 20:28

Any comment from PSC at this point

I thought this subject would have been discussed when the new IDE was being developed. What concepts have been adopted between the new tools and the supporting ABL code? I assume the existing ABL tools continue to be developed using a mix of include files and string pack/unpack - but how about some of the areas which acted a middle ware between the two toolsets (java/ABL).

This thread is closed