<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule">

<channel>
	<title>Thinking Inside a Bigger Box &#187; SOA</title>
	<atom:link href="http://johannesbrodwall.com/category/soa/feed/" rel="self" type="application/rss+xml" />
	<link>http://johannesbrodwall.com</link>
	<description>Johannes Brodwall&#039;s Musings on Software Architecture and Programming</description>
	<lastBuildDate>Mon, 03 May 2010 20:24:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>		<item>
		<title>Felles IKT-arkitektur for offentlig sektor</title>
		<link>http://johannesbrodwall.com/2008/09/25/felles-ikt-arkitektur-for-offentlig-sektor/</link>
		<comments>http://johannesbrodwall.com/2008/09/25/felles-ikt-arkitektur-for-offentlig-sektor/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 22:13:52 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Norsk]]></category>
		<category><![CDATA[Politics & Current Events]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2008/09/25/felles-ikt-arkitektur-for-offentlig-sektor/</guid>
		<description><![CDATA[This Norwegian language post describes my response to the report from a task force exploring a common IT-architecture for the public sector in Norway.
Den norske regjeringen har besluttet at en felles IKT-arkitektur for offentlig sektor ville være fint. Jeg fikk greie på arbeidet på tirsdag, og har lest rapport til den store gullmedalje. Jeg er [...]]]></description>
			<content:encoded><![CDATA[<p><i>This Norwegian language post describes my response to the report from a task force exploring a common IT-architecture for the public sector in Norway.</i></p>
<p>Den norske regjeringen har besluttet at <a href="http://www.regjeringen.no/nb/dep/fad/dok/Horinger/Horingsdokumenter/2008/horing---felles-elektronisk-tjenesteytin/horingsbrev.html">en felles IKT-arkitektur for offentlig sektor</a> ville være fint. Jeg fikk greie på arbeidet på tirsdag, og har lest rapport til den store gullmedalje. Jeg er fortsatt ikke helt sikker på hva som menes med &#8220;felles IKT-arkitekt&#8221;, men jeg kan se omrisset av mange store evighetsprosjekter i dokumentet.</p>
<p>Jeg har forfattet et <a href="http://docs.google.com/Doc?docid=dc62h3cn_262fcf9hzxs">svar på rapporten</a>.</p>
<p>Spesielt er jeg bekymret for at dette skal bli en unnskyldning for store SOA-prosjekter uten veldefinerte formål. Rapporten beskriver en god del ønskede effektmål, men disse beskrives i såpass runde former at man aldri kommer til å etterprøve om prosjekter faktisk oppfyller dem. Formålene er ting som økt grad av interoperabilitet.</p>
<p>Frykt nummer to ligger i hvordan SOA-krigen går om dagen. Rapporten nevner veldig lite konkret på teknologier, så jeg slapp unna å gå inn i dette minefeltet. I stedet må jeg ligge våken og frykte effekten av de usagte ordene i rapporten.</p>
<p>Jeg har startet å høre om dogmatiske SOA-prosjekter som ikke lykkes, til tross for store investeringer. REST starter å bli mer akseptabelt å snakke om i høflig selskap. Men fremdeles virker det som om at  &#8220;SOA prosjekt&#8221; er et kodeord for &#8220;vi skal kjøpe dyr WS-* programvare fra Oracle, IBM eller Microsoft&#8221;.</p>
<p>Jeg skulle ønske jeg hadde mer erfaring innen offentlig sektor før jeg skulle uttale meg om dette, men dersom det er som noe annet jeg har sett, handler interoperabilitet grunnleggende sett om å sende eller motta informasjon på et standardisert format. Det betyr tre ting: En aksjon (les, oppdater, lever), noe som identifiserer et objekt (søknad, personopplysning) og et innhold (&#8220;Jeg ønsker med dette herved å søke om bla bla bla&#8221;).</p>
<p>Og her har WS-* skadet oss mye. Når man bygde standarden SOAP (Simple Object Access Protocol, som verken er enkel eller handler om &#8220;object access&#8221;), skrellet man vekk to fine deler av HTTP standarden: Verb (GET, POST, PUT &#8211; det vil si &#8220;aksjoner&#8221;) og URL&#8217;er (det vil si den nøkkelen som representerer et objekt). Det betyr at vi ikke lenger kan si &#8220;legg til&#8221; (POST) en &#8220;søknad&#8221; (http://etat.no/tjeneste/soknad/) som inneholder noe data (ikke en del av standarden). I stedet må vi si &#8220;send en melding som inneholder informasjon om noe vi tenker å gjøre&#8221; (ikke en del av standarden).</p>
<p>I en rimelig verden burde interoperabilitet betydd at å utveksle informasjon om objekter burde være en del av en universell standard som er akseptert rundt hele verden. En standard basert på å sende meldinger om å utføre én eller annen oppgave (som for eksempel å utveksle et objekt) virker sørgelig utilstrekkelig. Og offentlig sektor i lille Norge kan vel ikke være den som brøyter vei her.</p>
<p>Så lenge SOA-krigen pågår er jeg ikke optimistisk for sjansene til at en rimelig standard dukker opp.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2008/09/25/felles-ikt-arkitektur-for-offentlig-sektor/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Users judge your service by its interface</title>
		<link>http://johannesbrodwall.com/2008/09/23/users-judge-your-service-by-its-interface/</link>
		<comments>http://johannesbrodwall.com/2008/09/23/users-judge-your-service-by-its-interface/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 22:57:20 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2008/09/23/users-judge-your-service-by-its-interface/</guid>
		<description><![CDATA[Sometimes it feels like I&#8217;m stating the obvious. But the fact that users only care about the interface of the service is something we often say, but seldom understand.
If this is true, how can we think that we can develop the interface as an after though to the central system.
Not all your users might be [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes it feels like I&#8217;m stating the obvious. But the fact that users only care about the interface of the service is something we often say, but seldom understand.</p>
<p>If this is true, how can we think that we can develop the interface as an after though to the central system.</p>
<p>Not all your users might be human. And the computerized users are treated even worse.</p>
<p>If the non-human users also care about the interface, how do we think that they will be satisfied with the same interface that is used internally between different parts of the application? These interfaces are the scraps of the service table.</p>
<p>If this is true, why do so many system diagrams display the &#8220;service&#8221; layer for external users <i>below</i> the user interface layer. It should be <i>next to</i> the human user interface layer, shouldn&#8217;t it?</p>
<p>External programmatic interfaces, whether they be SOAP, REST or otherwise, must be treated as any other user interface. This means both to understand the needs of the non-human users and to only develop parts of the service interface that are needed now.</p>
<p>Any user interface expert will tell you: There are no taking-backs with user interfaces. Once you&#8217;ve given something to the user, they will react very negative to substantial changes. The non-human user is even more unforgiving. Yet, the scraps of the system internals that we give them will be even more necessary to change.</p>
<p>If the users judge your service by its interface, we should only give non-human users interfaces that are developed based on their requirements, and that we don&#8217;t mind never getting to change.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2008/09/23/users-judge-your-service-by-its-interface/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Myth of the Silo</title>
		<link>http://johannesbrodwall.com/2008/06/15/the-myth-of-the-silo/</link>
		<comments>http://johannesbrodwall.com/2008/06/15/the-myth-of-the-silo/#comments</comments>
		<pubDate>Sun, 15 Jun 2008 19:49:16 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2008/06/15/the-myth-of-the-silo/</guid>
		<description><![CDATA[Warning: This article requires a lot of editing love before it is very useful. It might be somewhat incoherent. Read at your own risk. ;-)
Silo (software): A silo system cannot easily integrate with any other system. 
In software, the term &#8220;silo&#8221; is used to refer to a system that is constructed as one unit from [...]]]></description>
			<content:encoded><![CDATA[<p><em>Warning: This article requires a lot of editing love before it is very useful. It might be somewhat incoherent. Read at your own risk. ;-)</em></p>
<p><em>Silo (software): A silo system cannot easily integrate with any other system. </em></p>
<p>In software, the term &#8220;silo&#8221; is used to refer to a system that is constructed as one unit from the front end to the data storage. Everything is tied together to work with the rest of the silo, but not with other elements.</p>
<p>This is considered a bad thing.</p>
<p>The problem comes when we want to integrate the system with other systems or reuse parts of the system.</p>
<p>Many of the new ideas in software development has as one of their big goals to try and rectify the silo problem. In general this is achieved by splitting up the system into services that may or may not be distributed across different computers.</p>
<p>But the badness of the silo hinges on two claims: First, that the applications built as an integrated stack cannot be integrated with, and second, that a system of distributed services can be integrated with.</p>
<h3>Fact 1: Layers reduce understanding</h3>
<p>One way that services are introduced is as an abstraction on top of an existing system. More often that we&#8217;d think, that system is again an abstraction upon an older system. Each layer was added in an attempt to make it easier for someone to integrate with the system. Each layer makes the whole harder to understand.</p>
<p>Just a few weeks ago, I experienced a profound sense of deja vu as I had gradually peeled of layers of a set of services and discovered that integrating directly to the ultimate data source was the easiest option. Each layer had added confusion, complexity, delays and unneeded constraints. Integrating with the &#8220;silo&#8221; was easier than integrating with the service layers on top of it.</p>
<h3>Fact 2: Silos often aren&#8217;t</h3>
<p>We&#8217;re currently building Java-systems that will extend and ultimately (hopefully) replace systems running on old mainframes. The common perception is that the mainframe apps are silos. They are hard to understand and impossible to split up.</p>
<p>Have you tried? As it turned out, of our many Java-developers, almost none have dared to started looking into how the mainframe works. When someone finally did, he found that it was fairly easy to integrate with. It requires hard work, but when did integration not?</p>
<h3>Fact 3: Services might not be</h3>
<p>&#8220;Fine,&#8221; you say, &#8220;but what about large grained services?&#8221; My experience is that even these are hits and misses. For example, one would think that distributing information via postal mail, electronic channels and fax might be a reusable service. It can be, but it could also be a cost driver.</p>
<p>Even when it comes to large scale services, reuse is costly. If your &#8220;enterprise architecture&#8221; focuses on what services should be reused by whom, you might be wasting a lot of time for a lot of people.</p>
<h3>Ode to the silo</h3>
<p>Maybe the classical silo isn&#8217;t as bad as we&#8217;re often told. Focusing on just what the system needs to do and dealing with the integration by talking to others sure is expensive. But maybe trying to architect a reusable set of services is just as expensive.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2008/06/15/the-myth-of-the-silo/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Fire påstander om SOA</title>
		<link>http://johannesbrodwall.com/2008/06/14/fire-pastander-om-soa/</link>
		<comments>http://johannesbrodwall.com/2008/06/14/fire-pastander-om-soa/#comments</comments>
		<pubDate>Sat, 14 Jun 2008 19:32:22 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Norsk]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2008/06/14/fire-pastander-om-soa/</guid>
		<description><![CDATA[This article is a Norwegian-language version of my article Four bold claims about SOA.
Dette er et utkast til en artikkel jeg ønsker å få publisert. Jeg setter stor pris på tilbakemeldinger om uklare tanker og formuleringer.
To av de vanskeligste problemene vi møter innen programvareutvikling er integrasjon og det som gjerne kalles &#8220;business-IT alignment&#8221; eller forretningsorientering, [...]]]></description>
			<content:encoded><![CDATA[<p><em>This article is a Norwegian-language version of my article <a href="http://www.brodwall.com/johannes/blog/2008/04/30/four-bold-claims-about-soa/">Four bold claims about SOA</a>.</em></p>
<p><em>Dette er et utkast til en artikkel jeg ønsker å få publisert. Jeg setter stor pris på tilbakemeldinger om uklare tanker og formuleringer.</em></p>
<p>To av de vanskeligste problemene vi møter innen programvareutvikling er integrasjon og det som gjerne kalles &#8220;business-IT alignment&#8221; eller forretningsorientering, altså: IT skal understøtte virksomhetens strategiske mål.</p>
<p>Tjenesteorientert arkitektur, eller Service Oriented Architecture (SOA), hevder å kunne løse begge disse problemene. I det siste har jeg forsøkt å lytte mer aktivt til påstander fra evangelister av SOA, og jeg begynner å få en forståelse for hva det er SOA foreslår som løsningen på problemene vi står overfor. Dette er min oppfatning av påstandene om hvordan SOA skal løse problemene med integrasjon og forretningsorientering:</p>
<ul>
<li>Web service-standarder vil løse de tekniske integrasjonsproblemene (&#8220;WS-stjerne-påstanden&#8221;)</li>
<li>Å sentralisere integrasjon via ett knutepunkt vil løse de organisasjonsmessige utfordringene rundt integrasjon (&#8220;ESB-påstanden&#8221;)</li>
<li>Å modellere funksjonalitet som en arbeidsflyt mellom tjenester vil gi oss bedre forretningsorientering (&#8220;BPM-påstanden, del 1&#8243;)</li>
<li>Å kunne restrukturere arbeidsflyten mellom tjenestene vil gi oss en en smidig forretningslogikk (&#8220;BPM-påstanden, del 2&#8243;)</li>
</ul>
<p>Jeg håper at SOA-evangelister kjenner seg igjen i disse påstandene og er enige i at disse påstandene er sentrale når det gjelder SOA. Men jeg tror evangelistene vil være uenige i min vurdering av påstandene om SOA.</p>
<p>Forretningsorientering og integrasjon er svært viktige og vanskelige problemer. Dersom påstandene om SOA skal holde mål, betyr dette at problemene er unødvendige, at de er unngåelige eller at de tekniske og designmessige verktøyene SOA gir oss kan abstrahere vekk kompleksiteten.</p>
<p>Dette er en uvanlig vågal påstand. Og etter min dømmekraft, en usann påstand. Min erfaring er ikke så bred som den til mange SOA-evangelister. Jeg har erfaring med et fåtall organisasjoner og et fåtall systemer. Men de systemene jeg kjenner, kjenner jeg svært godt, og</p>
<h3>Systemer ser svært forskjellig ut på nært hold og når man ser dem fra 30 tusen fot.</h3>
<p>Når jeg har jobbet med systemer som består av web services, er min erfaring at standardene på dette feltet har vært langt fra å løse de tekniske integrasjonsproblemene. Å splitte et system opp i distribuerte komponenter øker antall feil og kostnaden ved å utvikle systemet, selv i de tilfellene der de to tjenestene kjører på samme plattform. Dersom man ønsker å integrere Java-løsninger med .NET-løsninger, er ting mye verre. Kanskje utvikling og testing av distribuerte systemer ville vært enklere om vi bare hadde hatt de rette verktøyene?</p>
<p>Eller kanskje ikke. Når vi integrerer to systemer, er de tekniske utfordringene små sammenlignet med de organisasjonsmessige utfordringene: &#8220;Når kan du utføre den endringen vi trenger?&#8221; Hvordan tester vi integrasjon mellom systemene? Hva er ytelsen, robustheten og påliteligheten til tjenesten jeg integrerer meg med? Slike spørsmål må besvares for hvert integrasjonspunkt. Når man ser på de organisasjonsmessige problemstillingene, er integrasjon alltid et bilateralt problem, selv når de tekniske problemstillingene er løst multilateralt. Kanskje problemene ville forsvinne dersom vi bare skjuler dem i en sentral komponent?</p>
<p>Programvareutvikling er forskjellig fra en samlebånd på en fabrikk. I de systemene jeg kjenner, er 99 % av den funksjonaliteten man har utviklet kun brukt én gang. Enkeltsteg i use cases eller andre kravbeskrivelser er sjelden gjenbrukbare. De er altfor avhengige av konteksten de brukes i. Ettersom funksjonaliteten essensielt er avhengig av konteksten, vil en utvikler som befales å ignorere denne konteksten etter min erfaring gjøre en dårligere jobb, fordi utvikleren vil tolke kravene til det som skal lages for bredt. Kanskje vi bare trenger en bedre måte å uttrykke kontrakten til det som skal utvikles på?</p>
<p>Fleksibilitet gjør en løsning mer kompleks. Aldri er dette så sant som når fleksibiliteten er oppnådd ved å distribuere delene av systemet. Personlig har jeg aldri vært flink til å vurdere hvilken fleksibilitet som er nødvendig, og hvilken fleksibilitet som jeg kun inkluderer for å tilfredsstille mitt tekniske ego. Men det jeg vet er at det er vanskeligere å teste fleksible, distribuerte systemer. Så feedback i prosessen blir blokkert av tekniske valg. Og min erfaring er at feedback er den eneste måten vi kan få en mer smidig forretning. Kanskje dersom verktøyene våre var bedre, så ville vi være i stand til å utvikle, teste, versjonshåndtere, driftsette og endre distribuerte systemer uten å sabotere feedback?</p>
<h3>Kan grunnleggende kompleksitet abstraheres bort?</h3>
<p>Til syvende og sist tror jeg svaret på alle disse spørsmålene blir &#8220;nei&#8221;. Å legge til teknologier og verktøy løser sjelden problemene våre. Mer avanserte programmeringsspråk lot oss løse vanskeligere problemer, fordi de lot oss abstrahere oss vekk fra teknisk, irrelevant kompleksitet. Nyere verktøy som for eksempel Object Relation Mapping som Hibernate gir oss en kraftig brekkstang til å løfte tunge løft, men vi kan ikke bruke denne type verktøy effektivt og trygt dersom vi ikke skjønner både databaser og selve verktøyet godt. Avanserte verktøy kan gi oss større effekt, men de er også vanskeligere å forstå.</p>
<p>Vil WS-*, ESB&#8217;er og BPM være verktøy som vil være i stand til å skjule kompleksiteten i problemene de forsøker å takle, eller vil de kun gi oss mer kraft når vi forsøker å løse disse problemene? Og hva vil være kostnaden av denne kraften når det gjelder ekstra kompleksitet?</p>
<p>Og nøyaktig hvilke problemer er det SOA-verktøy og -tankesett retter seg mot? De fokuserer på problemer rundt å håndtere et stort økosystem av distribuerte tjenester som må integreres. Men dersom det er kostbart å utvikle en tjeneste som kan brukes utenfor sin opprinnelige sammenheng, dersom tjenester ikke er så gjenbrukbare som vi skulle likt å tro og dersom distribuert arkitektur er et hinder for en smidig forretning, er ikke da SOA en måte å skape unødvendig kompleksitet på?</p>
<p>Hva om vi sparer komplekse problemstillinger som integrasjon til de tilfellene der det virkelig trengs? I slike situasjoner kan WS-* og ESB spille en rolle. Ikke som en sølvkule som skal ta livet av kompleksitetsmonsteret, men som avanserte, komplekse verktøy som kan øke effekten av arbeidet vårt. Kanskje. Jeg er ikke sikker på hvor mye effekt disse verktøyene egentlig gir. Men jeg er ganske sikker på de øker kompleksiteten på oppgaven.</p>
<p><em>Mange takk til Eivind Nordby, Hogne Kirkeby, min far Bjørn Brodwall, Anne Marie Baugstø-Hartvigsen, Geir Hedemark og Lars Arne Skår som har hjulpet meg med tilbakemeldinger på denne artikkelen.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2008/06/14/fire-pastander-om-soa/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Link: Open Source in the Enterprise</title>
		<link>http://johannesbrodwall.com/2007/03/11/link-open-source-in-the-enterprise/</link>
		<comments>http://johannesbrodwall.com/2007/03/11/link-open-source-in-the-enterprise/#comments</comments>
		<pubDate>Sun, 11 Mar 2007 12:45:01 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Links]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2007/03/11/link-open-source-in-the-enterprise/</guid>
		<description><![CDATA[CIO JP Rangaswami at investment bank Dresder Kleinwort Wasserstein talks about why he considers open source a corporate IT asset. In this talk, Rangaswami describes how DrKW wanted to create an internal incubator environment in order to combat skill attrition in the late 90s. In the course of doing this, they acquired OpenAdaptor and discovered [...]]]></description>
			<content:encoded><![CDATA[<p>CIO <a href="http://www.confusedofcalcutta.com/">JP Rangaswami</a> at investment bank Dresder Kleinwort Wasserstein talks about why he <a href="http://www.infoq.com/news/2007/03/jp-rangaswami-open-source">considers open source a corporate IT asset</a>. In this talk, Rangaswami describes how DrKW wanted to create an internal incubator environment in order to combat skill attrition in the late 90s. In the course of doing this, they acquired <a href="https://www.openadaptor.org/">OpenAdaptor</a> and discovered almost accidentally benefits of the open source development model.</p>
<p>The talk is a bit fleeting and unstructured (and someone&#8217;s phone keeps ringing during the presentation!), but Rangaswami presents a lot of very interesting opinions:</p>
<ul>
<li>He observes that the business environment in banking industry (and other industries?) are less focused on standards than before. He believes Open Source development has a better chance of achieving cooperation than standards in a business environment where &#8220;everyone want to be top dog&#8221;</li>
<li>He explores the model of Open Source Bonds. A company issues a bond promising to pay whoever develops X (for example) a sixth of what it would cost them to built it in house. He hints to a possible network of brokers and service providers.</li>
</ul>
<p>Personally, I found the Q&#038;A part the most valuable:</p>
<ul>
<li>Question: &#8220;What should I tell the executives in my company who consider open source &#8216;high risk&#8217;?&#8221; Rangaswami talks about how there are only four interesting risks during software procurement: 1) The vendor disappears, 2) The vendor gets a different focus from you, 3) quality, and 4) security. Open source has a &#8220;build-in escrow&#8221; clause (just without the lawyers), which takes care of the first two as well as commercial software can. He further points out that within the industry, nobody is held accountable for software failure. This means that quality is not something you can buy. Finally, the inspection value when it comes to security is considerable.</li>
<li>Question: &#8220;What should the architecture department be doing?&#8221; This was the most interesting question to me. Rangaswami gives a long and thoughtful answer. The architect is not unique and different from everyone else, except that (s)he is more committed to learning. The architect should work through &#8220;control-freakery&#8221;, but through influence, advice and support. An architect should not &#8220;try to write an architecture (I am proud of being accused of not having one)&#8221;</li>
<li>Question: &#8220;What is the main cause of project failure in the software industry?&#8221; Rangaswami points out how we&#8217;re not very good at saying &#8220;no&#8221; to the customers. Project failure is caused by a culture that is unwilling to accept failure. What is &#8220;worse than failure&#8221;? Not learning from that failure because you&#8217;re not accepting it.</li>
<ul>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2007/03/11/link-open-source-in-the-enterprise/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A Brief Adventure with Universal Repositories and REST Web Services</title>
		<link>http://johannesbrodwall.com/2007/03/03/a-brief-adventure-with-universal-repositories-and-rest-web-services/</link>
		<comments>http://johannesbrodwall.com/2007/03/03/a-brief-adventure-with-universal-repositories-and-rest-web-services/#comments</comments>
		<pubDate>Sun, 04 Mar 2007 03:17:03 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2007/03/03/a-brief-adventure-with-universal-repositories-and-rest-web-services/</guid>
		<description><![CDATA[Inspired by Per Mellqvist (and myself, to be fair), I wanted to explore the possibility of using a generic DAO or Repository interface for REST. Based on this simple idea, I was able to create a very cute and testable prototype of a full Web Service stack for REST based Web Services. The most interesting [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by <a href="http://www-128.ibm.com/developerworks/java/library/j-genericdao.html">Per Mellqvist</a> (and myself, to be fair), I wanted to explore the possibility of using a generic DAO or Repository interface for REST. Based on this simple idea, I was able to create a very cute and testable prototype of a full Web Service stack for REST based Web Services. The most interesting aspect was creating a universal test case for Repositories.</p>
<p>This article shows how little code is required to implement and test a REST based Web Service in Java, despite the horror of the Java HTTP client API. The source code <a href="http://svn.brodwall.com/demo/insanejava/trunk/rest-demo/">can be downloaded from my subversion repository</a>. I also want to illustrate how to create black box tests that can be reused efficiently with different implementations of a Repository.</p>
<h3>The generic Repository and its friend, the generic Repository Test</h3>
<p>A <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/main/java/no/brodwall/insanejava/rest/Repository.java?view=markup">Repository</a> or Data Access Object allows a client program to Create, Retrieve, Update and Delete object. A simple design that has served me well is something like this:</p>
<pre><code>public interface Repository&lt;T> {

    Serializable insert(T entity);

    public T retrieve(Serializable key);

    void update(Serializable key, T entity);

    void delete(Serializable key);

}</code></pre>
<p>However, when you start implementing this interface, you will soon find that you need a little more functionality even in the general case. Here is a <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/test/java/no/brodwall/insanejava/rest/RepositoryTest.java?view=markup">test case</a> that shows one of my favorite patterns for black box testing of repositories:</p>
<pre><code>public abstract class RepositoryTest&lt;T> extends TestCase {

    private T insertedObject = createDistinctObject();

    private Serializable key;

    protected abstract Repository&lt;T> getRepository();

    @Override
    protected final void setUp() throws Exception {
        key = getRepository().insert(insertedObject);
        getRepository().writeChanges();
    }

    public void testRetrieve() {
        T retrievedObject = getRepository().retrieve(key);
        assertNotSame("retrieve in new session should not return same",
                      insertedObject, retrievedObject);
        assertEquals(insertedObject, retrievedObject);

        assertSame("All retrieves in session should return same instance",
                   retrievedObject, getRepository().retrieve(key));
    }
</code></pre>
<p>Notice that I was the <code>insertedObject</code> to be <em>equals</em> to the <code>updatedObject</code>, but in order for this to make any sense, I need them to be different object <em>instances</em>. Most Repository implementations will have some sort of session cache, and the point of the <code>writeChanges()</code> method in this case is to flush this cache, so objects returned will be fresh. Having a session cache avoids a lot of confusion, so I like to test for it. That is what the final <code>assertSame</code> in <code>testRetrieve</code> verifies.</p>
<p>The second thing we need for a generic repository is a way to deal with unwanted aliasing. This is in particular an issue with Object-Relation Mapping technology such as Hibernate or TopLink. If I change an object I got back from the Repository, but don&#8217;t call <code>Repository.update</code>, the object may still be changed in the database. This is because the Object-Relation Mapper will keep track of all changes in objects that it has returned. Here is a test case that illustrates the problem (and solution):</p>
<pre><code>public void testDiscardedUpdate() {
    T updatedObject = getRepository().retrieve(key);
    assertNotSame(insertedObject, updatedObject);
    changeObject(updatedObject);
    assertFalse(insertedObject.equals(updatedObject));
    getRepository().discardChanges();

    assertEquals(insertedObject, getRepository().retrieve(key));
}</code></pre>
<p>With <code>discardChanges</code> in place to ensure that we don&#8217;t write to the Repository when we don&#8217;t want to, the final <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/main/java/no/brodwall/insanejava/rest/Repository.java?view=markup">Repository</a> interface looks like so:</p>
<pre><code>public interface Repository&lt;T> {

    Serializable insert(T entity);

    public T retrieve(Serializable key);

    void update(Serializable key, T entity);

    void delete(Serializable key);

    public void writeChanges();

    void discardChanges();

}</code></pre>
<p>This interface proves to be both generic enough that we can <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/test/java/no/brodwall/insanejava/rest/RepositoryTest.java?view=markup">construct a generic test case</a> for it, and powerful enough that it can be implemented in a variety of ways.</p>
<h3>The Memory Repository</h3>
<p>Since the interface is so small, I decided to implement a pure in-memory variant of <code>Repository</code> using <code>HashMap</code>s as the internal storage. The <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/main/java/no/brodwall/insanejava/rest/MemoryRepository.java?view=markup">code</a> is trivial, the only interesting thing is the <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/main/java/no/brodwall/insanejava/rest/SessionCachedRepository.java?view=markup">session cache</a> on top of it.</p>
<p>As it turns out, the <code>SessionCachedRepository</code> can be used in other scenarios as well, and I will reuse it for the REST implementation of the repository. There are a few challenges to a generic <code>SessionCachedRepository</code>. Most importantly, because <code>insert</code> returns the key for the object, we need to have it write through to the server. In order to implement <code>discardChanges</code>, I save a list of inserted objects that can be removed manually:</p>
<pre><code>public void discardChanges() {
    for (Serializable key : sessionInserts) {
        uncachedRepository.delete(key);
    }
    sessionUpdates.clear();
    sessionDeletes.clear();
}</code></pre>
<p><em>(Note to self: Could I implement the key with a smart proxy to get around this problem?)</em></p>
<h3>The REST repository</h3>
<p>I implemented both the server and the client side of the REST Web Service with many of the same pieces. By using the same Repository interface on both sides of HTTP, I can easily exchange remote and local tests. The great advantage of this is that it is usually much easier to get the local part to work first, and then work on the server. Here is the client side Repository:</p>
<pre><code>public class RESTClientRepository&lt;T> implements Repository&lt;T> {

    private RESTHttpClient httpClient;

    private EntityToXmlMapper&lt;T> mapper;

    private URL baseUrl;

    public RESTClientRepository(URL baseUrl, RESTHttpClient httpClient,
                                EntityToXmlMapper&lt;T> mapper) {
        this.baseUrl = baseUrl;
        this.httpClient = httpClient;
        this.mapper = mapper;
    }

    public Serializable insert(T entity) {
        return (URL)httpClient.doPostAndReturnLocation(
                resourceUrl(""), mapper.entityToWriter(entity));
    }

    public T retrieve(Serializable key) {
        return mapper.xmlToEntity(httpClient.doGet(resourceUrl(key)));
    }

    public void update(Serializable key, T entity) {
        httpClient.doPut(resourceUrl(key), mapper.entityToWriter(entity));
    }

    public void delete(Serializable key) {
        httpClient.doDelete(resourceUrl(key));
    }

    private URL resourceUrl(Serializable key) {
        try {
            return new URL(baseUrl, key.toString());
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("Invalid url " + key);
        }
    }
</code></pre>
<p>This code really shows off the beautiful simplicity of the REST scheme. Each method does an HTTP call to a URL that is determined by the ID, encodes the object as XML, and decodes the result as XML, too. The XML mapping can be as complex as you want, but it is independent of the REST stack. The only other complex part of this solution is the <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/main/java/no/brodwall/insanejava/rest/RESTHttpClientImpl.java?view=markup"><code>RESTHttpClient</code></a>. I implemented this on top of Java&#8217;s poor <code>HttpURLConnection</code> in order to avoid dependencies. It&#8217;s a horribly API, so please don&#8217;t blame me for the horrible client code. :-(</p>
<p>There is one thing that should make you go &#8220;that&#8217;s funny&#8221; in the <code>RESTRepostory</code> code, namely the <code>insert</code> method. Here, we get a String back and convert it to a URL. What is going on here?</p>
<p>With REST web services, the normal way of creating a new resource is to POST the resource. The server will respond with 201 &#8211; created, and it will have the URL to the new resource in the &#8220;Location&#8221; header. I have taken a shortcut with regard to this in the <code>RESTHttpClient.doPostAndReturnLocation</code>. An interesting point here is that I can use the URL as key throughout the client side. As long as the code doesn&#8217;t get too curious with the actual class of the key, this works fine.</p>
<p>Now for the other side of the equation, the servlet:</p>
<pre><code>public class RESTRepositoryServlet&lt;T> extends HttpServlet {

    private Repository&lt;T> repository;

    private EntityToXmlMapper&lt;T> mapper;

    public RESTRepositoryServlet(Repository&lt;T> repository,
			       EntityToXmlMapper&lt;T> mapper) {
        this.repository = repository;
        this.mapper = mapper;
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			      throws IOException {
        T entity = getEntity(req);
        mapper.entityToWriter(entity).doWithWriter(resp.getWriter());
        resp.setContentType("application/xml");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        Serializable key = repository.insert(mapper.xmlToEntity(req.getReader()));
        String url = req.getScheme() + "://" + req.getServerName() + ":"
                  + req.getServerPort() + req.getContextPath()
                  + req.getServletPath() + "/" + key;
        resp.setHeader("Location", url);
        resp.setStatus(HttpServletResponse.SC_CREATED);
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) {
        getEntity(req);
        repository.update(getKey(req), mapper.xmlToEntity(req.getReader()));
        resp.setStatus(HttpServletResponse.SC_OK);
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) {
        repository.delete(getKey(req));
    }
</code></pre>
<p>Again, REST maps one to one with the servlet specification. The <code>doPost</code> mirrors what we saw on the client side. It returns 201, and sets the Location header. There is a minor snafu, though. I have been unable to find the full path to the servlet, so I had to paste it together from all the different parts of the request properties. I would very much appreciate input on how this should be done.</p>
<p>I have one more trick up my sleeve when it comes to the servlet. The code for validating the content of the request is usually littered all over the Servlet. In order to fix this, I use an unchecked exception and override <code>HttpServlet.service</code> to deal with it:</p>
<pre><code>@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
	      throws ServletException, IOException {
    try {
        super.service(req, resp);
    } catch (ServletRequestException e) {
        resp.sendError(e.getStatusCode(), e.getMessage());
    }
}

private Serializable getKey(HttpServletRequest req) {
    // Called from doDelete, doPut and getEntity
    String[] parts = req.getPathInfo().split("/");
    if (parts.length <= 1) {
        throw new ServletRequestException(400, "Missing id");
    }
    return Long.valueOf(parts[1]);
}</code></pre>
<p>Who needs a web framework?! Hahaha!</p>
<h3>Testing it all</h3>
<p>I have created two implementations of the <code>RESTHttpClient</code> used by the <code>RESTClientRepository</code>. One is <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/test/java/no/brodwall/insanejava/rest/RESTServletClient.java?view=markup">a bridge</a> from the interface to HttpServletRequest and HttpServletResponse. This way, I can test the client and server connection in memory. This is very fast so it comes in quite handy. The code uses <code>spring-mock</code> <code>MockHttpServletRequest</code> and <code>MockHttpServletResponse</code>.</p>
<p>Here is <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/test/java/no/brodwall/insanejava/rest/CategoryRESTRepositoryTest.java?view=markup">the code</a> that runs the http to servlet bridge test:</p>
<pre><code>
public class CategoryRESTRepositoryTest extends RepositoryTest&lt;Category> {

    private final static String SERVLET_PATH = "/test";

    private Repository&lt;Category> serverRepo=new MemoryRepository&lt;Category>();

    private CategoryToXmlMapper entityToXmlMapper = new CategoryToXmlMapper();

    private Servlet restRepoServlet =
                new RESTRepositoryServlet&lt;Category>(serverRepo, entityToXmlMapper);

    private Repository&lt;Category> clientRepo = new SessionCachedRepository&lt;Category>(
                new RESTClientRepository&lt;Category>(
                      toUrl("http://foobar.com:83112", SERVLET_PATH),
                      new RESTServletClient(restRepoServlet, SERVLET_PATH),
                      entityToXmlMapper));

    @Override
    protected Repository&lt;Category> getRepository() {
        return clientRepo;
    }

    private int index = 0;

    @Override
    protected Category createDistinctObject() {
        return new Category("foo " + index++, CategoryType.OPEN);
    }
</pre>
<p></code></p>
<p>Notice how I wrap the <code>RESTClientRepository</code> in a <code>SessionCachedRepostory</code>. This way, we can reuse the implementation of this code.</p>
<p>Of course, no test of Web Services would be complete without there at least being some traffic over the network! Following the <a href="http://www.brodwall.com/johannes/blog/2006/12/10/in-process-web-integration-tests-with-jetty-and-jwebunit/">recipe on how to run unit test with Jetty</a>, I <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/test/java/no/brodwall/insanejava/rest/CategoryIntegrationTest.java?view=markup">start the servlet in Jetty</a> and run the unit tests with it. This code <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/main/java/no/brodwall/insanejava/rest/RESTHttpClientImpl.java?view=markup">implements</a> my <code>RESTHttpClient</code> using <code>java.net.HttpURLConnection</code>. It's a horrible class, but it's usable (barely).</p>
<h3>Conclusion</h3>
<p><a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/test/java/no/brodwall/insanejava/rest/RepositoryTest.java?view=markup">RepositoryTest</a> tests a generic <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/main/java/no/brodwall/insanejava/rest/Repository.java?view=markup">Repository</a> interface with three implementations: In-memory, simulated servlets, and real http traffic. The <code>RepositoryTest</code> has almost all the code, and there are only minimal overrides in the subclasses. This illustrates how to reuse tests in different contexts. The test is also a good example of how to test on a black-box level, focusing on the interesting behavior, and not the implementation.</p>
<p><a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/main/java/no/brodwall/insanejava/rest/RESTClientRepository.java?view=markup">RESTClientRepository</a> and <a href="http://svn.brodwall.com/index.cgi/demo/insanejava/trunk/rest-demo/src/main/java/no/brodwall/insanejava/rest/RESTRepositoryServlet.java?view=markup">RESTRepositoryServlet</a> implements the client and server-side parts of a full REST stack. I have done the XML binding as simple as possible in this article, but in a later post, I will explore how to do more interesting stuff with the XML binding, including implementing lazy relationships over REST.</p>
<p>The <a href="http://svn.brodwall.com/demo/insanejava/trunk/rest-demo/">source</a> of the article is available under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache Software License</a>. Feel free to use it any way you see fit. However: I will be extremely grateful if you <a href="mailto:johannes@brodwall.com">drop me a line</a> if you find it useful, or if there's anything you'd like to see improved.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2007/03/03/a-brief-adventure-with-universal-repositories-and-rest-web-services/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>CRUD, REST, DDD, Rails &#8211; these are a few of my favorite things</title>
		<link>http://johannesbrodwall.com/2007/02/27/crud-rest-rails/</link>
		<comments>http://johannesbrodwall.com/2007/02/27/crud-rest-rails/#comments</comments>
		<pubDate>Tue, 27 Feb 2007 23:27:53 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Ruby-on-Rails]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2007/02/27/crud-rest-rails/</guid>
		<description><![CDATA[Some time back, I watched a video David Heinemeier Hansson give a talk on ActiveResource on RailsConf. The thing that struck me is how much Rails&#8217; ideas are connected to those of Domain-Driven Design. Watching DHH is like seeing a version of Eric Evans on speed.
The video is long, but very entertaining. And it is [...]]]></description>
			<content:encoded><![CDATA[<p>Some time back, I watched a video David Heinemeier Hansson give <a href="http://www.scribemedia.org/2006/07/09/dhh/">a talk on ActiveResource</a> on RailsConf. The thing that struck me is how much Rails&#8217; ideas are connected to those of <a href="http://domaindrivendesign.org/">Domain-Driven Design</a>. Watching DHH is like seeing a version of Eric Evans on speed.</p>
<p>The video is long, but very entertaining. And it is well worth watching even if you couldn&#8217;t care less about Rails. DHH explains in real concrete terms how to <em>think</em> in terms of Domain-Driven Design, even though from the sound of it, I don&#8217;t think he&#8217;s heard of the term. The subtitle of DHH&#8217;s talk is &#8220;How I stopped worrying and learned to love the CRUD&#8221;. Besides being a reference to one of the best movies ever, this title explains the views of DHH on <a href="http://en.wikipedia.org/wiki/Create%2C_read%2C_update_and_delete">CRUD</a>, <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> and DDD and how they fit together.</p>
<p>CRUD means Create, Retrieve, Update, Delete &#8211; the elementary operations on data. In many ways the POST, GET, PUT, DELETE http verbs in REST correspond to INSERT, SELECT, UPDATE, DELETE in SQL and Create, Retrieve, Update, Delete in the CRUD acronym. Thinking in REST means that you can only Create, Retrieve, Update or Delete stuff. But what about, say, making a Prospect Party into a Customer Party. This is a Business Operation on the Party object, or something, isn&#8217;t it? The <a href="http://blueballfixed.ytmnd.com/">Enterprisey</a> thing to do is to create a method for it, right?</p>
<p>Not so fast, says DHH (and Evans!): We have a party entity. What if we instead insert a CustomerRelationship on the Party object? Or, in terms of REST:</p>
<pre><code>PUT /party/135122/relationships
&lt;customerRelationship>
  &lt;keyAccountManager>http://my.company.com/employee/652312&lt;/keyAccountManager>
  &lt;validUntil>2007/08/01&lt;/validUntil>
   &lt;customerStatus>GOLD&lt;/customerStatus>
&lt;/customerRelationship></code></pre>
<p>For every enterprisey business operation, there is a new entity trying to break out.</p>
<p>For an excellent example of the applicability of these ideas, see <a href="http://beast.caboo.se/">The Beast Forum implemented in Rails</a>. In not much more than 500 lines of code (yes, that is not a typo &#8211; five hundred! But there are about 1500 lines of template html code as well), they implement implement a fully featured forum, <strong>including</strong> RSS support up the wazzo (much better than PHPBB or JForum), and REST web services up the Wazzo. By following the CRUD conventions, you get it all for free!</p>
<p>CRUD is sooo goood! It taste like ice cream. With peanut butter! Yum!</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2007/02/27/crud-rest-rails/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>On Integration: Consolidated View</title>
		<link>http://johannesbrodwall.com/2006/11/19/on-integration-consolidated-view/</link>
		<comments>http://johannesbrodwall.com/2006/11/19/on-integration-consolidated-view/#comments</comments>
		<pubDate>Sun, 19 Nov 2006 21:24:13 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2006/11/19/on-integration-consolidated-view/</guid>
		<description><![CDATA[In my last post, I wrote about four integration scenarios using databases: Reference data, Consolidated view, Subscription and Publishing. Of these, the Consolidated View scenario requires the most interaction between the server and the client roles. This post will examine how to make the pieces fit together.
Consolidated view joins the data of multiple clients into [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="">last post</a>, I wrote about four integration scenarios using databases: Reference data, Consolidated view, Subscription and Publishing. Of these, the Consolidated View scenario requires the most interaction between the server and the client roles. This post will examine how to make the pieces fit together.</p>
<p>Consolidated view joins the data of multiple clients into a consolidated view. This makes you able to create administrative applications that span a set of subapplications without having to change the central view when a new application joins the mix.</p>
<p><a class="imagelink" href="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/consolidated-view-app.png" title="consolidated-view-application"><img id="image142" src="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/consolidated-view-app.png" alt="consolidated-view-application" width="400" /></a></p>
<p>In order to work smoothly, a Consolidated View application uses two forms of integration: The client application write to their partitions of a table in the server application, and the view of the server application redirects to the view of the client applications. Here is an example:</p>
<ol>
<li>A user wants to list all the contracts defined for a customer, regardless of what application manages that contract</li>
<li>The Consolidated View application lists some contracts from Client Application 1, some contracts from Client Application 2 and so on</li>
<li>The user clicks on the line associated with a Client Application 1 contract</li>
<li>The consolidated view application has registered the URL for this kind of contract to be handled by a another application. It redirects (or proxies) the user to (for example) http://a.server.name:3223/clientApp1/contracts/foo_contract/?id=3313</li>
<li>Client Application 1 lets the user interact with the data in any way the user desires</li>
<li>Client Application 2 updates the consolidated view application database to reflect any changes to the contract</li>
<li>The Contract has a link back to &#8220;View All Contracts for this Customer&#8221;. The user clicks this link and is brought back to the Consolidated View application</li>
<li>The user wants to add a new type of contract to this Customer. This particular type of contract is handled by Client Application 2. The user clicks &#8220;Add bar contract&#8221;</li>
<li>The consolidated view application has registered the URL for inserting new contracts like these for the customer. It redirects (or proxies) the user to (for example) http://b.server.name:3311/clientApp2/contracts/bar_contract/new?customer=1234</li>
<li>Client Application 2 lets the user enter the data to create the new contract</li>
<li>Client Application 2 updates the database for the consolidated application to include the new contract</li>
</ol>
<p>In this scenario, the <em>only thing</em> the Consolidated View application knows about specific types of contract is where the user can be redirected in order to create or modify them. If a new application is added, a new row needs to by added to the <tt>contract_type</tt> table in the Consolidated View database. That is all. This means that despite the fact that the user is presented with a unified view of the data, the applications are very decoupled.</p>
<p>The downsides of using this solution is that there is still some coupling, and this coupling is now more implicit. If any of the client applications move to a new URL, someone has to remember to update the consolidated view application. Even worse: If the client applications link back to the server application, we have to remember to update all client applications if the server application moves. Of course, the last problem can be solved (if we really want to) by having the consolidated view server application URL be part of a Reference Data domain.</p>
<p>I hope this article has been concrete enough to show you, dear reader, how to solve problems elegantly using no application-level integration mechanisms. In my next post, I plan on examining how to get the various scenarios to scale.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2006/11/19/on-integration-consolidated-view/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Integration: Organizing the data</title>
		<link>http://johannesbrodwall.com/2006/11/11/on-integration-organizing-the-data/</link>
		<comments>http://johannesbrodwall.com/2006/11/11/on-integration-organizing-the-data/#comments</comments>
		<pubDate>Sat, 11 Nov 2006 17:35:56 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2006/11/11/on-integration-organizing-the-data/</guid>
		<description><![CDATA[In my last post on using the database for integration, I argued that the best metaphor for creating systems that are interconnected is that of One-Large Database. Carl-Henrik asked some very relevant questions about this, which I will interpret (for now) mainly as &#8220;how do you avoid drowning in complexity&#8221;. This post will address the [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.brodwall.com/johannes/blog/2006/10/18/on-integration-why-i-enjoy-working-with-databases">last post</a> on using the database for integration, I argued that the best metaphor for creating systems that are interconnected is that of One-Large Database. Carl-Henrik asked some very relevant questions about this, which I will interpret (for now) mainly as &#8220;how do you avoid drowning in complexity&#8221;. This post will address the issue of maintainability, especially when things grow to be large.</p>
<p>The On Large Database metaphor is mostly useful as a starting point. The first thing I notice when I look at our systems that have been organized this way is the fact that the data-structure is far from flat. Each application will deal with four categories of tables. First, an application has a large private domain, containing tables that the rest of the world has no business messing with. Second, it exports some tables that other applications use. Third, it imports tables exported by other applications. And finally, there are some tables that are shared by a number of applications with no clear owner. The last case is something we normally want to avoid.</p>
<p>In my experience, the integration scenarios can further be divided into four cases: Reference data, Consolidated data, Published data, and Subscription data.</p>
<p>Perhaps the most useful of the integration scenarios is that of <em>Reference Data</em>. Reference Data is exported by an application that is responsible for maintaining the data. Applications import Reference Data <em>read-only</em>. Reference data is very common in all domains. It often contains customer databases and other core data entities.</p>
<p><a class="imagelink" href="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/reference-data.png" title="reference-data"><img id="image139" src="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/reference-data.png" alt="reference-data" width="300" /></a></p>
<p>In some special cases, you might want shared data to be updated by a distributed set of applications. I call this scenario <em>Consolidated View</em>. One application is responsible for displaying a shared view of data that is being maintained by a number of applications. Each application will normally be responsible for reading <em>and updating</em> a subset of the shared data. This scenario is not as common as Reference data, but we see it for example in a situation where we want a consolidated view of all the contracts a particular customer (which is in the Reference data domain) holds. The different contracts are defined in the applications that operate on them (for example, a contract for a payment service is defined in the payment service system). A consolidated view allows us to display all the contracts a customer holds, even though the details are distributed in a number of applications.</p>
<p><a class="imagelink" href="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/consolidated-view.png" title="consolidated-view"><img id="image135" src="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/consolidated-view.png" alt="consolidated-view" width="300" /></a></p>
<p>These two scenarios are the ones used for sharing data. The last two scenarios are used to delegate responsibility. I call them <em>Publishing</em> and <em>Subscription</em> domains, respectively. Essentially, the subscribing party in these scenarios will poll the database at an appropriate interval. A little or a lot of sophistication can be put into the polling implementation as desired.</p>
<p>Publishing domains distribute data from <em>one</em> application to many. The domain is exported by the publishing application. Each subscribing application is usually responsible for a partition of the data. They will remove or update this data as they consume it. The most common example is an application that receives files that should be processed by one of many applications, depending on the type of file.</p>
<p><a class="imagelink" href="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/published.png" title="published"><img id="image136" src="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/published.png" alt="published" width="300" /></a></p>
<p>Subscription domains collect data from <em>many</em> applications into one. The domain is exported by the subscribing application, which also may remove and update data. The publishing applications insert data into the subscription domain. The most common example of subscription domain is an application collecting events for distribution or for billing.</p>
<p><a class="imagelink" href="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/subscription1.png" title="subscription"><img id="image138" src="http://www.brodwall.com/johannes/blog/wp-content/uploads/2006/11/subscription1.png" alt="subscription" width="300" /></a></p>
<p>Notably absent from the list is the one-to-many event publishing scenario. All the publish-subscribe scenarios I have talked about are point-to-point, not broadcasts. This is by design. All the examples we have seen so far have been broadcasting changes to a Reference domain. So far, it seems like these scenarios are better served by having a tighter integration with the Reference domain. I am still looking for counter examples.</p>
<p>In each of the four scenarios I have listed (Reference Data, Consolidated View, Publishing, Subscription) there is a clear definition of who is the client and who is the server. There is also a clear definition of which operations should be allowed by each party. For example, in the Consolidated View, the clients should be able to Created, Update and Delete data in their segment of the domain, and the server should only Read data. We currently implement these restrictions as GRANTS in the database.</p>
<p>In most domain, the manageability can be improved by simplifying the exported domains. This can be implemented by using VIEWS. VIEWS will also allow the server to change the internal structure without breaking clients, and allow clients that need different versions of the exported domain to coexist. It is important to note that for an application, it is transparent whether it is accessing a TABLE or a VIEW. This means that we can at a later time replace tables with views. I might write more on views in a later post.</p>
<p>I hope this post explains how to make the Single Database vision Manageable. Seen from one application, we will still maintain the illusion that it has direct access to all data. By using SYNONYMS, we can make the logical division into imported and exported domains transparent. This means that the application will be deployed in a single database schema in development and test environments, and the full glory of the integrating applications will only be revealed when we put the application into integration tests or production environments.</p>
<p>The fact that we have defined a limited number of integration scenarios mean that we can analyze how to make each scale separately. Stay tuned for my next post, where I discuss how to make the Single Database Vision scale to scenarios where different applications have to use different database instances.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2006/11/11/on-integration-organizing-the-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Integration: Why I enjoy working with databases</title>
		<link>http://johannesbrodwall.com/2006/10/18/on-integration-why-i-enjoy-working-with-databases/</link>
		<comments>http://johannesbrodwall.com/2006/10/18/on-integration-why-i-enjoy-working-with-databases/#comments</comments>
		<pubDate>Wed, 18 Oct 2006 20:43:21 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2006/10/18/on-integration-why-i-enjoy-working-with-databases/</guid>
		<description><![CDATA[Status: This article is currently pretty dry. I&#8217;d like feedback on how to make it more eloquent.
In my previous blog post, I promised to write more about using databases as the main integration strategy. In the current post, I plan to cover maybe the most important question: &#8220;Why?&#8221;
Imagine an application where every time it wants [...]]]></description>
			<content:encoded><![CDATA[<p><i>Status: This article is currently pretty dry. I&#8217;d like feedback on how to make it more eloquent.</i></p>
<p>In my <a href="http://www.brodwall.com/johannes/blog/2006/10/07/on-integration-the-vision-of-a-single-database/">previous blog post</a>, I promised to write more about using databases as the main integration strategy. In the current post, I plan to cover maybe the most important question: &#8220;Why?&#8221;</p>
<p>Imagine an application where every time it wants to communicate with another system, it reads or writes to the database. For now, let&#8217;s ignore how this would work, and how it would evolve, which will be the subject of later posts. What advantages does this offer?</p>
<p>The alternative is usually to integrate with another system though a variety of means. In Java, the most common ones are Web Services, RMI, EJBs (which offers it own quirks in addition to those of RMI), Sockets, and various tricks using the file system.</p>
<p>The most important issue to me is invariably productivity. When I work with databases, I generally can use Object-Relation Mapping tools. This is a very productive way of accessing database data in an application. RMI offers similar advantages, but you will have to <a href="http://today.java.net/pub/a/today/2006/07/13/lazy-loading-is-easy.html">build lazy loading</a> on top of the domain model if you want to have a rich model where the objects are interconnected. Web Services generally have some bindings to Java, but in my experience, these are really inadequate. Either the Java side suffers, for example by forcing you to have getters and setters, by forcing you to use arrays instead of collections, or by forcing you to use strings as the main data type. Alternatively, the XML-side suffers by having non-specific types (if you use collections). Sockets, of course are very unproductive. They give up productivity for simplicity.</p>
<p>The data that is managed by the remote service generally will come from a database anyway. This means that the data access code will be have to be developed somewhere anyway. A remoting layer will have to be developed in addition.</p>
<p>To maintain sustainable productivity, we need unit tests. Unit testing has for me proved to be hard to do well for both Web Services and RMI, and EJBs are of course out of the question. As my regular readers know, <a href="http://today.java.net/pub/a/today/2005/10/11/testing-hibernate-mapping.html">using a test database</a> for standalone unit testing is quite simple. As an added bonus, tests that use the database will essentially have verified the integration. When I use a remoting protocol, I always run into strange problems very late in the test process.</p>
<p>Both unit testing and productivity benefits from the fact that dealing with databases is something we&#8217;ve done for a long time. The tools and techniques for doing so are very mature, compared to other methods of integration.</p>
<p>Secondly, there is the problem of reliability. If you use a single database, everything you do is within one transaction. Either all work will be committed, or it will be rolled back. This vastly simplifies your logic if you care about your correctness. For distributed systems, this will in theory be solved by the 2-phase commit protocol. However, my experience is that this adds so much complexity to a solution that the system can metaphorically collapse under its own weight. As a result, most solutions I&#8217;ve seen (and, I suspect, most solutions I haven&#8217;t) simply ignore this problem. This means that the odd resource error that occurs might very well have very unpredictable results.</p>
<p>A remote layer will also introduce another place where things can go wrong. Many developers end up coding recovery rutines for dealing with these kinds of errors. In my experience, this is some of the most error prone code you can write.</p>
<p>Third, performance-wise it is hard to beat the database. Most other methods will eventually hit the database anyway, and as a general rule, adding more steps to a solution seldom makes it faster. There are some issues with scalabilitity, however, that I will address in a later post.</p>
<p>Last, and maybe most importantly, I have never seen a standard interface for dealing with remote services. Solutions generally end up having half-a-dozen or more different policies for accessing different back end systems. There is one thing we will always be sure of, though: There&#8217;ll always be a database among these backend systems, no matter what else you have to talk to. Every extra communication mechanism you remove will reduce the shoestring-and-paperclip-factor of your system.</p>
<p>By using a single data source as the place for communicating with other systems, we will reduce complexity and improve testability, performance and reliabilty.</p>
<p>I hope that in this post, I have demonstrated why, in an ideal world, you would want to use a single database as your primary integration mechanism. However, the world is rarely ideal. Database schemas change, more load is added than what a single database can tackle, you have to understand a forest of database schemas, some applications should not be allowed to access all the data. In my next blog post, I will talk about how to solve these problems with database without giving up the single database vision. Stay tuned for evolution, scalability, security, reuse, and understandability.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2006/10/18/on-integration-why-i-enjoy-working-with-databases/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
