How to design backward compatibility and not turn your code into a mess? - web-services

I am developing a Java-based RESTful web application intended to be a centerpiece for its various client apps. Those client-apps can operate on the same assets in the main system (e.g. client-app A creates assets in main system, and client-app B fetches them from the system). We've rolled out the /v1/ API version and develop new features in /v2/. The requirement is to release v2, while still supporting backwards compatibility for v1 for some period of time, until all client-apps are ported to v2. The idea behind this requirement is that client-apps potentially written against different API versions should still be able to cooperate on the same assets.
Currently, we cover both API versions within a single instance of the system. While for some minor changes in HTTP API, it usually suffices to provide a new controller (sth like a bridge pattern), for slightly bigger changes it seems best to write a new controller & service layer (and hopefully both versions will "meet" at some level, reusing a common set of functionalities).
However, there are much broader changes to come. What's more, the main system is not just a dumb CRUD, it's rather a complex multi-component network, integrated with a handful of external services, involving some async jobs' processing, etc. Certainly it's all but a convenient place for keeping backward compatibility behavior-wise.
Are there any best practises to keep backwards compatibility of API & behavior behind it, while not turning the code into a mess?
We do care about the quality of code, and hate polluting it with copy-paste-adjust classes and maintaining duplicate/parallel feature implementations. And yes, we have already divided the java packages for v1 and v2.
Also, we'd like to avoid the situation where the old version's code ties our hands and keeps us from redesigning the new version's architecture, just for the sake of simplicity of keeping this back compatibility.

Related

static and dynamic evolution of services

I am reading about challenges of concurrent and networked software in pattern oriented software architecure vol 2.
Service access often involves invoking remote operations on resuable
components like OMG event service, etc. Supporting the static and
dynamic evolution of services and applications is antoher key
challenge in networked software system.
Evoution can occur in following way
Interfaces to and connectivity between component service roles can
change, often at run-time, and new service roles can be implemented
and installed into and installed into existing components.
It is even more challenging to determine how to access services that
are configured into a system 'on-demand' and whose implementations are
unknown when the system was designed origanally. Here design challenge
are two-fold.
First, an applicatoin must export new services, even though it may not know their detailed interfaces.
Second, an applicaiton must integrate these services into its own control flow and processing sequence transparently and robustly, even
at run-time.
I need your help in understanding above text by answering following questions.
What does author mean by "Interfaces to and connectivity between component service roles can change, often at run-time" ? Request to explain with easy to undestand example.
What does author mean by two points mentioned on-demand challenges which mentioned above. Request elobartion on above two points.
Thanks for your time and help.
1.What does author mean by "Interfaces to and connectivity between component service roles can change, often at run-time" ?
I'm not sure exactly. Interfaces change overtime because:
New technology standards can be adopted - say moving from SOAP to REST, or form XML to JSON, but that would happen slowly overtime through deployment - where as for me "runtime" is a memory space in which things run, and I don't see interfaces changing themselves taht fast - otherwise how could anyone integrate with them?
The API or interface contract itself changes to fulfill business need.
2.What does author mean by two points mentioned on-demand challenges which mentioned above.
Hmmm, good design patterns tend to survive time well (they never change, because they are never broken - like SOLID). The book you are refering to was written in 2000 I think - a lot has changed since then, so whilst the pattern may survive maybe the way we'd now describe it has changed (i.e what he means by "export new services" is open to interpretation)...
1.First, an application must export new services, even though it may not know their detailed interfaces.
Separation Of Concerns (basic OO stuff), all parts of your app don't (shouldn't) inherently know what the other parts are doing internally; likewise, as long as someone (including an external system) is satisfying the interface then who cares how it does so internally.
2.Second, an application must integrate these services into its own control flow and processing sequence transparently and robustly, even
at run-time.
I take this to mean that the program should never break, it should always compile, and if the application is dynamically creating and executing code (say based on user input) then there needs to be checks in-place so that the dynamic code doesn't break the app either.

services based architecture should not necessarily imply distribution?

In my workplace (and a lot of other areas), there is a lot of emphasis on building architecture around services. (I am working in an e-commerce startup). However, I think services are implicitly considered as distributed. I am a believer of the first law of distribution - "don't distribute". So, I believe that we should not un-necessarily complicate architecture. It should be an architecture which can evolve. So, one of the ways to approach the problem would be to create well defined namespaces and build code around it, but keep the communication via java api. (this keeps monitoring requirement low, and reliability/availability problems low). This can easily be evolved into a distributed architecture by wrapping modules into web service, as and when, the scale requirements kick-in. So, the question is - what are the cons of writing code as a single application and evolving into distributed services, rather than straight jumping into implementing web services based architecture? Am I right in assuming that services should imply the basic principles of design (abstraction, encapsulation etc), rather than distribution over network?
Distribution requires modularity. However, it requires more than just modularity: it also requires coarse-grained interaction between the modules.
For example, in a single-process ecommerce system, you might have separate modules for managing the user's shopping cart and calculating prices. They might interact by the cart asking the calculator to price an item, then another item, etc. That would be perfectly fine.
However, in a distributed system, that would require a torrent of small method calls, which is inefficient; you might get away with it if you used CORBA for distribution, but with SOAP, you'd be in trouble. Rather, you would want to have the cart ask the calculator to price the whole order in one go. That might be worse from a separation of concerns point of view (why should the calculator have to know about the idea of carts?), but it would be required to make the system perform adequately.
Related to granularity, there's also the problem of modules interacting via interfaces or implementations. With a single process, you can define a set of interfaces through which modules will interact; modules can pass each other objects implementing those interfaces without having to tell each other about the implementations (eg a scheduler module could be passed anything implementing interface Job { void run(); }). Across a network, the requirement for coarse grain means that any objects passed must be passed by value (because passing by reference would entail fine-grained calls back to the passing module - unless you were using mobile code, which you aren't, because nobody is), which means that both modules must know about and agree on the implementations of the objects.
So, while building a single-process system in a modular way makes it easier to implement SOA later, it doesn't make it as simple as wrapping each module in a SOAP interface. At least, not unless you build your system in a coarse-grained manner from the start, which means throwing away a number of sound and helpful good software engineering practices.

understand design of C++ framework

From some browsing on net, I just understood that any framework is set of libraries provided by the framework and we can simply use those library functions to develop the application.
I would like to know more about
what is a framework with respect to C++.
How are C++ frameworks designed?
How can we use them and develop applications.
Can someone provide me some links to understand the concept of "framework" in C++
A "framework" is something designed to provide the structure of a solution - much as the steel frame of a skyscraper gives it structure, but needs to be fleshed out with use-specific customisations. Both assume some particular problem space - whether it's multi-threaded client/server transactions, or a need for air-conditioned office space, and if your needs are substantively different - e.g. image manipulation or a government art gallery - then trying to use a poorly suited framework is often worse than using none. Indeed, if the evolving needs of your system pass beyond what the framework supports, you may find your options for customising the framework itself are insufficient, or the design you adopted to use it just doesn't suit the re-architected solution you later need. For example, a single-threaded framework encourages you to program in a non-threadsafe fashion, which may be a nightmare to make efficiently multi-threaded post-facto.
They're designed by observing that a large number of programs require a similar solution architecture, and abstracting that into a canned solution framework with facilities for those app-specific customisations.
How they're used depends on the problems they're trying to solve. A framework for transaction dispatch/handling will typically define a way to list IP ports to listen on, nominate functions to be called when connections are made and new data arrives, register timer events that call back to arbitrary functions. XML document, image manipulation, A.I. etc. frameworks would be totally different.... The whole idea is that they each provide a style of use that is simple and intuitive for the applications that might wish to use them.
A big hassle with many frameworks is that they assume ownership of the applications that use them, and relegate the application to a secondary role of filling in some callbacks. If the application needs to use several frameworks, or even one framework with some extra libraries doing e.g. asynchronous communications, then the frameworks may make that very difficult. A good framework is designed more like a set of libraries that the client can control, but need not be confined by. Good frameworks are rare.
More often than not, a framework (as opposed to "just" a library or set of libraries), in OOP languages (including C++), implies a software subsystem that, among other things, supplies classes you're supposed to inherit from, overriding certain methods to specialize the class's functionality for your application's needs, in your application code. If it was just some collection of functions and typedefs it should more properly be called a library, rather than a framework.
I hope this addresses your points 1 and 3. Regarding point 2, ideally, the designers of a framework have a lot of experience designing applications in a certain area, and they "distill" their experience and skill into a framework that lets (possibly less-experienced) developers build their own applications in that area more easily and expeditiously. In the real world, of course, such ideals are not always followed.
With a tool like CppDepend you can analyze any C++ framework, reverse engineer its design in a minute, but also have an accurate idea of the overall code quality of the framework.
An application framework (regardless of language) is a library that attempts to provide a complete framework within which you plug in functionality for your specific application.
The idea is that things like web applications and GUI applications typically require quite a bit of boilerplate to get working at all. The application framework provides all that boilerplate code, and some sort of organization (typically some variation of model-view-controller) where you can plug in the logic specific to your particular application, and it handles most of the other stuff like automatically routing messages and such as needed.

Does three-tier architecture ever work?

We are building three-tier architectures for over a decade now. Dividing presentation-, logic- and data-tier is supposed to allow us to exchange each layer individually, should the need ever arise, be it through changed requirements or new technologies.
I have never seen it working in practice...
Mostly because (at least) one of the following reasons:
The three tiers concept was only visible in the source code (e.g. package naming in Java) which was then deployed as one, tied together package.
The code representing each layer was nicely bundled in its own deployable format but then thrown into the same process (e.g. an "enterprise container").
Each layer was run in its own process, sometimes even on different machines but through the static nature they were connected to each other, replacing one of them meant breaking all of them.
Thus what you usually end up with, in is a monolithic, tightly coupled system that does not deliver what it's architecture promised.
I therefore think "three-tier architecture" is a total misnomer. The true benefit it brings is that the code is logically sound. But that's at "write time", not at "run time". A better name would be something like "layered by responsibility". In any case, the "architecture" word is misleading.
What are your thoughts on this? How could working three-tier architecture be achieved? By that I mean one which holds its promises: Allowing to plug out a layer without affecting the other ones. The system should survive that and be in a well defined state afterwards.
Thanks!
The true purpose of layered architectures (both logical and physical tiers) isn't to make it easy to replace a layer (which is quite rare), but to make it easy to make changes within a layer without affecting the others (and as Ben notes, to facilitate scalability, consistency, and security) - which works all the time all around us.
One example of a 3-tier architecture is a typical database-driven web application:
End-user's web browser
Server-side web application logic
Database engine
In every system, there is the nice, elegant architecture dreamed up at the beginning, then the hairy mess when its finally in production, full of hundreds of bug fixes and special case handlers, and other typical nasty changes made to address specific issues not realized during the design.
I don't think the problems you've described are specific to three-teir architecture at all.
If you haven't seen it working, you may just have bad luck. I've worked on projects that serve several UIs (presentation) from one web service (logic). In addition, we swapped data providers via configuration (data) so we could use a low-cost database while developing and Oracle in higher environments.
Sure, there's always some duplication - maybe you add validation in the UI for responsiveness and then validate again in the logic layer - but overall, a clean separation is possible and nice to work with.
Once you accept that n-tier's major benefits--namely scalability, logical consistency, security--could not easily be achieved through other means, the question of whether or not any of the tiers can be replaced outright without breaking the the others becomes more like asking whether there's any icing on the cake.
Any operating system will have a similar kind of architecture, or else it won't work. The presentation layer is independent of the hardware layer, which is abstracted into drivers that implement a certain interface. The data is handled using logic that changes depending on the type of data being read (think NTFS vs. FAT32 vs. EXT3 vs. CD-ROM). Linux can run on just about any hardware you can throw at it and it will still look and behave the same because the abstractions between the layers insulate each other from changes within a single layer.
One of the biggest practical benefits of the 3-tier approach is that it makes it easy to split up work. You can easily have a DBA and a business anylist or two building a data layer, a traditional programmer building the server side app code, and a graphic designer/ web designer building the UI. The three teams still need to communicate, of course, but this allows for much smoother development in most cases. In this regard, I see the 3-tier approach working reliably everyday, and this enough for me, even if I cannot count on "interchangeable parts", so to speak.

XA distributed transactions in C++

Is there a good C++ framework to implement XA distributed transactions?
With the term "good" I mean usable, simple (doesn't imply "easy"), well-structured.
Due to study reasons, at the moment I'm proceeding with a personal implementation, following X/Open XA specification.
Thank you in advance.
I am not aware of an open-source or free transaction monitor that has any degree of maturity, although This link does have some fan-out. The incumbent commercial ones are BEA's Tuxedo, Tibco's Enterprise Message Service (really a transactional message queue manager like IBM's MQ) and Transarc's Encina (now owned by IBM). These systems are all very expensive.
If you want to make your own (and incidentally make a bit of a name for yourself by filling a void in the open-source software space) get a copy of Grey and Reuter.
This is the definitive work on transaction processing systems architecture, written by two of the foremost experts in the field.
Interestingly, they claim that one can implement a working TP monitor in around 10,000 lines of C. This actually sounds quite reasonable, as what it does is not all that complex. On occasion I have been tempted to try.
Essentially you need to make a distributed transaction coordinator that runs as a daemon process. You will need to get the resource manager protocol working from it, so starting with this as a prototype is probably a good start. If you can get it to independently roll back or commit a transaction you have the basis of the TM-RM interface.
The XA API as defined in the spec is the API to control the transaction manager. Strictly speaking, you don't need to make a 3-tier architecture to use distributed transactions of this sort, but they are more or less pointless without a TP monitor. How you communicate from the front-end to the middle-tier can be left as an exercise for the reader. You are probably best off using an existing ORB, of which there are several good open-source implementations available.
Depending on whether you want to make the DTC and the app server separate processes (which is possibly desirable for stability but not strictly necessary) you could also use ACE as a basis for the DTC server.
If you want to make a high-performance middle-tier server, check out Douglas Schmidt's ACE framework. This comes with an ORB called TAO, and is flexible enough to allow you to use more or less any threading model that takes your fancy. Using this is a trade-off between learning it and the effort of writing your own and debugging all the synchronisation and concurrancy issues.
Maybe quite late for your task, but it can be useful for other users: LIXA is not a "framework", but it provides an implementation for the TX Transaction Demarcation specification and supports most of the XA features.
The TX specification is for C and COBOL languages, but the integration of the C version inside a C++ project should be effortless.
Other option is open source Enduro/X distributed transaction processing framework which allows to write simple C/C++ services which may operate with resource managers (e.g. databases) and gives capability to commit or abort works done by several different executables on same/different physical servers worked with different resources/databases.
Internally XA 2PC is used there.