02.03.2015 Views

SDN_Magazine_124

SDN_Magazine_124

SDN_Magazine_124

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

MAGAZINE<br />

SOFTWARE DEVELOPMENT NETWORK<br />

ISSN: 2211-6486<br />

IN DIT NUMMER O.A.:<br />

Remote debugging naar een Azure VM <<br />

Decrease dataflows between systems with CDC <<br />

SQL Server In-Memory OLTP <<br />

SCRUM is meer dan een project management methodologie <<br />

Nummer <strong>124</strong> februari 2015 <strong>SDN</strong> <strong>Magazine</strong> verschijnt elk kwartaal en is een uitgave van Software Development Network<br />

<strong>124</strong><br />

www.sdn.nl


Colofon<br />

Uitgave:<br />

Software Development Network<br />

Drieëntwintigste jaargang<br />

No. <strong>124</strong> • februari 2015<br />

Bestuur van <strong>SDN</strong>:<br />

Marcel Meijer, voorzitter<br />

Rob Suurland, penningmeester<br />

Remi Caron, secretaris<br />

Redactie:<br />

Marcel Meijer<br />

(redactie@sdn.nl)<br />

Aan dit magazine<br />

werd meegewerkt door:<br />

Roel Hans Bethlehem, Bob Swart, Maarten<br />

van Stam, Arjen Bos, Alexander Meijers,<br />

Remi Caron, Marcel Meijer en natuurlijk alle<br />

auteurs!<br />

Listings:<br />

Zie de website www.sdn.nl voor eventuele<br />

source files uit deze uitgave.<br />

Contact:<br />

Software Development Network<br />

Postbus 506, 7100 AM Winterswijk<br />

Tel. (085) 21 01 310<br />

E-mail: info@sdn.nl<br />

Vormgeving en opmaak:<br />

Reclamebureau Bij Dageraad, Winterswijk<br />

www.bijdageraad.nl<br />

©2015 Alle rechten voorbehouden. Niets uit<br />

deze uitgave mag worden overgenomen op<br />

welke wijze dan ook zonder voorafgaande<br />

schriftelijke toestemming van <strong>SDN</strong>. Tenzij<br />

anders vermeld zijn artikelen op persoonlijke<br />

titel geschreven en verwoorden zij dus niet<br />

noodzakelijkerwijs de mening van het bestuur<br />

en/of de redactie. Alle in dit magazine<br />

genoemde handelsmerken zijn het eigendom<br />

van hun respectievelijke eigenaren.<br />

Beste <strong>SDN</strong> <strong>Magazine</strong> lezer,<br />

voorwoord<br />

Hebben jullie met open mond naar de Windows 10 presentatie zitten kijken? Gezien<br />

hoe de opvolger van Windows 8 steeds volwassener wordt en alle plooien er nu wel<br />

uitstrijkt? Heb je al gespeeld met de volgende versie van Office 2015 welke meer gericht<br />

is op touch gebruik? Heb je al gekeken naar de nieuwe Visual Studio versie met<br />

daarin allerlei performance meters? Heb je de vele Microsoft applicaties op het Android<br />

en iOS platform al bekeken? Dat zijn er al ruim 100. In het verleden is<br />

Microsoft vaak verweten dat ze een gesloten omgeving waren, hoewel ze als eerste<br />

ooit voor de MAC applicaties ontwikkelde. Maar tegenwoordig zijn ze nog opener en<br />

laten dat ook graag weten.<br />

In de volgende magazines en events van de <strong>SDN</strong> komen jullie naast artikelen en<br />

sessies van de andere platformen ook verhalen tegen over Microsoft. De <strong>SDN</strong> is voor<br />

alle soorten developers en alle soorten platforms. En dat blijft zo.<br />

Op vrijdag 20 maart is het volgende <strong>SDN</strong> event. Op dit event zal ook de Algemene<br />

leden vergadering weer plaats vinden. Dit is naast natuurlijk rechtstreeks met mij te<br />

mailen of ons te bellen, de uitgelezen kans om je als lid van de vereniging te laten<br />

informeren en te horen over het reilen en zeilen van de vereniging. Kom dus allemaal<br />

en laat je stem spreken.<br />

Dit magazine <strong>124</strong> bevat wederom een uiteenlopende hoeveelheid aan onderwerpen.<br />

Over Dynamics CRM, Remote debugging op Azure, Application Insights deel 2, CDC<br />

wat is de zin en onzin hiervan, Azure Webjobs, Microservices een mooie<br />

verhandeling, de ELK stack wat is het, In-Memory OLTP databases, SCRUM is<br />

bruikbaar in meerdere onderdelen van een organisatie, de Delphi's REST Client<br />

Library, Microsoft Test Manager beschrijving en nog een paar kleine tips en tricks.<br />

Kortom, Bas van de Sande, Cary Jensen, Eric Tummers, Hassan Fadili, Jeffrey<br />

Verheul, Marcel Meijer, Patrick Kalkman, Peter ter Braake. Piet Willem Overvoorde,<br />

Sander Hoogendoorn en Wouter de Kort hebben weer veel tijd gestoken in deze<br />

stuk voor stuk mooie verhalen. Speciaal voor jullie als <strong>SDN</strong> magazine lezer.<br />

Het volgende magazine 125 maken we iets specialer. Daarover later meer.<br />

Heel veel leesplezier en tot 20 maart bij de ALV.<br />

Groeten,<br />

Marcel Meijer eindredacteur <strong>Magazine</strong> en Voorzitter <strong>SDN</strong> •<br />

Adverteerders<br />

Microsoft 2<br />

Achmea 44<br />

Adverteren?<br />

Informatie over adverteren en de advertentietarieven<br />

kunt u vinden op www.sdn.nl<br />

onder de rubriek <strong>Magazine</strong>.<br />

magazine voor software development 3


Agenda 2015<br />

Inhoud<br />

• 16-19 maart 2015<br />

Microsoft Convergence 2015<br />

Atlanta<br />

• 20 maart<br />

<strong>SDN</strong> event, Zeist<br />

• 29 april - 1 mei<br />

//Build<br />

San Francisco<br />

• 4-8 mei<br />

Microsoft Ignite<br />

Chicago at McCormick Place<br />

• 12-13 mei<br />

Techorama Belgium 2015<br />

• 28-29 mei<br />

TechDays, Den Haag<br />

• 12 juni<br />

<strong>SDN</strong> event<br />

• 12-16 juli<br />

Worldwide Partner Conference<br />

Orlando<br />

• 18 september<br />

<strong>SDN</strong> event<br />

03 Voorwoord<br />

Marcel Meijer<br />

04 Inhoudsopgave<br />

04 Agenda<br />

05 Microsoft Dynamics CRM<br />

Bas van de Sande<br />

08 Remote debugging naar een Azure VM<br />

Eric Tummers<br />

10 Application Insights<br />

for Visual Studio Online (Part 2)<br />

Hassan Fadili<br />

15 Decrease dataflows<br />

between systems with CDC<br />

Jeffrey Verheul<br />

17 Azure Webjobs<br />

Marcel Meijer<br />

19 Microservices.<br />

The good, the bad and the ugly<br />

Sander Hoogendoorn<br />

23 Improving traceability<br />

of distributed systems using the ELK stack<br />

Patrick Kalkman<br />

30 SQL Server In-Memory OLTP<br />

Peter ter Braake<br />

32 SCRUM is veel meer dan een<br />

project management methodologie<br />

Piet Willem Overvoorde<br />

36 Delphi's REST Debugger<br />

and REST Client Library, Part 1<br />

Cary Jensen<br />

41 Ken jij Microsoft Test Manager?<br />

Wouter de Kort<br />

43 API Management<br />

Marcel Meijer


GENERAL<br />

Bas van de Sande<br />

Microsoft Dynamics CRM<br />

“A journey of a SharePoint developer into the world of CRM”<br />

Na jarenlang software ontwikkeld te hebben in C#, SQL Server, BizTalk en SharePoint ben<br />

ik onlangs overgestapt op het Microsoft Dynamics CRM platform. In deze serie artikelen wil<br />

ik mijn ervaringen delen en jullie enthousiast maken voor dit relatief onbekende platform.<br />

In dit artikel beschrijf ik in hoofdlijnen wat CRM inhoudt en waarom de ‘C’ van CRM eigenlijk<br />

een ‘x’ hoort te zijn. Ten slotte werp ik een eerste blik onder de motorkap van Microsoft<br />

Dynamics CRM.<br />

Geschiedenis<br />

De eerste versie van Microsoft Dynamics CRM is uitgebracht in 2003.<br />

Microsoft was in die tijd bezig met het opkopen van een aantal<br />

spelers in de ERP en boekhoudmarkt (o.a. Great Plains, Navision) om<br />

zo een positie in de Enterprise markt te verwerven. De CRM, ERP en<br />

boekhoudproducten zijn later ondergebracht onder de noemer<br />

Microsoft Dynamics, te weten AX (ERP), NAV (boekhouding) en<br />

uiteraard CRM. Op dit moment is CRM 2015 net beschikbaar<br />

gekomen. Naast de on-premise versie is CRM ook verkrijgbaar als<br />

CRM Online.<br />

Wat is CRM?<br />

CRM staat voor Customer Relationship Management, oftewel het<br />

beheren van de relatie tussen een klant en een organisatie. Elke<br />

klantrelatie kent een levensduur die uit een aantal fases bestaat.<br />

De inzet van CRM is er opgericht om de klant in iedere fase van de<br />

relatie optimaal te kunnen bedienen om zo een maximaal rendement<br />

uit de relatie te halen.<br />

Maar niet iedereen die een relatie met een organisatie of bedrijf<br />

onderhoudt, is per definitie een ‘customer’. Je kan bijvoorbeeld lid<br />

van zijn van een vereniging, deelnemer aan een community, donateur<br />

van een goed doel, student bij een opleidingsinstituut of juist leverancier<br />

aan een bedrijf.<br />

Microsoft Dynamics CRM<br />

Net zoals bijvoorbeeld SharePoint is ook Microsoft Dynamics CRM<br />

beschikbaar als een on-premise versie (CRM 2013/2015) en online<br />

als CRM Online. Echter, in tegenstelling tot SharePoint lopen de<br />

on-premise en de online versie van CRM voor de ontwikkelaar niet ver<br />

uitelkaar en kun je de technieken die je gebruikt voor je on-premise<br />

oplossing gemakkelijk naar de online versie brengen. Zowel de<br />

on-premise als de online versie bieden een goede ondersteuning voor<br />

mobiele devices (iOS, Android en Windows Phone).<br />

Microsoft Dynamics CRM integreert nagenoeg naadloos binnen de<br />

Office suite (add-in voor Outlook) en leunt technologisch zwaar op<br />

de SQL Server database, SQL Server Reporting Services, Internet<br />

Information Server en het Microsoft.Net framework (sandbox). Kortom,<br />

alle bouwstenen voor een solide applicatieplatform zijn hiermee<br />

voorhanden.<br />

Zowel de on-premise als de online versie van CRM ziet er in hoofd lijnen<br />

als volgt uit:<br />

De ‘C’ in CRM moet je dus ruim zien en de essentie van CRM is het<br />

optimaal bedienen van de relatie tussen een persoon of organisatie en<br />

jouw organisatie. De ‘C’ moet je dan eigenlijk ook zien als een ‘x’,<br />

waarbij de ‘x’ staat voor de andere partij.<br />

Als ontwikkelaar moet je er altijd rekening mee houden dat CRM wordt<br />

ingezet om te voorzien in een functionele behoefte. CRM wordt, in<br />

tegenstelling tot andere softwareproducten, niet vanuit de IT-afdeling<br />

gepusht, maar juist geïnitieerd voor en/of door de gebruiker; vaak<br />

werkzaam op de klantgerichte afdelingen binnen het bedrijf (marketing,<br />

verkoop, ledenadministratie, klantenservice). Binnen CRM zijn<br />

de klantgegevens, en wat de organisatie wil met die klantgegevens<br />

leidend, de technologie is volgend.<br />

In projecten betekent dit dat oplossingen grotendeels door functionele<br />

consultants in samenwerking met de gebruikers in elkaar worden<br />

gezet. Daar waar nodig mogen wij - ontwikkelaars - bijspringen om<br />

de complexe onderdelen, rapportages, integraties te ontwikkelen en<br />

om de gebouwde oplossing in de vorm van een solution uit te rollen.<br />

Fig. 1: schematische weergave opbouw Microsoft Dynamics CRM<br />

De business functionaliteit van Microsoft Dynamics CRM wordt<br />

ontsloten door middel van een .NET API. Daarbovenop is een web<br />

magazine voor software development 5


GENERAL<br />

API geplaatst waarmee allerlei client applicaties verbinding kunnen<br />

maken. Binnen de formulieren kan gebruik gemaakt worden van<br />

javascript om extra functionaliteit te ontsluiten.<br />

The power of SQL Server<br />

De kern van CRM zijn de SQL Server databases. Een van de data -<br />

bases bevat metadata omtrent de configuratie, verder is er nog een<br />

content database. Deze database bevat de feitelijke data.<br />

Waarin CRM hemelsbreed verschilt ten opzichte van SharePoint, is<br />

dat in de CRM data fysieke entiteiten en velden worden aangemaakt<br />

waarin de data wordt opgeslagen. Dit in tegenstelling tot SharePoint,<br />

waarbij de database bestaat uit een aantal metatabellen en data -<br />

tabellen, waar op basis van de opgeslagen meta-informatie de echte<br />

data kan worden teruggevonden. Hier ligt dan ook echt de kracht van<br />

CRM, namelijk een échte database, met fysieke relaties tussen<br />

entiteiten (referentiële integriteit).<br />

Het is echter niet de bedoeling dat gegevens rechtstreeks in de<br />

database worden aangepast; je zou daarmee een aantal ingestelde<br />

business rules kunnen overtreden (constraints). Het aanpassen van<br />

de data gebeurt via het objectmodel dat CRM je ter beschikking stelt.<br />

Nu vraag je je waarschijnlijk af: “Ja… maar als ik nou niet de regels<br />

overtreed, waarom mag ik dan niet rechtstreeks de tabellen<br />

vullen?”. Dat heeft te maken met de manier waarop<br />

Microsoft Dynamics CRM omgaat met aanpassingen<br />

op het applicatieplatform.<br />

In de online versie is het niet mogelijk om rechtstreeks bij de<br />

onderliggende SQL Server databases te komen, waar je<br />

normaal als DBA extra indexen kan leggen om de performance<br />

te verbeteren. In dat geval zal je terug moeten<br />

vallen op Microsoft support. Zij kunnen dit voor je doen.<br />

Reporting<br />

Als CRM ontwikkelaar werk je normaal gesproken tegen<br />

het objectmodel aan. Echter, in het geval van rapportages<br />

werk je tegen een database view aan die door CRM wordt<br />

beheerd.Microsoft Dynamics CRM maakt gebruik van SQL<br />

Server Reporting Services. Juist omdat CRM geheel is<br />

gebaseerd op data, gebruikt het gelukkig ook de kracht van<br />

de onderliggende SQL Server database om query’s uit te<br />

voeren. Je kan dan ook in de datasets die je maakt<br />

volledig gebruik maken van de mogelijkheden van<br />

Transact SQL. De report definities die uit SSRS voort -<br />

komen, kun je later uitrollen via je eigen solution.In de online<br />

versie kun je geen gebruik maken van SQL query’s, je<br />

moet hier met FetchXML werken. FetchXML is een op<br />

XMLgebaseerde querytaal voor Dynamics CRM.<br />

van de solution worden aanpassingen binnen de database gemaakt,<br />

hierbij wordt de oorspronkelijke structuur met rust gelaten.<br />

Wanneer je met bijvoorbeeld SQL Server Management Studio naar de<br />

database kijkt, zie je dat van een bepaalde entiteit (bijvoorbeeld<br />

Account) meerdere tabellen bestaan. Wanneer je de geïnstalleerde<br />

solution verwijdert, dan zullen eventuele aangemaakte tabellen of<br />

relaties verdwijnen.<br />

Het solution mechanisme van Microsoft Dynamics CRM is erg<br />

krachtig en ook gemakkelijk in het gebruik. Je hoeft geen ingewikkelde<br />

provisioning te bouwen en je kunt de solution letterlijk in elkaar<br />

klikken.Solutions die zijn gemaakt op één omgeving kan je exporteren,<br />

zodat je deze op een andere omgeving kan importeren en uitrollen.<br />

Dit mechanisme leent zich uitstekend voor een OTAP straat.<br />

Autorisatie<br />

Net als ieder server platform, maakt ook Microsoft Dynamics CRM<br />

gebruik van autorisatie. Hierin gaat Microsoft Dynamics CRM erg ver<br />

- terecht trouwens, want je werkt vaak met erg gevoelige informatie.<br />

De data die in CRM is opgeslagen, wordt beschermd door middel van<br />

een zeer uitgebreide autorisatiematrix (door een beheerder instelbaar).<br />

Fig. 2: voorbeeld autorisatiematrix binnen CRM<br />

Het werken met solutions<br />

Net zoals Microsoft SharePoint is ook Microsoft Dynamics<br />

CRM een applicatieplatform, waarbij ontwikkelaars en<br />

gebruikers aanpassingen kunnen maken om zo toepassingen<br />

te maken die aansluiten op de processen binnen de<br />

organisatie.<br />

Binnen Microsoft Dynamics CRM is altijd minimaal één<br />

solution geïnstalleerd. Dit is de default solution. Als je<br />

wijzingen maakt op de default solution pas je hiermee de<br />

kern van CRM aan. De wijzigingen die je uitvoert, kunnen<br />

niet met één druk op de knop worden verwijderd.<br />

Om te waarborgen dat je aanpassingen wel ongedaan<br />

gemaakt kunnen worden, maak je gebruik van solutions.<br />

Binnen de solution wordt van alle objecten die je gaat<br />

aanpassen (die je dus toevoegt aan de solution) een kopie<br />

gemaakt en met deze kopie ga je aan het werk.<br />

Nadat je de wijzigingen hebt doorgevoerd publiceer je deze<br />

naar Microsoft Dynamics CRM toe. Tijdens het publiceren<br />

Fig. 3: autorisatieniveaus binnen CRM<br />

6<br />

MAGAZINE


GENERAL<br />

In de matrix wordt vastgelegd wie wat mag doen met welke data en<br />

wie eigenaar is van welke data. Dit is te vergelijken met item level<br />

security binnen SharePoint, maar dan vele malen krachtiger en<br />

uitgebreider uitgevoerd.<br />

Per gebied, rol, veld en/of entiteit kan worden vastgelegd wie wat met<br />

data mag doen en wie eigenaar is van de data. In onderstaande<br />

afbeelding geef ik aan wat de symbolen voorstellen<br />

Binnen CRM modelleer je de organisatie. Een organisatie bestaat uit<br />

business units (dit kunnen business units maar ook afdelingen zijn, en<br />

kunnen hiërarchisch worden weergegeven). Op het onderste niveau<br />

staat de gebruiker. De autorisatiematrix maakt gebruik van dit principe<br />

en de symbooltjes geven aan wie de eigenaar is van de gegevens<br />

binnen CRM. Naarmate het bolletje meer is ingekleurd, is er een<br />

grotere groep die toegang heeft tot de gegevens.<br />

Ogenschijnlijk een eenvoudig te gebruiken mechanisme, maar in de<br />

praktijk een van de lastigste onderdelen binnen CRM om te<br />

doorgronden.<br />

Ten slotte<br />

Mijn ervaringen tot zover met Microsoft Dynamics CRM is dat het een<br />

erg krachtig platform is om bedrijfstoepassingen te bouwen waarin<br />

relaties tussen organisaties en personen worden onderhouden.<br />

Wanneer je gewend bent om te ontwikkelen op een platform als<br />

SharePoint zal je aangenaam verrast worden door een aantal zaken<br />

die standaard voor je geregeld worden binnen CRM zonder dat je je<br />

hiervoor in allerlei bochten hoeft te wringen.<br />

Het prettige aan het ontwikkelen op CRM is dat het eigenlijk niet<br />

uitmaakt of je voor de on-premise of voor de online versie ontwikkelt.<br />

Het enige verschil dat ik ben tegengekomen zit hem in het moeten<br />

gebruiken van FetchXML wanneer je met SQL Server Reporting<br />

Services werkt.<br />

Microsoft Dynamics CRM is geen wondermiddel; maar wel een goed<br />

stuk gereedschap dat je moet inzetten waarvoor het bedoeld is,<br />

namelijk het onderhouden van relaties en processen die daarmee<br />

gerelateerd zijn. •<br />

Bas van de Sande<br />

Bas van de Sande heeft zich sinds<br />

1995 gespecialiseerd in softwareontwikkeling<br />

en advisering op het<br />

Microsoft platform. Hij heeft zich<br />

sinds 2005 voornamelijk bezig<br />

gehouden met SharePoint en<br />

Microsoft.Net. Op dit moment ligt<br />

zijn focus op Microsoft CRM en<br />

blogt hij zeer actief over zijn<br />

ervaringen met CRM. Bas is werkzaam als Senior Software<br />

Developer/Architect bij CRM Partners.<br />

ConnectionStrings / AppSettings Azure<br />

Zoals je op pagina 17 in dit magazine kunt lezen, wordt een Webjob gedeployed<br />

bij een Azure website. Bij de Webjob hoort ook een dashboard. Na het deployen<br />

van de Webjob waren er Errors en Warnings over een setting. Zoals de error/<br />

warning verteld, moet je de Connectionstring toevoegen aan het Connection string<br />

gedeelte van de Azure website. Daarna is de error/warning weg.<br />

In je code gebruik je:<br />

var storageAccount =<br />

CloudStorageAccount.Parse(<br />

ConfigurationManager.<br />

ConnectionStrings[“AzureWebJobsStorage”].<br />

ConnectionString<br />

);<br />

Maar de Connectionstrings of App settings geef je een waarde op de Configure<br />

tab van de Azure Website.<br />

Nu lijkt het net of je deze Connectionstring op twee plekken moest configureren.<br />

Een keer op de portal en een keer in de app.config van de Webjob. Dat zou niet<br />

mooi zijn, maar dat blijkt ook niet te hoeven.<br />

En dit werkt ook voor de App.config van een Azure Webjob.<br />

Meer informatie: http://www.asp.net/identity/overview/features-api/best-practices-for-deploying-passwords-and-other-sensitive-data-to-aspnet-and-azure<br />

magazine voor software development 7


CLOUD<br />

Eric Tummers<br />

Remote debugging<br />

naar een Azure VM<br />

Je hebt OTAP met Windows Azure virtual machines ingericht. Deployment gebeurd automatisch<br />

na een nightly build. Alles is koek-en-ei totdat er een probleem optreedt dat je wil debuggen.<br />

Hoe doe je dat in Azure? Installeren van Visual Studio op de VM lijkt de enige optie? Gebruik<br />

Remote Debugging vanuit je development machine naar een Azure VM.<br />

Debugger extension<br />

Via de Server Explorer in Visual Studio kan de debugger extension op<br />

een Azure VM geïnstalleerd worden. Integratie in Visual Studio maakt<br />

het makkelijker om een debug session te starten.<br />

VPN<br />

Als jouw development machine in hetzelfde network zit, kun je een<br />

remote debugging sessie starten. Hiervoor maak je een VPN aan.<br />

Ga naar het virtual network in de azure portal. Open de Configure tab<br />

en check Configure point-to-site connectivity. Kies daarna een<br />

starting IP.<br />

Fig. 2: Point-to-site connectivity van virtual network<br />

De sectie eronder zal de melding geven dat een gateway nodig is. Klik<br />

add gateway subnet en wijzig indien nodig het starting IP. Kies Save<br />

en wacht tot alle wijzigingen zijn doorgevoerd.<br />

Fig. 1: Remote debugger extension installation<br />

Hiermee worden echter wel drie poorten geopend en dat is een optie<br />

die je mogelijk niet hebt. Dan moet een VPN gebruikt worden en de<br />

remote debugging tools.<br />

Virtual Network<br />

Een best practice is om je VM’s in een virtual network te plaatsen.<br />

Hierdoor kunnen machines elkaar makkelijker vinden. Ook bied het<br />

een extra laag van beveiliging, omdat poorten voor interne<br />

communicatie niet naar de boze buitenwereld open staan.<br />

Fig. 3: Gateway van virtual network<br />

Open een Visual Studio Command prompt en maak een self-signed<br />

root certificate aan. Maak ook een authenticatie certificaat aan voor het<br />

root certificaat.<br />

8<br />

MAGAZINE


CLOUD<br />

makecert -sky exchange -r -n "CN=MyNetwork"<br />

-pe -a sha1 -len 2048 -ss My "MyNetwork.cer"<br />

makecert -n "CN=Developer" -pe -sky exchange<br />

-m 96 -ss My -in "MyNetwork" -is my -a sha1<br />

Listing 1: Self-signed root certificate en<br />

authenticatie certificaat aanmaken<br />

Upload het root certificaat (MyNetwork.cer) op<br />

de Certificates tab. Dit wordt gebruikt om de<br />

client VPN te configureren.<br />

Op de Dashboard tab wordt de gateway nou<br />

weergegeven als niet aangemaakt. Klik CREATE<br />

GATEWAY, dit zal ongeveer 15 minuten duren.<br />

Als de gateway aangemaakt is, kun je de Client<br />

VPN Package downloaden en installeren.<br />

Start de VPN in Network Connections van<br />

Windows.<br />

Remote debugging<br />

Maak een Remote Desktop connectie naar de<br />

Azure VM. Download en installeer de visual<br />

studio remote debugging tools van Microsoft. Bij<br />

de eerste keer starten van de Remote Debugger<br />

moet deze geconfigureerd worden. Kies<br />

configure remote debugging om de defaults te<br />

gebruiken. Daarna opent de Remote Debugger<br />

en wacht op connectie van een machine.<br />

Fig. 4: Download client vpn package<br />

Open Visual Studio op de development machine.<br />

Ga naar Debug > Attach to Process … Laat het<br />

transport op Default staan. Gebruik bij Qualifier<br />

het IP adres dat bij de machine staat op het virtual<br />

network dashboard (Figure 3) en de default<br />

poort 4018. Log in met dezelfde credentials als<br />

de Remote Desktop.<br />

Selecteer het process en klik Attach. Remote<br />

Debugging naar een Azure VM zonder poorten<br />

open te zetten.<br />

Conclusie<br />

Met remote debugging kun je ook in een Azure VM sneller bugs<br />

oplossen. OTAP in Windows Azure is de toekomst. De redenen om het<br />

niet te doen worden steeds minder.<br />

Links<br />

Remote debugging tools<br />

(http://www.microsoft.com/en-us/download/details.aspx?id=43724)<br />

Debugging a Cloud Service or Virtual Machine in Visual Studio<br />

(http://msdn.microsoft.com/en-us/library/azure/ff683670.aspx) •<br />

Fig. 5: Attach to remote process<br />

Eric Tummers<br />

Eric Tummers is werkzaam als<br />

technisch consultant bij Valid en<br />

richt zich op kwaliteit in software<br />

development. Denk hierbij aan unit<br />

testen, build en deployment<br />

processen. Bloggen doet Eric voornamelijk<br />

over zijn werk, maar af en<br />

toe komt een thuis project erop te<br />

staan, een productiviteit tip of een review. Als het maar bijdraagt<br />

aan het sociale internet.In 2015 gaat Eric aan de slag met devops.<br />

Daarbij staan powershell en Windows Azure centraal.<br />

magazine voor software development 9


.NET /<br />

CLOUD<br />

Hassan Fadili<br />

Application Insights<br />

for Visual Studio Online (Part 2)<br />

In one of the previous <strong>SDN</strong> <strong>Magazine</strong>s (<strong>Magazine</strong> 121), I have introduced Application Insights<br />

on VSO basics and usage of it on project level and on Visual Studio Online Dashboards. In this<br />

article, I will go a step further and explain & show “How Application Insights can help by many<br />

scenarios to get more out telemetry of your Application / Systems?”<br />

To make this concrete, I will walk through the following scenario: “Use<br />

Application Insights to understand application behavior”. To do so,<br />

I have split this scenario into the following tasks:<br />

• Create MVC Web Application and Add Application Insights to It<br />

• Create load / Web tests to simulate the scenarios.<br />

• Use App Insights and Load test to validate the assumptions.<br />

By clicking Add Application Insights To Project, this process starts as<br />

shown below (Fig.3) where the NuGet packages needed are installed:<br />

To start, an ASP.NET MVC Web Application is created. During this<br />

creation, the Application Insights are added to that MVC Web<br />

Application as shown below (Fig 1):<br />

Fig. 3: Adding progress of AI to Project and<br />

NuGet packages Install process<br />

Once this step is finished, the Application<br />

Insights.config and Web ApplicationI Ovreview files<br />

are added to project as shown below (Fig.4):<br />

Fig. 1: Creation of MVC Web Application with Add Application<br />

Insights selected<br />

As part of the Add Application<br />

Insights Process, a resource<br />

MUST be specified<br />

to send telemetry to. This<br />

can be an existing resource<br />

or a new created one as<br />

shown below (Fig 2):<br />

Fig. 2: Add Application<br />

Insights to Project and<br />

specifying the resource<br />

to send telemetry to<br />

Fig. 4: Added Application<br />

Insights Resources to Project<br />

10<br />

MAGAZINE


.NET /<br />

CLOUD<br />

Beside the Application Insights Resources added to Project, there are<br />

also some Application Insights References added to the project as<br />

well. This specific references are shown below (Fig.5):<br />

Open Application Insights from Visual Studio (Solution Explorer)<br />

guides to VSO Dashboard:<br />

Fig. 7: Opening AI from Solution Explorer guides to VSO Dashboard<br />

Because the VSO Dashboard is on Microsoft Azure, the user MUST be<br />

authenticated and authorized to access the specific Azure Instance<br />

by signing to it as shown below (Fig.8):<br />

Fig. 5: Application Insights Specific References added to Project<br />

To examine the added ApplicationInsights.config, this can be opened<br />

by double click on It. The content of it is shown below (Fig.6):<br />

Application Insights Configuration file content:<br />

Fig. 8: Signing to Azure Portal for Accessing Application Insights<br />

on Project Level in Microsoft Azure<br />

By Signing into Microsoft Azure Portal with the right credentials (Email<br />

and Password), Microsoft Azure Portal is shown and Application<br />

Insights can be added as Tile on this Dashboard as shown below<br />

(Fig.9 + Fig.10)<br />

Adding Application Insights to Project from Azure Portal:<br />

Fig. 6: Application Insights Configuration File Content<br />

Once the Add process and examining the Application Insights<br />

content on Visual Studio are done, the next step can be to get into<br />

Visual Studio Online Dashboard (VSO) to see the Application Insights<br />

Information in action. This can be done in 2 ways:<br />

• By right click the Web Application Overview file and select Open<br />

Application Insights (see below Fig.7)<br />

• By double click on the same Web Application Overview file<br />

Fig. 9: Adding AI to Azure Project Dashboard<br />

magazine voor software development 11


.NET /<br />

CLOUD<br />

Adding Application Insights from Azure Portal Futures to Project:<br />

Progress of Adding AI to Project on Azure Portal:<br />

Fig. 10: Adding Application Insights to Project from Azure Portal<br />

Futures<br />

To be more specific on this add process, the user MUST specify the<br />

Web Application Information that can be used to be added as shown<br />

below (Fig.11) like:<br />

• Application Name<br />

• Application Type<br />

• Resource Group<br />

• Subscription<br />

• Location<br />

Fig. 12: Progress of Adding Application Insights to Project on Azure<br />

Portal<br />

From this point, all Application Insights information of a specific Web<br />

Application can be analyzed from the Application Insights Dashboard<br />

like “Events” a shown below (Fig.13):<br />

Status of Application Insights Events on Azure Portal after<br />

Creation:<br />

Application Information Specifying for Application Insights on<br />

the Azure Portal:<br />

Fig. 13: Status of AI Events on Azure portal after Creation<br />

To monitor telemetry for the Web Application, the selected source<br />

code below (Fig.14) MUST be added to all pages that must be<br />

tracked for Application Insights telemetry like we have done below for<br />

Index.cshtml file:<br />

Adding Source code to all webpages that have to be tracked for<br />

Application Insights:<br />

Fig. 11: Application Information to be added for Application Insights<br />

on Azure Portal<br />

When all the necessary information is provided, the user can click on<br />

Create button and creation progress is shown on the Microsoft Azure<br />

Dashboard as shown below (Fig.12)<br />

Fig. 14: Code to be added to all Web Pages that have to be tracked<br />

for AI<br />

12<br />

MAGAZINE


.NET /<br />

CLOUD<br />

When all the specific pages are updated with the code above (Fig.14),<br />

The Web Application can be compiled and executed. At that moment<br />

the first Application Insights Events are sent to Visual Studio<br />

Online Dashboard that is configured as show below (Fig.15)<br />

Overview Page Views Information on Azure Portal:<br />

First Application Insights Events sending to Azure Portal after<br />

Adding code to Specific Page(s) that have to be tracked:<br />

Fig. 18: More Application Insights Info (Page Views) on Azure<br />

Dashboard<br />

Overview Page Views Charts Information on Azure Portal:<br />

Fig. 15: First Application Insights Events sent to Azure Portal after<br />

adding the specific source code to It<br />

Below (Fig.16, Fig.17, Fig.18, Fig.19, Fig.20 ) some specific Application<br />

Insights Information you can track from the Microsoft Azure<br />

Portal on Visual Studio Online like:<br />

• TimeLine overview<br />

• Pages Views<br />

• Page Views Charts<br />

• Diagnostic Search<br />

• ……<br />

Overview TimeLine Information on Azure Portal:<br />

Fig. 19: Application Insights Page Views Charts Info Configuration<br />

Overview Diagnostic Search Information on Azure Portal:<br />

Fig. 20: Application Insights-Diagnostic Search on Azure Dashboard<br />

Fig. 16: Overview TimeLine Information on Azure Portal<br />

Usage TimeLine Information on Azure Portal:<br />

Creating Load Test / Web Test for the application and Instrument It:<br />

Adding Load / Performance Test Project to Solution for instrumen -<br />

tation:<br />

Fig. 17: Usage TimeLine Information on Azure Portal<br />

Fig. 21: Adding Web-Performance-Load Test Project<br />

magazine voor software development 13


.NET /<br />

CLOUD<br />

Running Web Test of AI_WebApplication:<br />

Fig. 25: WebTest Results after investigation in Visual Studio<br />

Fig. 22: Running Web Test Status of AI_WebApplication<br />

After you've deployed your web application, you can set up web tests<br />

to monitor its availability and responsiveness. Application Insights will<br />

send web requests at regular intervals from points around the world,<br />

and can alert you if your application responds slowly or not at all.<br />

So we can act directly by tracking all information needed on applica<br />

tion level and simulate the load and usage of our application /<br />

System. Because of the good integration of Visual Studio, Visual<br />

Studio Online and Microsoft Azure Dashboard, we can request all<br />

Application Insights information for our applications to track like:<br />

• Application Health<br />

• Diagnostics<br />

• Performance<br />

• Usage Analytics ( X Days)<br />

• Operations<br />

• Access<br />

In the next series of this articles, I will take this topic a step further and<br />

walk through other cool Application Insights futures and configurations.<br />

So I will discuss the “Segmentation; Application Insights support<br />

for Multiple Environments, Stamps and App Versions; Search your logs<br />

instantly using property filters”. Stay Tuned ;-).<br />

Fig. 23: Web Tests Response time (ms)<br />

NB: You can set up web tests for any HTTP endpoint that is<br />

accessible from the public internet.<br />

Overview All WebTest Response Information on Azure Portal:<br />

Links:<br />

Getting started with Application Insights:<br />

http://azure.microsoft.com/en-us/documentation/articles/<br />

app-insights-get-started/<br />

Channel 9: Application Insights overview:<br />

https://channel9.msdn.com/Events/Visual-Studio/Connect-event-<br />

2014/216<br />

Application Insights SDK:<br />

http://blogs.msdn.com/b/visualstudioalm/archive/2014/10/21/<br />

application-insights-sdk-0-11-0-prerelease.aspx<br />

Application Insights: Exception Telemetry<br />

http://blogs.msdn.com/b/visualstudioalm/archive/2014/12/12/<br />

application-insights-exception-telemetry.aspx<br />

Monitor any web site's availability and responsiveness:<br />

http://azure.microsoft.com/en-us/documentation/articles/<br />

app-insights-monitor-web-app-availability/<br />

Web tests for Microsoft Azure Websites:<br />

http://azure.microsoft.com/en-us/documentation/articles/<br />

insights-create-web-tests/ •<br />

Hassan Fadili<br />

Fig. 24: All Web Test Investigation of Failed Request<br />

Failed tests can be analyzed to determine why they failed. Drill into a<br />

failed web test and download and open Visual Studio Web Test<br />

Result File to analyze and understand why the test failed.<br />

After investigation in Visual Studio by correcting the WebTest errors,<br />

the results looks like below on the Microsoft Azure portal (Fig.25):<br />

Conclusion:<br />

With the actual Application Insights future in Visual Studio Online, we<br />

have more control on the status of our applications / Systems in terms<br />

of investigation when things goes wrong or applications / systems failed.<br />

Hassan Fadili is werkzaam als Freelance<br />

Lead Architect / Consultant en<br />

VS ALM Consultant (MVP) voor zijn<br />

eigen bedrijf FadiliCT Consultancy<br />

(http://www.fadilict-consultancy.nl).<br />

Hassan is zeer actief in de Community<br />

en mede bestuurslid van<br />

DotNed (.NET & VS ALM UG NL) en<br />

VS ALM Track Owner. Hassan<br />

houdt zijn blog op: http://hassanfad001. blogspot.com en te<br />

bereiken via: hfadili@fadilict-consultancy.nl, hassan@dotned.nl,<br />

hassanfad11 @hotmail.com en/of via Twitter op: @HassanFad<br />

14<br />

MAGAZINE


SQL<br />

Jeffrey Verheul<br />

Decrease dataflows<br />

between systems with CDC<br />

Dealing with data is becoming a bigger challenge every day, if you work with a wrongly<br />

designed system. And haven’t we all been there? One of the senior software engineers<br />

designed the system, and tested it with 10.000 records. But in the past few years, he left, and<br />

the system increased so much in size, that it’s impossible to work with it. And now a new<br />

invoice system (or a BI team for example) needs to read data from the same system. Throwing<br />

hardware at the problem isn’t an option, so what do you do next?<br />

In the past, reading data from that one core production system wasn’t<br />

an issue. The invoice processes ran at night, and the process used to<br />

finish before the first employee got in the office in the morning. But<br />

with the amounts of data currently being poured in the system, this<br />

becomes impossible. Redesigning the system takes up too much time<br />

and money, so that’s off the table. So how do you technically solve<br />

this puzzle, without rebuilding your entire architecture?<br />

What is CDC?<br />

CDC (Change Data Capture) is a feature that’s included in SQL<br />

Server Enterprise. This gives you the opportunity to capture Inserts,<br />

Updates and Deletes of records on specific objects. This can be used<br />

to perform “incremental updates” to the invoice system, instead of<br />

reading the entire content of the database at night. So how does it<br />

work?<br />

In SQL Server, every change you make to a record or table, is stored<br />

in the transaction log before your database is changed on disk. CDC<br />

reads the transaction log, and records all changes on the tables you<br />

have enabled CDC on.<br />

Enabling CDC<br />

Enabling CDC is as easy as running a query. First, let’s create some<br />

resources:<br />

/* Create a database */<br />

CREATE DATABASE CompanyInfo<br />

GO<br />

/* Use the database we just created */<br />

USE CompanyInfo<br />

GO<br />

/* Create the Customer table */<br />

CREATE TABLE dbo.Customer<br />

(CustomerID INT IDENTITY(1,1),<br />

FirstName VARCHAR(50),<br />

LastName VARCHAR(50),<br />

PhoneNumber VARCHAR(50),<br />

AccountNumber VARCHAR(50),<br />

CONSTRAINT PK_Customer PRIMARY KEY(CustomerID))<br />

GO<br />

In order to use CDC, we need to enable CDC on the database, and<br />

on the table:<br />

USE CompanyInfo<br />

GO<br />

/* Enable CDC on database */<br />

EXEC sys.sp_cdc_enable_db<br />

GO<br />

/* Enable CDC on table */<br />

EXEC sys.sp_cdc_enable_table<br />

@source_schema = 'dbo',<br />

@source_name = 'Customer',<br />

@supports_net_changes = 1,<br />

@role_name = NULL,<br />

@index_name = 'PK_Customer',<br />

@captured_column_list = 'CustomerID, FirstName, LastName,<br />

AccountNumber'<br />

GO<br />

The query above only captures changed on the “FirstName”, “Last-<br />

Name” and “AccountNumber” columns (ID needs to be included,<br />

because it’s the primary key on the table). Changes on the “Phone-<br />

Number” column aren’t interesting for the invoice system. If you do<br />

want to capture changed to that column, you can add it to the list<br />

passed into “@captured_column_list” parameter. Another option is to<br />

leave out the “@captures_column_list” parameter, so it will capture all<br />

columns in the table.<br />

After running these statements, SQL Server created a number of<br />

objects for CDC. The most important things: 2 functions you can query<br />

to get data, 2 jobs (capture and cleanup), and a “Customer_CT” table<br />

(system table), where the data changes are stored.<br />

Capture and Cleanup<br />

As long as the SQL Server Agent is running, changes are captured.<br />

The capture job, that is responsible for capturing all changes on<br />

CDC-enabled tables, runs every 5 seconds by default. This value can<br />

be changed, but I’ve never seen a reason to change this.<br />

The cleanup job is responsible for removing old data from the<br />

“Customer_CT” table. By default, old data is removed after 4320<br />

minutes (3 days). You can change this by executing this statement:<br />

magazine voor software development 15


SQL<br />

USE CompanyInfo<br />

GO<br />

/* Change the retention for cleanup */<br />

EXEC sys.sp_cdc_change_job<br />

@job_type = 'cleanup',<br />

@retention = 7200<br />

GO<br />

/* Check the result of the change */<br />

SELECT<br />

job_type,<br />

retention<br />

FROM msdb.dbo.cdc_jobs<br />

In this case the retention of the data is changed to 7200 minutes. This<br />

means that old data is deleted after 5 days. This setting gives you the<br />

opportunity to feed the invoice system with data for 5 days. This could<br />

help you if there is downtime of your system, or if you have a maintenance<br />

windows for the system every week for example. If that’s not<br />

needed, you could set it to a smaller value. How larger the value is,<br />

how longer you could query the change data, but also the more<br />

storage you need to store the change data.<br />

Querying the data<br />

Now that we’re storing the changed data, how do we query it? There<br />

are several options, all with their own pros and cons. Before we start<br />

querying the data, let’s insert and update a record in the table:<br />

USE CompanyInfo<br />

GO<br />

/* Insert a customer record */<br />

INSERT INTO dbo.Customer<br />

(FirstName, LastName, PhoneNumber, AccountNumber)<br />

VALUES<br />

('John', 'Doe', '555-6162', 'AA-5206204855882426')<br />

GO<br />

/* Update the LastName of the customer */<br />

UPDATE dbo.Customer<br />

SET LastName = 'Smith'<br />

WHERE LastName = 'Doe'<br />

GO<br />

The best practice to query the data, is to use the build-in functions.<br />

These functions (all_changes for the entire change set, or net_changes<br />

for the combined changes), all work with LSN’s (Log Sequence<br />

Numbers). An LSN uniquely identifies a record in the SQL Server<br />

transaction log. These LSN’s can be translated to a readable<br />

“datetime” datatype. Also, a “datetime” datatype can be translated in<br />

an LSN. Translating can be done with the build-in functions:<br />

/* Translate LSN to datetime */<br />

SELECT sys.fn_cdc_map_lsn_to_time(0x00000000000000000000)<br />

GO<br />

/* Translate datetime to LSN */<br />

SELECT sys.fn_cdc_map_time_to_lsn('smallest greater than or<br />

equal', '1900-01-01')<br />

GO<br />

With these functions, you can create your own “window” of data<br />

extraction. In practice this means that you can start your invoice<br />

process at 10PM, and in that window query data changed from<br />

yesterday 10PM, till today 10PM. Another option is to only query<br />

changes for a specific day, for example between 10AM and 2PM on<br />

Wednesday. The possibilities are endless, and can be fully customized<br />

to work for your system.<br />

So how does this look in the 2 different functions?<br />

As you can see, the all_changes function will return the inserted record<br />

(operation code 2), and the record after the update (operation code 4).<br />

The net_changes function, returns the combined result within the<br />

window you created. In this case, the inserted and updated record<br />

are combined within a single record.<br />

Another option you have, is to retrieve data directly from the<br />

“Customer_CT” table. This option isn’t considered a best practice, but<br />

you have the opportunity to do that if that suits you better.<br />

Design decisions<br />

If you decide to use CDC, there are some design decisions you need<br />

to take a look at. One of the first things you need to think about is<br />

storage. Data changes are captured and stored, so you need some<br />

extra storage to save these records. Another thing to think about, is<br />

the way your invoice system reads data from the primary system. If<br />

you’re going to use CDC, you might need to change the way data is<br />

retrieved. But these changes might be easier, and much safer than<br />

changing your primary system. And if you use SQL Server Integration<br />

Services (SSIS) for example, there are some standard components<br />

you could use. The changed you need to make depend on the<br />

system and architecture you have in your company.<br />

Conclusion<br />

With the options you’ve seen you can decide what works the best for<br />

your system. There are alternatives you could use, but these options<br />

all require system changes, or are more intrusive on your system than<br />

CDC. For example, you could use triggers on your tables, but those<br />

tend to slow down your system.One thing is certain: CDC reduces the<br />

amount of data that needs to be exchanged between systems, and<br />

the time needed to update secondary systems by a lot. And maybe<br />

even more important to the business, it saves you from a huge<br />

investment needed to re-design the entire system!<br />

Personally, I would say CDC isn’t the silver bullet that solves all your<br />

cross-system dataflow problems, but it is very effective when you use<br />

it the way it was intended: capture changes in a very lightweight way.<br />

The only real downside of CDC is that it’s an Enterprise-only feature.<br />

But the flexibility and compatibility (for example with SSIS and BIML)<br />

makes up for these shortcomings. CDC is definitely something to take<br />

a look at, even if you’re not a data professional! •<br />

Jeffrey Verheul<br />

Jeffrey Verheul is a DBA and database<br />

developer from the Netherlands,<br />

with over 10 years experience<br />

in the Microsoft stack. After a short<br />

side-track as a software engineer,<br />

he returned to his true love: SQL<br />

Server. His main focus is on database<br />

development, performance tuning and database administration.<br />

He is a member of the Friends of Red Gate, and blogs<br />

regularly on devjef.wordpress.com. You can contact him on his<br />

blog, or via Twitter (@DevJef).<br />

16<br />

MAGAZINE


CLOUD<br />

Marcel Meijer<br />

Azure Webjobs<br />

Tijdens de afgelopen Microsoft Techdays 2014 deed ik een sessie over Azure Cloud Services.<br />

De opname is te vinden op Channel 9. In het begin van Azure waren Cloud services de<br />

“way to go”.<br />

Cloud Servies is een krachtig concept, maar er kleefde ook de nodige<br />

nadelen aan. Bestaande applicaties konden niet zomaar via de Lift en<br />

Shift methode naar de Cloud gebracht worden. Meestal was dit<br />

gewoon te wijten aan de applicaties zelf. Weinig applicaties zijn of<br />

waren zuiver stateless, asynchroon in de basis en in staat als meerdere<br />

instanties naast elkaar te draaien.<br />

Zoals gezegd bestond het uit een WebRole en een WorkerRole.<br />

De WebRole voor het uploaden en bekijken van de plaatjes.<br />

In de afgelopen jaren is het Azure platform rijker geworden met<br />

verschillende diensten. In plaats van iets zelf te verzinnen of te<br />

kopieren van anderen, zijn er nu bestaande tools/producten opgepakt<br />

en in samenwerking geschikt gemaakt voor Azure (Hadoop, Docker,<br />

etc). Maar ook is IT development een stuk volwassener geworden.<br />

Developers en architecten realiseren zich steeds vaker dat Scale up<br />

niet helpt met availability, dat services/servers stuk gaan en dat een<br />

internet applicatie de potentie van een miljoenen publiek heeft.<br />

Standaard dogma’s als SOA architecture, Servicebussen of SOAP<br />

webservices lijken ook hun kracht te verliezen, Microservices krijgen<br />

meer draagvlak en betere tooling. Daarover ga ik zeker nog vaker<br />

bloggen.<br />

Terug naar mijn Techdays demo. Die zag er zo uit:<br />

De flow van de applicatie zag er zo uit.<br />

Zoals je ziet, de WebRole moest naast het uploaden ook een bericht<br />

op een queue zetten voor de WorkerRole. Aan de WorkerRole kant<br />

moet er een mechanisme zijn om de queue leeg te lezen. Zoals ik<br />

vertelde in mijn sessie, moet je dan ook het Busy waiting oplossen.<br />

Het lezen van de queue is een transactie en dat kost geld. Een<br />

belangrijk onderdeel van architectuur op Azure is Cost Based design.<br />

Dus wil je het lezen van bijvoorbeeld een queue zo efficiënt en<br />

effectief mogelijk houden met het oog op de kosten.<br />

Op Azure zijn tegenwoordig Webjobs beschikbaar. Met deze webjobs<br />

is het mogelijk om deze te laten triggeren na het toevoegen van een<br />

nieuwe blob op storage. Dat scheelt in mijn geval een bericht op de<br />

queue en eigen check actie van de queue. Het hele wachten en kijken<br />

of er werk (nieuwe blob op storage) is, wordt nu door het platform<br />

verzorgd en geregeld. En wat ik niet hoef te doen, dat scheelt tijd en<br />

het platform kan dat efficiënter. Dus de WorkerRole wordt vervangen<br />

door een Webjob. De WebRole heeft ook een alternatief. Moest ik voor<br />

de WebRole toch nog iets aparts leren, zoals bijvoorbeeld het lezen<br />

van de configuratie settings. Met een Azure Website kan ik de<br />

technieken gebruiken die ik altijd al gebruikte. En voor de settings zie<br />

je in mijn vorige blogpost de oplossing.<br />

Het proces plaatje ziet er dan zo uit.<br />

De solution zag er zo uit. De code is te downloaden of op te vragen.<br />

magazine voor software development 17


CLOUD<br />

En de website ziet er na een kleine redesign zo uit.<br />

De WorkerRole besloeg ongeveer het dubbele aantal regels code,<br />

waarvan het grootste gedeelte zaken die niets met het proces te<br />

maken hebben.<br />

Op deze manier krijg je precies zoals ik altijd zeg tijdens presentaties.<br />

We kunnen ons richten op de functionaliteit en het echte werk, de rest<br />

wordt overgenomen en geregeld door het Azure platform.<br />

Nu moet de Client op een andere manier genotificeerd worden en niet<br />

op een queue hoeven te kijken.<br />

NB In dit artikel beweer ik niet dat Cloud Services niet bruikbaar zijn.<br />

Voor het hier genoemde scenario waren de uitgebreide mogelijk heden<br />

van Cloud Services niet nodig. Er is op de Azure site (http:/ /azure.<br />

microsoft.com/nl-nl/documentation/articles/choose-web-site-cloudservice-vm/)<br />

een vergelijkend overzicht van de mogelijk -heden tussen<br />

de verschillende oplossingen. •<br />

En de code van de Webjob is eigenlijk alleen dit, ongeveer 55 regels.<br />

Marcel Meijer<br />

Marcel is een allround Microsoft<br />

Architect en Microsoft Cloud<br />

specialist bij Xpirit Nederland<br />

(www.xpirit.com), Marcel heeft al<br />

meerdere bedrijven geholpen met<br />

succesvolle Cloud/Microsoft Azure<br />

implementaties. Hij is voorzitter van<br />

de Software Development Network<br />

(<strong>SDN</strong>), redacteur end event organisator.<br />

Hij is ook een frequente blogger en spreker op verschillende<br />

community events en conferences in Nederland. Since 2010 mag<br />

hij zich Microsoft MVP noemen.<br />

TIP:<br />

Macro’s in Excel Werken niet meer<br />

na Office update<br />

Als je Excel 2013 macro’s bevat en deze werken niet meer na<br />

de laatste Office update. De oplossing hiervoor is, zoek het<br />

bestand MSForms.exd op. Deze staat normaal gesproken in<br />

de folder C:\Users\user.name\AppData\Local\Temp\Excel8.0\.<br />

Verwijder het bestand MSForms.exd.<br />

Bij het opnieuw opstarten van Excel 2013 wordt dit bestand<br />

opnieuw aangemaakt. Daarna werken alle VBA macro’s<br />

werken weer.<br />

20 maart<br />

<strong>SDN</strong> Event<br />

Zeist<br />

18<br />

MAGAZINE


GENERAL<br />

Sander Hoogendoorn<br />

Microservices.<br />

The good, the bad and the ugly<br />

Back in 1988, when I was first employed by a company for writing software, the world was fairly<br />

simple. The development environment we had was character-based, the database was<br />

integrated and traversed with cursors, and we built a whole new administrative system<br />

covering everything but the kitchen sink. It took us five years to complete the project, basically<br />

because the client kept changing his mind every now and then, and because every change<br />

in the code could break code elsewhere in the system. Unit testing hadn’t been invented yet,<br />

and testing was done by the end users. In production..<br />

So far for monoliths. Then in 1994 I joined a company that build<br />

desktop applications - remember the world wide web was only a<br />

couple of years old, and web applications hadn’t been invented yet.<br />

We used a great tool called PowerBuilder and now we had two<br />

components to worry about; the application on the desktop and the<br />

database on the server. The applications we build usually served<br />

departments or sometimes even a whole company. Not highly<br />

complicated, but not highly scalable either. Ah well, we had fun as long<br />

as the client-server paradigm lasted.<br />

Component based development<br />

The world got more complex in the mid-nineties. Companies wanted<br />

web applications, basically running on intranets to get rid of desktop<br />

deployments. And applications needed to serve multiple departments,<br />

and sometimes even break company borders. A new paradigm set<br />

in: component based development, also known as CBD. The<br />

paradigm promised us re-use, scalability, flexibility and a way to<br />

harvest existing code (usually written in COBOL). We started breaking<br />

up our systems into big functional chunks, and tried hard to have those<br />

components communicate to each other. Java was invented and<br />

everybody now wanted to write code in Java (apparently some<br />

people still to this nowadays). Components where running in<br />

impossible technologies such as application servers and CORBA (to<br />

impress your co-workers, look that one up on Wikipedia). The good<br />

old days of object request brokers!<br />

At that time I was working for a large international bank trying to set<br />

up an methodology for doing component based development. Even<br />

with a heavily armed team of Anderson consultants it took us three<br />

years to write the damn thing. In the end both the paradigm and the<br />

technology where too complex to write decent and well-performing<br />

software. It just never took off.<br />

Service oriented architecture<br />

At that point in time, the early years of this century, I thought we got<br />

rid of distributed software development, and happily started building<br />

web applications. I guess everyone bravely ignored Martin Fowler’s<br />

first law of distributed objects: do not distribute your objects.<br />

Gradually we moved into the next paradigm of distributed computing,<br />

re-packaging the promises of component based development into a<br />

renewed set of technologies. We now started doing business process<br />

modeling (BPM), and implemented these processes in enterprise<br />

services buses (ESB’s), with components delivering services.<br />

Fig. 1: Scary stuff, an object request broker architecture<br />

Fig. 2: An enterprise service bus<br />

magazine voor software development 19


GENERAL<br />

We were in the age of service oriented architecture, better known as<br />

SOA.<br />

Coming from CBD, SOA seemed easier. As long as your components<br />

- the producers - were hooked into the enterprise service bus, we<br />

figured out how to build-up scalable and flexible systems. We now<br />

had much smaller components that we could actually extract from our<br />

existing systems (now not only written in COBOL, but also in<br />

PowerBuilder, .NET and Java). The mandatory design patterns books<br />

where published and the world was ready to go. This time we would<br />

crack it!<br />

I found myself working for an international transport company, and we<br />

happily build around SAP middleware – delivering both ESB and BPM<br />

tooling. We now not only needed regular Java and .NET developers,<br />

but we employed middleware developers and SAP consultants as<br />

well. And although agile was introduced to speed up development<br />

(I know, this is not the right argument), projects still suffered from<br />

sluggishness and moreover, when we got pieces of the puzzle in place,<br />

we started to realize that integration testing and deployment of new<br />

releases got more complicated by the day.<br />

At last: microservices!<br />

I do hope you forgive me this long and winding introduction to the<br />

actual topic: microservices. You might think: why do we need yet<br />

another article on microservices? Isn’t there enough literature already<br />

on the topic. Well yes there is. But if you look closely to the flood of<br />

articles that you find on the internet, most of them only describe the<br />

benefits and possibilities of microservices (sing hallelujah), some of<br />

them take a look at the few famous path finding examples (Netflix,<br />

Amazon, and Netflix, and Amazon, and Netflix…). Only a few articles<br />

actually dig a bit deeper, and they usually consist of summing up the<br />

technologies people seem to be using when implementing<br />

microservices. It’s still early in the game.<br />

That’s were a little historical perspective won’t hurt. I find it interesting<br />

to witness that the benefits and possibilities of the predecessors of<br />

microservices are still with us. Microservices seem to promise<br />

scalable and flexible systems, based on small components that can<br />

easily be deployed independently, and thus promote use of the best<br />

choice in technologies per component. Basically the same promises<br />

we fell for with CBD and SOA in the past. Nothing new here, but that<br />

doesn’t mean that microservices aren’t worthwhile investigating.<br />

Is it different this time around?<br />

So why is it different this time? What will make microservices the<br />

winning paradigm, where its predecessors clearly were not? What<br />

makes it tick? As a developer, there’s no doubt that I am rather<br />

enthusiastic about microservices, but I was enthusiastic as well (more<br />

or less) when people came up with CBD and SOA.<br />

I do suppose there are differences. For the first time we seem to have<br />

the technology in place to build these type of architectures. All the<br />

fancy and complex middleware is gone, and we rely solely on very<br />

basic and long-time existing web protocols and technologies. Just<br />

compare REST to CORBA. Also we seem to understand deployment<br />

much better, due to the fact that we’ve learned how to do continuous<br />

integration, unit testing, and even continuous delivery. These differences<br />

suggest that we can get it to work this time around.<br />

Still, from my historical viewpoint some skepticism is unavoidable. Ten<br />

years ago, we also really believed that service oriented architecture<br />

would be technologically possible, it would solve all our issues, and we<br />

would be able to build stuff faster, reusable and more reliable. So, to<br />

be honest, the fact that we believe that the technology is ready, is not<br />

much of an argument. Meanwhile the world also got more complex.<br />

Over the last year I’ve been involved with a company that is moving<br />

away from their mainframe (too expensive) and a number of older Java<br />

monoliths (too big, and hard to maintain). Also time-to-market plays an<br />

important role. IT need to support introducing a new product in<br />

months, if not in weeks. So we decided to be hip and go micro -<br />

services. Here’s my recap of the good, the bad and the ugly of<br />

microservice architectures, looking back on our first year on the road.<br />

The good<br />

Let’s start with the good parts. We build small components, each<br />

offering about two to six services. Good examples of such small<br />

components are a PDF component, that does nothing more than<br />

generate PDF’s from a template with some data, or a Customer<br />

component that allows users to search for existing customers. These<br />

components offer the right size. The right size of code, he right size of<br />

understandability, to right size to document, to test an to deploy.<br />

The good<br />

Our team tend to evolve towards small teams designing, implementing<br />

and supporting individual components. We didn’t enforce ownership,<br />

but over time small teams are picking up the work on a specific<br />

component and start feeling responsible for it.<br />

When we outlined the basic architecture for our microservices landscape<br />

we set a number of guidelines. We are not only building small<br />

components, but are also building small single-purpose web applications.<br />

Applications can talk to other applications, and can talk to<br />

components. Components handle their own persistence and storage,<br />

and can also talk to other components. Applications do not talk<br />

directly to storage. Components do not talk to each others storage.<br />

For us these guidelines work.<br />

Microservices lives up to some of its promises. You can pick the right<br />

technology and persistence mechanisms for each of you components.<br />

Some components persist to relational databases (DB2 or SQLServer),<br />

others persist to document databases (MongoDB in our case).<br />

The hipster term here of course is polyglot persistence.<br />

We also stated that every application and component has it’s own<br />

domain model. We employ the principles and patterns of domain<br />

driven design straightforward. We have domain objects, value objects,<br />

aggregates, repositories and factories. Because our components are<br />

small, the domain models are fairly uncomplicated, and thus<br />

maintainable.<br />

Although we have had quite a journey towards testing our<br />

components and services, from Fitnesse to hand-written tests, we are<br />

now moving towards testers specifying tests in SoapUI, which we are<br />

running both as separate tests and during builds. We had to learn to<br />

understand REST, but we’ve got this one figured out for now.<br />

Andtesters love it.<br />

20<br />

MAGAZINE


GENERAL<br />

When we started our microservices journey, the team I’m was in a<br />

highly reactive mode – tell us what to program and how to program it,<br />

and we’ll do our job. I probably won’t have explain what that does<br />

with the motivation of the team members. However, with micro services<br />

there is no such thing as a ready-to-use cookbook or a predefined<br />

architecture. It simply doesn’t exist. That means that we continuous<br />

find ourselves solving new pieces of the microservices puzzle, from<br />

discovering how to design microservices (we use smart use case), to<br />

how implement REST interfaces, how to work with a whole new set<br />

of frameworks, and a brand new way of deploying components. It’s<br />

this puzzle that make working on this architecture interesting. We allow<br />

ourselves to learn everyday.<br />

The bad<br />

But as always, there’s a downside. When you start going down the<br />

microservices road – for whatever you may find it beneficial - you need<br />

to realize that this is all brand new. Just think of it: if you’re not working<br />

for Netflix or Amazon, who do you know who actually already<br />

does this already? Who has actively deployed services into production,<br />

with a full load? Who can you ask?<br />

The bad<br />

You need to be aware that you really need to dig in and get your hands<br />

dirty. You will have to do a lot of research yourself. There are no<br />

standards yet. You will realize that any choices you now make in<br />

techniques, protocols, frameworks, and tools is probably temporarily.<br />

When you are learning on a daily basis, newer and better options<br />

become available or necessary, and your choices will alter. So if you’re<br />

looking for a ready-made IKEA construction kit for implementing<br />

microservices the right way, you might want to stay away from<br />

microservices for the next five to seven years. Just wait for the big<br />

vendors, they will jump in soon enough, as there’s money to make.<br />

From a design perspective you will have to start to think differently.<br />

Designing small components is not as easy as it appears. What makes<br />

a good size component? Yes, it has a single business purpose,<br />

undoubtedly, but how do you define the boundaries of your<br />

component? When do you decide to split a working, operational<br />

component into two or more separate components? We’ve come<br />

across a number of these challenges over the past year. Although we<br />

have split up existing components, there are no hard rules on when to<br />

actually do this. We decided mainly based on gut feeling, usually when<br />

we didn’t understand a components structure anymore, or when we<br />

realized it was implementing multiple business functions. It gets even<br />

harder when you are chipping off components from large systems.<br />

There’s usually a lot of wiring to cut, and in the meantime you will need<br />

to guarantee that the system doesn’t break. Also, you will need a fair<br />

amount of domain knowledge to componentize your existing systems.<br />

Basically we found that components are not as stable as we first<br />

thought. Occasionally we merge components, but it appeared far<br />

more common to break components into smaller ones to provide<br />

reuse and shorter time-to-market. As an example, we pulled out a<br />

Q&A component from ourProduct component that now supplies<br />

questionnaires for other purposes than just about products. And more<br />

recently we created a new component that only deals with validating<br />

and storing filled-in questionnaires.<br />

There’s lots of technical questions you will need to answer too. What’s<br />

the architecture of a component? Is an application a component as<br />

well? Or, a less visible one, if you are thinking of using REST as your<br />

communication protocol – and you probably are – is: how does REST<br />

actually work? What does it mean that a service interface is RESTful?<br />

What return codes do you use when? How do we implement error<br />

handling in consumers if something isn’t handled as intended by one<br />

of our services? REST is not as easy as it appears. You will need to<br />

invest a lot of time and effort to find out your preferred way of dealing<br />

with your service interfaces. We figured out that to make sure that<br />

services are more or less called in a uniform way, we’d better create<br />

a small framework that does the requests, and also that deals with<br />

responses and errors. This way communication is handled similar with<br />

every request, and if we need to change the underlying protocol or<br />

framework (JAX-RS in our case), we only need to change it in one<br />

location.<br />

That automatically brings me to the next issue. Yes, microservices<br />

deliver on the promise that you can find the best technology for every<br />

components. We recognize that in our projects. Some of our<br />

components are using Hibernate to persist, some are using a<br />

MongoDB connector, some rely on additional frameworks, such as<br />

Dozer for mapping stuff, or use some PDF-generating framework. But<br />

with additional frameworks comes the need for additional knowledge.<br />

At this company, we will easily grow to over a hundred small<br />

components and maybe even more. If even only a quarter of these<br />

use some specific framework, we will end up with twenty-five to thirty<br />

different frameworks( did I mention we do Java?). We will need to<br />

know about all of these. And even worse, all of these frameworks<br />

(unless they’re dead) version too.<br />

Then there’s the need to standardize some of the code you are writing.<br />

Freedom of technology is all good, but if every component is literally<br />

implemented differently, you will end up with an almost unmaintainable<br />

code base, especially since it is likely that no-one oversees all the<br />

code that is being written. I strongly suggest to make sure there’s<br />

coherence over your components on aspects of your code base that<br />

you could and probably should unify. Think of your UI components<br />

(grids, buttons, pop-ups, error boxes), validation (of domain models),<br />

talking to databases or how responses from services are formulated.<br />

Also, although I strongly oppose having a shared domain model<br />

(please don’t go that route), there’s elements in your domain models<br />

you might need to share. We share a number of enumerations and<br />

value objects for instance, such as CustomerId orIBAN.<br />

If you’re a bit like us this generic code ends up in a set of libraries<br />

- a framework if you will – that is reused by your components. We have<br />

learned that with every new release of this home-grown framework<br />

we end up refactoring some of the code of our components. I rewrote<br />

the interface of our validation framework last week, which was<br />

necessary to get rid of some state it kept - components need to be<br />

stateless for clear reasons of scalability - and I’m a bit reluctant to<br />

merge it back into the trunk when I get back to work after the<br />

weekend. Most of our components use it, and their code might not<br />

compile. I guess what I’m saying here is that it’s good to have a<br />

home-grown framework. With some discipline it will help keep your<br />

magazine voor software development 21


GENERAL<br />

code somewhat cleaner and a tad more uniform, but you will have to<br />

reason about committing to it and releasing new versions of it.<br />

The ugly<br />

So what about the really nasty parts of microservices? Let’s start with<br />

deployment pipelines. One of the promises of microservices is that<br />

they can and should be individually deployed and released. If you are<br />

currently used to having a single build and deployment pipeline for the<br />

one system you are building or extending, you might be in for a treat.<br />

With microservices you are creating individual pipelines for individual<br />

components.<br />

The hockey stick model<br />

Early in the game? Yes, we’ve only been on the road to microservices<br />

for about a year. And I still haven’t figured out whether we are on a<br />

stairway to heaven or on a highway to hell. I do suppose, as with it’s<br />

historical predecessors, we will end up somewhere in the middle,<br />

although I really do believe that we do have the technology to get this<br />

paradigm working – and with we I don’t just mean Netflix, Amazon or<br />

some hipster mobile company, but the regular mid-size companies<br />

you and I work for.<br />

But will it be worthwhile? Shorten time-to-market? Deliver all the<br />

goodies the paradigm promises us? To be honest, I don’t know yet -<br />

despite or maybe even because of all the hype surrounding microservices.<br />

What I did notice is that, given the complexity of everything<br />

surrounding microservices, it takes quite a while before you get your<br />

first services up and running, and we are only just passing this point.<br />

Some weeks ago, I was having a beer with Sam Newman, author of<br />

Building Microservices. Sam confirmed my observations from his own<br />

examples and referred to this pattern as the hockey stick model.<br />

The ugly<br />

Releasing the first version of a component is not that hard. We<br />

started with a simple Jenkins pipeline, but are currently investigating<br />

TeamCity. We have four different environments. One for development,<br />

one for testing, one for acceptance and of course the production<br />

environment. Now we are slowly getting in the process of releasing<br />

our components, most of them with their own database, we start to<br />

realize that we can not do this without the support and collaboration<br />

of the operations team. Our expectations are that we will slowly evolve<br />

into a continuous delivery mode, with operations incorporated in the<br />

team. Right now we already have enough trouble getting operations<br />

on-board. They are now used to quarterly releases of the whole<br />

landscape, and certainly have no wish for individually deploying<br />

components.<br />

Another that worries me is versioning. If it is already hard enough to<br />

version a few collaborating applications, what about a hundred<br />

applications and components each relying on a bunch of other ones<br />

for delivering the required services? Of course, your services are all<br />

independent, as the microservices paradigm promises. But it’s only<br />

together that your services become the system. How do you avoid to<br />

turn your pretty microservices architecture into versioning hell - which<br />

seems a direct descendant of DLL hell?<br />

To be honest, at this point in time, I couldn’t advice you well on this<br />

topic, but a fair warning is probably wise. We started out with a<br />

simple three digit numbering scheme (such as 1.2.5). The rightmost<br />

number changes when minor bugs have been solved. The number in<br />

the middle raises when minor additional functionality has been added<br />

to a component, and the leftmost number changes when we deploy<br />

a new version of a component with breaking changes to its interface.<br />

Not that we strongly promote regularly changing interfaces, but it does<br />

happen.<br />

Next to that, we test our services during the build, both using coded<br />

tests and tests we assemble in SoapUI. And we document the<br />

requirements in smart use cases and domain models of our<br />

applications and components using UML. I’m quite sure in the future<br />

we need to take more precautions to keep our landscape sane, such<br />

as adding Swagger to document our coded services, but it’s still to<br />

early in the game to tell.<br />

There’s a lot to take care of before you are ready to release you first<br />

service. Think of infrastructure, sorting out how to do REST properly,<br />

setting up you deployment pipelines, and foremost change the way<br />

you think about developing software. But as soon as the first service<br />

is up and running, more and more follow faster and faster.<br />

Be patient<br />

So, if there’s one thing I’ve learned over the past year, it is to be<br />

patient – a word which definitively did not appear in my dictionary yet.<br />

Don’t try to enforce all kinds of (company) standards if they just don’t<br />

exist yet. Figure it out on the fly. Allow yourself to learn. Take it step by<br />

step. Simply try to do stuff a little bit better than the day before. And<br />

as always, have fun! •<br />

Sander Hoogendoorn<br />

Sander is an independent consultant;<br />

as a mentor, trainer, coach,<br />

software architect, developer, writer,<br />

speaker, for his company<br />

ditisagile.nl (after the Dutch title of<br />

my latest book This Is Agile).<br />

Over the past decade, in my roles<br />

as Principal Technology Officer and<br />

Global Agile Thoughtleader at<br />

Capgemini. During this period I’ve learned a great deal and have<br />

contributed to the innovation of software development at<br />

Capgemini and its many international clients.<br />

22<br />

MAGAZINE


GENERAL<br />

Patrick Kalkman<br />

Improving traceability<br />

of distributed systems<br />

using the ELK stack<br />

With all IT systems, traceability is an important non-functional requirement. If the traceability of<br />

a system is high, it is easier to find the root cause of a problem that occurs in a production<br />

environment. As a system gets distributed over multiple applications or services, tracing a<br />

problem in a production environment becomes more difficult. As there are simply more application<br />

and services to check. New architectures such as a microservices architecture makes this<br />

even more difficult because the functionality of the system can literally be distributed over<br />

dozens or hundreds of services. The services could be implemented using different development<br />

languages and be running on different platforms. This article describes a solution for increasing<br />

the traceability of a distributed system by using Log aggregation via the ELK stack.<br />

Tracing using the Elk stack<br />

Most distributed systems consist of different types of applications<br />

implemented using different programming language running on<br />

different operating systems. Normally these systems grow organically<br />

over time. There is not a single standard way of logging when a<br />

service or application fails.<br />

Elasticsearch uses Java and Kibana is implemented using HTML, CSS<br />

and JavaScript. Although these three products work great together,<br />

they can also be used separately.<br />

Fig. 1: Microservices architecture<br />

The most common way to log error events is writing these events in<br />

log files. Each row of these text files minimally contain a timestamp<br />

and some data about the event. With a distributed system such as a<br />

microservices architecture this could mean that an engineer has to go<br />

through hundreds of log files to find a problem.<br />

The ELK stack provides a solution for this problem by aggregating all<br />

of these log files into a single system. The ELK stack combines the<br />

Elasticsearch, Logstash and Kibana products. Elasticsearch is a<br />

search and analytics engine, Logstash is a tool for scrubbing and<br />

parsing log data into a single format and Kibana is a visualization<br />

engine to interact with Elasticsearch.<br />

The logs of a system are transported through and enhanced by<br />

Logstash. The data is then indexed and stored by Elasticsearch and<br />

finally visualized using the Kibana dashboard. All the components of<br />

the ELK stack are open source. Logstash is implemented using JRuby,<br />

Fig. 2: ELK stack overview<br />

After the ELK stack is installed and configured you are able to search<br />

in real-time through the logs of all your applications and services. Using<br />

Kibana you are able to visualize trends and spot anomalies in your log<br />

files.<br />

There is not a single standard way<br />

of logging when a service or<br />

application fails<br />

Installing the ELK stack<br />

The ELK stack can be installed on Unix as well as Windows. For this<br />

article, I will be installing the ELK stack on a single Ubuntu server.<br />

The Ubuntu server will be running as a VM on the Microsoft Azure<br />

platform. The version of Ubuntu that I will be using is 14.04 LTS.<br />

magazine voor software development 23


GENERAL<br />

The installation of all components is done through a remote shell, using<br />

putty as an ssh client.<br />

Installing Elasticsearch<br />

As Elasticsearch runs on top of Java, the first prerequisite we have to<br />

fulfill before we can install Elasticsearch is Java. We install Java by<br />

entering the following command on the command line.<br />

$ sudo apt-get install openjdk-7-jre-headless<br />

The name of the Elasticsearch node is automatically generated, so it<br />

will probably be different in your installation.<br />

We now have the E of the ELK stack running. Next, we will install<br />

Logstash.<br />

Installing Logstash<br />

Before we can install Logstash we first have to download the Logstash<br />

package. We download Logstash with the following command.<br />

This will download and install Java version 1.7. To validate if Java was<br />

installed correctly we enter the following command.<br />

$ wget https://download.elasticsearch.org/logstash/logstash/packages/debian/logstash_1.4.2-1-2c0f5a1_all.deb<br />

$ java –version<br />

If Java was installed correctly the following response will be generated<br />

(the version number may differ)<br />

And install it by entering the following command<br />

$ sudo dpkg -i logstash_1.4.2-1-2c0f5a1_all.deb<br />

java version "1.7.0_65"<br />

OpenJDK Runtime Environment (IcedTea 2.5.3) (7u71-2.5.3-<br />

0ubuntu0.14.04.1)<br />

OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode)<br />

To install Elasticsearch we first have to download the package.<br />

We download Elasticsearch with the following command.<br />

$ wget https://download.elasticsearch.org/elasticsearch/<br />

elasticsearch/elasticsearch-1.4.1.deb<br />

There is an additional package with community added contributions<br />

for Logstash that we need. We download this package with the<br />

following command.<br />

$ wget https://download.elasticsearch.org/logstash/log-<br />

stash/packages/debian/logstash-contrib_1.4.2-1-<br />

efd53ef_all.deb<br />

And install it using this command.<br />

$ sudo dpkg –i logstash-contrib_1.4.2-1-efd53ef_all<br />

When downloaded we can install Elasticsearch with the following<br />

command.<br />

$ sudo dpkg -i elasticsearch-1.4.1.deb<br />

We then issue the following command to start Logstash<br />

$ sudo service logstash start<br />

And start it with the following command<br />

$ sudo service elasticsearch start<br />

We can validate if Elasticsearch was installed and is running correctly<br />

by entering the following command.<br />

$ curl http://localhost:9200<br />

Elasticsearch should give a JSON response that looks like the<br />

following<br />

{<br />

"status" : 200,<br />

"name" : "Ultron",<br />

"cluster_name" : "elasticsearch",<br />

"version" : {<br />

"number" : "1.4.1",<br />

"build_hash" :<br />

"89d3241d670db65f994242c8e8383b169779e2d4",<br />

"build_timestamp" : "2014-11-26T15:49:29Z",<br />

"build_snapshot" : false,<br />

"lucene_version" : "4.10.2"<br />

},<br />

"tagline" : "You Know, for Search"<br />

}<br />

This concludes the installation of the L part of the ELK stack. We move<br />

to the last part, installing Kibana, the front-end.<br />

Kibana is implemented using HTML,<br />

CSS and JavaScript<br />

Installing Kibana<br />

Kibana is implemented using HTML, CSS and JavaScript. Therefore,<br />

to run Kibana we need a web server. Kibana runs completely clientside<br />

in the browser, so we don’t have any server side dependencies.<br />

If the web server can serve HMTL you will be ok. I will be using nginx.<br />

To install nginx enter the following command<br />

$ sudo apt-get install nginx<br />

The installation process will automatically start nginx. To validate if<br />

nginx is installed correctly and running issue the following command.<br />

$ curl http://localhost<br />

nginx should respond as follows<br />

24<br />

MAGAZINE


GENERAL<br />

<br />

<br />

<br />

Welcome to nginx!<br />

<br />

…<br />

We download and extract Kibana by entering the following command<br />

$ curl https://download.elasticsearch.org/kibana/kibana/kibana-3.1.2.tar.gz<br />

| tar xvz<br />

Configuring Logstash<br />

The community maintaining Logstash has an interesting project<br />

principle. They say that if a newbie has a bad time using Logstash it’s<br />

probably a bug. The documentation should have be better and more<br />

instructive.<br />

If a newbie has a bad time,<br />

it's a bug<br />

Logstash is configured using a configuration file. A Logstash<br />

configuration file has the following structure.<br />

We then have to copy the Kibana folder to the nginx html folder by<br />

entering the following command.<br />

$ sudo cp kibana-3.1.2/* /usr/share/nginx/html –R<br />

To validate if Kibana is working correctly we have to open two<br />

additional endpoints on the virtual machine running on Microsoft<br />

Azure. One endpoint for port 80 to be able to talk to the web server<br />

and another endpoint for port 9200 to let Kibana talk to Elasticsearch.<br />

The Logstash configuration file describes how events should flow<br />

through the Logstash pipeline with an input, filter and an output stage.<br />

Input specifies the source of the data. This could be a file, a TCP port<br />

or other input plugins that are available.<br />

Filter defines how the input stream should be parsed.<br />

Output defines where the parsed output should be sent and stored.<br />

Each part of the pipeline can be configured using the logstash<br />

configuration file. The configuration file resembles the structure of the<br />

pipeline.<br />

input {<br />

}<br />

filter {<br />

}<br />

output {<br />

}<br />

Fig. 3: Azure Endpoints<br />

When you now browse to your webserver you should be welcomed by<br />

the Kibana start screen.<br />

Logstash contains several plugins that can be configured in each part<br />

of the pipeline. The list is too extensive to list here, but these are some<br />

examples.<br />

• Input plugins (log4j, collectd, eventlog, tcp, wmi, udp, heroku, file)<br />

• Filter plugins (grok, json, split, translate, drop)<br />

• Output plugins (elasticsearch, agios, http, stdout, rabbitmq,<br />

websocket, tcp)<br />

See the Logstash website (http://logstash.net/) for a complete list of<br />

available plugins.<br />

The first real configuration we create is for parsing and indexing logs<br />

from an IIS server. We choose an IIS log because it contains a lot of<br />

different tokens we have to configure in the configuration file. Note<br />

that this could be any log file.<br />

The Logstash configuration file should be stored on our Ubuntu<br />

server in /etc/logstash/conf.d/logstash.conf<br />

Fig. 4: Kibana welcome screen<br />

Congratulations, you have just installed all parts of the ELK stack.<br />

Next, we will look at configuring Logstash to get events into the<br />

system.<br />

Fig. 5: Logstash configuration file structure<br />

input {<br />

lumberjack {<br />

port => 6379<br />

type => "IISLogs"<br />

ssl_certificate => "/home/azureuser/logstash.crt"<br />

ssl_key => "/home/azureuser/logstash.key"<br />

}<br />

}<br />

filter {<br />

if [type] == "IISLogs" {<br />

if [message] =~ "^#" {<br />

drop {}<br />

}<br />

grok {<br />

magazine voor software development 25


GENERAL<br />

match => ["message",<br />

"%{TIMESTAMP_ISO8601:log_timestamp}<br />

%{IPORHOST:site}<br />

%{WORD:method}<br />

%{URIPATH:page}<br />

%{NOTSPACE:querystring}<br />

%{NUMBER:port}<br />

%{NOTSPACE:username}<br />

%{IPORHOST:clienthost}<br />

%{NOTSPACE:useragent}<br />

%{NUMBER:response}<br />

%{NUMBER:subresponse}<br />

%{NUMBER:scstatus}<br />

%{NUMBER:time_taken}"]<br />

}<br />

date {<br />

match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss" ]<br />

timezone => "Etc/UCT"<br />

}<br />

useragent {<br />

source => "useragent"<br />

prefix => "browser"<br />

}<br />

mutate {<br />

remove_field => [ "log_timestamp"]<br />

}<br />

}<br />

}<br />

output {<br />

elasticsearch {<br />

}<br />

}<br />

Filter<br />

The filter actually tries to parse the data of the event. The first line of<br />

the filter contains a condition which checks the type of the event.<br />

if [type] == "IISLogs" {<br />

This means that the lines following this condition will only be executed<br />

if the type of the event equals “IISLogs”. As you remember we added<br />

this type to events that are input using the lumberjack input plugin.<br />

The next line states that events that start with a hash should be<br />

ignored.<br />

if [message] =~ "^#" { drop {} }<br />

Lines in an IIS log file that start with a hash indicate a comment. These<br />

are normally only present in the header of the IIS logfile.<br />

The next part uses the Logstash GROK plugin. GROK is a wrapper<br />

around a regular expression engine which enables you to reuse<br />

existing regex patterns. It is the ideal solution for parsing custom log<br />

messages and comes with 120 existing patterns.<br />

Using GROK we are going to parse a IIS log event. A log line of a IIS<br />

log event looks like the following:<br />

2014-12-08 00:00:17 172.16.12.172 POST /url1/api.asmx - 443<br />

VODKIJKWIN 192.168.16.135 PHP-SOAP/5.3.28-1~dotdeb.0 200 0 0<br />

343<br />

I will describe each part of the configuration file, starting with the input.<br />

Input<br />

The input plugin I am using is called lumberjack which is a specific<br />

input plugin specially created for securely receiving events from<br />

Logstash-forwarder. Logstash-forwarder is a type of application runs<br />

on your server and sends log events to the log server. Logstashforwarder<br />

is an application that consume low resources.<br />

The Logstash-forwarders motto:<br />

I'm a lumberjack and I'm ok!<br />

I sleep when idle, then I ship logs<br />

all day! I parse your logs, I eat the<br />

JVM agent for lunch!<br />

The lumberjack input plugin has several configuration fields which<br />

define on what port and which certificate is used to setup an<br />

encrypted connection. We are using port 6379 for the lumberjack<br />

input. To be able to send the log events securely to the server we need<br />

a certificate. This can be a self-signed certificate or a real certificate.<br />

I will show later how to create this certificate.<br />

The type fields adds a new field called ‘type’ to each event. The value<br />

of this field when events are retrieved by lumberjack is “IISlogs”. Types<br />

are mainly used for filter activation, we can specify that a certain filter<br />

should only be used for events that have type=”IISLogs”, which we<br />

will describe next.<br />

The grok match parameter specifies the pattern to parse this line.<br />

grok {<br />

match => ["message",<br />

"%{TIMESTAMP_ISO8601:log_timestamp}<br />

%{IPORHOST:site}<br />

%{WORD:method}<br />

%{URIPATH:page}<br />

%{NOTSPACE:querystring}<br />

%{NUMBER:port}<br />

%{NOTSPACE:username}<br />

%{IPORHOST:clienthost}<br />

%{NOTSPACE:useragent}<br />

%{NUMBER:response}<br />

%{NUMBER:subresponse}<br />

%{NUMBER:scstatus}<br />

%{NUMBER:time_taken}"]<br />

}<br />

Note, that for readability the grok pattern has been split on to multiple<br />

lines. The actual grok match line should be on a single line.<br />

It starts by reusing an existing pattern in grok called TIMESTAMP_<br />

ISO8601 which parses the date and time from the event and stores it<br />

into the field log_timestamp and ends with NUMBER which is stored<br />

into the time_taken field. An online tool is available http://grok<br />

debug.herokuapp.com/ for testing grok patterns.<br />

After the GROK stage of the filter we have parsed the IIS log line into<br />

several specific fields.<br />

26<br />

MAGAZINE


GENERAL<br />

The filter continues with using the date plugin. The date plugin is able<br />

to convert a field into a date time and use that date time as the<br />

timestamp of this specific event.<br />

No other fields are specified as we are running Elasticsearch on the<br />

same machine as Logstash. Otherwise we could have specified, for<br />

example the host and port.<br />

date {<br />

match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss" ]<br />

timezone => "Etc/UTC"<br />

}<br />

Restart Logstash<br />

We have to restart Logstash after we have added or changed the<br />

Logstash configuration file. We restart Logstash with the following<br />

command.<br />

If no time zone is specified it adds a default time zone of “Etc/UTC” to<br />

the event.<br />

$ sudo service logstash restart<br />

The user agent plugin parses user agentstring into structured data.<br />

It uses BrowserScope data to add information like family, operating<br />

system, version and device. Browserscope is an open-source project<br />

for profiling web browsers and storing and aggregating crowd-sourced<br />

data about browser performance.<br />

useragent {<br />

source => "useragent"<br />

prefix => "browser"<br />

}<br />

The prefix field specifies to add “browser” to all of the extracted fields.<br />

The last part of the filter shows the mutate plugin which enables you<br />

to mutate fields. You can remove, rename, replace or modify fields in<br />

events.<br />

mutate {<br />

remove_field => [ "log_timestamp"]<br />

}<br />

Here we remove the log_timestamp field because we don’t need it<br />

anymore as it already converted into a timestamp.<br />

As the log event is now parsed and has a timestamp it is time to move<br />

it to the output.<br />

Output<br />

In the output we specify a single output plugin. The elasticsearch<br />

plugin is obviously used for sending the event to Elasticsearch.<br />

output {<br />

elasticsearch {<br />

}<br />

}<br />

This concludes installing and configuring our ELK stack using a single<br />

server. The final part to getting log events into the server is adding and<br />

configuring a shipper on the server that contains the logs of the<br />

application that we want to monitor.<br />

Sending events to Logstash<br />

We first have to send the events to Logstash before we can parse,<br />

index and search through them. There are several so called shippers<br />

which are responsible for transmitting events to Logstash.<br />

There are several shippers available that move events to Logstash.<br />

Logstash itself can also be used as a shipper. As Logstash runs with<br />

a footprint that is not friendly to under provisioned systems, several<br />

alternatives were created that have a smaller footprint, for example, the<br />

earlier mentioned Logstash-forwarder. Other alternatives are Beaver<br />

(written in Python) and Woodchuck (written in Ruby).<br />

I will be using Logstash-forwarder as I develop a lot of software that<br />

has to run on Windows. Logstash-forwarder is developed in Go and<br />

as such can be compiled and run on Windows.<br />

Currently there is no binary distribution of Logstash-forwarder, therefore<br />

to use it you have to compile it first. Instructions can be found at<br />

https://github.com/elasticsearch/logstash-forwarder.<br />

As you may recall the input filter of Logstash used the lumberjack<br />

plugin to receive events from the logstash-forwarder.<br />

input {<br />

lumberjack {<br />

port => 6379<br />

type => "IISLogs"<br />

ssl_certificate => "/home/azureuser/logstash.crt"<br />

ssl_key => "/home/azureuser/logstash.key"<br />

}<br />

}<br />

We are using port 6379 for the lumberjack input. To be able to send<br />

the log events securely to the server we need a certificate. This can be<br />

a self-signed certificate or a real certificate. I will be generating and<br />

using a self-signed certificate.<br />

I used the openssl command line to generate the self-signed certificate<br />

on the Ubuntu server. We generate a private key and certificate with<br />

the following command.<br />

$ openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout<br />

logstash.key -out logstash.crt<br />

Fig. 6: Shippers move events to Logstash<br />

The self-signed certificate needs several types of information to put<br />

into the certificate. The only thing that is important is the Common<br />

Name, this must be set to the fully qualified domain name of the<br />

logstash server.<br />

magazine voor software development 27


GENERAL<br />

After the self-signed certificate is created, you have to copy the<br />

logstash.key and the logstash.crt files from the Unbuntu server to the<br />

folder on the machine that contains the logstash-forwarder.<br />

Creating the logstash-forwarder configuration file<br />

Before we can start the logstash-forwarder we have to create a<br />

configuration file that instructs the forwarder where to get the log event<br />

from and where to send them. Below a configuration file called<br />

logstash-forwarder.conf I use on a machine to send IIS logs to my<br />

central logstash server.<br />

{<br />

"network": {<br />

"servers": [ "elkstack.cloudapp.net:6379" ],<br />

"ssl ca": "Logstash.crt"<br />

},<br />

"files": [<br />

{<br />

"paths": [ " C:\\inetpub\\logs\\LogFiles\\W3SVC1\\*.log"<br />

],<br />

"type": ["IISLogs"]<br />

}<br />

]<br />

}<br />

The logstash-forwarder will monitor the folder for new or added<br />

logfiles and will send them to the logstash server. To run logstashforwarder<br />

in the background as a Windows service, we have to convert<br />

it into a Windows service. This can be done using NSSM (the<br />

Non-Sucking Service Manager) from http://nssm.cc/<br />

Filtering events using Kibana<br />

After we got the event flowing into the server, we can visualize the<br />

events using Kibana. With Kibana you can create and save custom<br />

dashboards. The default installation already contains a dashboard<br />

which is configured for Logstash as can be seen in Figure 8.<br />

The default Logstash dashboard contains a graph which counts the<br />

number of events over time and includes a search field which allows<br />

you to search on free text or search in specific fields.<br />

The functionality of Kibana deserves a separate article on its own.<br />

There are multiple ways to create graphs, combine geo-ip data and<br />

filters.<br />

It specifies under network which certificate to use and to what server<br />

the logs should be sent The files parameter specifies which paths and<br />

pattern should be used to search the log files. Pay special interest to<br />

using the double backslash on Windows as a folder separator. Before<br />

starting the logstash forwarder I have to add another end point to my<br />

Azure virtual machine to let Logstash connect to port 6379.<br />

Fig. 9: Kibana extended dashboard<br />

Scaling the ELK stack<br />

As we are going to expand our system to receive and group more<br />

logs, the single Logstash server that we are currently using won’t<br />

be sufficient. We have to scale our architecture. Current it looks like<br />

Figure 8.<br />

Fig. 7: Specific end point for Lumberjack<br />

Fig. 10: Current Architecture<br />

The first thing we can scale is the Broker. Broker is the part that<br />

receives the log events. Currently we are using the message buffer<br />

from Logstash. A good way to scale the broker is to use Redis on a<br />

separate server to acts as a broker. Redis is a popular open source key<br />

value storage. Logstash includes plugins for using Redis.<br />

Fig. 8: Default Logstash dashboard in Kibana<br />

Redis is a popular open source key<br />

value storage<br />

The Logstash forwarder can now be started with the following<br />

command.<br />

C:\lgf> logstash-forwarder.exe -config=logstash-forwarder.conf<br />

To increase the throughput of the Indexer, we could also separate<br />

Logstash from Elasticsearch. So the new architecture looks like<br />

28<br />

MAGAZINE


GENERAL<br />

The protocol that Logstash-forwarder uses includes compression,<br />

encryption and message acknowledgement, which Redis does not<br />

support. There are alternative shippers which do, such as beaver and<br />

woodchuck.<br />

Fig. 11: Scaled Architecture<br />

Elasticsearch can be scaled<br />

by adding new Elasticsearch nodes<br />

to the cluster<br />

If we switch to using Logstash as a shipper we could configure it using<br />

the following output filter in which the events are sent to one of the<br />

two configured Redis servers.<br />

output {<br />

redis {<br />

host => ["redis-server1:6379", "redis-server2:6380"]<br />

}<br />

}<br />

Fig. 12: Horizontally Scaled Architecture<br />

This architecture can be scale horizontally very easily. We can add<br />

more Redis servers to increase the queue capacity, we can add more<br />

Logstash server to increase indexing capacity and add more nodes to<br />

the Elasticsearch cluster to increase the performance of querying and<br />

filtering of data. A first step into scaling horizontally looks like Figure 10.<br />

By cross connecting both Redis servers and the Logstash indexer we<br />

also create redundancy and fault tolerance between the systems. The<br />

shippers also can connect to both Redis servers so that if one of the<br />

servers goes down, a shipper is still able to send its events.<br />

Elasticsearch can be scaled by adding new Elasticsearch nodes to<br />

the Elasticsearch cluster. It will automatically detect and distribute data<br />

over the available nodes.<br />

Configuring the Scaled Architecture<br />

To configure the horizontally scaled ELK stack we need to make some<br />

changes to the configuration files.<br />

The Logstash configuration file on both indexers needs to change.<br />

We use the Redis plugin to get the input from both Redis servers.<br />

input {<br />

redis {<br />

host => "redis-server1"<br />

port => 6379<br />

data_type => "list"<br />

key => "logstash"<br />

}<br />

redis {<br />

host => "redis-server2"<br />

port => 6380<br />

data_type => "list"<br />

key => "logstash"<br />

}<br />

}<br />

Conclusion<br />

In this article I showed how to install and configure the ELK stack in<br />

such a way that enables transfering application logs from a Windows<br />

machine using logstash-forwarder to the machine that hosts the ELK<br />

stack. The host parses the application logs using Logstash, indexes<br />

the logs using Elasticsearch and allows visualizing hem using Kibana.<br />

By combining the logs from all your services and applications you can<br />

improve the traceability of your IT system. All your logs become<br />

searchable in almost real-time. By parsing extra information using<br />

Logstash per application you could give more meaning to your<br />

existing logs without having to go through all the logs individually.<br />

To scale out the ELK stack, Redis servers can be added together with<br />

separate Logstash servers. Scaling Elasticsearch is as easy as adding<br />

nodes to the cluster. The easy way the ELK stack can be scaled<br />

horizontally really shows the strength of the platform.<br />

This article barely scratched the surface of what you can do with the<br />

ELK stack. Topics I did not cover but are very interesting are security,<br />

creating dashboards with Kibana, adding semantics to log events,<br />

alerting, exporting and creating your own Logstash plugins.<br />

Other alternative platforms for log aggregation that you should<br />

consider when evaluating a log aggregation platform are Splunk,<br />

Sumologic and Scribe. •<br />

Patrick Kalkman<br />

Patrick Kalkman is a software<br />

architect at HintTech where he<br />

designs and implements state of the<br />

art web applications using an agile<br />

proces.<br />

Currently Logstash-forwarder does not support connecting to Redis.<br />

magazine voor software development 29


SQL<br />

Peter ter Braake<br />

SQL Server In-Memory OLTP<br />

2014 was het jaar van de release van SQL Server 2014. Nog meer dan dat was het het jaar van<br />

de release van tientallen nieuwe cloud services. Dit artikel gaat (een keer) niet over de cloud of<br />

over Azure. Dit artikel gaat over een nieuwe revolutionaire engine die volledig is geïntegreerd in<br />

SQL Server: Hekaton!<br />

Hekaton<br />

Hekaton was de code naam voor de In-Memory engine van SQL<br />

Server. Hekaton komt uit het Grieks en verwijst naar de ambitie van<br />

Microsoft om SQL Server honderd keer zo snel te maken. Honderd<br />

keer! Honderd keer is bij lange na niet gehaald, maar de resultaten zijn<br />

ondanks dat meer dan indrukwekkend.<br />

Hekaton, ofwel memory optimized tabellen, is één van de vele nieuwe<br />

in-memory features. De database engine van SQL Server is in de kern<br />

alle ruim twintig jaar oud. Veel designkeuzes zijn dus ook al meer dan<br />

twintig jaar geleden gemaakt. Weet u nog met welke computer u<br />

twintig jaar geleden werkte?<br />

De hardware van toen was ontzettend beperkt ten opzichte van de<br />

huidige hardware. Voornamelijk de hoeveelheid geheugen die we<br />

tegenwoordig met 64-bits computers kunnen is drastisch toegenomen.<br />

Tegelijkertijd is de prijs gekelderd zodat ook iedereen zich dat<br />

geheugen kan permitteren. Door de dure en beperkte hoeveelheid<br />

geheugen van toen is SQL Server een file-based database. Hoewel de<br />

engine zoveel mogelijk gebruik maakt van geheugen middels de<br />

buffer pool, is het uitgangspunt dat de gegevens op disk staan.<br />

De datafiles op disk waar de gegevens in opgeslagen worden, zijn<br />

opgedeeld in blokken van 8 KB, de pages. Ook in het geheugen<br />

zitten de records nog steeds opgeslagen op die pages.<br />

Latches<br />

Hoewel het concept van pages een optimalisatie betekende voor filebased<br />

databases, levert het ook beperkingen op. Op het moment dat<br />

SQL Server een nieuw record moet wegschrijven, of dat een bestaand<br />

record gewijzigd moet worden, bestaat er de kans dat records over<br />

elkaars ruimte heen schrijven. Dat zou inconsistenties (corruptie)<br />

veroorzaken. Daartegen moet SQL Server ons beschermen.<br />

werken. Als er maar één proces actief is in uw database, is dat geen<br />

probleem. Maar hoe meer cores u heeft, hoe meer processen tegelijkertijd<br />

actief zijn. Dat houdt in dat de kans dat een proces moet<br />

wachten op een ander proces steeds groter wordt. Wachtende<br />

processen is wat mensen ervaren als slechte performance.<br />

In het screenshot van figuur 1 ziet u het aantal transacties per seconde<br />

in een voorbeeld applicatie van Microsoft. In dit voorbeeld zijn dat 520<br />

transacties per seconde. Opvallend is het CPU verbruik van nog geen<br />

50%. Meer CPU’s gaat waarschijnlijk niet helpen om meer transacties<br />

te verwerken. Tweede opvallende feit is het aantal latches per<br />

seconde. Die latches kosten overhead in het systeem en veroorzaken<br />

wachttijden bij andere user processen. Daar zit de grote bottleneck.<br />

Memory optimized tables<br />

Met Memory optimized tables draait Microsoft het uitgangspunt van<br />

SQL Server om. Gegevens zitten in principe in het geheugen. Uiteraard<br />

moet alle data uiteindelijk ‘landen’ op disk, anders bent u die data<br />

kwijt. Memory optimized tables zijn wat in theorie genoemd wordt:<br />

fully durable. Dat wil zeggen dat als een transactie succesvol is<br />

afgerond, de gegevens gegarandeerd in de database zitten en niet<br />

meer kwijt kunnen raken. Gegevens worden dus weggeschreven naar<br />

disk, maar het uitgangspunt is dat de gegevens in het geheugen<br />

zitten. Daarvoor wordt geoptimaliseerd.<br />

Memory optimized tables omgekeerd<br />

uitgangspunt van SQL Server;<br />

Memory first then disk<br />

Omdat gegevens worden opgeslagen in geheugen is het concept van<br />

pages niet langer nodig. Een record zit in geheugen op een<br />

willekeurige plek die toevallig vrij was toen het geschreven werd.<br />

Omdat een record niet op een pagina staat, hoeft er ook geen latch<br />

te zijn om per ongeluk overschrijven van gegevens te voorkomen.<br />

Zonder latches zijn er ook geen processen die moeten wachten op<br />

latches. En minder wachtende processen is betere benutting van de<br />

beschikbare CPU’s, is betere performance.<br />

Fig. 1<br />

De bescherming die SQL Server biedt wordt een latch genoemd.<br />

Latches worden vaak uitgelegd als zijnde light-weight locks. Maar nu<br />

weet u nog niet veel meer. Als een proces begint met schrijven, wordt<br />

de hele pagina geblokkeerd voor dat proces. Totdat het proces klaar<br />

is met schrijven, kunnen andere processen niet met die pagina<br />

Locks<br />

Pagina’s worden beschermd met latches, records worden beschermd<br />

door middel van locks. Naast het feit dat twee processen op dezelfde<br />

pagina moeten zijn, kan het ook voorkomen dat ze met hetzelfde<br />

record werken. Locks voorkomen problemen door één van de<br />

processen te laten wachten. Memory optimized tabellen hanteren een<br />

lock and latch free mechanisme. Of in een moeilijk woord: optimistic<br />

multi version concurrency control. Een record wordt eigenlijk nooit<br />

meer gewijzigd. Een record wordt simpelweg met een timestamp<br />

30<br />

MAGAZINE


SQL<br />

gemarkeerd als oud en er wordt een nieuw record aangemaakt. Twee<br />

processen die tegelijkertijd met een record werken krijgen allebei hun<br />

eigen versie van het record.<br />

Natively compiled stored procedures<br />

Zonder locks en latches wordt een grote performance bottleneck<br />

weggenomen. Maar valt er nog meer te winnen? Zonder locks and<br />

latches wordt de CPU voor 100% gebruikt in de voorbeeldapplicatie<br />

van figuur 1. SQL Server zou eigenlijk in staat moeten zijn om met<br />

dezelfde hoeveelheid CPU cycles, meer werk te doen. Dat is precies<br />

wat u bereikt met natively compiled stored procedures. Tijdens de<br />

CREATE van deze stored procedures worden deze gecompileerd tot<br />

een C-dll. Deze vooraf gecompileerde code is veel beter geoptimaliseerd<br />

dan interpreted T-SQL en daardoor veel sneller.<br />

Natively compiled stored procedures kunnen nog niet de volledige<br />

SQL functionaliteit gebruiken. Niet alle data types worden ondersteund,<br />

niet alle functies worden ondersteund. Bovendien kunt u met<br />

een natively compiled stored procedure alleen werken met memory<br />

optimized tables, niet met klassieke file based tables. Andersom kan<br />

wel. Met Query interop wordt bedoeld dat u met gewoon SQL zowel<br />

gewone tabellen als memory optimized tables kunt benaderen.<br />

Alles bij elkaar krijgt u een architectuur zoals in figuur 2.<br />

Dat is niet meteen vanzelfsprekend.<br />

De CREATE TABLE ziet er als volgt uit.<br />

CREATE TABLE Sales.SalesOrderDetailHashOnly<br />

(<br />

[SalesOrderID] [int] NOT NULL,<br />

[SalesOrderDetailID] [int] NOT NULL PRIMARY KEY NON-<br />

CLUSTERED HASH WITH (BUCKET_COUNT=200000),<br />

[CarrierTrackingNumber] [nvarchar](25) NULL,<br />

[OrderQty] [smallint] NOT NULL,<br />

[ProductID] [int] NOT NULL INDEX IXH_ProductID NON-<br />

CLUSTERED HASH WITH (BUCKET_COUNT=300),<br />

[SpecialOfferID] [int] NOT NULL,<br />

[UnitPrice] [money] NOT NULL,<br />

[UnitPriceDiscount] [money] NOT NULL CONSTRAINT<br />

[DF_SalesOrderDetail_UnitPriceDiscount] DEFAULT ((0.0)),<br />

[LineTotal] [money],<br />

[rowguid] [uniqueidentifier] NOT NULL CONSTRAINT<br />

[DF_SalesOrderDetail_rowguid] DEFAULT (newid()),<br />

[ModifiedDate] [datetime] NOT NULL CONSTRAINT<br />

[DF_SalesOrderDetail_ModifiedDate] DEFAULT (getdate())<br />

) WITH (MEMORY_OPTIMIZED = ON, DURABILITY =<br />

SCHEMA_AND_DATA);<br />

Het goede nieuws is dat dit hoofdzakelijk is wat u gewent bent. Let<br />

vooral op de inline indexen en de bucket count bij de hash indexen.<br />

Verder valt op dat het statement eindigt met MEMORY_OPTIMIZED = ON<br />

en DURABILITY = SCHEMA_AND_DATA. Voor durability zijn er twee<br />

opties: schema_and_data en schema_only. Met die laatste zitten de<br />

gegevens alleen in memory, nooit op disk. Bij een server herstart bent<br />

u dus alle gegevens kwijt. Voor situaties als state van een website of<br />

staging tabellen bij ETL kan dat grote voordelen hebben.<br />

Bij het maken van een natively compiled stored procedure komt net<br />

iets meer nieuwe kennis kijken. De code begint altijd als volgt:<br />

Fig. 2<br />

Impact voor de programmeur<br />

Dit klinkt allemaal fantastisch, maar waarom dat verhaal in het<br />

Developers <strong>Magazine</strong>? Helaas is memory optimized tables geen<br />

feature die je aan of uit zet en die zonder verdere aanpassingen<br />

voordeel oplevert. De programmeur zal in zijn of haar code rekening<br />

moeten houden met de feature. Allereerst zijn er enkele zaken om over<br />

na te denken bij het maken van de tabel.<br />

CREATE PROCEDURE usp_InsertOrderMemoryOptimized<br />

@SalesOrderID int, @SalesOrderDetailID int, @OrderQty smallint,<br />

@ProductID int<br />

WITH NATIVE_COMPILATION<br />

, SCHEMABINDING<br />

, EXECUTE AS OWNER<br />

AS<br />

BEGIN ATOMIC WITH (<br />

TRANSACTION ISOLATION LEVEL = SNAPSHOT<br />

, LANGUAGE = 'us_english'<br />

, DELAYED_DURABILITY = OFF)<br />

Memory optimized tables<br />

een Developers taak<br />

Een memory optimized tabel kent geen ALTER TABLE. Van een tabel<br />

wordt, net als een natively compiled stored procedure, tijdens de<br />

CREATE een dll gemaakt. De enige manier om die aan te passen is<br />

hem weggooien om hem daarna opnieuw aan te maken. Dit klinkt<br />

misschien nog wel overkomelijk, maar geldt ook voor indexen. Ook<br />

indexen kunnen niet later aangemaakt worden of verandert worden.<br />

Memory optimized tabellen kennen twee soorten indexen, hash<br />

indexes en range indexes. Beide worden tijdens de CREATE TABLE al<br />

gedefinieerd. Bij de hash index moet u opgeven uit hoeveel hash<br />

buckets de index bestaat. De vuistregel is dat u ongeveer twee keer<br />

zoveel hashbuckets maakt als dat u unieke waarden in de te indexeren<br />

kolom heeft. Maar u moet wel vooraf een keuze maken.<br />

Het eerste dat opvalt, is de optie WITH NATIVE_COMPILATION. Die<br />

optie heeft geen verdere uitleg nodig. Omdat er een dll gemaakt wordt<br />

is de optie SCHEMABINDING verplicht. Verder is het verplicht een<br />

execution context te bepalen, de owner in dit voorbeeld.<br />

Vervolgens begint u altijd met de clausule BEGIN ATOMIC BLOCK.<br />

Zoals gezegd gaat memory optimized uit van optimistic multi version<br />

concurrency control. Dat houdt in dat er niet vooraf door middel van<br />

locks beschermd wordt tegen concurrency problemen. Iedereen werkt<br />

met zijn eigen versie van de records. Op het moment dat u uw transactie<br />

commit, wordt pas gekeken of uw versie wel commitbaar is. Het<br />

kan zijn dat iemand anders u voor is geweest en al een wijziging heeft<br />

doorgevoerd. U krijgt dan een foutmelding. Error handling code is dus<br />

van essentieel belang binnen uw stored procedure. Gelukkig kent<br />

T-SQL TRY … CATCH en sinds SQL Server 2012 ook THROW.<br />

Uw stored procedure is altijd een atomic block, ofwel een transactie.<br />

lees verder op pagina 35 ><br />

magazine voor software development 31


SCRUM<br />

Piet Willem Overvoorde<br />

SCRUM is veel meer dan<br />

een project management<br />

methodologie<br />

Dat is zonder meer waar en een methodologie die, mits die op de goede manier wordt gebruikt,<br />

heel goed toepasbaar is op allerlei soorten projecten. Dus het gebruik ervan is zeker niet beperkt<br />

tot ICT (gerelateerde) ontwikkelingen. Scrum is prima toepasbaar bij complexe producten<br />

(eindproduct is moeilijk vooraf tot in detail te beschrijven) en bij complexe organisaties (veel<br />

stakeholders).<br />

De uitdaging (opdracht) is om de effecten van het werken op basis<br />

van SCRUM te delen met de organisatie met het doel als collectief<br />

nog effectiever en efficiënter samen te werken.<br />

Belangrijke kernmerken van SCRUM zijn:<br />

• Eenduidig interpreteerbare werk- en projectafspraken;<br />

• Op basis van geplande evaluatie momenten continue aandacht<br />

voor opzet en inhoud van de werkzaamheden; maar aan<br />

gemaakte afspraken wordt niet getoornd;<br />

• Korte, afgeronde werkzaamheden;<br />

• Geen ad-hoc interventies;<br />

• Team prestatie is bepalend (zelfsturende en zelflerende<br />

organisatie);<br />

• Continue aandacht voor de kwaliteit van het door alle betrokken<br />

partijen geleverde product;<br />

• Rust en duidelijkheid in het project en in het proces.<br />

SCRUM is veel breder toepasbaar<br />

Overal waar er sprake is van een opdrachtgever en van het halen van<br />

financiële, inhoudelijke- en planningsdoelstellingen is SCRUM<br />

toepasbaar. Inderdaad niet altijd in de meest zuivere vorm maar wel als<br />

handvat voor het maken van afspraken en het opvolgen en managen<br />

hiervan. Als het eindproduct vast staat, heeft SCRUM geen toegevoegde<br />

waarde. Als voorbeeld de auto: het ontwikkelen kan met<br />

scrum, het produceren van de auto bijvoorbeeld met lean.<br />

Wanneer je de hiervoor beschreven kenmerken van SCRUM nog een<br />

keer doorneemt en projecteert op de dagelijkse werkelijkheid van<br />

bijvoorbeeld de samenwerking tussen sales en delivery in verkoop en<br />

implementatie trajecten dan blijkt dat deze aanpak zonder meer ook<br />

hierop prima toepasbaar is.<br />

SCRUM leidt tot verbeterd begrip<br />

tussen de verschillende bloedgroepen<br />

binnen een organisatie<br />

Waarom het SCRUM gedachtengoed als basis voor het beheer<br />

van processen?<br />

De voordelen van het gebruik van (een variant) van SCRUM in sales<br />

processen zijn onder andere:<br />

• Duidelijke afspraken tussen alle deelnemers (sales, pre-sales,<br />

delivery/operations, prospect, adviseur etc.);<br />

• Heldere lijnen voor het managen van het proces;<br />

• Alle deelnemers worden ‘gedwongen’ vooraf heel goed nagedacht<br />

te hebben;<br />

• Voor en bij het afsluiten van het contract zijn alle relevante partijen<br />

betrokken geweest.<br />

Naast een eenvoudiger en succesvoller beheer van de genoemde<br />

voorbeeld processen leidt een breder gebruik van (de uitgangspunten<br />

van) SCRUM ook tot een verbeterd begrip, over en weer, tussen<br />

de verschillende bloedgroepen binnen een organisatie. De zaken<br />

waarmee sales, project management, consultancy en ontwikkeling<br />

dagelijks te maken hebben in hun ‘eigen wereld’ worden binnen het<br />

team gedeeld. Het team is verantwoordelijk voor het realiseren van de<br />

doelstellingen en niemand kan zich achter de performance van een<br />

ander verschuilen.<br />

Een andere, meer effectieve en resultaatgerichte vorm van<br />

samenwerking<br />

De eerder in dit stuk genoemde rust en duidelijkheid komen, wanneer<br />

deze manier van werken effectief is geïmplementeerd, iedereen ten<br />

goede. Ad hoc vragen en interventies van collega’s en zeker ook van<br />

managers mogen in principe niet meer voorkomen.<br />

32<br />

MAGAZINE


SCRUM<br />

Ieder lid van het team moet acteren als eigenaar en verantwoordelijke<br />

voor het eindresultaat (overall en van een sprint). En in die rol wil je<br />

zaken niet over hoeven doen omdat de WAT vraag niet voldoende is<br />

uitgevraagd. Of het antwoord op de HOE vraag niet op de beste<br />

manier is afgestemd en geformuleerd.<br />

SCRUM kan in een bepaalde vorm worden toegepast voor de<br />

beheersing van andere processen. Maar de volgende zaken kunnen<br />

zonder meer organisatie breed worden geadopteerd:<br />

• Het benoemen van de doelstelling(en)/het product van de samenwerking,<br />

de WAT vraag;<br />

• Het definiëren van sprints/stappen waarbinnen het antwoord op de<br />

HOE vraag vorm moet krijgen (of deze allemaal van een gelijke duur<br />

moeten en kunnen zijn is sterk afhankelijk van het project en de<br />

hierin onderkende stappen; het verzorgen van een demo kost bijvoorbeeld<br />

minder tijd dan het beantwoorden van een RFI of RFP);<br />

• Het toekennen van duidelijke taken en verantwoordelijkheden aan<br />

de Product Owner, de SCRUM Master (of de procesbeheerder) en<br />

het team (of de teams, wanneer die per sprint verschillend zouden<br />

zijn; dit laatste is een concreet verschil tussen SCRUM in de<br />

zuivere vorm als project management tool (vooral gebruikt binnen de<br />

ontwikkeling van softwarematige toepassingen) en de SCRUM<br />

methodologie als kapstok voor het managen van andere soorten<br />

projecten/activiteiten);<br />

• Gebruik maken van de praktische hulpmiddelen zoals de rol van de<br />

SCRUM Master, de dagelijkse afstemming/update, het SCRUM<br />

bord (met alles dat daar deel vanuit maakt) en de pokerkaarten;<br />

• En na afloop een integrale evaluatie van de kennis en ervaring die<br />

vanuit het project kan worden meegenomen en ingezet om<br />

toekomstige projecten nog beter te laten verlopen.<br />

bedrijfsprocessen. Combinaties van allerhande, technische en<br />

functioneel, rol/ functie gerichte, tools. Dat is nu ook mogelijk omdat<br />

het koppelen van oplossingen en het synchroniseren van databases<br />

veel eenvoudiger is geworden. Door de focus van alle betrokken<br />

partijen is de kans groot dat een investering een veel meer toekomstbestendige<br />

blijkt te zijn. De behoefte aan het eenvoudig kunnen delen<br />

van informatie zal ook verder toe gaan nemen.<br />

De samenwerking is gebaseerd op<br />

onderling vertrouwen<br />

De ontwikkeling die hiervoor is beschreven met betrekking tot ICT<br />

oplossingen geldt ook voor heel veel andere soorten projecten. Steeds<br />

meer is er sprake van virtuele, project specifieke, teams van professionals<br />

die het afgesproken resultaat tot stand moeten brengen.<br />

Het gebruik van een erkende en gestandaardiseerde project aanpak<br />

biedt dan uitkomst. En voorkomt allerhande spraakverwarring met<br />

betrekking tot verwachtingen, communicatie, voortgangsrapportage<br />

etc. Het is om die reden dat het aantal online SCRUM ondersteunende<br />

tools zeker toe zal nemen in de komende periode.<br />

Gaat die samenwerking vanzelf en gelijk goed?<br />

Het is voor medewerkers en managers wennen wanneer SCRUM<br />

breed in de onderneming wordt geïntroduceerd. De hiervoor zo<br />

benoemde verschillende bloedgroepen binnen een organisatie, sales,<br />

consultants, ontwikkelaars, project leiders en managers, zullen stuk<br />

voor stuk het gevoel kunnen hebben dat anderen in hun domein<br />

‘binnen dringen’.<br />

Dat is natuurlijk ook zo, maar erg is anders! De samenwerking moet<br />

worden gebaseerd op een oprecht onderling vertrouwen: gemaakte<br />

afspraken moeten gestand worden gedaan. En als daar reden voor is<br />

dan worden zorgen en aandachtspunten tijdig onderkend en gedeeld.<br />

Een heel groot voordeel voor de betrokken managers is dat zij hun<br />

eigenlijke rol en opdracht inhoud kunnen geven.<br />

Het succes moet zijn gebaseerd op het op deze manier WILLEN<br />

werken. En iedereen beperkt zich in dit geval niet tot de interne<br />

organisatie. Binnen de teams zullen ook partners, prospects en klanten<br />

actief zijn. Het is goed om de introductie van deze werkwijze op te<br />

pakken samen met een of meerdere bestaande klanten en partners.<br />

Een andere vorm van samenwerking is noodzakelijk<br />

We zitten in de eindigende periode dat alles binnen dezelfde<br />

zogenaamde ERP oplossing moet kunnen worden opgelost. Op basis<br />

van de standaard set aan functionaliteiten gecombineerd met branche<br />

specifieke modules en maatwerk. Initieel is dit zonder meer een goede<br />

gedachte.<br />

De ervaring heeft geleerd dat er in de loop van de tijd vaak sprake is<br />

van a-synchronisatie tussen de ondersteunde versies van applicaties,<br />

besturingssystemen, ontwikkelomgevingen en databases. Dit heeft te<br />

maken met de periodieke heroverweging met betrekking tot branchefocus<br />

en de wil en mogelijkheid om in een ontwikkeling te blijven<br />

investeren. De wil wordt o.a. bepaald door de kans op een redelijk<br />

rendement.<br />

Er zal gebruik gemaakt gaan worden van ‘best of breed’ oplossingen<br />

als basis voor de ondersteuning van alle voor een organisatie relevante<br />

Is dit de basis voor het succes van ieder project?<br />

Nee! Hoe goed een project aanpak ook is, het team bepaalt het<br />

succes. Ook in sectoren waar er sprake is van strikte regels en<br />

procedures, zoals in de luchtvaart, de gezondheidszorg en de off<br />

shore, gaan er dingen mis. Maar oorzaken worden snel achterhaald.<br />

En de nodige maatregelen snel genomen.<br />

Wanneer het aantal variabelen toeneemt, neemt de behoefte aan<br />

duidelijke afspraken en kortlopende trajecten toe. Korte, overzichtelijke<br />

trajecten waardoor de risico’s tot een minimum worden beperkt<br />

worden steeds meer geëist door de klant. En dat is de basis van<br />

SCRUM. Dingen opnieuw doen is vaak mogelijk. Maar werkzaam -<br />

heden over-/anders doen is altijd kosten¬verhogend, marge verlagend<br />

en reputatie schadend.<br />

De implementatie<br />

Voor iedere verandering die wordt doorgevoerd geldt dat deze gaande<br />

het proces en mede op basis van de input van alle betrokkenen vorm<br />

moet krijgen.<br />

Een heel groot voordeel van de introductie van SCRUM als uitgangspunt<br />

voor de vormgeving van de samenwerking is dat vanaf het prille<br />

begin op deze manier gewerkt kan, beter zal worden.<br />

magazine voor software development 33


SCRUM<br />

Daardoor worden stap voor stap meer mensen hiermee bekend en<br />

groeit het vertrouwen dat dit inderdaad een positieve bijdrage zal gaan<br />

leveren. Naast het organiseren van allerhande praktische zaken moet<br />

in dit proces de ‘menselijke’ kant zeker niet worden onderschat en<br />

vergeten. Diverse rollen binnen de organisatie zullen een ander<br />

karakter krijgen. Dit vraagt aanpassing van het dagelijkse doen en<br />

laten.<br />

Zoals eerder gememoreerd is het ontwikkelen van een authentiek<br />

onderling vertrouwen een heel belangrijk aspect. Naast een goede<br />

uitwerking van de praktische aspecten en tools is een goede,<br />

professionele begeleiding op het ‘menselijke’ vlak zonder meer<br />

noodzakelijk.<br />

De beoordeling van de medewerkers moet primair gericht zijn op de<br />

realisatie van (collectieve) lange(re) termijn doelstellingen. Wanneer<br />

persoonlijke belangen (beloning, prestige, kans op promotie etc.) de<br />

boventoon voeren in het besluit onderdeel te willen zijn van bepaalde<br />

projecten dan zal deze methodiek nagenoeg zeker haar doel niet<br />

bereiken.<br />

Het management moet er klaar voor zijn of klaar voor gestoomd<br />

willen worden. Zo nodig ondersteund door een vorm van professionele<br />

inhoudelijke en persoonlijke coaching. Het commitment van alle<br />

managers is een essentiële bouwsteen van een succesvolle<br />

implementatie.<br />

Is dit alles nieuw en innoverend?<br />

Nee, bijna altijd is er voor elk proces een projecten<br />

procesaanpak aanwezig. Gedreven vanuit de<br />

primaire behoeften van de ‘bloedgroep’.<br />

Ja, want heel weinig organisaties gebruiken, om<br />

een veelheid aan (historische) redenen, voor alle<br />

aanwezige processen dezelfde uitgangspunten en<br />

werk¬methodiek.<br />

Een praktische voorbeeld: de opvolging van een RFI/RFP<br />

Zoals hiervoor is beschreven is het zeker niet het primaire doel om<br />

SCRUM in de meest zuivere vorm toe te willen passen. Wel wordt<br />

zoveel als mogelijk gebruik gemaakt van praktische handvatten die de<br />

methodologie biedt om processen op basis van heldere en eenduidige<br />

uitgangspunten professioneel en maximaal effectief en efficiënt<br />

te organiseren en realiseren. Opmerkingen als ‘dat wist ik niet’, ‘Maar<br />

wat nu als we toch/alsnog op basis van deze oplossing aanbieden<br />

….’ en ‘o, ik dacht dat …’ worden hiermee voorkomen. Door het team<br />

worden tenslotte voor in ieder geval een bepaalde periode (sprint)<br />

afspraken gemaakt op basis waarvan gewerkt wordt.<br />

De basis motivatie voor deze benadering is het creëren en behouden<br />

van het bewustzijn dat iedereen binnen een organisatie een rol kan<br />

spelen in de positieve afronding van projecten.<br />

Globaal kunnen in het proces van opvolging van een RFI/RFP de<br />

volgende fases worden onderscheiden:<br />

• Initiële evaluatie van de aanvraag;<br />

• Beantwoording van de functionele en technische vragen;<br />

• Oplevering van de documentatie;<br />

• Presentatie van de organisatie, de oplossing en het voorstel;<br />

• Proces om te komen tot een overeenkomst;<br />

• Realisatie van het project;<br />

• Doorontwikkeling van de relatie.<br />

Fase ‘0’van het project<br />

In deze fase worden onder andere de ‘opdrachtgever’ en de (potentiële)<br />

teamleden, eventueel per onderdeel/fase, bepaald. In vervolg<br />

hierop worden in de eerste samenwerking tussen opdrachtgever en<br />

team de hoofdfases benoemd.<br />

SCRUM binnen organisaties levert<br />

voordelen op<br />

Conclusie<br />

De introductie van een op de uitgangspunten van SCRUM gebaseerde<br />

samenwerking tussen alle bij een organisatie betrokken partijen biedt<br />

eigenlijk alleen maar voordelen. Mits dit proces vanaf het begin op een<br />

goede en professionele manier is gemanaged.<br />

• Duidelijkheid in doelstellingen, werkwijze, taken en verantwoordelijkheden;<br />

• Substantiële verbetering van de juistheid van het antwoord op de<br />

vraag WAT er wordt verwacht;<br />

• Een duidelijke kwaliteitsverbetering van het antwoord op de HOE<br />

vraag;<br />

• Efficiency verbetering op vele fronten, bezig zijn met de juiste<br />

dingen;<br />

• Verbetering en verduurzaming van de relatie en samenwerking met<br />

klanten en partners;<br />

• Versterking en verdieping van het onderlinge begrip en vertrouwen<br />

en daarmee de teamgeest.<br />

Kortom: zeker het overwegen waard!<br />

Handvatten na Fase ‘0’<br />

Geen RFI/RFP is hetzelfde en er wordt steeds meer op basis van<br />

business cases gewerkt in plaats van (of in combinatie met) lijsten met<br />

technische en functionele eisen en wensen. Hierdoor wordt het steeds<br />

belangrijker goed in staat te zijn om vat te krijgen op de werkelijke<br />

vraagstelling. Naast de standaard acties zoals het in kaart brengen<br />

van het beslistraject en de hierbij (in)direct betrokkenen.<br />

De WAT vraag bestaat in deze fase uit de volgende elementen (basis<br />

voor het definiëren van de sprints in deze fase):<br />

• WAT is de werkelijke behoefte van de prospect<br />

nu en in de toekomst;<br />

• WAT zijn de werkelijke technische en inhoudelijke wensen en eisen;<br />

34<br />

MAGAZINE


SCRUM<br />

• WAT is de planning van het voortraject en de realisatie;<br />

• WAT zijn de argumenten om deze RFI/RFP in te vullen;<br />

• WAT kunnen wij bieden dat ons bijzonder maakt en onze kansen<br />

maximaliseert;<br />

• WAT moeten wij doen om dit project tot een succes te maken;<br />

• WAT …..<br />

Op basis van de lijst (inderdaad er is geen enkelvoudige WAT vraag in<br />

deze toepassing te benoemen) met WAT vragen moet het antwoord<br />

worden gegeven op de HOE vragen die niet zonder meer vanuit de<br />

beschikbare documentatie kan worden beantwoord:<br />

• HOE gaan we de werkelijk behoeften, wensen en eisen in kaart<br />

brengen;<br />

• HOE brengen we de beslissers, beïnvloeders etc. in kaart;<br />

• HOE gaan we de beantwoording inhoudelijk en wat betreft<br />

presentatie vormgeven;<br />

• HOE (op basis van welke oplossingen, met welke partners, etc.)<br />

geven we technisch en functioneel het beste invulling aan hetgeen<br />

in de RFI/RFP is beschreven<br />

• ……..<br />

Alle vragen worden gesteld en beantwoord<br />

binnen een team. Daarbij wordt<br />

van iedereen verwacht dat die zich open<br />

en kwetsbaar opstelt. Wat voorheen<br />

vaak binnen de comfortzone van een<br />

afdeling werd besproken wordt nu<br />

gedeeld, beoordeeld en daarmee<br />

verrijkt. Door het toevoegen van de input<br />

en invloed vanuit andere perspectieven<br />

vindt er op meerdere manieren en<br />

diverse fronten een verbetering plaats die bijdraagt aan de kwaliteit en<br />

de uitkomst van het project.<br />

Waar de antwoorden op deze vragen bij het ‘reguliere’ gebruik van<br />

SCRUM in de methodologie zijn ingebakken moeten deze bij het<br />

beoogde bredere gebruik van deze aanpak specifiek worden<br />

beantwoord:<br />

• Op basis van de antwoorden op de HOE vragen zal het antwoord<br />

op de WIE vragen moeten gegeven. WIE (welk TEAM) maakt zich<br />

verantwoordelijk voor welke onderdeel. In tegenstelling tot SCRUM<br />

in de zuiver vorm zal er naar verwachting sprake zijn van een<br />

wisselende samenstelling van de teams.<br />

• Tenslotte moet het antwoord worden gegeven op de WANNEER<br />

vragen. Wanneer moet welke ‘sprint’ zijn afgerond en hoe wordt de<br />

(continue) evaluatie vorm gegeven. In tegenstelling tot SCRUM in<br />

de zuivere vorm zullen ‘sprints’ in deze toepassing per stuk in lengte<br />

kunnen variëren.Voor het managen van het proces is het logisch<br />

om een SCRUM Master in te zetten. Maar wel een die begrip heeft<br />

voor de wijze waarop het SCRUM gedachtengoed in het project<br />

wordt gebruikt.<br />

Een groot voordeel van het inzetten van een SCRUM Master is ook dat<br />

de overgang van bijvoorbeeld de sales naar de delivery organisatie en<br />

vervolgens de uitvoering van het project nog makkelijker zal verlopen.<br />

En op het gewenste kwaliteitsniveau. De borging van alle aspecten<br />

die nodig zijn voor een succesvol verloop van het project zijn tenslotte<br />

door de SCRUM Master geborgd. •<br />

Pietwillem Overvoorde<br />

Pietwillem Overvoorde (1964) heeft<br />

in de loop van de tijd nagenoeg alle<br />

mogelijke rollen vervuld binnen<br />

(inter)nationale ICT projecten.<br />

Software ontwikkeling, business<br />

consultancy, project management,<br />

business development, sales- en<br />

accountmanagement maken deel uit van zijn CV.<br />

Bij zijn werkgever, Yellowstar Solutions (www.yellowstarsolutions.nl),<br />

wordt SCRUM sinds de oprichting toegepast in alle<br />

processen. Voor bijna alle activiteiten geldt: geen lange<br />

vergaderingen maar korte, effectieve stand-ups. De zelfsturende<br />

teams zijn verantwoordelijk voor het resultaat. In deze manier van<br />

werken zijn ook medewerkers van klanten betrokken. Vaak gaat<br />

dit in de eerste fase van samenwerking gepaard met een<br />

gewenningsproces; iets waarin de medewerkers van Yellowstar<br />

coachend optreden. De praktijk heeft geleerd dat het kort op de<br />

bal spelen voor alle betrokken partijen zeer effectief is.<br />

vervolg van pagina 31 ><br />

Scenario’s<br />

De feature heet niet voor niets in-memory OLTP. SQL Server kent sinds<br />

SQL Server 2012 de zogenaamde ColumnStore index. Dit is een<br />

feature die ook valt in de range in-memory features. ColumnStore is<br />

specifiek voor datawarehouse queries. Memory optimized tables heel<br />

specifiek niet. Als u een workload heeft met veel schrijven, en als de<br />

transactie throughput wordt beperkt door locking and latching, dan<br />

kunnen memory optimized tables uitkomst bieden. Zoals gezegd is<br />

het uitgangspunt waar gegevens leven anders (geheugen in plaats van<br />

disk). Nog belangrijker is dat het programmeermodel anders is. Van<br />

pessimistic concurrency met locking gaat u over op optimistic<br />

concurrency met versioning. Dat vergt een andere opbouw van uw<br />

code. Een tweede scenario zijn de tabellen met durability op<br />

SCHEMA_ONLY. Gegevens in een database die kwijt kunnen raken?<br />

Eigenlijk een soort temp tables dus, maar dan zonder de overhead<br />

van IO on TempDB.<br />

Conclusie<br />

Dit artikel is slechts een high level overview van memory optimized<br />

tabellen. De belangrijkste take-away is dat er een ongelofelijke<br />

perfomance winst valt te halen. Maar die winst is er alleen in heel<br />

specifieke situaties. En een nieuw concurrency model vergt<br />

waarschijnlijk wat aanpassingen aan uw code. •<br />

Peter ter Braake<br />

Peter ter Braake is sinds de zomer<br />

van 2008 zelfstandig trainer / consultant<br />

/ MVP op het gebied van<br />

SQL Server. Ik verzorg voor klanten<br />

database en Business Intelligence<br />

trainingen. Tevens doe ik korte projecten<br />

in dezelfde aandachtsgebieden.<br />

In 2005 heb ik met een aantal<br />

mensen PASS Nederland opgericht.<br />

PASS is de gebruikersgroep voor SQL Server. Ik ben daar<br />

momenteel vice-voorzitter en verantwoordelijk voor de events die<br />

PASS organiseert.<br />

magazine voor software development 35


DELPHI<br />

Cary Jensen<br />

Delphi's REST Debugger and<br />

REST Client Library, Part 1<br />

At <strong>SDN</strong>'s Software Development Conference in Papendal this December I presented a session<br />

on DataSnap and REST using FireDAC. In that presentation I demonstrated a DataSnap server<br />

that used FireDAC FDMemTables to create special data streams that could be delivered to client<br />

applications written in Delphi, and from which specialized streams containing a user's updates<br />

to the data could be returned. Importantly, the client/server communication made use of HTTP<br />

(hypertext transfer protocol) requests and JSON (JavaScript Object Notation), two elements<br />

central to a distributed application style typically referred to as REST (REpresentational State<br />

Transfer).<br />

The client application that I demonstrated made use of a TDSREST-<br />

Connection component, which was then used to import the interface<br />

of the TServerMethods class found on the DataSnap server. Much of<br />

that interface was designed to demonstrate FireDACJSONReflect, a<br />

set of classes and interfaces designed to wrap and unwrap data for<br />

use with FDMemTables in the client application.<br />

I bring up that presentation as a starting point for a discussion about<br />

REST clients, client applications that connect to data using HTTP. I<br />

am not going to get into a detailed discussion of FireDACJSONReflect,<br />

as that is just one of many possible ways to wrap data that is<br />

consumed by a REST client, and one that is somewhat limited, in that<br />

it more or less requires a Delphi client. Instead, I am going to use that<br />

server to demonstrate some of the REST-related tools that have<br />

shipped in Delphi since Delphi XE5. These include the REST<br />

Debugger and the REST Client Library But before we do that, it is<br />

necessary to first understand some features of the DataSnap server.<br />

The DataSnap Server<br />

Methods exposed by a REST-based DataSnap server are those<br />

methods associated with the TServerMethods class. When you use<br />

the DataSnap Server wizard from the Object Repository, you have the<br />

option of creating this class as a TComponent, a TDataModule, or a<br />

TDSDataModule. So long as you are not using the server to expose<br />

TDataSetProviders, it really doesn't matter which one you pick.<br />

Personally, I prefer either the TDataModule or TDSDataModule options,<br />

as they provide a design surface on which to place components.<br />

If your DataSnap server is data-aware, as this one is, these components<br />

will be associated with connecting to a database and executing<br />

queries. Figure 1 shows how my DataSnap server methods data<br />

module looks like in Delphi's designer. Note that some of the components<br />

on this data module, such as the TFDStanStorageBinLink and<br />

the TFDStanStorageJSONLink, are there to support FireDACJSON<br />

Reflect, and not necessarily required by a DataSnap REST server.<br />

Fig. 1: The server methods data module in the designer<br />

Here is the declaration of the TDSDataModule class, showing some of<br />

the methods exposed through this class (for the most part, I am only<br />

showing the methods that I will be calling in the clients I discuss later<br />

in this article). The methods being exposed are those found in the<br />

public section of the class declaration.<br />

type<br />

TServerMethods1 = class(TDSServerModule)<br />

CustomerQuery: TFDQuery;<br />

FDConnection1: TFDConnection;<br />

FDStanStorageBinLink1: TFDStanStorageBinLink;<br />

FDStanStorageJSONLink1: TFDStanStorageJSONLink;<br />

OrdersQuery: TFDQuery;<br />

CustomerOrdersQuery: TFDQuery;<br />

private<br />

{ Private declarations }<br />

public<br />

{ Public declarations }<br />

function EchoString(Value: string): string;<br />

function ReverseString(Value: string): string;<br />

function EchoStringRaw(Value: string): string;<br />

function ReverseStringRaw(Value: string): string;<br />

function GetCustomerCDSRaw: string;<br />

end;<br />

EchoString and ReverseString are the sample methods generated by<br />

the DataSnap Server wizard, and they return a JSON result. The other<br />

methods are custom methods whose names ends with Raw. Those<br />

methods return a custom string that does not necessarily wrap the<br />

result in a JSON object.<br />

REST = REpresentational State<br />

Transfer; JSON = JavaScript Object<br />

Notation<br />

I don't want to focus too much on the implementation of these<br />

methods, instead permitting you to learn more about them by<br />

36<br />

MAGAZINE


DELPHI<br />

examining the source code from the download I will reference later in<br />

this article. However, permit me to show two methods: EchoString,<br />

and EchoStringRaw, so that you can see the basic difference between<br />

how Delphi's default server returns data (EchoString) and how you<br />

can take control over the returned content.<br />

Since the path to these files must be defined before the server starts,<br />

I insert a reference to the certificate files upon creation of the data<br />

module that holds the DataSnap-enabling components. This class is<br />

referred to as the server container unit, and the relevant code is shown<br />

in the following code segment.<br />

function TServerMethods1.ReverseString(Value: string):<br />

string;<br />

begin<br />

Result := System.StrUtils.ReverseString(Value);<br />

end;<br />

function TServerMethods1.ReverseStringRaw(Value: string):<br />

string;<br />

begin<br />

//Must use the DBXPlatform unit for GetInvocationMetadata<br />

GetInvocationMetadata().ResponseCode := 200;<br />

GetInvocationMetadata().ResponseContent :=<br />

System.StrUtils.ReverseString(Value);<br />

end;<br />

GetInvocationMetadata is discussed later in this article.<br />

{$DEFINE UseAuthentication}<br />

var<br />

AppDir: string;<br />

procedure TServerContainer1.DataModuleCreate(Sender: TObject);<br />

begin<br />

AppDir := ExtractFilePath(ParamStr(0)) + 'keys\';<br />

DSCertFiles1.CertFile := AppDir + 'MyDataSnap.pem';<br />

DSCertFiles1.KeyFile := AppDir + 'MyDataSnap.key';<br />

{$IFDEF UseAuthentication}<br />

DSHTTPService1.AuthenticationManager := DSAuthenticationManager1;<br />

{$ENDIF}<br />

end;<br />

DataSnap Servers and Security<br />

This DataSnap server implements security through secure socket layer<br />

and, optionally, through authentication. Since both of these features<br />

impose requirements for any REST client application, permit me to<br />

spend a moment explaining this in more detail.<br />

Secure socket layer, or SSL, is implemented in DataSnap using<br />

OpenSSL. OpenSSL is an open source technology used to provide<br />

encrypted communications between a server (which is an HTTP<br />

server in this case) and an HTTP client. The HTTP client could<br />

potentially be any client, such as a Delphi application, a Web browser,<br />

or a mobile application employing JavaScript.<br />

Note: If you are using OpenSSL on<br />

your server, you should ensure that<br />

you are using a recent version of the<br />

OpenSSL libraries (libeay32.dll and<br />

libssl32.dll). Older versions of<br />

OpenSSL contain a vunerability<br />

named heartbleed<br />

For this demonstration, I created an SSL certificate using OpenSSL.<br />

This process is described by Paweł Głowacki, Embarcadero's<br />

European Technical Lead for Delphi and RAD Studio technologies, in<br />

his blog found at:<br />

http://blogs.embarcadero.com/pawelglowacki/2013/10/16/40089.<br />

When you download and install OpenSSL, and then run the batch file<br />

provided by Pawel in his blog, you can generate a certificate that is<br />

suitable for testing, but not for deployment. In order to create a<br />

certificate for deployment, you need to purchase one from a trusted<br />

certificate authority, such as Symantec, Thawte, or GoDaddy.<br />

In order to simplify your use of the DataSnap server demo, I have<br />

included a directory containing the certificate files that I generated.<br />

As you can see from this code, there is a conditional define that can<br />

be used to turn on or off authentication. This allows me to easily<br />

enabled or disable authentication, and then show how doing so<br />

affects the client applications. When authentication is turned on, the<br />

first attempt by a client to connect to the DataSnap server will be<br />

challenged for a username and password. This is handled by the<br />

OnUserAuthenticate event handler associated with the TDSAuthenticationManager<br />

component. In my simple demonstration I am only<br />

requiring the user to enter the password Delphi, as you can see from<br />

the following event handler.<br />

procedure TServerContainer1.DSAuthenticationManager1UserAuthenticate(<br />

Sender: TObject; const Protocol, Context, User, Password:<br />

string;<br />

var valid: Boolean; UserRoles: TStrings);<br />

begin<br />

valid := Password = 'Delphi';<br />

end;<br />

Because the primary concern of this article is about REST clients,<br />

I have described as much as I intend to about the DataSnap server.<br />

REST Clients<br />

As mentioned earlier, REST clients come in a variety of flavors. Let's<br />

begin by using one of the more ubiquitous, the everyday web<br />

browser.<br />

Making REST Calls using a Browser<br />

To begin with, you need to run the DataSnap server. In this first<br />

demonstration, the UseAuthentication define is commented out,<br />

meaning that only SSL encryption is used.<br />

Let's start by calling the ReverseString method. Since my server is<br />

listening on port 8081, and I am using the default DSContext and<br />

RESTContext properties of the TDSHTTPService component in the<br />

server container unit, and my server methods class name is TServer-<br />

Methods1, I can call ReverseString, passing the string "Delphi," using<br />

the following URL:<br />

https://localhost:8081/datasnap/rest/tservermethods1/Reverse-<br />

String/Delphi<br />

magazine voor software development 37


DELPHI<br />

Since I have used a custom (some would say phoney) SSL certificate,<br />

Internet Explorer balks at my attempt to go to this URL, instead<br />

warning me of a potential problem, as shown in Figure 2.<br />

Fig. 5: A username and password is requested prior to connecting<br />

to the DataSnap server<br />

Fig. 2: IE warns that the custom certificate was not issued by a<br />

trusted certificate authority<br />

Since I know that there is no threat, I click Continue to this website.<br />

So long as the browser is open, this is the last time I am going to have<br />

to verify that I want to go to this URL. Having accepted the risk,<br />

IE now shows the value returned by the call to ReverseString,<br />

as shown in Figure 3.<br />

The value shown in Figure 3 is a JSON object containing a single<br />

name/value pair. As you can see, the name is result. The value part is<br />

a JSON array, and this is where all of the data returned by a REST call<br />

to a DataSnap server will appear, by default. In some cases, such as<br />

when you return a data set, this array can contain a great deal of data.<br />

Authentication happens the first time you touch a given DataSnap<br />

server from a given client. Authorization, by comparison, happens<br />

upon each and every REST method invocation. You use authorization<br />

to implement role-based permissions, either permitting or denying a<br />

particular user the right to invoke the method they are trying to call. A<br />

further discussion of authorization is beyond the scope of this article.<br />

Calling REST Methods Using the REST Debugger<br />

Introduced in Delphi XE5, Delphi's REST Debugger is a stand alone<br />

application that permits you to test calls to REST services. In it's<br />

simplest form, you enter a URL with a correctly formed REST<br />

invocation into the REST Debugger and then click Send Request.<br />

Figure 6 shows how the REST Debugger looks after sending the same<br />

request used in Figure 3 to the DataSnap server. In this figure, the<br />

Body tab of the Response pane is selected, displaying a formatted<br />

view of the returned JSON.<br />

Fig. 3: The JSON object returned by DataSnap<br />

There might be some cases where you do not want to use the default<br />

format employed by DataSnap. In that case you can use a technique<br />

like that shown in the implementation of the ReverseStringRaw<br />

method. There I've used the TDSInvocationMetadata object returned<br />

by the GetInvocationMetadata function to return a string without<br />

wrapping it in a JSON object. This permits me to create my own string,<br />

even one that represents a JSON object using a different format.<br />

Figure 4 shows the text returned by the call to ReverseStringRaw,<br />

which is simple text in this case.<br />

Fig. 4: You can return custom formats using a TDSInvocation<br />

Metadata object<br />

Things are a little different if we invoke our methods with authentication<br />

enabled. In that case, the first time we invoke one of the methods<br />

on the DataSnap server, in other words, the first time we touch the<br />

DataSnap server through HTTP, we are challenged for a username<br />

and password, as shown in Figure 5.<br />

Since my implementation of the OnUserAuthenticate event handler<br />

only requires a password of Delphi, so long as I provide the password<br />

Delphi (a case-sensitive string), the method being invoked will return<br />

its value. If I do not pass a valid username/password pair, the browser<br />

will display an error, and the call to the REST method will fail.<br />

Fig. 6: The REST Debugger executes the same URL as shown in<br />

Fig.3.<br />

Entering the full URL for the invocation of the REST method in the URL<br />

field of the Request tab of the Request pane is convenient. However,<br />

when you later move to the REST client components in Delphi it is<br />

better to partition the pieces of the request URL between the base<br />

URL and the specific method invocation segment. Specifically, all of<br />

the methods from the DataSnap server being used in this sample have<br />

the same base URL, as shown here:<br />

https://localhost:8081/datasnap/rest/tservermethods1<br />

38<br />

MAGAZINE


DELPHI<br />

The remainder of the URL specifies the method to invoke and any<br />

required parameters. The REST Debugger can accept the method<br />

name and its parameters in a property it calls the resource, where the<br />

resource specifies the method to be invoked, and, if the method<br />

requires one or more parameters, defines named placeholders, one for<br />

each parameter. With respect to the ReverseString method being<br />

invoked in Figure 6, this resource looks something like this:<br />

ReverseString/{Value}<br />

In this resource, ReverseString specifies the method to be invoked,<br />

and the single required parameter is represented by a name within<br />

curly braces. The actual name used for a particular parameter is<br />

irrelevant, just so long as it is unique within the resource. Specifically,<br />

that I've used the name Value in the resource has nothing to do with<br />

the fact that the formal parameter name of the single parameter of the<br />

ReverseString method is called Value. I could have used something<br />

else.<br />

resource and parameter value assignments are combined with<br />

the base URL defined on the Request tab (this base URL is set to the<br />

string shown earlier in this section).<br />

The REST call shown in Figure 6 was performed against the Data-<br />

Snap server using SSL, but not authentication. (Since this DataSnap<br />

server only permits HTTPS calls (SSL), a call using HTTP would fail. If<br />

you have downloaded the code samples, you can test this for<br />

yourself.) If your REST server requires authentication, you use the<br />

Authentication tab of the Request pane to provide the require<br />

information before clicking Send Request. Figure 8 shows a username<br />

and password entered into the Authentication tab, and the resulting<br />

response from the server. The password is masked in the figure, but<br />

trust me that I entered Delphi.<br />

I've used BASIC authentication in this case, which inserts the username<br />

and password into the HTTP header. This is how the DataSnap<br />

server is expecting to receive this data when authentication is implemented.<br />

There are three additional authentication methods. SIMPLE<br />

passes the user name and password in a manner similar to how you<br />

would pass a username and password field from an HTML form. The<br />

last two, OAUTH and OAUTH2, use the corresponding protocol for<br />

OAuth. OAuth is an open standard for delegated authorization,<br />

permitting a site to accept access tokens from a third party service, for<br />

example, authorizing access to a site using the user's Facebook or<br />

Google account.<br />

The REST Client Library<br />

In addition to the REST Debugger, the release of Delphi XE5 also saw<br />

the introduction of the REST Client Library, a set of cross-platform<br />

components that you can use from any of Delphi's supported platforms.<br />

In this section I will focus on four of these: TRESTClient,<br />

TRESTRequest, and TRESTResponse. I will also talk about the<br />

authentication components, but only in passing.<br />

Fig. 7: You use the Parameters tab of the Request pane to define the<br />

resource and assign values to your named parameters<br />

If you enter a base URL in the URL field of the Request tab of the<br />

Request pane, you use the Parameters pane to enter the resource,<br />

after which you assign a value to each of the parameter placeholders<br />

appearing in the resource. This can be seen in the Figure 7, where the<br />

At a minimum, a REST request requires that you use a TRESTClient<br />

and a TRESTRequest. The TRESTClient takes responsibility for the<br />

HTTP communication to the REST server, and also holds the REST<br />

service end point, or base URL. Most applications need only one<br />

TRESTClient for each REST service to which it will connect.<br />

In most applications you will have one TRESTRequest for each<br />

method you want to execute. A given TRESTRequest object holds the<br />

resource definition for the corresponding method using the format<br />

described in Figure 7, as well as any parameters, which are used to<br />

associate values with each of the names that appear in the resource.<br />

The Client property of each TRESTRequest must point to a properly<br />

configured TRESTClient component.<br />

The use of TRESTResponse is optional. You use this component if<br />

you want to persist any data returned from a TRESTRequest. The<br />

TRESTRequest in question is the one whose Response property<br />

points to the TRESTResponse.<br />

If you execute a TRESTRequest, and its Response property does not<br />

point to a TRESTResponse, a TRESTResponse is created on-the-fly,<br />

and you can access it using the Response property of the TRESTRequest<br />

any time after the successful execution of the TRESTRequest<br />

and prior to freeing the TRESTRequest or clearing its content by calling<br />

ResetToDefaults.<br />

Fig. 8: With Authorization turned on, you need to pass a user<br />

name and password to the server<br />

The use of TRESTClient and TRESTRequest is demonstrated in the<br />

RESTClientDemo project, whose main form is shown in Figure 9. This<br />

project invokes three of the methods exported by the DataSnap REST<br />

server (the methods being invoked should be pretty obvious). There is<br />

a single TRESTClient, which points to the base URL of the DataSnap<br />

magazine voor software development 39


DELPHI<br />

server. In addition, there are three TRESTRequest objects, one for<br />

each of the methods that are invoked.<br />

RRGetCustomerCDS.Execute;<br />

cds.XMLData := RRGetCustomerCDS.Response.Content;<br />

DataSource1.DataSet := cds;<br />

end;<br />

Figure 10 shows the running application. In this figure, both the<br />

ReverseString and Get Customer Data buttons have been pressed.<br />

Fig. 9: The main form of RESTClientDemo<br />

In this particular project there was no need to employ a TREST<br />

Response component, since the returned data is already being<br />

persisted in the application's user interface. For the ReverseString and<br />

ReverseStringRaw REST calls, the data is being stored in a memo.<br />

The value returned by GetCustomerCDSRaw is being stored in a<br />

ClientDataSet.<br />

There is an additional REST client component on this form, the<br />

TRESTBasicAuthentication component. This component, and its<br />

proper configuration, is required if your REST service implements<br />

authentication.<br />

Here are the three event handlers, each one associated with one of the<br />

buttons that appear on the left side of this form. Each event handler<br />

assigns values to the named parameters in the associated<br />

TRESTRequest.Resource properties, with the exception of Get<br />

CustomerCDSRaw, which has no parameters.<br />

procedure TForm1.ReverseStringBtnClick(Sender: TObject);<br />

begin<br />

RRReverseString.Params.ParameterByName('ValueToReverse').Valu<br />

e :=<br />

ValueToReverseEdit.Text;<br />

RRReverseString.Execute;<br />

ResponseMemo.Lines.Text := RRReverseString.Response.Content;<br />

end;<br />

procedure TForm1.ReverseStringRawBtnClick(Sender: TObject);<br />

begin<br />

RRReverseStringRaw.Params.ParameterByName('ValueToReverse').Value<br />

:=<br />

ValueToReverseEdit.Text;<br />

RRReverseStringRaw.Execute;<br />

ResponseMemo.Lines.Text := RRReverseStringRaw.Response.Content;<br />

end;<br />

procedure TForm1.GetCustomerDataBtnClick(Sender: TObject);<br />

var<br />

cds: TClientDataSet;<br />

begin<br />

if DataSource1.DataSet nil then<br />

DataSource1.DataSet.Free;<br />

cds := TClientDataSet.Create(Self);<br />

Fig. 10: The running RESTClientDemo application<br />

You can download the code sample for this article from the following<br />

URL: http://www.JensenDataSystems.com/sdnmag_rest.zip<br />

Summary<br />

In this article I have introduced the REST Debugger and several of the<br />

components of the REST Client Library. In the next issue of the <strong>SDN</strong><br />

<strong>Magazine</strong> I will demonstrate more capabilities of the REST debugger,<br />

as well as show how to use the REST Debugger and REST Client<br />

Library on REST services other than DataSnap. •<br />

Cary Jensen<br />

Cary Jensen is Chief Technology<br />

Officer of Jensen Data Systems.<br />

Since 1988 he has built and<br />

deployed database applications in a<br />

wide range of industries. Cary is an<br />

Embarcadero MVP, a best selling<br />

author of more than 20 books on software development, and<br />

holds a Ph.D. in Engineering Psychology, specializing in humancomputer<br />

interaction. His latest book is Delphi in Depth: Client-<br />

DataSets 2nd Edition. You can learn more about this book at<br />

http://www.JensenDataSystems/cdsbook2.<br />

OPROEP!<br />

Lijkt het je leuk een bijdrage te leveren aan (het volgende) <strong>SDN</strong> magazine?<br />

We nodigen je van harte uit om een artikel te schrijven over je vakgebied,<br />

over ontwikkelingen en/ of achtergronden.<br />

Stuur je kopij naar redactie@sdn.nl, er zit een auteur in ons allemaal!<br />

40<br />

MAGAZINE


TFS<br />

Wouter de Kort<br />

Ken jij Microsoft Test Manager?<br />

At <strong>SDN</strong>'s Software Development Conference in Papendal this December I presented a session<br />

on DataSnap and REST using FireDAC. In that presentation I demonstrated a DataSnap server<br />

that used FireDAC FDMemTables to create special data streams that could be delivered to client<br />

applications written in Delphi, and from which specialized streams containing a user's updates<br />

to the data could be returned. Importantly, the client/server communication made use of HTTP<br />

(hypertext transfer protocol) requests and JSON (JavaScript Object Notation), two elements<br />

central to a distributed application style typically referred to as REST (REpresentational State<br />

Transfer).<br />

DevOps, Application Lifecycle Management, Agile. Het zijn termen<br />

die we allemaal kennen. Maar hoe past een tester binnen dit verhaal?<br />

We weten allemaal dat Microsoft voor developers erg goede tooling<br />

heeft. Teams gebruiken vaak versie beheer, build servers en project<br />

management tooling in TFS. Sommige teams gaan echt al richting<br />

continuous deployment door bijvoorbeeld Release Management te<br />

gebruiken. Maar hoe zit het met testers? Worden zij ook ondersteund?<br />

Vaak zie ik testers hun test cases nog bijhouden in Excel. Of ze<br />

gebruiken totaal andere tooling van bijvoorbeeld HP of Tosca zonder<br />

verder echt te integreren met de ontwikkelaars. Testers zijn veel tijd<br />

kwijt aan het handmatig uitvoeren van test cases en het bijhouden van<br />

voortgang. Maar als je echt naar continuous delivery wilt, kan een niet<br />

efficiënt test proces een steeds groter probleem worden.<br />

Fast forwarding van tests<br />

In plaats van Excel lijstjes te gebruiken laat MTM testers hun tests bijhouden,<br />

organiseren en delen met het team als een echt onderdeel<br />

van TFS. Figuur 1 laat een test case zien zoals die er in MTM uitziet.<br />

Eén van de best bewaarde geheimen van de Microsoft ALM tooling is<br />

Microsoft Test Manager (MTM). MTM is voor testers wat Visual Studio<br />

voor ontwikkelaars is. Door testers MTM te laten gebruiken integreren<br />

ze helemaal in het ALM proces.<br />

In dit artikel wil ik een paar van de mogelijkheden van MTM bespreken<br />

die mij enthousiast hebben gemaakt en die jou kunnen helpen om met<br />

testers binnen je organisatie in gesprek te gaan.<br />

Ontmoet Microsoft Test Manager<br />

Als ontwikkelaars gebruiken we Visual Studio. Project managers<br />

gebruiken de web-interface van TFS en Excel. Testers gebruiken<br />

Microsoft Test Manager. MTM is speciaal gemaakt voor testers.<br />

De applicatie is een stuk<br />

eenvoudiger te gebruiken dan<br />

Visual Studio en helpt testers<br />

echt om hun werk gedaan te<br />

krijgen.<br />

MTM is een onderdeel van Visual Studio Test Professional.<br />

Je kunt een gratis 90 dagen trial downloaden op<br />

http://www.visualstudio.com/products/visual-studio-testprofessional-with-msdn-vs<br />

Fig. 1: Een test case in MTM<br />

Hier zie je een test case met een aantal stappen en het verwachte<br />

resultaat. Als een tester deze test case nu gaat draaien verschijnt de<br />

interface in Figuur 2 bij de tester op zijn scherm. Tijdens het afspelen<br />

van de test kan de tester hierin direct bijhouden welke stappen goed<br />

gaan, eventueel commentaar toevoegen of direct een bug inschieten<br />

in TFS.<br />

Terwijl de tester zijn test case uitvoert, helpt MTM door de acties van<br />

de tester op te nemen. Stel bijvoorbeeld dat je een wizard test waarbij<br />

je verschillende velden moet invullen om door te kunnen naar de<br />

volgende stap. MTM helpt je door het invullen van de velden op te<br />

nemen en de volgende keer dat je deze test case uitvoert kun<br />

je automatisch doorspoelen en worden alle velden automatisch voor<br />

je ingevuld.<br />

Stel je eens voor hoeveel tijd dit een tester bespaart. In plaats van<br />

iedere keer handmatig alle stappen herhalen kan de tester de minder<br />

belangrijke stappen nu doorspoelen en zich focussen op de stappen<br />

die echt interessant zijn.<br />

magazine voor software development 41


TFS<br />

Dit soort opnames zijn dan weer de basis<br />

voor volledig geautomatiseerde testen die<br />

bijvoorbeeld door de build server of<br />

tijdens een automatische deployment<br />

gedraaid kunnen worden zodat er nog<br />

meer tijd bespaart wordt.<br />

plan tot je beschikking. In plaats daarvan ga je naar eigen inzicht door<br />

de applicatie heen terwijl ondertussen MTM alles bijhoud wat je doet.<br />

Vind je dus een bug, dan kun je rechtstreeks vanuit je Exploratory Testing<br />

sessie een bug aanmaken met daaraan gekoppeld de stappen<br />

die je hebt gedaan en eventueel weer info zoals een video opname,<br />

Event Log, System Information of IntelliTrace data.<br />

Fig. 2: Uitvoeren van een test<br />

case<br />

Data Collection<br />

Naast dat MTM de acties die een tester<br />

uitvoert kan bijhouden, kan er nog veel<br />

meer data automatisch verzameld<br />

worden. Standaard wordt er bijvoorbeeld<br />

bijgehouden op wat voor systeem de<br />

tester zijn werk doet zoals Windows<br />

versie, gebruikte browser en systeem<br />

specificaties. Maar zoals Figuur 3 laat zien<br />

is er veel meer mogelijk.<br />

Met één simpel vinkje kun je hier bijvoorbeeld<br />

een video opname maken van het<br />

scherm van de tester en eventueel zelfs<br />

audio opnamen. Of wat dacht je van<br />

IntelliTrace data, event logs en code<br />

coverage info? Al deze data wordt<br />

gekoppeld aan het test result en<br />

toegevoegd aan bugs die de tester<br />

inschiet. Dus als ontwikkelaar heb je nu<br />

een stappenplan van wat de tester heeft<br />

gedaan samen met allerlei data waaronder<br />

zelfs een video opname.<br />

Als je naar Figuur 4 kijkt zie je een bug die is aangemaakt vanuit een<br />

Exploratory Testing sessie. Als je kijkt naar de Steps To Reproduce zie<br />

je dat MTM precies heeft bijgehouden welke acties de gebruiker heeft<br />

uitgevoerd. De andere tabs geven extra info die allemaal in TFS wordt<br />

opgeslagen.<br />

Fig. 4: Bug vanuit Exploratory Testing<br />

MTM is cool!<br />

Dit zijn maar een paar features van MTM waar ik enthousiast van werd.<br />

Maar er zijn er nog veel meer. Denk bijvoorbeeld aan het gebruik van<br />

parameters in test cases, rapportages over je voortgang, het gebruik<br />

van verschillende systeem configuraties voor testen (bijvoorbeeld<br />

Windows 7 en 8, of IE en Chrome) en nog veel meer.<br />

Beginnen met MTM is eenvoudig. Download gewoon de trial en<br />

koppel deze aan een gratis Visual Studio Online account zodat je<br />

meteen kunt beginnen. Als je wat gerichter met MTM aan de gang wilt<br />

kun je ook de Brian Keller Virtual Machine downloaden compleet met<br />

Hands On Labs die je alles van MTM laten zien. •<br />

Fig. 3: Data Collectors<br />

Een andere optie die zeker interessant is, is Test Impact analysis.<br />

Als je je test omgevingen ook koppelt aan TFS, is TFS instaat om te<br />

analyseren welke code er tussen verschillende builds is gewijzigd en<br />

welke test cases daar dan weer bij horen. Op deze manier krijgt een<br />

tester dus een overzicht van de test cases die het belangrijkste zijn<br />

om te draaien voor een nieuwe versie van de applicatie.<br />

Exploratory Testing<br />

Tot nu toe hebben we vooral gekeken naar het gebruik van vooraf<br />

geschreven test cases. Maar wat nu als je in een Agile proces deze<br />

test cases nog niet hebt gemaakt? Of wat als je als ontwikkelaar of<br />

stakeholder gewoon even door de applicatie heen wilt gaan om te<br />

kijken of bepaalde dingen werken? En natuurlijk wil je dan, dat als het<br />

mis gaat je ook nog kunt reproduceren waar de fout zit.<br />

Dit is waar je Exploratory Testing voor gebruikt. Als je een Exploratory<br />

Testing sessie begint vanuit MTM, heb je geen voor gedefinieerd test<br />

Wouter de Kort<br />

Wouter begon met software ontwikkeling<br />

toen hij 7 was. Hij werkt nu als<br />

Lead Microsoft ALM Consultant bij<br />

Ordina waar hij leiding geeft aan een<br />

team van ALM Consultants. Wouter<br />

helpt organisaties om voorop te blijven<br />

met alle ontwikkelingen op de<br />

Microsoft Stack. Hij richt zich vooral op Application Lifecycle<br />

Management en software architectuur. Hij houdt er van om complexe<br />

problemen op te lossen en anderen nieuwe dingen te leren.<br />

Wouter heeft een paar boeken geschreven, is een Microsoft Certified<br />

Trainer en ALM Ranger. Je kunt hem vinden op Twitter<br />

(@wouterdekort) en op zijn blog http://wouterdekort.blogspot.com<br />

42<br />

MAGAZINE


CLOUD<br />

Marcel Meijer<br />

API Management<br />

Het is voor leveranciers van producten bijna onmogelijk om voor ieder platform mobiele<br />

applicaties te maken. Natuurlijk kun je dan als leverancier zorgen voor een goede responsieve<br />

mobiele website. Het nadeel van deze manier is dat je de capaciteiten en mogelijkheden van een<br />

mobiel device niet volledig uit nut.<br />

Daarom zijn er ook leveranciers die hun backoffice via API’s beschikbaar<br />

stellen aan de wereld. Meestal wil je dat niet zonder pardon doen<br />

en wil je er als leverancier wellicht geld aan verdienen. Dus je wil een<br />

Developer portal maken met verschillende groepen, help pagina’s,<br />

voorbeeldcode, monitoring, issue lijst, FAQ, maar ook malafide<br />

gebruikers/applicaties blacklisten. Kortom het vergt meer dan even<br />

het beschikbaar stellen van een paar webservicesje.<br />

Enige tijd geleden had ik ook zo’n droom. Ik wilde voor de <strong>SDN</strong> een<br />

evaluatie app maken. Bezoekers van een <strong>SDN</strong> event kunnen dan<br />

mobiel een evaluatie formulier invullen. Deze evaluatie data wordt in<br />

een data store op Azure bewaard. Uiteraard wil ik niet mijn tokens/<br />

connectionstrings/passwords etc in mijn mobiele apps opslaan.<br />

En aangezien ik niet voor elk device zelf een applicatie kan schrijven,<br />

deze gegevens delen met wildvreemde developers.<br />

Uiteraard is het dan wel verstandig om de endpoints op deze URL te<br />

beveiligen met een Certificaten, UserName/Password combinatie of<br />

via OAuth.<br />

Dit is de management portal voor de beheerder van de<br />

API(https://marcelmeijer.portal. azure-api.net/admin), voor de ontwikkelaars<br />

is er een aparte portal (https://marcelmeijer.portal.azureapi.net/).<br />

Deze kan tot op zekere hoogte ook gestyled en aangepast<br />

worden. Deze Developer portal is redelijk compleet. Alle genoemde<br />

zaken zijn hier wel te vinden.<br />

Dus bedacht ik dat ik een aantal Webapi<br />

services beschikbaar moest stellen. Maar<br />

zoals hierboven genoemd, had ik behoefte<br />

aan eer developers portal om mijn services<br />

uit te leggen en wat ze opleveren. Dat is veel<br />

werk voor zo’n API als dit. Dit is mijn landingspagina nu;<br />

http://sdnevalapp.azurewebsites.net/.<br />

Gelukkig is daar een oplossing<br />

voor op het Azure platform. De<br />

API management service (documentatie<br />

site). Als je de service<br />

gemaakt hebt, dan is er een<br />

aparte portal (https://marcelmeijer.portal.azure-api.net/<br />

admin) waar je alle instellingen<br />

doet, waar je de metrics van je API ziet, de applicaties die aangemeld<br />

zijn, welke API het vaakst aangeroepen wordt etc.<br />

Bij de settings kun je dan de<br />

webservices beschikbaar stellen.<br />

De verschillende operaties,<br />

welke http verb, welke responses<br />

er verwacht kunnen<br />

worden, welke URL, omschrijving<br />

en helpteksten. De URL<br />

naar de bron services kan ook<br />

on-premises gehost worden.<br />

Zo is er een handig overzicht van de beschikbare API’s.<br />

Van de beschikbare API kun je de beschikbare endpoints zien. Je ziet<br />

dan de omschrijving en de URL om API aan te spreken. Om het endpoint<br />

te gebruiken moet je een subscription key meegeven. Het hele<br />

idee van deze portal is dan ook<br />

om gebruik te reguleren en met<br />

behulp van de subscription key<br />

is de API per applicatie/ontwikkelaar<br />

apart. Aangezien de endpoints<br />

aan de basis beveiligd<br />

zijn met Certificaten, Username/<br />

Passwords of via OAuth, heeft<br />

het geen zin om rechtstreeks<br />

naar de bron te gaan.<br />

Op deze Developer portal kun je<br />

API methode ook uitproberen<br />

en de verschillende gedefinieerde<br />

HTTP acties uitvoeren. Je<br />

krijgt dan de trace en het resultaat<br />

te zien.<br />

Helemaal onderaan de pagina<br />

kun je per programmeertaal<br />

voorbeeldcode krijgen. Alles om<br />

de ‘klanten’ van je API te<br />

ondersteunen en te helpen.<br />

Door deze Azure service kun je je richten op het echte leuke en<br />

belangrijkste van de API, de functionaliteit. Waarom zou je het zelf<br />

doen, als je gebruik kunt maken van de expertise van andere.<br />

“You can reach further while standing on the shoulders of giants”. •<br />

magazine voor software development 43

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!