jdubray
09/17/14

Switching to the Galaxy S5

So I did it, I switched from an iPhone 5 to a Galaxy S5. Why? I am just tired of the self-congratulating attitude of the company and its leadership. I just can't watch another Jony Ive video or Tim Cook keynote. They delivered nothing since 2011 with more than $150 B in the bank. And I am not even talking about the iPhone 6 ordering "process". I was told by a "Genius", that it was a reservation only process and if I logged in at midnight (sic), I could get a chance to get one for the next day. Really? I mean, Apple, Tim, Jony, ... you think that in 2014, you can ask customers to wake up in the middle of the night to order a commodity product? Only dillusional executives could cook up a process like that.

Indeed the Galaxy S5 is a much better phone and now that all the apps have caught up, I don't see -and I can't see- any reason why I would pay 30-50% more for half the hardware. The screen and the camera are spectacular. 

The switch was painless and did not cost me a penny because most apps I use are either free or follow a freemium model that allows me to use my account from any device/platform.

You may ask how did I move my iTunes library to the GS5? just use Kies (I do plan to continue using iTunes to buy music to have it available on my Mac and iPad).

You may also ask about FaceTime, but the reality is that Line is far more convenient to use than FaceTime, it's not just about Video Calling, it is above and beyond about communicating of which video calls are part of. For international landline calls/SMS, I use Google Hangouts which, not surprisingly works better on Android. 

I had tried a GS2 for 9 months before the release of the iPhone 5, that phone was a complete disaster (battery, UX, case...), but Samsung has gone well beyond correcting all the "immaturities". For instance on the GS5 you can turn on a super saver power mode that give you up to 10 days on a full charge. 

The only weak point left is Android itself. That OS is messy and makes little sense. That's pretty much an embarrassment 7 years after it's original launch. It's UX is about a decade behind and reminiscent of Java Swing. Fortunately, apps no longer use the Android Graphical Libraries, they come with their own UX. The trick is to run Android in "Simple" mode, which actually makes your phone usable ! 

To sum up...

The very good: price and hardware

The good: all my apps and music library are running exactly as they were in my iPhone 5. As a bonus you also get Google Now and Hangout, not to mention the spooky but seamless integration based on your Google ID.

The Ugly: Android, but at this point the OS is irrelevant. Running it in simple mode is good enough. 

Apple is totally underestimating how easy and compelling it has become to switch today, it's just a matter of time before their customers get it. 

I have been involved in an interesting discussion with Jeppe Cramon, Clemens Vasters, Arnon Rotem-Gal-Oz and Udi Dahan on twitter and google docs. It's a bit strange to be debating what SOA is in 2014, but it seems to me at least that SOA is still vastly misunderstood. So allow me, with a dose of humor, to make it very simple to understand. Next time you'll pump gas at the gas station you'll become a SOA expert.

I'll pass on the history (and future) of gas stations just to reflect on this most evolved piece of service engineering: the pumping station.

PKN Orlen in Germany.jpg
"PKN Orlen in Germany". Licensed under CC BY-SA 3.0 via Wikimedia Commons.

So here it goes, SOA is simple, very simple:

1. Intent

There is no service without intent. It's best to express your intent in terms of outcomes, e.g. my gas tank is empty, the outcome I am trying to reach is to fill it up. As a driver, I don't care much about how this outcome is reached, I just want my intent to be realized. The fundamental goal of service is to ensure a consistent outcome for any given intent. 

2. Common Information Model

A service cannot operate without an information model that is "commonly" known to the consumers. Imagine if every gas companies came up with their own name for the various types of gas and before pumping gas you had to translate the gas station nomenclature.

3. Interface

Many pundits and extremely competent software engineers keep talking about "Cohesion" which in software engineering is defined as:

cohesion refers to the degree to which the elements of a module belong together

How can they explain that "Payment" and "Select/Pump Gas" "belong together" (not to mention gas stations where you can watch a video while pumping gas). They don't! the payment implementation is not coupled in any way to the gas tank. But, just imagine a pumping station without a payment operation...

In SOA the service interface must be decoupled from its implementation. The service implementation obey the proper laws of software engineering, not the interface! I know it sounds expensive to systematically decouple the service interface from its implementation, but just try to other way around and let's talk again. 

4. Implementation

The key to understand SOA is that services ensure a "consistent" outcome, not just for you, but for the service provider too. Yes, indeed, the pump communicates the amount of gas you pumped to the payment system, indeed the gas station would send a notification that it's running out of gas and a truck would show up to fill it up. Just imagine a gas station where you would have to key in the volume of gas pump in your calculator, figure out the amount to pay and key in that amount in the payment system? imagine a gas station where you would be responsible for scheduling a delivery just because when you filled up your car tank, the station's tank crossed the threshold where it needs to be refilled?

You are smiling, yes, I see it, but how many software "services" are implemented by pushing some responsibilities to the consumers that clearly belong to the service?

Yes, a "Service Implementation" is and must be orchestrated to deliver a consistent outcome, period, there is just no other way around. If you don't "orchestrate" your service implementation, that orchestration will need to happen somewhere else, and that will be ugly, very ugly. 

Orchestration also helps handle transient information very well. For instance you do not want anywhere to store the payment information entered prior to filling up your car. Most likely the payment processor issues a transaction id when the payment information is submitted and that transaction information need to be held somewhere. Would you want to store that transaction id in a "System of Record"? no, not at all. Orchestration engines (such as chorus or ODE/BPEL) are very good at keep that information in a stateful way until the payment needs to be made.

Service Orchestrations typically manage end-to-end lifecycles (not processes), here is a rough sketch of the fill-up lifecycle which also shows how the service interface connects to the lifecycle.

pump-lifecycle


5. Systems of Record

You must understand that "Systems of Record" (here the payment system and the gas station tanks) do not expose "services", they expose integration points, plumbing if you will. The confusion often comes from the fact that the plumbing looks the same, or often is the same between the customer/pumping station and pumping station/tank (consumer/service and service/systems of record), but the nature of these two interfaces (services and integration points) are very different.

The whole goal of SOA is to make the systems of record autonomous, there is no code in an SoR that knows about or handles another SoR. What you want here is that the tank knows nothing about the payment system and the payment system knows nothing about the tank/pump. It is the coupling of SoR that is wrong. In SOA Loose Coupling means two things:

  • Intentional interfaces (consumer/service interface)
  • Orchestrated Implementation that manage SoR dependencies
  • Autonomous SoRs


6. Scalability and Availability

How do you "scale" a gas station? well you build it with a "big tank" and an interface that can serve concurrent requests. Yep, you get the idea. You also need a bit of redundancy, including for some key aspect of the service such as "payment".  

7. Events

Events are generally produced by Systems of Record when a particular state is reached (payment received, ...). However, event are best handled by coordinators, which are also orchestrated. When the gas station tank is empty, an event message is published. The subscriber of that event will coordinate the response to the event (issue a sales order, schedule the truck, ...).

To sum it up, this is how you design "services" in your SOA:

SOA is not very hard, if you care/date to apply simple, timeless principles. If you think that SOA is a protocol, plumbing or if you do not separate intent, interface, implementation and "Systems of Record" (Tank, Payment Processor), you will most likely fail at SOA.

There have been a lot of talks in our industry about what software engineering is and how it should be done. For those who don't know, the foundation of Computer Science, and unfortunately Software Engineering, is λ-calculus. If you are not familiar with it, it's an algebra that defines formally how "computations" are performed: 

  • a variable, x, is itself a valid lambda term
  • if t is a lambda term, and x is a variable, then (\lambda x.t) is a lambda term (called a lambda abstraction);
  • if t and s are lambda terms, then (ts) is a lambda term (called an application).

If this is not clear enough, here are how lambda expressions are defined and computed (again from Wikipedia's article): 

lambda abstraction \lambda x.t is a definition of an anonymous function that is capable of taking a single input x and substituting it into the expression t. It thus defines an anonymous function that takes x and returns t. For example \lambda x.x^2+2 is a lambda abstraction for the function f(x) = x^2 + 2 using the term x^2+2 for t. The definition of a function with a lambda abstraction merely "sets up" the function but does not invoke it. The abstraction binds the variable x in the term t.

An application ts represents the application of a function t to an input s, that is, it represents the act of calling function t on input s to produce t(s).

There is no concept in lambda calculus of variable declaration. In a definition such as \lambda x.x+y (i.e. f(x) = x + y), the lambda calculus treats y as a variable that is not yet defined. The lambda abstraction \lambda x.x+y is syntactically valid, and represents a function that adds its input to the yet-unknown y.

Bracketing may be used and may be needed to disambiguate terms. For example, \lambda x.((\lambda x.x)x) and (\lambda x.(\lambda x.x)) x denote different terms.

λ-calculus comes from a time where the main value proposition of "computers" was to compute ballistic trajectories, decode encrypted message and occasionally crunch a few profit reports. 

Times have changed, we now use "computers" for a bunch of other stuff. Anybody who has had to write some code has probably noticed that we typically wrestle with four concepts:

These concepts form an interesting symmetry that spans across four views: physical/conceptual and static/dynamic. The very problem introduced by  λ-calculus is that a variable, x, is used interchangeably to deal with a type, a relationship or a state, but types, relationships and states are fundamentally different from one another. Great developers will natively sort them out, others will at best create a maze. 

Object Orientation, for instance, is just a bunch of actions and types. There is no way to express directly states and relationships. States are systematically reified behind type properties and relationships behind type composition mechanisms (a.k.a. containment). Even in SQL, where relationality is the norm, relationships are "coded" as an attribute of a type. Conceptual frameworks like UML have tried to correct this myopic behavior by adding a layer of higher semantics, but again if you look at the structure of UML, i.e. MOF, it is "essentially" physical (actions ant types).

One could actually argue that the adoption of OO has been so wide spread precisely because it enables to code "what you see" (the physical view). You see a "customer", hence, you code a customer class... right? 

Depending on the domain, relationships and states will be more or less important/trivial which will make traditional λ-calculus based software engineering paradigms more or less effective, but thinking that you can translate reliably and consistently state and relationship semantics into actions and types is the biggest fallacy of software engineering and the root cause of pretty much any problem you see today.

Thinking that one can fix software engineering without changing its foundation, or simply by developing higher semantics that suffer from the same myopy, it a bit like a doctor trying to treat a fever with a couple of TUMs.

Here is a fun project you can do with an entry level Raspberry Pi board. In this project you'll learn how to create a set of APIs which control the Raspberry Pi GPIOs and an orchestration which turns on and off a LED connected to one of the output ports of the board's GPIO. We use a a kit such as this one.

Disclaimer: There is a great probability to damage your board if you connect pins incorrectly

Here is what our project looks like:

rpi  


Chorus.js generates a complete environment (APIs+Orchestration) which is deployed to and therefore runs on the Raspberry Pi.

architecture

Figure 2.1 Architecture of the Raspberry Pi project

 

sd          

Figure 2.2. API Orchestration

Let's start by implementing a service that will control the LED. Conveniently, there are several node.js modules which can be used to read or write to the board's IOs. We used the rpi-gpio module. The service implements three operations: turnOn, turnOff and read

service

Figure 2.3. The service definition

We introduce here a new module concept: the service definition references the gpio module which is defined as follows: require


This code is added to the generated service code. The name of the module is used as:

var moduleName = requires('moduleName') ;

If the name of the module is different, you need to use add a module statement such as above:

var gpio = requires('rpi-gpio') ;

You can then invoke these functions from the operation implementation:

operation

You can also take a look at the message and entity definitions:

message

entity

You are now ready to orchestrate these APIs:

process

The last step is to define the environment in which the service and the orchestration will be deployed:

env

 

The cord definition can be downloaded here and here is the native types declaration. You are now ready to deploy the files to your Raspberry Pi. We use the Arch Linux distribution. We successfully installed Node.js and MongoDB All you need to do is add the rpi-gpio module:

$ npm install rpi-gpio

You may run into an error if the time is not initialized properly on your raspberry pi. Depending on its configuration it will not pick up the time from the network and npm will fail if the computer time is set to 1970. We highly recommend that you install the GPIO utilityto be able to troubleshoot your electronics. The "gpio reset" command is pretty handy... After that, just type

$ npm start

and you should see something like that:

console

You can curl a request like that one:

POST /turnOnOff/v1/receive/switchRequest HTTP/1.1
Content-Type: application/json
{ "input" : { "IOPort" : "18"}}

Here are some more details to complete the project. Our GPIO service uses 4 pins:

  • Pin 1: 3.3V
  • Pin 6: GND
  • Pin 12: BCM GPIO18 (configured as an input)
  • Pin 24: BCM GPIO08 (configured as an output)

We turned off the ability to read/write other pins, but the code is easy enough to modify to use the port value passed in the API invocation should you want to extend the project. Raspberry Pi boards come in different sizes and shapes. We recommend that you check your connector rather than trusting our schematics.

gpio-port

 

The input as such is configured with a switch to change its value:

input-gpio

 

A LED is mounted on the output. The cord should turn the LED on, then off.

output-gpio  

There is an area in Service and API engineering that has never been really solved: how do you associate the request and response message formats to their underlying information model? We are not talking about a physical data model, the underlying information model is often known as the “Common Information Model” or “Logical Information Model” and provides a coherent structure to all the message types of a service/API or set of services/APIs. 

Developers design message formats and interactions by hand without a deliberate traceability to any kind of information model. 

People usually try to factor of their XML Schemas into an information model (complex types) and a message model (derived from these types). However these initiatives end up in failure as the information model and the message model need to evolve independently but the structure XML Schemas do not allow for that to happen. When you use XML Schema imports and includes, a change in the information model definition would immediately be reflected in all message definitions that depend on it, making it impossible to deploy that hierarchy at runtime. So you would have to create individual copies of all the versions of your XML Schema based information model. Eventually people realize that this approach amounts to creating self-standing message models.  However, in doing so, message types quickly become misaligned with one another. 

Due to the same broken design, XML Schema cannot solve another important problem. There is an asymmetry between queries and commands. Queries are generally implemented using a “Query by example (QBE)” mechanism, and require a flexible data structure where most if not all the data elements are optional. On the other hand commands require a rigid format to help validate the input data prior to executing the command. Yes, both query and command types are derived from the Common Information Model. Developers typically result in using the common denominator and making all elements of a type optional rather than having types for queries and other (albeit similar) types for commands. 

This is not specific to XML Schema, any Schema language that would be built following the same principles would feature the same problems. For instance, the Swagger’s Pet Shop example has all entities are defined with optional parameter:

 

Figure 1. Swagger's Order Definition (note everything is optional)

Really?

Since when a purchase order is a valid structure when it does not have an id? an item id? a quantity? ... Is that truly “the model”? The reason for that is that this particular structure fits all usage scenarios: create (where the id is not known yet, query by example, or even partial update a particular property (e.g. quantity).

Chorus.js solves that problem directly at the language level by introducing a new concept, projections, which connects with precision message definitions to the Common Information Model. This approach is based on an an article published on InfoQ in 2009: “Message Type Architecture”.

With Cord you can define your Common Information Model (in this case, the Pet Order, Figure 2) and then define message projections for various scenarios (create, query, update...). For instance the  CreateOrderMessage expresses that to create an order, you must specify a petId, a quantity, a status, but the shipDate is optional, as it may only be known (and updated) later, once you have made shipping arrangements. Note that the order id is now optional, and that’s all we had to specify, the “deltas”, between the base type and the message type. 

Figure 2. Cord's Order definiton (note the Order's projections to create and query orders)

Similarly, the query by example message definition specifies that we can query by petId, by status or both, by id also, but we cannot query by quantity. The quantity property has been “subtracted” from the order base type

We can now create a service definition. Let’s start with the operation definitions:

Figure 3. Cord's Service definition

The message type definitions use the base entity and the projection, for proper validation. Here is the WSDL file that was generated by Chorus.

As usual, Chorus also generated a PlantUML class diagram. 

Figure 4. Class Diagram of the PetShop example, as generated by Chorus.js

1 2 3 4 5 6 7 8 9 10 11 ... 22 >>

Search

 Subscribe







blog engine