SOFTWARE DEVELOPMENT NETWORK
MAGAZINE ISSN: 2211-6486
IN DIT NUMMER O.A.: Remote debugging naar een Azure VM <
Decrease dataflows between systems with CDC < SQL Server In-Memory OLTP <
SCRUM is meer dan een project management methodologie <
Nummer 124 februari 2015 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network
124
www.sdn.nl
Colofon Uitgave:
Software Development Network Drieëntwintigste jaargang No. 124 • februari 2015
voorwoord
Bestuur van SDN:
Marcel Meijer, voorzitter Rob Suurland, penningmeester Remi Caron, secretaris
Redactie:
Beste SDN Magazine lezer,
Marcel Meijer (
[email protected])
Aan dit magazine werd meegewerkt door:
Roel Hans Bethlehem, Bob Swart, Maarten van Stam, Arjen Bos, Alexander Meijers, Remi Caron, Marcel Meijer en natuurlijk alle auteurs!
Listings:
Hebben jullie met open mond naar de Windows 10 presentatie zitten kijken? Gezien hoe de opvolger van Windows 8 steeds volwassener wordt en alle plooien er nu wel uitstrijkt? Heb je al gespeeld met de volgende versie van Office 2015 welke meer gericht is op touch gebruik? Heb je al gekeken naar de nieuwe Visual Studio versie met daarin allerlei performance meters? Heb je de vele Microsoft applicaties op het Android en iOS platform al bekeken? Dat zijn er al ruim 100. In het verleden is Microsoft vaak verweten dat ze een gesloten omgeving waren, hoewel ze als eerste ooit voor de MAC applicaties ontwikkelde. Maar tegenwoordig zijn ze nog opener en laten dat ook graag weten.
Zie de website www.sdn.nl voor eventuele source files uit deze uitgave.
In de volgende magazines en events van de SDN komen jullie naast artikelen en sessies van de andere platformen ook verhalen tegen over Microsoft. De SDN is voor alle soorten developers en alle soorten platforms. En dat blijft zo.
Software Development Network Postbus 506, 7100 AM Winterswijk Tel. (085) 21 01 310 E-mail:
[email protected]
Op vrijdag 20 maart is het volgende SDN event. Op dit event zal ook de Algemene leden vergadering weer plaats vinden. Dit is naast natuurlijk rechtstreeks met mij te mailen of ons te bellen, de uitgelezen kans om je als lid van de vereniging te laten informeren en te horen over het reilen en zeilen van de vereniging. Kom dus allemaal en laat je stem spreken.
Reclamebureau Bij Dageraad, Winterswijk www.bijdageraad.nl
Dit magazine 124 bevat wederom een uiteenlopende hoeveelheid aan onderwerpen. Over Dynamics CRM, Remote debugging op Azure, Application Insights deel 2, CDC wat is de zin en onzin hiervan, Azure Webjobs, Microservices een mooie verhandeling, de ELK stack wat is het, In-Memory OLTP databases, SCRUM is bruikbaar in meerdere onderdelen van een organisatie, de Delphi's REST Client Library, Microsoft Test Manager beschrijving en nog een paar kleine tips en tricks. Kortom, Bas van de Sande, Cary Jensen, Eric Tummers, Hassan Fadili, Jeffrey Verheul, Marcel Meijer, Patrick Kalkman, Peter ter Braake. Piet Willem Overvoorde, Sander Hoogendoorn en Wouter de Kort hebben weer veel tijd gestoken in deze stuk voor stuk mooie verhalen. Speciaal voor jullie als SDN magazine lezer.
Contact:
Vormgeving en opmaak:
©2015 Alle rechten voorbehouden. Niets uit deze uitgave mag worden overgenomen op welke wijze dan ook zonder voorafgaande schriftelijke toestemming van SDN. Tenzij anders vermeld zijn artikelen op persoonlijke titel geschreven en verwoorden zij dus niet noodzakelijkerwijs de mening van het bestuur en/of de redactie. Alle in dit magazine genoemde handelsmerken zijn het eigendom van hun respectievelijke eigenaren.
Adverteerders Microsoft Achmea
Het volgende magazine 125 maken we iets specialer. Daarover later meer. Heel veel leesplezier en tot 20 maart bij de ALV. Groeten, Marcel Meijer eindredacteur Magazine en Voorzitter SDN •
2 44
Adverteren? Informatie over adverteren en de advertentietarieven kunt u vinden op www.sdn.nl onder de rubriek Magazine.
magazine voor software development 3
Agenda 2015 • 16-19 maart 2015 Microsoft Convergence 2015 Atlanta • 20 maart SDN event, Zeist • 29 april - 1 mei //Build San Francisco • 4-8 mei Microsoft Ignite Chicago at McCormick Place • 12-13 mei Techorama Belgium 2015 • 28-29 mei TechDays, Den Haag • 12 juni SDN event • 12-16 juli Worldwide Partner Conference Orlando • 18 september SDN event
Inhoud 03
Marcel Meijer
04 04 05
Voorwoord
Inhoudsopgave Agenda
Bas van de Sande
08
Microsoft Dynamics CRM
Eric Tummers
10
Remote debugging naar een Azure VM
Application Insights for Visual Studio Online (Part 2)
Hassan Fadili
15
Decrease dataflows between systems with CDC
Jeffrey Verheul
17
Marcel Meijer
Azure Webjobs
19
Microservices. The good, the bad and the ugly
23
Improving traceability of distributed systems using the ELK stack
Sander Hoogendoorn Patrick Kalkman
30
Peter ter Braake
SQL Server In-Memory OLTP
32
SCRUM is veel meer dan een project management methodologie
36
Delphi's REST Debugger and REST Client Library, Part 1
Piet Willem Overvoorde Cary Jensen
41
Wouter de Kort
43
Ken jij Microsoft Test Manager?
Marcel Meijer
API Management
GENERAL
Bas van de Sande
Microsoft Dynamics CRM “A journey of a SharePoint developer into the world of CRM” Na jarenlang software ontwikkeld te hebben in C#, SQL Server, BizTalk en SharePoint ben ik onlangs overgestapt op het Microsoft Dynamics CRM platform. In deze serie artikelen wil ik mijn ervaringen delen en jullie enthousiast maken voor dit relatief onbekende platform. In dit artikel beschrijf ik in hoofdlijnen wat CRM inhoudt en waarom de ‘C’ van CRM eigenlijk een ‘x’ hoort te zijn. Ten slotte werp ik een eerste blik onder de motorkap van Microsoft Dynamics CRM. Geschiedenis De eerste versie van Microsoft Dynamics CRM is uitgebracht in 2003. Microsoft was in die tijd bezig met het opkopen van een aantal spelers in de ERP en boekhoudmarkt (o.a. Great Plains, Navision) om zo een positie in de Enterprise markt te verwerven. De CRM, ERP en boekhoudproducten zijn later ondergebracht onder de noemer Microsoft Dynamics, te weten AX (ERP), NAV (boekhouding) en uiteraard CRM. Op dit moment is CRM 2015 net beschikbaar gekomen. Naast de on-premise versie is CRM ook verkrijgbaar als CRM Online. Wat is CRM? CRM staat voor Customer Relationship Management, oftewel het beheren van de relatie tussen een klant en een organisatie. Elke klantrelatie kent een levensduur die uit een aantal fases bestaat. De inzet van CRM is er opgericht om de klant in iedere fase van de relatie optimaal te kunnen bedienen om zo een maximaal rendement uit de relatie te halen. Maar niet iedereen die een relatie met een organisatie of bedrijf onderhoudt, is per definitie een ‘customer’. Je kan bijvoorbeeld lid van zijn van een vereniging, deelnemer aan een community, donateur van een goed doel, student bij een opleidingsinstituut of juist leverancier aan een bedrijf.
Microsoft Dynamics CRM Net zoals bijvoorbeeld SharePoint is ook Microsoft Dynamics CRM beschikbaar als een on-premise versie (CRM 2013/2015) en online als CRM Online. Echter, in tegenstelling tot SharePoint lopen de on-premise en de online versie van CRM voor de ontwikkelaar niet ver uitelkaar en kun je de technieken die je gebruikt voor je on-premise oplossing gemakkelijk naar de online versie brengen. Zowel de on-premise als de online versie bieden een goede ondersteuning voor mobiele devices (iOS, Android en Windows Phone). Microsoft Dynamics CRM integreert nagenoeg naadloos binnen de Office suite (add-in voor Outlook) en leunt technologisch zwaar op de SQL Server database, SQL Server Reporting Services, Internet Information Server en het Microsoft.Net framework (sandbox). Kortom, alle bouwstenen voor een solide applicatieplatform zijn hiermee voorhanden. Zowel de on-premise als de online versie van CRM ziet er in hoofdlijnen als volgt uit:
De ‘C’ in CRM moet je dus ruim zien en de essentie van CRM is het optimaal bedienen van de relatie tussen een persoon of organisatie en jouw organisatie. De ‘C’ moet je dan eigenlijk ook zien als een ‘x’, waarbij de ‘x’ staat voor de andere partij. Als ontwikkelaar moet je er altijd rekening mee houden dat CRM wordt ingezet om te voorzien in een functionele behoefte. CRM wordt, in tegenstelling tot andere softwareproducten, niet vanuit de IT-afdeling gepusht, maar juist geïnitieerd voor en/of door de gebruiker; vaak werkzaam op de klantgerichte afdelingen binnen het bedrijf (marketing, verkoop, ledenadministratie, klantenservice). Binnen CRM zijn de klantgegevens, en wat de organisatie wil met die klantgegevens leidend, de technologie is volgend. In projecten betekent dit dat oplossingen grotendeels door functionele consultants in samenwerking met de gebruikers in elkaar worden gezet. Daar waar nodig mogen wij - ontwikkelaars - bijspringen om de complexe onderdelen, rapportages, integraties te ontwikkelen en om de gebouwde oplossing in de vorm van een solution uit te rollen.
Fig. 1: schematische weergave opbouw Microsoft Dynamics CRM De business functionaliteit van Microsoft Dynamics CRM wordt ontsloten door middel van een .NET API. Daarbovenop is een web
magazine voor software development 5
GENERAL
API geplaatst waarmee allerlei client applicaties verbinding kunnen maken. Binnen de formulieren kan gebruik gemaakt worden van javascript om extra functionaliteit te ontsluiten. The power of SQL Server De kern van CRM zijn de SQL Server databases. Een van de databases bevat metadata omtrent de configuratie, verder is er nog een content database. Deze database bevat de feitelijke data. Waarin CRM hemelsbreed verschilt ten opzichte van SharePoint, is dat in de CRM data fysieke entiteiten en velden worden aangemaakt waarin de data wordt opgeslagen. Dit in tegenstelling tot SharePoint, waarbij de database bestaat uit een aantal metatabellen en datatabellen, waar op basis van de opgeslagen meta-informatie de echte data kan worden teruggevonden. Hier ligt dan ook echt de kracht van CRM, namelijk een échte database, met fysieke relaties tussen entiteiten (referentiële integriteit). Het is echter niet de bedoeling dat gegevens rechtstreeks in de database worden aangepast; je zou daarmee een aantal ingestelde business rules kunnen overtreden (constraints). Het aanpassen van de data gebeurt via het objectmodel dat CRM je ter beschikking stelt. Nu vraag je je waarschijnlijk af: “Ja… maar als ik nou niet de regels overtreed, waarom mag ik dan niet rechtstreeks de tabellen vullen?”. Dat heeft te maken met de manier waarop Microsoft Dynamics CRM omgaat met aanpassingen op het applicatieplatform. In de online versie is het niet mogelijk om rechtstreeks bij de onderliggende SQL Server databases te komen, waar je normaal als DBA extra indexen kan leggen om de performance te verbeteren. In dat geval zal je terug moeten vallen op Microsoft support. Zij kunnen dit voor je doen. Reporting Als CRM ontwikkelaar werk je normaal gesproken tegen het objectmodel aan. Echter, in het geval van rapportages werk je tegen een database view aan die door CRM wordt beheerd.Microsoft Dynamics CRM maakt gebruik van SQL Server Reporting Services. Juist omdat CRM geheel is gebaseerd op data, gebruikt het gelukkig ook de kracht van de onderliggende SQL Server database om query’s uit te voeren. Je kan dan ook in de datasets die je maakt volledig gebruik maken van de mogelijkheden van Transact SQL. De report definities die uit SSRS voortkomen, kun je later uitrollen via je eigen solution.In de online versie kun je geen gebruik maken van SQL query’s, je moet hier met FetchXML werken. FetchXML is een op XMLgebaseerde querytaal voor Dynamics CRM.
van de solution worden aanpassingen binnen de database gemaakt, hierbij wordt de oorspronkelijke structuur met rust gelaten. Wanneer je met bijvoorbeeld SQL Server Management Studio naar de database kijkt, zie je dat van een bepaalde entiteit (bijvoorbeeld Account) meerdere tabellen bestaan. Wanneer je de geïnstalleerde solution verwijdert, dan zullen eventuele aangemaakte tabellen of relaties verdwijnen. Het solution mechanisme van Microsoft Dynamics CRM is erg krachtig en ook gemakkelijk in het gebruik. Je hoeft geen ingewikkelde provisioning te bouwen en je kunt de solution letterlijk in elkaar klikken.Solutions die zijn gemaakt op één omgeving kan je exporteren, zodat je deze op een andere omgeving kan importeren en uitrollen. Dit mechanisme leent zich uitstekend voor een OTAP straat. Autorisatie Net als ieder server platform, maakt ook Microsoft Dynamics CRM gebruik van autorisatie. Hierin gaat Microsoft Dynamics CRM erg ver - terecht trouwens, want je werkt vaak met erg gevoelige informatie. De data die in CRM is opgeslagen, wordt beschermd door middel van een zeer uitgebreide autorisatiematrix (door een beheerder instelbaar).
Fig. 2: voorbeeld autorisatiematrix binnen CRM
Het werken met solutions Net zoals Microsoft SharePoint is ook Microsoft Dynamics CRM een applicatieplatform, waarbij ontwikkelaars en gebruikers aanpassingen kunnen maken om zo toepassingen te maken die aansluiten op de processen binnen de organisatie. Binnen Microsoft Dynamics CRM is altijd minimaal één solution geïnstalleerd. Dit is de default solution. Als je wijzingen maakt op de default solution pas je hiermee de kern van CRM aan. De wijzigingen die je uitvoert, kunnen niet met één druk op de knop worden verwijderd. Om te waarborgen dat je aanpassingen wel ongedaan gemaakt kunnen worden, maak je gebruik van solutions. Binnen de solution wordt van alle objecten die je gaat aanpassen (die je dus toevoegt aan de solution) een kopie gemaakt en met deze kopie ga je aan het werk. Nadat je de wijzigingen hebt doorgevoerd publiceer je deze naar Microsoft Dynamics CRM toe. Tijdens het publiceren
6
MAGAZINE
Fig. 3: autorisatieniveaus binnen CRM
GENERAL
In de matrix wordt vastgelegd wie wat mag doen met welke data en wie eigenaar is van welke data. Dit is te vergelijken met item level security binnen SharePoint, maar dan vele malen krachtiger en uitgebreider uitgevoerd. Per gebied, rol, veld en/of entiteit kan worden vastgelegd wie wat met data mag doen en wie eigenaar is van de data. In onderstaande afbeelding geef ik aan wat de symbolen voorstellen Binnen CRM modelleer je de organisatie. Een organisatie bestaat uit business units (dit kunnen business units maar ook afdelingen zijn, en kunnen hiërarchisch worden weergegeven). Op het onderste niveau staat de gebruiker. De autorisatiematrix maakt gebruik van dit principe en de symbooltjes geven aan wie de eigenaar is van de gegevens binnen CRM. Naarmate het bolletje meer is ingekleurd, is er een grotere groep die toegang heeft tot de gegevens. Ogenschijnlijk een eenvoudig te gebruiken mechanisme, maar in de praktijk een van de lastigste onderdelen binnen CRM om te doorgronden. Ten slotte Mijn ervaringen tot zover met Microsoft Dynamics CRM is dat het een erg krachtig platform is om bedrijfstoepassingen te bouwen waarin relaties tussen organisaties en personen worden onderhouden. Wanneer je gewend bent om te ontwikkelen op een platform als SharePoint zal je aangenaam verrast worden door een aantal zaken die standaard voor je geregeld worden binnen CRM zonder dat je je hiervoor in allerlei bochten hoeft te wringen.
Het prettige aan het ontwikkelen op CRM is dat het eigenlijk niet uitmaakt of je voor de on-premise of voor de online versie ontwikkelt. Het enige verschil dat ik ben tegengekomen zit hem in het moeten gebruiken van FetchXML wanneer je met SQL Server Reporting Services werkt. Microsoft Dynamics CRM is geen wondermiddel; maar wel een goed stuk gereedschap dat je moet inzetten waarvoor het bedoeld is, namelijk het onderhouden van relaties en processen die daarmee gerelateerd zijn. •
Bas van de Sande Bas van de Sande heeft zich sinds 1995 gespecialiseerd in softwareontwikkeling en advisering op het Microsoft platform. Hij heeft zich sinds 2005 voornamelijk bezig gehouden met SharePoint en Microsoft.Net. Op dit moment ligt zijn focus op Microsoft CRM en blogt hij zeer actief over zijn ervaringen met CRM. Bas is werkzaam als Senior Software Developer/Architect bij CRM Partners.
ConnectionStrings / AppSettings Azure Zoals je op pagina 17 in dit magazine kunt lezen, wordt een Webjob gedeployed bij een Azure website. Bij de Webjob hoort ook een dashboard. Na het deployen van de Webjob waren er Errors en Warnings over een setting. Zoals de error/ warning verteld, moet je de Connectionstring toevoegen aan het Connectionstring gedeelte van de Azure website. Daarna is de error/warning weg.
In je code gebruik je: var storageAccount = CloudStorageAccount.Parse( ConfigurationManager. ConnectionStrings[“AzureWebJobsStorage”]. ConnectionString ); Maar de Connectionstrings of App settings geef je een waarde op de Configure tab van de Azure Website.
Nu lijkt het net of je deze Connectionstring op twee plekken moest configureren. Een keer op de portal en een keer in de app.config van de Webjob. Dat zou niet mooi zijn, maar dat blijkt ook niet te hoeven.
En dit werkt ook voor de App.config van een Azure Webjob. Meer informatie: http://www.asp.net/identity/overview/features-api/best-practices-for-deploying-passwords-and-other-sensitive-data-to-aspnet-and-azure
magazine voor software development 7
CLOUD
Eric Tummers
Remote debugging naar een Azure VM Je hebt OTAP met Windows Azure virtual machines ingericht. Deployment gebeurd automatisch na een nightly build. Alles is koek-en-ei totdat er een probleem optreedt dat je wil debuggen. Hoe doe je dat in Azure? Installeren van Visual Studio op de VM lijkt de enige optie? Gebruik Remote Debugging vanuit je development machine naar een Azure VM. Debugger extension Via de Server Explorer in Visual Studio kan de debugger extension op een Azure VM geïnstalleerd worden. Integratie in Visual Studio maakt het makkelijker om een debug session te starten.
VPN Als jouw development machine in hetzelfde network zit, kun je een remote debugging sessie starten. Hiervoor maak je een VPN aan. Ga naar het virtual network in de azure portal. Open de Configure tab en check Configure point-to-site connectivity. Kies daarna een starting IP.
Fig. 2: Point-to-site connectivity van virtual network De sectie eronder zal de melding geven dat een gateway nodig is. Klik add gateway subnet en wijzig indien nodig het starting IP. Kies Save en wacht tot alle wijzigingen zijn doorgevoerd.
Fig. 1: Remote debugger extension installation Hiermee worden echter wel drie poorten geopend en dat is een optie die je mogelijk niet hebt. Dan moet een VPN gebruikt worden en de remote debugging tools. Virtual Network Een best practice is om je VM’s in een virtual network te plaatsen. Hierdoor kunnen machines elkaar makkelijker vinden. Ook bied het een extra laag van beveiliging, omdat poorten voor interne communicatie niet naar de boze buitenwereld open staan. Fig. 3: Gateway van virtual network Open een Visual Studio Command prompt en maak een self-signed root certificate aan. Maak ook een authenticatie certificaat aan voor het root certificaat.
8
MAGAZINE
CLOUD
makecert -sky exchange -r -n "CN=MyNetwork" -pe -a sha1 -len 2048 -ss My "MyNetwork.cer" makecert -n "CN=Developer" -pe -sky exchange -m 96 -ss My -in "MyNetwork" -is my -a sha1
Listing 1: Self-signed root certificate en authenticatie certificaat aanmaken Upload het root certificaat (MyNetwork.cer) op de Certificates tab. Dit wordt gebruikt om de client VPN te configureren. Op de Dashboard tab wordt de gateway nou weergegeven als niet aangemaakt. Klik CREATE GATEWAY, dit zal ongeveer 15 minuten duren. Als de gateway aangemaakt is, kun je de Client VPN Package downloaden en installeren. Start de VPN in Network Connections van Windows. Fig. 4: Download client vpn package Remote debugging Maak een Remote Desktop connectie naar de Azure VM. Download en installeer de visual studio remote debugging tools van Microsoft. Bij de eerste keer starten van de Remote Debugger moet deze geconfigureerd worden. Kies configure remote debugging om de defaults te gebruiken. Daarna opent de Remote Debugger en wacht op connectie van een machine. Open Visual Studio op de development machine. Ga naar Debug > Attach to Process … Laat het transport op Default staan. Gebruik bij Qualifier het IP adres dat bij de machine staat op het virtual network dashboard (Figure 3) en de default poort 4018. Log in met dezelfde credentials als de Remote Desktop. Selecteer het process en klik Attach. Remote Debugging naar een Azure VM zonder poorten open te zetten. Conclusie Met remote debugging kun je ook in een Azure VM sneller bugs oplossen. OTAP in Windows Azure is de toekomst. De redenen om het niet te doen worden steeds minder. Links Remote debugging tools (http://www.microsoft.com/en-us/download/details.aspx?id=43724) Debugging a Cloud Service or Virtual Machine in Visual Studio (http://msdn.microsoft.com/en-us/library/azure/ff683670.aspx) •
Fig. 5: Attach to remote process
Eric Tummers Eric Tummers is werkzaam als technisch consultant bij Valid en richt zich op kwaliteit in software development. Denk hierbij aan unit testen, build en deployment processen. Bloggen doet Eric voornamelijk over zijn werk, maar af en toe komt een thuis project erop te staan, een productiviteit tip of een review. Als het maar bijdraagt aan het sociale internet.In 2015 gaat Eric aan de slag met devops. Daarbij staan powershell en Windows Azure centraal.
magazine voor software development 9
.NET / CLOUD
Hassan Fadili
Application Insights for Visual Studio Online (Part 2) In one of the previous SDN Magazines (Magazine 121), I have introduced Application Insights on VSO basics and usage of it on project level and on Visual Studio Online Dashboards. In this article, I will go a step further and explain & show “How Application Insights can help by many scenarios to get more out telemetry of your Application / Systems?” To make this concrete, I will walk through the following scenario: “Use Application Insights to understand application behavior”. To do so, I have split this scenario into the following tasks: • Create MVC Web Application and Add Application Insights to It • Create load / Web tests to simulate the scenarios. • Use App Insights and Load test to validate the assumptions.
By clicking Add Application Insights To Project, this process starts as shown below (Fig.3) where the NuGet packages needed are installed:
To start, an ASP.NET MVC Web Application is created. During this creation, the Application Insights are added to that MVC Web Application as shown below (Fig 1): Fig. 3: Adding progress of AI to Project and NuGet packages Install process Once this step is finished, the Application Insights.config and Web ApplicationI Ovreview files are added to project as shown below (Fig.4):
Fig. 1: Creation of MVC Web Application with Add Application Insights selected As part of the Add Application Insights Process, a resource MUST be specified to send telemetry to. This can be an existing resource or a new created one as shown below (Fig 2):
Fig. 2: Add Application Insights to Project and specifying the resource to send telemetry to
10
MAGAZINE
Fig. 4: Added Application Insights Resources to Project
.NET / CLOUD Beside the Application Insights Resources added to Project, there are also some Application Insights References added to the project as well. This specific references are shown below (Fig.5):
Open Application Insights from Visual Studio (Solution Explorer) guides to VSO Dashboard:
Fig. 7: Opening AI from Solution Explorer guides to VSO Dashboard Because the VSO Dashboard is on Microsoft Azure, the user MUST be authenticated and authorized to access the specific Azure Instance by signing to it as shown below (Fig.8):
Fig. 5: Application Insights Specific References added to Project To examine the added ApplicationInsights.config, this can be opened by double click on It. The content of it is shown below (Fig.6): Application Insights Configuration file content: Fig. 8: Signing to Azure Portal for Accessing Application Insights on Project Level in Microsoft Azure By Signing into Microsoft Azure Portal with the right credentials (Email and Password), Microsoft Azure Portal is shown and Application Insights can be added as Tile on this Dashboard as shown below (Fig.9 + Fig.10) Adding Application Insights to Project from Azure Portal:
Fig. 6: Application Insights Configuration File Content Once the Add process and examining the Application Insights content on Visual Studio are done, the next step can be to get into Visual Studio Online Dashboard (VSO) to see the Application Insights Information in action. This can be done in 2 ways: • By right click the Web Application Overview file and select Open Application Insights (see below Fig.7) • By double click on the same Web Application Overview file Fig. 9: Adding AI to Azure Project Dashboard
magazine voor software development 11
.NET / CLOUD Adding Application Insights from Azure Portal Futures to Project:
Fig. 10: Adding Application Insights to Project from Azure Portal Futures To be more specific on this add process, the user MUST specify the Web Application Information that can be used to be added as shown below (Fig.11) like: • Application Name • Application Type • Resource Group • Subscription • Location
Progress of Adding AI to Project on Azure Portal:
Fig. 12: Progress of Adding Application Insights to Project on Azure Portal From this point, all Application Insights information of a specific Web Application can be analyzed from the Application Insights Dashboard like “Events” a shown below (Fig.13): Status of Application Insights Events on Azure Portal after Creation:
Application Information Specifying for Application Insights on the Azure Portal:
Fig. 13: Status of AI Events on Azure portal after Creation To monitor telemetry for the Web Application, the selected source code below (Fig.14) MUST be added to all pages that must be tracked for Application Insights telemetry like we have done below for Index.cshtml file: Adding Source code to all webpages that have to be tracked for Application Insights:
Fig. 11: Application Information to be added for Application Insights on Azure Portal When all the necessary information is provided, the user can click on Create button and creation progress is shown on the Microsoft Azure Dashboard as shown below (Fig.12)
12
MAGAZINE
Fig. 14: Code to be added to all Web Pages that have to be tracked for AI
.NET / CLOUD When all the specific pages are updated with the code above (Fig.14), The Web Application can be compiled and executed. At that moment the first Application Insights Events are sent to Visual Studio Online Dashboard that is configured as show below (Fig.15)
Overview Page Views Information on Azure Portal:
First Application Insights Events sending to Azure Portal after Adding code to Specific Page(s) that have to be tracked:
Fig. 18: More Application Insights Info (Page Views) on Azure Dashboard Overview Page Views Charts Information on Azure Portal:
Fig. 15: First Application Insights Events sent to Azure Portal after adding the specific source code to It Below (Fig.16, Fig.17, Fig.18, Fig.19, Fig.20 ) some specific Application Insights Information you can track from the Microsoft Azure Portal on Visual Studio Online like: • TimeLine overview • Pages Views • Page Views Charts • Diagnostic Search • ……
Fig. 19: Application Insights Page Views Charts Info Configuration
Overview TimeLine Information on Azure Portal:
Overview Diagnostic Search Information on Azure Portal:
Fig. 20: Application Insights-Diagnostic Search on Azure Dashboard Fig. 16: Overview TimeLine Information on Azure Portal Usage TimeLine Information on Azure Portal:
Creating Load Test / Web Test for the application and Instrument It: Adding Load / Performance Test Project to Solution for instrumentation:
Fig. 17: Usage TimeLine Information on Azure Portal
Fig. 21: Adding Web-Performance-Load Test Project
magazine voor software development 13
.NET / CLOUD Running Web Test of AI_WebApplication:
Fig. 25: WebTest Results after investigation in Visual Studio
Fig. 22: Running Web Test Status of AI_WebApplication After you've deployed your web application, you can set up web tests to monitor its availability and responsiveness. Application Insights will send web requests at regular intervals from points around the world, and can alert you if your application responds slowly or not at all.
Fig. 23: Web Tests Response time (ms) NB: You can set up web tests for any HTTP endpoint that is accessible from the public internet. Overview All WebTest Response Information on Azure Portal:
So we can act directly by tracking all information needed on applica tion level and simulate the load and usage of our application / System. Because of the good integration of Visual Studio, Visual Studio Online and Microsoft Azure Dashboard, we can request all Application Insights information for our applications to track like: • Application Health • Diagnostics • Performance • Usage Analytics ( X Days) • Operations • Access In the next series of this articles, I will take this topic a step further and walk through other cool Application Insights futures and configurations. So I will discuss the “Segmentation; Application Insights support for Multiple Environments, Stamps and App Versions; Search your logs instantly using property filters”. Stay Tuned ;-). Links: Getting started with Application Insights: http://azure.microsoft.com/en-us/documentation/articles/ app-insights-get-started/ Channel 9: Application Insights overview: https://channel9.msdn.com/Events/Visual-Studio/Connect-event2014/216 Application Insights SDK: http://blogs.msdn.com/b/visualstudioalm/archive/2014/10/21/ application-insights-sdk-0-11-0-prerelease.aspx Application Insights: Exception Telemetry http://blogs.msdn.com/b/visualstudioalm/archive/2014/12/12/ application-insights-exception-telemetry.aspx Monitor any web site's availability and responsiveness: http://azure.microsoft.com/en-us/documentation/articles/ app-insights-monitor-web-app-availability/ Web tests for Microsoft Azure Websites: http://azure.microsoft.com/en-us/documentation/articles/ insights-create-web-tests/ •
Hassan Fadili
Fig. 24: All Web Test Investigation of Failed Request Failed tests can be analyzed to determine why they failed. Drill into a failed web test and download and open Visual Studio Web Test Result File to analyze and understand why the test failed. After investigation in Visual Studio by correcting the WebTest errors, the results looks like below on the Microsoft Azure portal (Fig.25): Conclusion: With the actual Application Insights future in Visual Studio Online, we have more control on the status of our applications / Systems in terms of investigation when things goes wrong or applications / systems failed.
14
MAGAZINE
Hassan Fadili is werkzaam als Freelance Lead Architect / Consultant en VS ALM Consultant (MVP) voor zijn eigen bedrijf FadiliCT Consultancy (http://www.fadilict-consultancy.nl). Hassan is zeer actief in de Community en mede bestuurslid van DotNed (.NET & VS ALM UG NL) en VS ALM Track Owner. Hassan houdt zijn blog op: http://hassanfad001. blogspot.com en te bereiken via:
[email protected],
[email protected], hassanfad11 @hotmail.com en/of via Twitter op: @HassanFad
SQL
Jeffrey Verheul
Decrease dataflows between systems with CDC Dealing with data is becoming a bigger challenge every day, if you work with a wrongly designed system. And haven’t we all been there? One of the senior software engineers designed the system, and tested it with 10.000 records. But in the past few years, he left, and the system increased so much in size, that it’s impossible to work with it. And now a new invoice system (or a BI team for example) needs to read data from the same system. Throwing hardware at the problem isn’t an option, so what do you do next? In the past, reading data from that one core production system wasn’t an issue. The invoice processes ran at night, and the process used to finish before the first employee got in the office in the morning. But with the amounts of data currently being poured in the system, this becomes impossible. Redesigning the system takes up too much time and money, so that’s off the table. So how do you technically solve this puzzle, without rebuilding your entire architecture?
In order to use CDC, we need to enable CDC on the database, and on the table: USE CompanyInfo GO /* Enable CDC on database */ EXEC sys.sp_cdc_enable_db
What is CDC? CDC (Change Data Capture) is a feature that’s included in SQL Server Enterprise. This gives you the opportunity to capture Inserts, Updates and Deletes of records on specific objects. This can be used to perform “incremental updates” to the invoice system, instead of reading the entire content of the database at night. So how does it work? In SQL Server, every change you make to a record or table, is stored in the transaction log before your database is changed on disk. CDC reads the transaction log, and records all changes on the tables you have enabled CDC on.
GO /* Enable CDC on table */ EXEC sys.sp_cdc_enable_table @source_schema = 'dbo', @source_name = 'Customer', @supports_net_changes = 1, @role_name = NULL, @index_name = 'PK_Customer', @captured_column_list = 'CustomerID, FirstName, LastName, AccountNumber' GO
Enabling CDC Enabling CDC is as easy as running a query. First, let’s create some resources: /* Create a database */ CREATE DATABASE CompanyInfo GO /* Use the database we just created */ USE CompanyInfo GO /* Create the Customer table */ CREATE TABLE dbo.Customer (CustomerID INT IDENTITY(1,1), FirstName VARCHAR(50), LastName VARCHAR(50), PhoneNumber VARCHAR(50), AccountNumber VARCHAR(50), CONSTRAINT PK_Customer PRIMARY KEY(CustomerID)) GO
The query above only captures changed on the “FirstName”, “LastName” and “AccountNumber” columns (ID needs to be included, because it’s the primary key on the table). Changes on the “PhoneNumber” column aren’t interesting for the invoice system. If you do want to capture changed to that column, you can add it to the list passed into “@captured_column_list” parameter. Another option is to leave out the “@captures_column_list” parameter, so it will capture all columns in the table. After running these statements, SQL Server created a number of objects for CDC. The most important things: 2 functions you can query to get data, 2 jobs (capture and cleanup), and a “Customer_CT” table (system table), where the data changes are stored. Capture and Cleanup As long as the SQL Server Agent is running, changes are captured. The capture job, that is responsible for capturing all changes on CDC-enabled tables, runs every 5 seconds by default. This value can be changed, but I’ve never seen a reason to change this. The cleanup job is responsible for removing old data from the “Customer_CT” table. By default, old data is removed after 4320 minutes (3 days). You can change this by executing this statement:
magazine voor software development 15
SQL USE CompanyInfo GO /* Change the retention for cleanup */ EXEC sys.sp_cdc_change_job @job_type = 'cleanup', @retention = 7200 GO /* Check the result of the change */ SELECT job_type, retention FROM msdb.dbo.cdc_jobs
In this case the retention of the data is changed to 7200 minutes. This means that old data is deleted after 5 days. This setting gives you the opportunity to feed the invoice system with data for 5 days. This could help you if there is downtime of your system, or if you have a maintenance windows for the system every week for example. If that’s not needed, you could set it to a smaller value. How larger the value is, how longer you could query the change data, but also the more storage you need to store the change data. Querying the data Now that we’re storing the changed data, how do we query it? There are several options, all with their own pros and cons. Before we start querying the data, let’s insert and update a record in the table: USE CompanyInfo GO
/* Insert a customer record */ INSERT INTO dbo.Customer (FirstName, LastName, PhoneNumber, AccountNumber) VALUES ('John', 'Doe', '555-6162', 'AA-5206204855882426') GO
/* Update the LastName of the customer */ UPDATE dbo.Customer SET LastName = 'Smith' WHERE LastName = 'Doe' GO
The best practice to query the data, is to use the build-in functions. These functions (all_changes for the entire change set, or net_changes for the combined changes), all work with LSN’s (Log Sequence Numbers). An LSN uniquely identifies a record in the SQL Server transaction log. These LSN’s can be translated to a readable “datetime” datatype. Also, a “datetime” datatype can be translated in an LSN. Translating can be done with the build-in functions: /* Translate LSN to datetime */ SELECT sys.fn_cdc_map_lsn_to_time(0x00000000000000000000) GO /* Translate datetime to LSN */ SELECT sys.fn_cdc_map_time_to_lsn('smallest greater than or equal', '1900-01-01') GO
With these functions, you can create your own “window” of data extraction. In practice this means that you can start your invoice process at 10PM, and in that window query data changed from yesterday 10PM, till today 10PM. Another option is to only query changes for a specific day, for example between 10AM and 2PM on
16
MAGAZINE
Wednesday. The possibilities are endless, and can be fully customized to work for your system. So how does this look in the 2 different functions?
As you can see, the all_changes function will return the inserted record (operation code 2), and the record after the update (operation code 4). The net_changes function, returns the combined result within the window you created. In this case, the inserted and updated record are combined within a single record. Another option you have, is to retrieve data directly from the “Customer_CT” table. This option isn’t considered a best practice, but you have the opportunity to do that if that suits you better. Design decisions If you decide to use CDC, there are some design decisions you need to take a look at. One of the first things you need to think about is storage. Data changes are captured and stored, so you need some extra storage to save these records. Another thing to think about, is the way your invoice system reads data from the primary system. If you’re going to use CDC, you might need to change the way data is retrieved. But these changes might be easier, and much safer than changing your primary system. And if you use SQL Server Integration Services (SSIS) for example, there are some standard components you could use. The changed you need to make depend on the system and architecture you have in your company. Conclusion With the options you’ve seen you can decide what works the best for your system. There are alternatives you could use, but these options all require system changes, or are more intrusive on your system than CDC. For example, you could use triggers on your tables, but those tend to slow down your system.One thing is certain: CDC reduces the amount of data that needs to be exchanged between systems, and the time needed to update secondary systems by a lot. And maybe even more important to the business, it saves you from a huge investment needed to re-design the entire system! Personally, I would say CDC isn’t the silver bullet that solves all your cross-system dataflow problems, but it is very effective when you use it the way it was intended: capture changes in a very lightweight way. The only real downside of CDC is that it’s an Enterprise-only feature. But the flexibility and compatibility (for example with SSIS and BIML) makes up for these shortcomings. CDC is definitely something to take a look at, even if you’re not a data professional! •
Jeffrey Verheul Jeffrey Verheul is a DBA and database developer from the Netherlands, with over 10 years experience in the Microsoft stack. After a short side-track as a software engineer, he returned to his true love: SQL Server. His main focus is on database development, performance tuning and database administration. He is a member of the Friends of Red Gate, and blogs regularly on devjef.wordpress.com. You can contact him on his blog, or via Twitter (@DevJef).
CLOUD
Marcel Meijer
Azure Webjobs Tijdens de afgelopen Microsoft Techdays 2014 deed ik een sessie over Azure Cloud Services. De opname is te vinden op Channel 9. In het begin van Azure waren Cloud services de “way to go”. Cloud Servies is een krachtig concept, maar er kleefde ook de nodige nadelen aan. Bestaande applicaties konden niet zomaar via de Lift en Shift methode naar de Cloud gebracht worden. Meestal was dit gewoon te wijten aan de applicaties zelf. Weinig applicaties zijn of waren zuiver stateless, asynchroon in de basis en in staat als meerdere instanties naast elkaar te draaien. In de afgelopen jaren is het Azure platform rijker geworden met verschillende diensten. In plaats van iets zelf te verzinnen of te kopieren van anderen, zijn er nu bestaande tools/producten opgepakt en in samenwerking geschikt gemaakt voor Azure (Hadoop, Docker, etc). Maar ook is IT development een stuk volwassener geworden. Developers en architecten realiseren zich steeds vaker dat Scale up niet helpt met availability, dat services/servers stuk gaan en dat een internet applicatie de potentie van een miljoenen publiek heeft. Standaard dogma’s als SOA architecture, Servicebussen of SOAP webservices lijken ook hun kracht te verliezen, Microservices krijgen meer draagvlak en betere tooling. Daarover ga ik zeker nog vaker bloggen. Terug naar mijn Techdays demo. Die zag er zo uit:
Zoals gezegd bestond het uit een WebRole en een WorkerRole. De WebRole voor het uploaden en bekijken van de plaatjes.
De flow van de applicatie zag er zo uit. Zoals je ziet, de WebRole moest naast het uploaden ook een bericht op een queue zetten voor de WorkerRole. Aan de WorkerRole kant moet er een mechanisme zijn om de queue leeg te lezen. Zoals ik vertelde in mijn sessie, moet je dan ook het Busy waiting oplossen. Het lezen van de queue is een transactie en dat kost geld. Een belangrijk onderdeel van architectuur op Azure is Cost Based design. Dus wil je het lezen van bijvoorbeeld een queue zo efficiënt en effectief mogelijk houden met het oog op de kosten. Op Azure zijn tegenwoordig Webjobs beschikbaar. Met deze webjobs is het mogelijk om deze te laten triggeren na het toevoegen van een nieuwe blob op storage. Dat scheelt in mijn geval een bericht op de queue en eigen check actie van de queue. Het hele wachten en kijken of er werk (nieuwe blob op storage) is, wordt nu door het platform verzorgd en geregeld. En wat ik niet hoef te doen, dat scheelt tijd en het platform kan dat efficiënter. Dus de WorkerRole wordt vervangen door een Webjob. De WebRole heeft ook een alternatief. Moest ik voor de WebRole toch nog iets aparts leren, zoals bijvoorbeeld het lezen van de configuratie settings. Met een Azure Website kan ik de technieken gebruiken die ik altijd al gebruikte. En voor de settings zie je in mijn vorige blogpost de oplossing. Het proces plaatje ziet er dan zo uit.
De solution zag er zo uit. De code is te downloaden of op te vragen.
magazine voor software development 17
CLOUD
En de website ziet er na een kleine redesign zo uit.
De WorkerRole besloeg ongeveer het dubbele aantal regels code, waarvan het grootste gedeelte zaken die niets met het proces te maken hebben. Op deze manier krijg je precies zoals ik altijd zeg tijdens presentaties. We kunnen ons richten op de functionaliteit en het echte werk, de rest wordt overgenomen en geregeld door het Azure platform. Nu moet de Client op een andere manier genotificeerd worden en niet op een queue hoeven te kijken. NB In dit artikel beweer ik niet dat Cloud Services niet bruikbaar zijn. Voor het hier genoemde scenario waren de uitgebreide mogelijkheden van Cloud Services niet nodig. Er is op de Azure site (http:/ /azure. microsoft.com/nl-nl/documentation/articles/choose-web-site-cloudservice-vm/) een vergelijkend overzicht van de mogelijk-heden tussen de verschillende oplossingen. •
En de code van de Webjob is eigenlijk alleen dit, ongeveer 55 regels.
Marcel Meijer Marcel is een allround Microsoft Architect en Microsoft Cloud specialist bij Xpirit Nederland (www.xpirit.com), Marcel heeft al meerdere bedrijven geholpen met succesvolle Cloud/Microsoft Azure implementaties. Hij is voorzitter van de Software Development Network (SDN), redacteur end event organisator. Hij is ook een frequente blogger en spreker op verschillende community events en conferences in Nederland. Since 2010 mag hij zich Microsoft MVP noemen.
TIP:
Macro’s in Excel Werken niet meer na Office update Als je Excel 2013 macro’s bevat en deze werken niet meer na de laatste Office update. De oplossing hiervoor is, zoek het bestand MSForms.exd op. Deze staat normaal gesproken in de folder C:\Users\user.name\AppData\Local\Temp\Excel8.0\. Verwijder het bestand MSForms.exd. Bij het opnieuw opstarten van Excel 2013 wordt dit bestand opnieuw aangemaakt. Daarna werken alle VBA macro’s werken weer.
18
MAGAZINE
20
ma a rt
SDN Event Zeist
GENERAL
Sander Hoogendoorn
Microservices. The good, the bad and the ugly Back in 1988, when I was first employed by a company for writing software, the world was fairly simple. The development environment we had was character-based, the database was integrated and traversed with cursors, and we built a whole new administrative system covering everything but the kitchen sink. It took us five years to complete the project, basically because the client kept changing his mind every now and then, and because every change in the code could break code elsewhere in the system. Unit testing hadn’t been invented yet, and testing was done by the end users. In production.. So far for monoliths. Then in 1994 I joined a company that build desktop applications - remember the world wide web was only a couple of years old, and web applications hadn’t been invented yet. We used a great tool called PowerBuilder and now we had two components to worry about; the application on the desktop and the database on the server. The applications we build usually served departments or sometimes even a whole company. Not highly complicated, but not highly scalable either. Ah well, we had fun as long as the client-server paradigm lasted.
impossible technologies such as application servers and CORBA (to impress your co-workers, look that one up on Wikipedia). The good old days of object request brokers! At that time I was working for a large international bank trying to set up an methodology for doing component based development. Even with a heavily armed team of Anderson consultants it took us three years to write the damn thing. In the end both the paradigm and the technology where too complex to write decent and well-performing software. It just never took off.
Component based development The world got more complex in the mid-nineties. Companies wanted web applications, basically running on intranets to get rid of desktop deployments. And applications needed to serve multiple departments, and sometimes even break company borders. A new paradigm set in: component based development, also known as CBD. The paradigm promised us re-use, scalability, flexibility and a way to harvest existing code (usually written in COBOL). We started breaking up our systems into big functional chunks, and tried hard to have those components communicate to each other. Java was invented and everybody now wanted to write code in Java (apparently some people still to this nowadays). Components where running in
Service oriented architecture At that point in time, the early years of this century, I thought we got rid of distributed software development, and happily started building web applications. I guess everyone bravely ignored Martin Fowler’s first law of distributed objects: do not distribute your objects. Gradually we moved into the next paradigm of distributed computing, re-packaging the promises of component based development into a renewed set of technologies. We now started doing business process modeling (BPM), and implemented these processes in enterprise services buses (ESB’s), with components delivering services.
Fig. 1: Scary stuff, an object request broker architecture
Fig. 2: An enterprise service bus
magazine voor software development 19
GENERAL
We were in the age of service oriented architecture, better known as SOA. Coming from CBD, SOA seemed easier. As long as your components - the producers - were hooked into the enterprise service bus, we figured out how to build-up scalable and flexible systems. We now had much smaller components that we could actually extract from our existing systems (now not only written in COBOL, but also in PowerBuilder, .NET and Java). The mandatory design patterns books where published and the world was ready to go. This time we would crack it! I found myself working for an international transport company, and we happily build around SAP middleware – delivering both ESB and BPM tooling. We now not only needed regular Java and .NET developers, but we employed middleware developers and SAP consultants as well. And although agile was introduced to speed up development (I know, this is not the right argument), projects still suffered from sluggishness and moreover, when we got pieces of the puzzle in place, we started to realize that integration testing and deployment of new releases got more complicated by the day. At last: microservices! I do hope you forgive me this long and winding introduction to the actual topic: microservices. You might think: why do we need yet another article on microservices? Isn’t there enough literature already on the topic. Well yes there is. But if you look closely to the flood of articles that you find on the internet, most of them only describe the benefits and possibilities of microservices (sing hallelujah), some of them take a look at the few famous path finding examples (Netflix, Amazon, and Netflix, and Amazon, and Netflix…). Only a few articles actually dig a bit deeper, and they usually consist of summing up the technologies people seem to be using when implementing microservices. It’s still early in the game. That’s were a little historical perspective won’t hurt. I find it interesting to witness that the benefits and possibilities of the predecessors of microservices are still with us. Microservices seem to promise scalable and flexible systems, based on small components that can easily be deployed independently, and thus promote use of the best choice in technologies per component. Basically the same promises we fell for with CBD and SOA in the past. Nothing new here, but that doesn’t mean that microservices aren’t worthwhile investigating. Is it different this time around? So why is it different this time? What will make microservices the winning paradigm, where its predecessors clearly were not? What makes it tick? As a developer, there’s no doubt that I am rather enthusiastic about microservices, but I was enthusiastic as well (more or less) when people came up with CBD and SOA. I do suppose there are differences. For the first time we seem to have the technology in place to build these type of architectures. All the fancy and complex middleware is gone, and we rely solely on very basic and long-time existing web protocols and technologies. Just compare REST to CORBA. Also we seem to understand deployment much better, due to the fact that we’ve learned how to do continuous integration, unit testing, and even continuous delivery. These differences suggest that we can get it to work this time around. Still, from my historical viewpoint some skepticism is unavoidable. Ten years ago, we also really believed that service oriented architecture would be technologically possible, it would solve all our issues, and we would be able to build stuff faster, reusable and more reliable. So, to be honest, the fact that we believe that the technology is ready, is not much of an argument. Meanwhile the world also got more complex. Over the last year I’ve been involved with a company that is moving away from their mainframe (too expensive) and a number of older Java monoliths (too big, and hard to maintain). Also time-to-market plays an
20
MAGAZINE
important role. IT need to support introducing a new product in months, if not in weeks. So we decided to be hip and go microservices. Here’s my recap of the good, the bad and the ugly of microservice architectures, looking back on our first year on the road. The good Let’s start with the good parts. We build small components, each offering about two to six services. Good examples of such small components are a PDF component, that does nothing more than generate PDF’s from a template with some data, or a Customer component that allows users to search for existing customers. These components offer the right size. The right size of code, he right size of understandability, to right size to document, to test an to deploy.
The good Our team tend to evolve towards small teams designing, implementing and supporting individual components. We didn’t enforce ownership, but over time small teams are picking up the work on a specific component and start feeling responsible for it. When we outlined the basic architecture for our microservices landscape we set a number of guidelines. We are not only building small components, but are also building small single-purpose web applications. Applications can talk to other applications, and can talk to components. Components handle their own persistence and storage, and can also talk to other components. Applications do not talk directly to storage. Components do not talk to each others storage. For us these guidelines work. Microservices lives up to some of its promises. You can pick the right technology and persistence mechanisms for each of you components. Some components persist to relational databases (DB2 or SQLServer), others persist to document databases (MongoDB in our case). The hipster term here of course is polyglot persistence. We also stated that every application and component has it’s own domain model. We employ the principles and patterns of domain driven design straightforward. We have domain objects, value objects, aggregates, repositories and factories. Because our components are small, the domain models are fairly uncomplicated, and thus maintainable. Although we have had quite a journey towards testing our components and services, from Fitnesse to hand-written tests, we are now moving towards testers specifying tests in SoapUI, which we are running both as separate tests and during builds. We had to learn to understand REST, but we’ve got this one figured out for now. Andtesters love it.
GENERAL When we started our microservices journey, the team I’m was in a highly reactive mode – tell us what to program and how to program it, and we’ll do our job. I probably won’t have explain what that does with the motivation of the team members. However, with microservices there is no such thing as a ready-to-use cookbook or a predefined architecture. It simply doesn’t exist. That means that we continuous find ourselves solving new pieces of the microservices puzzle, from discovering how to design microservices (we use smart use case), to how implement REST interfaces, how to work with a whole new set of frameworks, and a brand new way of deploying components. It’s this puzzle that make working on this architecture interesting. We allow ourselves to learn everyday. The bad But as always, there’s a downside. When you start going down the microservices road – for whatever you may find it beneficial - you need to realize that this is all brand new. Just think of it: if you’re not working for Netflix or Amazon, who do you know who actually already does this already? Who has actively deployed services into production, with a full load? Who can you ask?
The bad You need to be aware that you really need to dig in and get your hands dirty. You will have to do a lot of research yourself. There are no standards yet. You will realize that any choices you now make in techniques, protocols, frameworks, and tools is probably temporarily. When you are learning on a daily basis, newer and better options become available or necessary, and your choices will alter. So if you’re looking for a ready-made IKEA construction kit for implementing microservices the right way, you might want to stay away from microservices for the next five to seven years. Just wait for the big vendors, they will jump in soon enough, as there’s money to make. From a design perspective you will have to start to think differently. Designing small components is not as easy as it appears. What makes a good size component? Yes, it has a single business purpose, undoubtedly, but how do you define the boundaries of your component? When do you decide to split a working, operational component into two or more separate components? We’ve come across a number of these challenges over the past year. Although we have split up existing components, there are no hard rules on when to actually do this. We decided mainly based on gut feeling, usually when we didn’t understand a components structure anymore, or when we realized it was implementing multiple business functions. It gets even harder when you are chipping off components from large systems. There’s usually a lot of wiring to cut, and in the meantime you will need to guarantee that the system doesn’t break. Also, you will need a fair amount of domain knowledge to componentize your existing systems.
Basically we found that components are not as stable as we first thought. Occasionally we merge components, but it appeared far more common to break components into smaller ones to provide reuse and shorter time-to-market. As an example, we pulled out a Q&A component from ourProduct component that now supplies questionnaires for other purposes than just about products. And more recently we created a new component that only deals with validating and storing filled-in questionnaires. There’s lots of technical questions you will need to answer too. What’s the architecture of a component? Is an application a component as well? Or, a less visible one, if you are thinking of using REST as your communication protocol – and you probably are – is: how does REST actually work? What does it mean that a service interface is RESTful? What return codes do you use when? How do we implement error handling in consumers if something isn’t handled as intended by one of our services? REST is not as easy as it appears. You will need to invest a lot of time and effort to find out your preferred way of dealing with your service interfaces. We figured out that to make sure that services are more or less called in a uniform way, we’d better create a small framework that does the requests, and also that deals with responses and errors. This way communication is handled similar with every request, and if we need to change the underlying protocol or framework (JAX-RS in our case), we only need to change it in one location. That automatically brings me to the next issue. Yes, microservices deliver on the promise that you can find the best technology for every components. We recognize that in our projects. Some of our components are using Hibernate to persist, some are using a MongoDB connector, some rely on additional frameworks, such as Dozer for mapping stuff, or use some PDF-generating framework. But with additional frameworks comes the need for additional knowledge. At this company, we will easily grow to over a hundred small components and maybe even more. If even only a quarter of these use some specific framework, we will end up with twenty-five to thirty different frameworks( did I mention we do Java?). We will need to know about all of these. And even worse, all of these frameworks (unless they’re dead) version too. Then there’s the need to standardize some of the code you are writing. Freedom of technology is all good, but if every component is literally implemented differently, you will end up with an almost unmaintainable code base, especially since it is likely that no-one oversees all the code that is being written. I strongly suggest to make sure there’s coherence over your components on aspects of your code base that you could and probably should unify. Think of your UI components (grids, buttons, pop-ups, error boxes), validation (of domain models), talking to databases or how responses from services are formulated. Also, although I strongly oppose having a shared domain model (please don’t go that route), there’s elements in your domain models you might need to share. We share a number of enumerations and value objects for instance, such as CustomerId orIBAN. If you’re a bit like us this generic code ends up in a set of libraries - a framework if you will – that is reused by your components. We have learned that with every new release of this home-grown framework we end up refactoring some of the code of our components. I rewrote the interface of our validation framework last week, which was necessary to get rid of some state it kept - components need to be stateless for clear reasons of scalability - and I’m a bit reluctant to merge it back into the trunk when I get back to work after the weekend. Most of our components use it, and their code might not compile. I guess what I’m saying here is that it’s good to have a home-grown framework. With some discipline it will help keep your
magazine voor software development 21
GENERAL code somewhat cleaner and a tad more uniform, but you will have to reason about committing to it and releasing new versions of it. The ugly So what about the really nasty parts of microservices? Let’s start with deployment pipelines. One of the promises of microservices is that they can and should be individually deployed and released. If you are currently used to having a single build and deployment pipeline for the one system you are building or extending, you might be in for a treat. With microservices you are creating individual pipelines for individual components.
The hockey stick model Early in the game? Yes, we’ve only been on the road to microservices for about a year. And I still haven’t figured out whether we are on a stairway to heaven or on a highway to hell. I do suppose, as with it’s historical predecessors, we will end up somewhere in the middle, although I really do believe that we do have the technology to get this paradigm working – and with we I don’t just mean Netflix, Amazon or some hipster mobile company, but the regular mid-size companies you and I work for. But will it be worthwhile? Shorten time-to-market? Deliver all the goodies the paradigm promises us? To be honest, I don’t know yet despite or maybe even because of all the hype surrounding microservices. What I did notice is that, given the complexity of everything surrounding microservices, it takes quite a while before you get your first services up and running, and we are only just passing this point. Some weeks ago, I was having a beer with Sam Newman, author of Building Microservices. Sam confirmed my observations from his own examples and referred to this pattern as the hockey stick model.
The ugly Releasing the first version of a component is not that hard. We started with a simple Jenkins pipeline, but are currently investigating TeamCity. We have four different environments. One for development, one for testing, one for acceptance and of course the production environment. Now we are slowly getting in the process of releasing our components, most of them with their own database, we start to realize that we can not do this without the support and collaboration of the operations team. Our expectations are that we will slowly evolve into a continuous delivery mode, with operations incorporated in the team. Right now we already have enough trouble getting operations on-board. They are now used to quarterly releases of the whole landscape, and certainly have no wish for individually deploying components. Another that worries me is versioning. If it is already hard enough to version a few collaborating applications, what about a hundred applications and components each relying on a bunch of other ones for delivering the required services? Of course, your services are all independent, as the microservices paradigm promises. But it’s only together that your services become the system. How do you avoid to turn your pretty microservices architecture into versioning hell - which seems a direct descendant of DLL hell? To be honest, at this point in time, I couldn’t advice you well on this topic, but a fair warning is probably wise. We started out with a simple three digit numbering scheme (such as 1.2.5). The rightmost number changes when minor bugs have been solved. The number in the middle raises when minor additional functionality has been added to a component, and the leftmost number changes when we deploy a new version of a component with breaking changes to its interface. Not that we strongly promote regularly changing interfaces, but it does happen. Next to that, we test our services during the build, both using coded tests and tests we assemble in SoapUI. And we document the requirements in smart use cases and domain models of our applications and components using UML. I’m quite sure in the future we need to take more precautions to keep our landscape sane, such as adding Swagger to document our coded services, but it’s still to early in the game to tell.
22
MAGAZINE
There’s a lot to take care of before you are ready to release you first service. Think of infrastructure, sorting out how to do REST properly, setting up you deployment pipelines, and foremost change the way you think about developing software. But as soon as the first service is up and running, more and more follow faster and faster. Be patient So, if there’s one thing I’ve learned over the past year, it is to be patient – a word which definitively did not appear in my dictionary yet. Don’t try to enforce all kinds of (company) standards if they just don’t exist yet. Figure it out on the fly. Allow yourself to learn. Take it step by step. Simply try to do stuff a little bit better than the day before. And as always, have fun! •
Sander Hoogendoorn Sander is an independent consultant; as a mentor, trainer, coach, software architect, developer, writer, speaker, for his company ditisagile.nl (after the Dutch title of my latest book This Is Agile). Over the past decade, in my roles as Principal Technology Officer and Global Agile Thoughtleader at Capgemini. During this period I’ve learned a great deal and have contributed to the innovation of software development at Capgemini and its many international clients.
GENERAL
Patrick Kalkman
Improving traceability of distributed systems using the ELK stack With all IT systems, traceability is an important non-functional requirement. If the traceability of a system is high, it is easier to find the root cause of a problem that occurs in a production environment. As a system gets distributed over multiple applications or services, tracing a problem in a production environment becomes more difficult. As there are simply more application and services to check. New architectures such as a microservices architecture makes this even more difficult because the functionality of the system can literally be distributed over dozens or hundreds of services. The services could be implemented using different development languages and be running on different platforms. This article describes a solution for increasing the traceability of a distributed system by using Log aggregation via the ELK stack. Tracing using the Elk stack Most distributed systems consist of different types of applications implemented using different programming language running on different operating systems. Normally these systems grow organically over time. There is not a single standard way of logging when a service or application fails.
Elasticsearch uses Java and Kibana is implemented using HTML, CSS and JavaScript. Although these three products work great together, they can also be used separately.
Fig. 2: ELK stack overview Fig. 1: Microservices architecture The most common way to log error events is writing these events in log files. Each row of these text files minimally contain a timestamp and some data about the event. With a distributed system such as a microservices architecture this could mean that an engineer has to go through hundreds of log files to find a problem. The ELK stack provides a solution for this problem by aggregating all of these log files into a single system. The ELK stack combines the Elasticsearch, Logstash and Kibana products. Elasticsearch is a search and analytics engine, Logstash is a tool for scrubbing and parsing log data into a single format and Kibana is a visualization engine to interact with Elasticsearch. The logs of a system are transported through and enhanced by Logstash. The data is then indexed and stored by Elasticsearch and finally visualized using the Kibana dashboard. All the components of the ELK stack are open source. Logstash is implemented using JRuby,
After the ELK stack is installed and configured you are able to search in real-time through the logs of all your applications and services. Using Kibana you are able to visualize trends and spot anomalies in your log files.
There is not a single standard way of logging when a service or application fails Installing the ELK stack The ELK stack can be installed on Unix as well as Windows. For this article, I will be installing the ELK stack on a single Ubuntu server. The Ubuntu server will be running as a VM on the Microsoft Azure platform. The version of Ubuntu that I will be using is 14.04 LTS.
magazine voor software development 23
GENERAL
The installation of all components is done through a remote shell, using putty as an ssh client.
The name of the Elasticsearch node is automatically generated, so it will probably be different in your installation.
Installing Elasticsearch As Elasticsearch runs on top of Java, the first prerequisite we have to fulfill before we can install Elasticsearch is Java. We install Java by entering the following command on the command line.
We now have the E of the ELK stack running. Next, we will install Logstash.
$ sudo apt-get install openjdk-7-jre-headless
Installing Logstash Before we can install Logstash we first have to download the Logstash package. We download Logstash with the following command. $ wget https://download.elasticsearch.org/logstash/log-
This will download and install Java version 1.7. To validate if Java was installed correctly we enter the following command.
stash/packages/debian/logstash_1.4.2-1-2c0f5a1_all.deb
$ java –version
And install it by entering the following command If Java was installed correctly the following response will be generated (the version number may differ) java version "1.7.0_65" OpenJDK Runtime Environment (IcedTea 2.5.3) (7u71-2.5.30ubuntu0.14.04.1)
$ sudo dpkg -i logstash_1.4.2-1-2c0f5a1_all.deb
There is an additional package with community added contributions for Logstash that we need. We download this package with the following command.
OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode) $ wget https://download.elasticsearch.org/logstash/logstash/packages/debian/logstash-contrib_1.4.2-1-
To install Elasticsearch we first have to download the package. We download Elasticsearch with the following command. $ wget
https://download.elasticsearch.org/elasticsearch/
efd53ef_all.deb
And install it using this command.
elasticsearch/elasticsearch-1.4.1.deb $ sudo dpkg –i logstash-contrib_1.4.2-1-efd53ef_all
When downloaded we can install Elasticsearch with the following command. $ sudo dpkg -i elasticsearch-1.4.1.deb
And start it with the following command
We then issue the following command to start Logstash $ sudo service logstash start
This concludes the installation of the L part of the ELK stack. We move to the last part, installing Kibana, the front-end.
$ sudo service elasticsearch start
We can validate if Elasticsearch was installed and is running correctly by entering the following command.
Kibana is implemented using HTML, CSS and JavaScript
$ curl http://localhost:9200
Elasticsearch should give a JSON response that looks like the following
Installing Kibana Kibana is implemented using HTML, CSS and JavaScript. Therefore, to run Kibana we need a web server. Kibana runs completely clientside in the browser, so we don’t have any server side dependencies. If the web server can serve HMTL you will be ok. I will be using nginx.
{ "status" : 200, "name" : "Ultron", "cluster_name" : "elasticsearch", "version" : { "number" : "1.4.1", "build_hash" : "89d3241d670db65f994242c8e8383b169779e2d4", "build_timestamp" : "2014-11-26T15:49:29Z", "build_snapshot" : false, "lucene_version" : "4.10.2" }, "tagline" : "You Know, for Search" }
24
MAGAZINE
To install nginx enter the following command $ sudo apt-get install nginx
The installation process will automatically start nginx. To validate if nginx is installed correctly and running issue the following command. $ curl http://localhost
nginx should respond as follows
GENERAL
Welcome to nginx! <style>
Configuring Logstash The community maintaining Logstash has an interesting project principle. They say that if a newbie has a bad time using Logstash it’s probably a bug. The documentation should have be better and more instructive.
…
We download and extract Kibana by entering the following command
If a newbie has a bad time, it's a bug
$ curl https://download.elasticsearch.org/kibana/kibana/kibana-3.1.2.tar.gz | tar xvz
We then have to copy the Kibana folder to the nginx html folder by entering the following command. $ sudo cp kibana-3.1.2/* /usr/share/nginx/html –R
To validate if Kibana is working correctly we have to open two additional endpoints on the virtual machine running on Microsoft Azure. One endpoint for port 80 to be able to talk to the web server and another endpoint for port 9200 to let Kibana talk to Elasticsearch.
Logstash is configured using a configuration file. A Logstash configuration file has the following structure. The Logstash configuration file describes how events should flow through the Logstash pipeline with an input, filter and an output stage. Input specifies the source of the data. This could be a file, a TCP port or other input plugins that are available. Filter defines how the input stream should be parsed. Output defines where the parsed output should be sent and stored. Each part of the pipeline can be configured using the logstash configuration file. The configuration file resembles the structure of the pipeline. input { } filter { } output { }
Fig. 3: Azure Endpoints When you now browse to your webserver you should be welcomed by the Kibana start screen.
Logstash contains several plugins that can be configured in each part of the pipeline. The list is too extensive to list here, but these are some examples. • Input plugins (log4j, collectd, eventlog, tcp, wmi, udp, heroku, file) • Filter plugins (grok, json, split, translate, drop) • Output plugins (elasticsearch, agios, http, stdout, rabbitmq, websocket, tcp) See the Logstash website (http://logstash.net/) for a complete list of available plugins. The first real configuration we create is for parsing and indexing logs from an IIS server. We choose an IIS log because it contains a lot of different tokens we have to configure in the configuration file. Note that this could be any log file. The Logstash configuration file should be stored on our Ubuntu server in /etc/logstash/conf.d/logstash.conf input { lumberjack { port => 6379
Fig. 4: Kibana welcome screen
type => "IISLogs" ssl_certificate => "/home/azureuser/logstash.crt"
Congratulations, you have just installed all parts of the ELK stack. Next, we will look at configuring Logstash to get events into the system.
ssl_key => "/home/azureuser/logstash.key" } } filter { if [type] == "IISLogs" { if [message] =~ "^#" { drop {} }
Fig. 5: Logstash configuration file structure
grok {
magazine voor software development 25
GENERAL
match => ["message", "%{TIMESTAMP_ISO8601:log_timestamp} %{IPORHOST:site}
Filter The filter actually tries to parse the data of the event. The first line of the filter contains a condition which checks the type of the event.
%{WORD:method} %{URIPATH:page}
if [type] == "IISLogs" {
%{NOTSPACE:querystring} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clienthost} %{NOTSPACE:useragent}
This means that the lines following this condition will only be executed if the type of the event equals “IISLogs”. As you remember we added this type to events that are input using the lumberjack input plugin.
%{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:scstatus}
The next line states that events that start with a hash should be ignored.
%{NUMBER:time_taken}"] }
if [message] =~ "^#" {
drop {}
}
date { match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss" ] timezone => "Etc/UCT" }
Lines in an IIS log file that start with a hash indicate a comment. These are normally only present in the header of the IIS logfile.
useragent { source => "useragent" prefix => "browser" } mutate {
The next part uses the Logstash GROK plugin. GROK is a wrapper around a regular expression engine which enables you to reuse existing regex patterns. It is the ideal solution for parsing custom log messages and comes with 120 existing patterns.
remove_field => [ "log_timestamp"] }
Using GROK we are going to parse a IIS log event. A log line of a IIS log event looks like the following:
output {
2014-12-08 00:00:17 172.16.12.172 POST /url1/api.asmx - 443
} } elasticsearch {
VODKIJKWIN 192.168.16.135 PHP-SOAP/5.3.28-1~dotdeb.0 200 0 0
}
343
}
The grok match parameter specifies the pattern to parse this line. I will describe each part of the configuration file, starting with the input. grok { match => ["message",
Input The input plugin I am using is called lumberjack which is a specific input plugin specially created for securely receiving events from Logstash-forwarder. Logstash-forwarder is a type of application runs on your server and sends log events to the log server. Logstashforwarder is an application that consume low resources.
"%{TIMESTAMP_ISO8601:log_timestamp} %{IPORHOST:site} %{WORD:method} %{URIPATH:page} %{NOTSPACE:querystring} %{NUMBER:port} %{NOTSPACE:username}
The Logstash-forwarders motto:
%{IPORHOST:clienthost}
I'm a lumberjack and I'm ok! I sleep when idle, then I ship logs all day! I parse your logs, I eat the JVM agent for lunch!
%{NOTSPACE:useragent} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:scstatus} %{NUMBER:time_taken}"] }
Note, that for readability the grok pattern has been split on to multiple lines. The actual grok match line should be on a single line. The lumberjack input plugin has several configuration fields which define on what port and which certificate is used to setup an encrypted connection. We are using port 6379 for the lumberjack input. To be able to send the log events securely to the server we need a certificate. This can be a self-signed certificate or a real certificate. I will show later how to create this certificate. The type fields adds a new field called ‘type’ to each event. The value of this field when events are retrieved by lumberjack is “IISlogs”. Types are mainly used for filter activation, we can specify that a certain filter should only be used for events that have type=”IISLogs”, which we will describe next.
26
MAGAZINE
It starts by reusing an existing pattern in grok called TIMESTAMP_ ISO8601 which parses the date and time from the event and stores it into the field log_timestamp and ends with NUMBER which is stored into the time_taken field. An online tool is available http://grok debug.herokuapp.com/ for testing grok patterns. After the GROK stage of the filter we have parsed the IIS log line into several specific fields.
GENERAL
The filter continues with using the date plugin. The date plugin is able to convert a field into a date time and use that date time as the timestamp of this specific event. date { match => [ "log_timestamp", "YYYY-MM-dd HH:mm:ss" ] timezone => "Etc/UTC" }
If no time zone is specified it adds a default time zone of “Etc/UTC” to the event. The user agent plugin parses user agentstring into structured data. It uses BrowserScope data to add information like family, operating system, version and device. Browserscope is an open-source project for profiling web browsers and storing and aggregating crowd-sourced data about browser performance. useragent { source => "useragent" prefix => "browser"
No other fields are specified as we are running Elasticsearch on the same machine as Logstash. Otherwise we could have specified, for example the host and port. Restart Logstash We have to restart Logstash after we have added or changed the Logstash configuration file. We restart Logstash with the following command. $ sudo service logstash restart
This concludes installing and configuring our ELK stack using a single server. The final part to getting log events into the server is adding and configuring a shipper on the server that contains the logs of the application that we want to monitor. Sending events to Logstash We first have to send the events to Logstash before we can parse, index and search through them. There are several so called shippers which are responsible for transmitting events to Logstash.
}
The prefix field specifies to add “browser” to all of the extracted fields. The last part of the filter shows the mutate plugin which enables you to mutate fields. You can remove, rename, replace or modify fields in events. mutate { remove_field => [ "log_timestamp"]
There are several shippers available that move events to Logstash. Logstash itself can also be used as a shipper. As Logstash runs with a footprint that is not friendly to under provisioned systems, several alternatives were created that have a smaller footprint, for example, the earlier mentioned Logstash-forwarder. Other alternatives are Beaver (written in Python) and Woodchuck (written in Ruby). I will be using Logstash-forwarder as I develop a lot of software that has to run on Windows. Logstash-forwarder is developed in Go and as such can be compiled and run on Windows.
}
Here we remove the log_timestamp field because we don’t need it anymore as it already converted into a timestamp. As the log event is now parsed and has a timestamp it is time to move it to the output.
Currently there is no binary distribution of Logstash-forwarder, therefore to use it you have to compile it first. Instructions can be found at https://github.com/elasticsearch/logstash-forwarder. As you may recall the input filter of Logstash used the lumberjack plugin to receive events from the logstash-forwarder. input { lumberjack {
Output In the output we specify a single output plugin. The elasticsearch plugin is obviously used for sending the event to Elasticsearch.
port => 6379 type => "IISLogs" ssl_certificate => "/home/azureuser/logstash.crt"
output {
ssl_key => "/home/azureuser/logstash.key"
elasticsearch { }
} }
}
We are using port 6379 for the lumberjack input. To be able to send the log events securely to the server we need a certificate. This can be a self-signed certificate or a real certificate. I will be generating and using a self-signed certificate. I used the openssl command line to generate the self-signed certificate on the Ubuntu server. We generate a private key and certificate with the following command. $ openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout logstash.key -out logstash.crt
Fig. 6: Shippers move events to Logstash
The self-signed certificate needs several types of information to put into the certificate. The only thing that is important is the Common Name, this must be set to the fully qualified domain name of the logstash server.
magazine voor software development 27
GENERAL
After the self-signed certificate is created, you have to copy the logstash.key and the logstash.crt files from the Unbuntu server to the folder on the machine that contains the logstash-forwarder. Creating the logstash-forwarder configuration file Before we can start the logstash-forwarder we have to create a configuration file that instructs the forwarder where to get the log event from and where to send them. Below a configuration file called logstash-forwarder.conf I use on a machine to send IIS logs to my central logstash server.
The logstash-forwarder will monitor the folder for new or added logfiles and will send them to the logstash server. To run logstashforwarder in the background as a Windows service, we have to convert it into a Windows service. This can be done using NSSM (the Non-Sucking Service Manager) from http://nssm.cc/ Filtering events using Kibana After we got the event flowing into the server, we can visualize the events using Kibana. With Kibana you can create and save custom dashboards. The default installation already contains a dashboard which is configured for Logstash as can be seen in Figure 8.
{ "network": { "servers": [ "elkstack.cloudapp.net:6379" ], "ssl ca": "Logstash.crt" }, "files": [ {
The default Logstash dashboard contains a graph which counts the number of events over time and includes a search field which allows you to search on free text or search in specific fields. The functionality of Kibana deserves a separate article on its own. There are multiple ways to create graphs, combine geo-ip data and filters.
"paths": [ " C:\\inetpub\\logs\\LogFiles\\W3SVC1\\*.log" ], "type": ["IISLogs"] } ] }
It specifies under network which certificate to use and to what server the logs should be sent The files parameter specifies which paths and pattern should be used to search the log files. Pay special interest to using the double backslash on Windows as a folder separator. Before starting the logstash forwarder I have to add another end point to my Azure virtual machine to let Logstash connect to port 6379.
Fig. 9: Kibana extended dashboard Scaling the ELK stack As we are going to expand our system to receive and group more logs, the single Logstash server that we are currently using won’t be sufficient. We have to scale our architecture. Current it looks like Figure 8.
Fig. 7: Specific end point for Lumberjack
Fig. 10: Current Architecture The first thing we can scale is the Broker. Broker is the part that receives the log events. Currently we are using the message buffer from Logstash. A good way to scale the broker is to use Redis on a separate server to acts as a broker. Redis is a popular open source key value storage. Logstash includes plugins for using Redis.
Fig. 8: Default Logstash dashboard in Kibana The Logstash forwarder can now be started with the following command. C:\lgf> logstash-forwarder.exe -config=logstash-forwarder.conf
28
MAGAZINE
Redis is a popular open source key value storage To increase the throughput of the Indexer, we could also separate Logstash from Elasticsearch. So the new architecture looks like
GENERAL
The protocol that Logstash-forwarder uses includes compression, encryption and message acknowledgement, which Redis does not support. There are alternative shippers which do, such as beaver and woodchuck.
Fig. 11: Scaled Architecture
Elasticsearch can be scaled by adding new Elasticsearch nodes to the cluster If we switch to using Logstash as a shipper we could configure it using the following output filter in which the events are sent to one of the two configured Redis servers. output { redis { host => ["redis-server1:6379", "redis-server2:6380"] } }
Fig. 12: Horizontally Scaled Architecture This architecture can be scale horizontally very easily. We can add more Redis servers to increase the queue capacity, we can add more Logstash server to increase indexing capacity and add more nodes to the Elasticsearch cluster to increase the performance of querying and filtering of data. A first step into scaling horizontally looks like Figure 10. By cross connecting both Redis servers and the Logstash indexer we also create redundancy and fault tolerance between the systems. The shippers also can connect to both Redis servers so that if one of the servers goes down, a shipper is still able to send its events. Elasticsearch can be scaled by adding new Elasticsearch nodes to the Elasticsearch cluster. It will automatically detect and distribute data over the available nodes. Configuring the Scaled Architecture To configure the horizontally scaled ELK stack we need to make some changes to the configuration files. The Logstash configuration file on both indexers needs to change. We use the Redis plugin to get the input from both Redis servers. input { redis {
Conclusion In this article I showed how to install and configure the ELK stack in such a way that enables transfering application logs from a Windows machine using logstash-forwarder to the machine that hosts the ELK stack. The host parses the application logs using Logstash, indexes the logs using Elasticsearch and allows visualizing hem using Kibana. By combining the logs from all your services and applications you can improve the traceability of your IT system. All your logs become searchable in almost real-time. By parsing extra information using Logstash per application you could give more meaning to your existing logs without having to go through all the logs individually. To scale out the ELK stack, Redis servers can be added together with separate Logstash servers. Scaling Elasticsearch is as easy as adding nodes to the cluster. The easy way the ELK stack can be scaled horizontally really shows the strength of the platform. This article barely scratched the surface of what you can do with the ELK stack. Topics I did not cover but are very interesting are security, creating dashboards with Kibana, adding semantics to log events, alerting, exporting and creating your own Logstash plugins. Other alternative platforms for log aggregation that you should consider when evaluating a log aggregation platform are Splunk, Sumologic and Scribe. •
host => "redis-server1" port => 6379 data_type => "list" key => "logstash"
Patrick Kalkman
} redis { host => "redis-server2" port => 6380 data_type => "list"
Patrick Kalkman is a software architect at HintTech where he designs and implements state of the art web applications using an agile proces.
key => "logstash" } }
Currently Logstash-forwarder does not support connecting to Redis.
magazine voor software development 29
SQL
Peter ter Braake
SQL Server In-Memory OLTP 2014 was het jaar van de release van SQL Server 2014. Nog meer dan dat was het het jaar van de release van tientallen nieuwe cloud services. Dit artikel gaat (een keer) niet over de cloud of over Azure. Dit artikel gaat over een nieuwe revolutionaire engine die volledig is geïntegreerd in SQL Server: Hekaton! Hekaton Hekaton was de code naam voor de In-Memory engine van SQL Server. Hekaton komt uit het Grieks en verwijst naar de ambitie van Microsoft om SQL Server honderd keer zo snel te maken. Honderd keer! Honderd keer is bij lange na niet gehaald, maar de resultaten zijn ondanks dat meer dan indrukwekkend. Hekaton, ofwel memory optimized tabellen, is één van de vele nieuwe in-memory features. De database engine van SQL Server is in de kern alle ruim twintig jaar oud. Veel designkeuzes zijn dus ook al meer dan twintig jaar geleden gemaakt. Weet u nog met welke computer u twintig jaar geleden werkte? De hardware van toen was ontzettend beperkt ten opzichte van de huidige hardware. Voornamelijk de hoeveelheid geheugen die we tegenwoordig met 64-bits computers kunnen is drastisch toegenomen. Tegelijkertijd is de prijs gekelderd zodat ook iedereen zich dat geheugen kan permitteren. Door de dure en beperkte hoeveelheid geheugen van toen is SQL Server een file-based database. Hoewel de engine zoveel mogelijk gebruik maakt van geheugen middels de buffer pool, is het uitgangspunt dat de gegevens op disk staan. De datafiles op disk waar de gegevens in opgeslagen worden, zijn opgedeeld in blokken van 8 KB, de pages. Ook in het geheugen zitten de records nog steeds opgeslagen op die pages. Latches Hoewel het concept van pages een optimalisatie betekende voor filebased databases, levert het ook beperkingen op. Op het moment dat SQL Server een nieuw record moet wegschrijven, of dat een bestaand record gewijzigd moet worden, bestaat er de kans dat records over elkaars ruimte heen schrijven. Dat zou inconsistenties (corruptie) veroorzaken. Daartegen moet SQL Server ons beschermen.
werken. Als er maar één proces actief is in uw database, is dat geen probleem. Maar hoe meer cores u heeft, hoe meer processen tegelijkertijd actief zijn. Dat houdt in dat de kans dat een proces moet wachten op een ander proces steeds groter wordt. Wachtende processen is wat mensen ervaren als slechte performance. In het screenshot van figuur 1 ziet u het aantal transacties per seconde in een voorbeeld applicatie van Microsoft. In dit voorbeeld zijn dat 520 transacties per seconde. Opvallend is het CPU verbruik van nog geen 50%. Meer CPU’s gaat waarschijnlijk niet helpen om meer transacties te verwerken. Tweede opvallende feit is het aantal latches per seconde. Die latches kosten overhead in het systeem en veroorzaken wachttijden bij andere user processen. Daar zit de grote bottleneck. Memory optimized tables Met Memory optimized tables draait Microsoft het uitgangspunt van SQL Server om. Gegevens zitten in principe in het geheugen. Uiteraard moet alle data uiteindelijk ‘landen’ op disk, anders bent u die data kwijt. Memory optimized tables zijn wat in theorie genoemd wordt: fully durable. Dat wil zeggen dat als een transactie succesvol is afgerond, de gegevens gegarandeerd in de database zitten en niet meer kwijt kunnen raken. Gegevens worden dus weggeschreven naar disk, maar het uitgangspunt is dat de gegevens in het geheugen zitten. Daarvoor wordt geoptimaliseerd.
Memory optimized tables omgekeerd uitgangspunt van SQL Server; Memory first then disk Omdat gegevens worden opgeslagen in geheugen is het concept van pages niet langer nodig. Een record zit in geheugen op een willekeurige plek die toevallig vrij was toen het geschreven werd. Omdat een record niet op een pagina staat, hoeft er ook geen latch te zijn om per ongeluk overschrijven van gegevens te voorkomen. Zonder latches zijn er ook geen processen die moeten wachten op latches. En minder wachtende processen is betere benutting van de beschikbare CPU’s, is betere performance.
Fig. 1 De bescherming die SQL Server biedt wordt een latch genoemd. Latches worden vaak uitgelegd als zijnde light-weight locks. Maar nu weet u nog niet veel meer. Als een proces begint met schrijven, wordt de hele pagina geblokkeerd voor dat proces. Totdat het proces klaar is met schrijven, kunnen andere processen niet met die pagina
30
MAGAZINE
Locks Pagina’s worden beschermd met latches, records worden beschermd door middel van locks. Naast het feit dat twee processen op dezelfde pagina moeten zijn, kan het ook voorkomen dat ze met hetzelfde record werken. Locks voorkomen problemen door één van de processen te laten wachten. Memory optimized tabellen hanteren een lock and latch free mechanisme. Of in een moeilijk woord: optimistic multi version concurrency control. Een record wordt eigenlijk nooit meer gewijzigd. Een record wordt simpelweg met een timestamp
SQL
gemarkeerd als oud en er wordt een nieuw record aangemaakt. Twee processen die tegelijkertijd met een record werken krijgen allebei hun eigen versie van het record.
Dat is niet meteen vanzelfsprekend. De CREATE TABLE ziet er als volgt uit. CREATE TABLE Sales.SalesOrderDetailHashOnly
Natively compiled stored procedures Zonder locks en latches wordt een grote performance bottleneck weggenomen. Maar valt er nog meer te winnen? Zonder locks and latches wordt de CPU voor 100% gebruikt in de voorbeeldapplicatie van figuur 1. SQL Server zou eigenlijk in staat moeten zijn om met dezelfde hoeveelheid CPU cycles, meer werk te doen. Dat is precies wat u bereikt met natively compiled stored procedures. Tijdens de CREATE van deze stored procedures worden deze gecompileerd tot een C-dll. Deze vooraf gecompileerde code is veel beter geoptimaliseerd dan interpreted T-SQL en daardoor veel sneller. Natively compiled stored procedures kunnen nog niet de volledige SQL functionaliteit gebruiken. Niet alle data types worden ondersteund, niet alle functies worden ondersteund. Bovendien kunt u met een natively compiled stored procedure alleen werken met memory optimized tables, niet met klassieke file based tables. Andersom kan wel. Met Query interop wordt bedoeld dat u met gewoon SQL zowel gewone tabellen als memory optimized tables kunt benaderen. Alles bij elkaar krijgt u een architectuur zoals in figuur 2.
( [SalesOrderID] [int] NOT NULL, [SalesOrderDetailID] [int] NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT=200000), [CarrierTrackingNumber] [nvarchar](25) NULL, [OrderQty] [smallint] NOT NULL, [ProductID] [int] NOT NULL INDEX IXH_ProductID NONCLUSTERED HASH WITH (BUCKET_COUNT=300), [SpecialOfferID] [int] NOT NULL, [UnitPrice] [money] NOT NULL, [UnitPriceDiscount] [money] NOT NULL CONSTRAINT [DF_SalesOrderDetail_UnitPriceDiscount]
DEFAULT ((0.0)),
[LineTotal] [money], [rowguid] [uniqueidentifier] NOT NULL CONSTRAINT [DF_SalesOrderDetail_rowguid]
DEFAULT (newid()),
[ModifiedDate] [datetime] NOT NULL CONSTRAINT [DF_SalesOrderDetail_ModifiedDate]
DEFAULT (getdate())
) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);
Het goede nieuws is dat dit hoofdzakelijk is wat u gewent bent. Let vooral op de inline indexen en de bucket count bij de hash indexen. Verder valt op dat het statement eindigt met MEMORY_OPTIMIZED = ON en DURABILITY = SCHEMA_AND_DATA. Voor durability zijn er twee opties: schema_and_data en schema_only. Met die laatste zitten de gegevens alleen in memory, nooit op disk. Bij een server herstart bent u dus alle gegevens kwijt. Voor situaties als state van een website of staging tabellen bij ETL kan dat grote voordelen hebben. Bij het maken van een natively compiled stored procedure komt net iets meer nieuwe kennis kijken. De code begint altijd als volgt: CREATE PROCEDURE usp_InsertOrderMemoryOptimized @SalesOrderID int, @SalesOrderDetailID int, @OrderQty smal-
Fig. 2
lint, @ProductID int WITH
Impact voor de programmeur Dit klinkt allemaal fantastisch, maar waarom dat verhaal in het Developers Magazine? Helaas is memory optimized tables geen feature die je aan of uit zet en die zonder verdere aanpassingen voordeel oplevert. De programmeur zal in zijn of haar code rekening moeten houden met de feature. Allereerst zijn er enkele zaken om over na te denken bij het maken van de tabel.
Memory optimized tables een Developers taak Een memory optimized tabel kent geen ALTER TABLE. Van een tabel wordt, net als een natively compiled stored procedure, tijdens de CREATE een dll gemaakt. De enige manier om die aan te passen is hem weggooien om hem daarna opnieuw aan te maken. Dit klinkt misschien nog wel overkomelijk, maar geldt ook voor indexen. Ook indexen kunnen niet later aangemaakt worden of verandert worden. Memory optimized tabellen kennen twee soorten indexen, hash indexes en range indexes. Beide worden tijdens de CREATE TABLE al gedefinieerd. Bij de hash index moet u opgeven uit hoeveel hash buckets de index bestaat. De vuistregel is dat u ongeveer twee keer zoveel hashbuckets maakt als dat u unieke waarden in de te indexeren kolom heeft. Maar u moet wel vooraf een keuze maken.
NATIVE_COMPILATION , SCHEMABINDING , EXECUTE AS OWNER
AS BEGIN ATOMIC WITH ( TRANSACTION ISOLATION LEVEL = SNAPSHOT , LANGUAGE = 'us_english' , DELAYED_DURABILITY = OFF)
Het eerste dat opvalt, is de optie WITH NATIVE_COMPILATION. Die optie heeft geen verdere uitleg nodig. Omdat er een dll gemaakt wordt is de optie SCHEMABINDING verplicht. Verder is het verplicht een execution context te bepalen, de owner in dit voorbeeld. Vervolgens begint u altijd met de clausule BEGIN ATOMIC BLOCK. Zoals gezegd gaat memory optimized uit van optimistic multi version concurrency control. Dat houdt in dat er niet vooraf door middel van locks beschermd wordt tegen concurrency problemen. Iedereen werkt met zijn eigen versie van de records. Op het moment dat u uw transactie commit, wordt pas gekeken of uw versie wel commitbaar is. Het kan zijn dat iemand anders u voor is geweest en al een wijziging heeft doorgevoerd. U krijgt dan een foutmelding. Error handling code is dus van essentieel belang binnen uw stored procedure. Gelukkig kent T-SQL TRY … CATCH en sinds SQL Server 2012 ook THROW. Uw stored procedure is altijd een atomic block, ofwel een transactie. lees verder op pagina 35 >
magazine voor software development 31
SCRUM
Piet Willem Overvoorde
SCRUM is veel meer dan een project management methodologie Dat is zonder meer waar en een methodologie die, mits die op de goede manier wordt gebruikt, heel goed toepasbaar is op allerlei soorten projecten. Dus het gebruik ervan is zeker niet beperkt tot ICT (gerelateerde) ontwikkelingen. Scrum is prima toepasbaar bij complexe producten (eindproduct is moeilijk vooraf tot in detail te beschrijven) en bij complexe organisaties (veel stakeholders). De uitdaging (opdracht) is om de effecten van het werken op basis van SCRUM te delen met de organisatie met het doel als collectief nog effectiever en efficiënter samen te werken. Belangrijke kernmerken van SCRUM zijn: • Eenduidig interpreteerbare werk- en projectafspraken; • Op basis van geplande evaluatie momenten continue aandacht voor opzet en inhoud van de werkzaamheden; maar aan gemaakte afspraken wordt niet getoornd; • Korte, afgeronde werkzaamheden; • Geen ad-hoc interventies; • Team prestatie is bepalend (zelfsturende en zelflerende organisatie); • Continue aandacht voor de kwaliteit van het door alle betrokken partijen geleverde product; • Rust en duidelijkheid in het project en in het proces.
SCRUM is veel breder toepasbaar Overal waar er sprake is van een opdrachtgever en van het halen van financiële, inhoudelijke- en planningsdoelstellingen is SCRUM toepasbaar. Inderdaad niet altijd in de meest zuivere vorm maar wel als handvat voor het maken van afspraken en het opvolgen en managen hiervan. Als het eindproduct vast staat, heeft SCRUM geen toegevoegde waarde. Als voorbeeld de auto: het ontwikkelen kan met scrum, het produceren van de auto bijvoorbeeld met lean. Wanneer je de hiervoor beschreven kenmerken van SCRUM nog een keer doorneemt en projecteert op de dagelijkse werkelijkheid van
32
MAGAZINE
bijvoorbeeld de samenwerking tussen sales en delivery in verkoop en implementatie trajecten dan blijkt dat deze aanpak zonder meer ook hierop prima toepasbaar is.
SCRUM leidt tot verbeterd begrip tussen de verschillende bloedgroepen binnen een organisatie Waarom het SCRUM gedachtengoed als basis voor het beheer van processen? De voordelen van het gebruik van (een variant) van SCRUM in sales processen zijn onder andere: • Duidelijke afspraken tussen alle deelnemers (sales, pre-sales, delivery/operations, prospect, adviseur etc.); • Heldere lijnen voor het managen van het proces; • Alle deelnemers worden ‘gedwongen’ vooraf heel goed nagedacht te hebben; • Voor en bij het afsluiten van het contract zijn alle relevante partijen betrokken geweest. Naast een eenvoudiger en succesvoller beheer van de genoemde voorbeeld processen leidt een breder gebruik van (de uitgangspunten van) SCRUM ook tot een verbeterd begrip, over en weer, tussen de verschillende bloedgroepen binnen een organisatie. De zaken waarmee sales, project management, consultancy en ontwikkeling dagelijks te maken hebben in hun ‘eigen wereld’ worden binnen het team gedeeld. Het team is verantwoordelijk voor het realiseren van de doelstellingen en niemand kan zich achter de performance van een ander verschuilen. Een andere, meer effectieve en resultaatgerichte vorm van samenwerking De eerder in dit stuk genoemde rust en duidelijkheid komen, wanneer deze manier van werken effectief is geïmplementeerd, iedereen ten goede. Ad hoc vragen en interventies van collega’s en zeker ook van managers mogen in principe niet meer voorkomen.
SCRUM
Ieder lid van het team moet acteren als eigenaar en verantwoordelijke voor het eindresultaat (overall en van een sprint). En in die rol wil je zaken niet over hoeven doen omdat de WAT vraag niet voldoende is uitgevraagd. Of het antwoord op de HOE vraag niet op de beste manier is afgestemd en geformuleerd. SCRUM kan in een bepaalde vorm worden toegepast voor de beheersing van andere processen. Maar de volgende zaken kunnen zonder meer organisatie breed worden geadopteerd: • Het benoemen van de doelstelling(en)/het product van de samenwerking, de WAT vraag; • Het definiëren van sprints/stappen waarbinnen het antwoord op de HOE vraag vorm moet krijgen (of deze allemaal van een gelijke duur moeten en kunnen zijn is sterk afhankelijk van het project en de hierin onderkende stappen; het verzorgen van een demo kost bijvoorbeeld minder tijd dan het beantwoorden van een RFI of RFP); • Het toekennen van duidelijke taken en verantwoordelijkheden aan de Product Owner, de SCRUM Master (of de procesbeheerder) en het team (of de teams, wanneer die per sprint verschillend zouden zijn; dit laatste is een concreet verschil tussen SCRUM in de zuivere vorm als project management tool (vooral gebruikt binnen de ontwikkeling van softwarematige toepassingen) en de SCRUM methodologie als kapstok voor het managen van andere soorten projecten/activiteiten); • Gebruik maken van de praktische hulpmiddelen zoals de rol van de SCRUM Master, de dagelijkse afstemming/update, het SCRUM bord (met alles dat daar deel vanuit maakt) en de pokerkaarten; • En na afloop een integrale evaluatie van de kennis en ervaring die vanuit het project kan worden meegenomen en ingezet om toekomstige projecten nog beter te laten verlopen.
bedrijfsprocessen. Combinaties van allerhande, technische en functioneel, rol/ functie gerichte, tools. Dat is nu ook mogelijk omdat het koppelen van oplossingen en het synchroniseren van databases veel eenvoudiger is geworden. Door de focus van alle betrokken partijen is de kans groot dat een investering een veel meer toekomstbestendige blijkt te zijn. De behoefte aan het eenvoudig kunnen delen van informatie zal ook verder toe gaan nemen.
De samenwerking is gebaseerd op onderling vertrouwen De ontwikkeling die hiervoor is beschreven met betrekking tot ICT oplossingen geldt ook voor heel veel andere soorten projecten. Steeds meer is er sprake van virtuele, project specifieke, teams van professionals die het afgesproken resultaat tot stand moeten brengen. Het gebruik van een erkende en gestandaardiseerde project aanpak biedt dan uitkomst. En voorkomt allerhande spraakverwarring met betrekking tot verwachtingen, communicatie, voortgangsrapportage etc. Het is om die reden dat het aantal online SCRUM ondersteunende tools zeker toe zal nemen in de komende periode. Gaat die samenwerking vanzelf en gelijk goed? Het is voor medewerkers en managers wennen wanneer SCRUM breed in de onderneming wordt geïntroduceerd. De hiervoor zo benoemde verschillende bloedgroepen binnen een organisatie, sales, consultants, ontwikkelaars, project leiders en managers, zullen stuk voor stuk het gevoel kunnen hebben dat anderen in hun domein ‘binnen dringen’. Dat is natuurlijk ook zo, maar erg is anders! De samenwerking moet worden gebaseerd op een oprecht onderling vertrouwen: gemaakte afspraken moeten gestand worden gedaan. En als daar reden voor is dan worden zorgen en aandachtspunten tijdig onderkend en gedeeld. Een heel groot voordeel voor de betrokken managers is dat zij hun eigenlijke rol en opdracht inhoud kunnen geven. Het succes moet zijn gebaseerd op het op deze manier WILLEN werken. En iedereen beperkt zich in dit geval niet tot de interne organisatie. Binnen de teams zullen ook partners, prospects en klanten actief zijn. Het is goed om de introductie van deze werkwijze op te pakken samen met een of meerdere bestaande klanten en partners.
Een andere vorm van samenwerking is noodzakelijk We zitten in de eindigende periode dat alles binnen dezelfde zogenaamde ERP oplossing moet kunnen worden opgelost. Op basis van de standaard set aan functionaliteiten gecombineerd met branche specifieke modules en maatwerk. Initieel is dit zonder meer een goede gedachte. De ervaring heeft geleerd dat er in de loop van de tijd vaak sprake is van a-synchronisatie tussen de ondersteunde versies van applicaties, besturingssystemen, ontwikkelomgevingen en databases. Dit heeft te maken met de periodieke heroverweging met betrekking tot branchefocus en de wil en mogelijkheid om in een ontwikkeling te blijven investeren. De wil wordt o.a. bepaald door de kans op een redelijk rendement. Er zal gebruik gemaakt gaan worden van ‘best of breed’ oplossingen als basis voor de ondersteuning van alle voor een organisatie relevante
Is dit de basis voor het succes van ieder project? Nee! Hoe goed een project aanpak ook is, het team bepaalt het succes. Ook in sectoren waar er sprake is van strikte regels en procedures, zoals in de luchtvaart, de gezondheidszorg en de off shore, gaan er dingen mis. Maar oorzaken worden snel achterhaald. En de nodige maatregelen snel genomen. Wanneer het aantal variabelen toeneemt, neemt de behoefte aan duidelijke afspraken en kortlopende trajecten toe. Korte, overzichtelijke trajecten waardoor de risico’s tot een minimum worden beperkt worden steeds meer geëist door de klant. En dat is de basis van SCRUM. Dingen opnieuw doen is vaak mogelijk. Maar werkzaamheden over-/anders doen is altijd kosten¬verhogend, marge verlagend en reputatie schadend. De implementatie Voor iedere verandering die wordt doorgevoerd geldt dat deze gaande het proces en mede op basis van de input van alle betrokkenen vorm moet krijgen. Een heel groot voordeel van de introductie van SCRUM als uitgangspunt voor de vormgeving van de samenwerking is dat vanaf het prille begin op deze manier gewerkt kan, beter zal worden.
magazine voor software development 33
SCRUM
Daardoor worden stap voor stap meer mensen hiermee bekend en groeit het vertrouwen dat dit inderdaad een positieve bijdrage zal gaan leveren. Naast het organiseren van allerhande praktische zaken moet in dit proces de ‘menselijke’ kant zeker niet worden onderschat en vergeten. Diverse rollen binnen de organisatie zullen een ander karakter krijgen. Dit vraagt aanpassing van het dagelijkse doen en laten.
Zoals eerder gememoreerd is het ontwikkelen van een authentiek onderling vertrouwen een heel belangrijk aspect. Naast een goede uitwerking van de praktische aspecten en tools is een goede, professionele begeleiding op het ‘menselijke’ vlak zonder meer noodzakelijk.
Is dit alles nieuw en innoverend? Nee, bijna altijd is er voor elk proces een projecten procesaanpak aanwezig. Gedreven vanuit de primaire behoeften van de ‘bloedgroep’. Ja, want heel weinig organisaties gebruiken, om een veelheid aan (historische) redenen, voor alle aanwezige processen dezelfde uitgangspunten en werk¬methodiek. Een praktische voorbeeld: de opvolging van een RFI/RFP Zoals hiervoor is beschreven is het zeker niet het primaire doel om SCRUM in de meest zuivere vorm toe te willen passen. Wel wordt zoveel als mogelijk gebruik gemaakt van praktische handvatten die de methodologie biedt om processen op basis van heldere en eenduidige uitgangspunten professioneel en maximaal effectief en efficiënt te organiseren en realiseren. Opmerkingen als ‘dat wist ik niet’, ‘Maar wat nu als we toch/alsnog op basis van deze oplossing aanbieden ….’ en ‘o, ik dacht dat …’ worden hiermee voorkomen. Door het team worden tenslotte voor in ieder geval een bepaalde periode (sprint) afspraken gemaakt op basis waarvan gewerkt wordt. De basis motivatie voor deze benadering is het creëren en behouden van het bewustzijn dat iedereen binnen een organisatie een rol kan spelen in de positieve afronding van projecten.
De beoordeling van de medewerkers moet primair gericht zijn op de realisatie van (collectieve) lange(re) termijn doelstellingen. Wanneer persoonlijke belangen (beloning, prestige, kans op promotie etc.) de boventoon voeren in het besluit onderdeel te willen zijn van bepaalde projecten dan zal deze methodiek nagenoeg zeker haar doel niet bereiken.
Globaal kunnen in het proces van opvolging van een RFI/RFP de volgende fases worden onderscheiden: • Initiële evaluatie van de aanvraag; • Beantwoording van de functionele en technische vragen; • Oplevering van de documentatie; • Presentatie van de organisatie, de oplossing en het voorstel; • Proces om te komen tot een overeenkomst; • Realisatie van het project; • Doorontwikkeling van de relatie.
Het management moet er klaar voor zijn of klaar voor gestoomd willen worden. Zo nodig ondersteund door een vorm van professionele inhoudelijke en persoonlijke coaching. Het commitment van alle managers is een essentiële bouwsteen van een succesvolle implementatie.
Fase ‘0’van het project In deze fase worden onder andere de ‘opdrachtgever’ en de (potentiële) teamleden, eventueel per onderdeel/fase, bepaald. In vervolg hierop worden in de eerste samenwerking tussen opdrachtgever en team de hoofdfases benoemd.
SCRUM binnen organisaties levert voordelen op Conclusie De introductie van een op de uitgangspunten van SCRUM gebaseerde samenwerking tussen alle bij een organisatie betrokken partijen biedt eigenlijk alleen maar voordelen. Mits dit proces vanaf het begin op een goede en professionele manier is gemanaged. • Duidelijkheid in doelstellingen, werkwijze, taken en verantwoordelijkheden; • Substantiële verbetering van de juistheid van het antwoord op de vraag WAT er wordt verwacht; • Een duidelijke kwaliteitsverbetering van het antwoord op de HOE vraag; • Efficiency verbetering op vele fronten, bezig zijn met de juiste dingen; • Verbetering en verduurzaming van de relatie en samenwerking met klanten en partners; • Versterking en verdieping van het onderlinge begrip en vertrouwen en daarmee de teamgeest. Kortom: zeker het overwegen waard!
34
MAGAZINE
Handvatten na Fase ‘0’ Geen RFI/RFP is hetzelfde en er wordt steeds meer op basis van business cases gewerkt in plaats van (of in combinatie met) lijsten met technische en functionele eisen en wensen. Hierdoor wordt het steeds belangrijker goed in staat te zijn om vat te krijgen op de werkelijke vraagstelling. Naast de standaard acties zoals het in kaart brengen van het beslistraject en de hierbij (in)direct betrokkenen. De WAT vraag bestaat in deze fase uit de volgende elementen (basis voor het definiëren van de sprints in deze fase): • WAT is de werkelijke behoefte van de prospect nu en in de toekomst; • WAT zijn de werkelijke technische en inhoudelijke wensen en eisen;
SCRUM
• WAT is de planning van het voortraject en de realisatie; • WAT zijn de argumenten om deze RFI/RFP in te vullen; • WAT kunnen wij bieden dat ons bijzonder maakt en onze kansen maximaliseert; • WAT moeten wij doen om dit project tot een succes te maken; • WAT ….. Op basis van de lijst (inderdaad er is geen enkelvoudige WAT vraag in deze toepassing te benoemen) met WAT vragen moet het antwoord worden gegeven op de HOE vragen die niet zonder meer vanuit de beschikbare documentatie kan worden beantwoord: • HOE gaan we de werkelijk behoeften, wensen en eisen in kaart brengen; • HOE brengen we de beslissers, beïnvloeders etc. in kaart; • HOE gaan we de beantwoording inhoudelijk en wat betreft presentatie vormgeven; • HOE (op basis van welke oplossingen, met welke partners, etc.) geven we technisch en functioneel het beste invulling aan hetgeen in de RFI/RFP is beschreven • …….. Alle vragen worden gesteld en beantwoord binnen een team. Daarbij wordt van iedereen verwacht dat die zich open en kwetsbaar opstelt. Wat voorheen vaak binnen de comfortzone van een afdeling werd besproken wordt nu gedeeld, beoordeeld en daarmee verrijkt. Door het toevoegen van de input en invloed vanuit andere perspectieven vindt er op meerdere manieren en diverse fronten een verbetering plaats die bijdraagt aan de kwaliteit en de uitkomst van het project. Waar de antwoorden op deze vragen bij het ‘reguliere’ gebruik van SCRUM in de methodologie zijn ingebakken moeten deze bij het beoogde bredere gebruik van deze aanpak specifiek worden beantwoord: • Op basis van de antwoorden op de HOE vragen zal het antwoord op de WIE vragen moeten gegeven. WIE (welk TEAM) maakt zich verantwoordelijk voor welke onderdeel. In tegenstelling tot SCRUM in de zuiver vorm zal er naar verwachting sprake zijn van een wisselende samenstelling van de teams.
• Tenslotte moet het antwoord worden gegeven op de WANNEER vragen. Wanneer moet welke ‘sprint’ zijn afgerond en hoe wordt de (continue) evaluatie vorm gegeven. In tegenstelling tot SCRUM in de zuivere vorm zullen ‘sprints’ in deze toepassing per stuk in lengte kunnen variëren.Voor het managen van het proces is het logisch om een SCRUM Master in te zetten. Maar wel een die begrip heeft voor de wijze waarop het SCRUM gedachtengoed in het project wordt gebruikt. Een groot voordeel van het inzetten van een SCRUM Master is ook dat de overgang van bijvoorbeeld de sales naar de delivery organisatie en vervolgens de uitvoering van het project nog makkelijker zal verlopen. En op het gewenste kwaliteitsniveau. De borging van alle aspecten die nodig zijn voor een succesvol verloop van het project zijn tenslotte door de SCRUM Master geborgd. •
Pietwillem Overvoorde Pietwillem Overvoorde (1964) heeft in de loop van de tijd nagenoeg alle mogelijke rollen vervuld binnen (inter)nationale ICT projecten. Software ontwikkeling, business consultancy, project management, business development, sales- en accountmanagement maken deel uit van zijn CV. Bij zijn werkgever, Yellowstar Solutions (www.yellowstarsolutions.nl), wordt SCRUM sinds de oprichting toegepast in alle processen. Voor bijna alle activiteiten geldt: geen lange vergaderingen maar korte, effectieve stand-ups. De zelfsturende teams zijn verantwoordelijk voor het resultaat. In deze manier van werken zijn ook medewerkers van klanten betrokken. Vaak gaat dit in de eerste fase van samenwerking gepaard met een gewenningsproces; iets waarin de medewerkers van Yellowstar coachend optreden. De praktijk heeft geleerd dat het kort op de bal spelen voor alle betrokken partijen zeer effectief is.
vervolg van pagina 31 > Scenario’s De feature heet niet voor niets in-memory OLTP. SQL Server kent sinds SQL Server 2012 de zogenaamde ColumnStore index. Dit is een feature die ook valt in de range in-memory features. ColumnStore is specifiek voor datawarehouse queries. Memory optimized tables heel specifiek niet. Als u een workload heeft met veel schrijven, en als de transactie throughput wordt beperkt door locking and latching, dan kunnen memory optimized tables uitkomst bieden. Zoals gezegd is het uitgangspunt waar gegevens leven anders (geheugen in plaats van disk). Nog belangrijker is dat het programmeermodel anders is. Van pessimistic concurrency met locking gaat u over op optimistic concurrency met versioning. Dat vergt een andere opbouw van uw code. Een tweede scenario zijn de tabellen met durability op SCHEMA_ONLY. Gegevens in een database die kwijt kunnen raken? Eigenlijk een soort temp tables dus, maar dan zonder de overhead van IO on TempDB. Conclusie Dit artikel is slechts een high level overview van memory optimized tabellen. De belangrijkste take-away is dat er een ongelofelijke
perfomance winst valt te halen. Maar die winst is er alleen in heel specifieke situaties. En een nieuw concurrency model vergt waarschijnlijk wat aanpassingen aan uw code. •
Peter ter Braake Peter ter Braake is sinds de zomer van 2008 zelfstandig trainer / consultant / MVP op het gebied van SQL Server. Ik verzorg voor klanten database en Business Intelligence trainingen. Tevens doe ik korte projecten in dezelfde aandachtsgebieden. In 2005 heb ik met een aantal mensen PASS Nederland opgericht. PASS is de gebruikersgroep voor SQL Server. Ik ben daar momenteel vice-voorzitter en verantwoordelijk voor de events die PASS organiseert.
magazine voor software development 35
DELPHI
Cary Jensen
Delphi's REST Debugger and REST Client Library, Part 1 At SDN's Software Development Conference in Papendal this December I presented a session on DataSnap and REST using FireDAC. In that presentation I demonstrated a DataSnap server that used FireDAC FDMemTables to create special data streams that could be delivered to client applications written in Delphi, and from which specialized streams containing a user's updates to the data could be returned. Importantly, the client/server communication made use of HTTP (hypertext transfer protocol) requests and JSON (JavaScript Object Notation), two elements central to a distributed application style typically referred to as REST (REpresentational State Transfer). The client application that I demonstrated made use of a TDSRESTConnection component, which was then used to import the interface of the TServerMethods class found on the DataSnap server. Much of that interface was designed to demonstrate FireDACJSONReflect, a set of classes and interfaces designed to wrap and unwrap data for use with FDMemTables in the client application. I bring up that presentation as a starting point for a discussion about REST clients, client applications that connect to data using HTTP. I am not going to get into a detailed discussion of FireDACJSONReflect, as that is just one of many possible ways to wrap data that is consumed by a REST client, and one that is somewhat limited, in that it more or less requires a Delphi client. Instead, I am going to use that server to demonstrate some of the REST-related tools that have shipped in Delphi since Delphi XE5. These include the REST Debugger and the REST Client Library But before we do that, it is necessary to first understand some features of the DataSnap server.
Here is the declaration of the TDSDataModule class, showing some of the methods exposed through this class (for the most part, I am only showing the methods that I will be calling in the clients I discuss later in this article). The methods being exposed are those found in the public section of the class declaration. type TServerMethods1 = class(TDSServerModule) CustomerQuery: TFDQuery; FDConnection1: TFDConnection; FDStanStorageBinLink1: TFDStanStorageBinLink; FDStanStorageJSONLink1: TFDStanStorageJSONLink; OrdersQuery: TFDQuery; CustomerOrdersQuery: TFDQuery; private { Private declarations } public
The DataSnap Server Methods exposed by a REST-based DataSnap server are those methods associated with the TServerMethods class. When you use the DataSnap Server wizard from the Object Repository, you have the option of creating this class as a TComponent, a TDataModule, or a TDSDataModule. So long as you are not using the server to expose TDataSetProviders, it really doesn't matter which one you pick. Personally, I prefer either the TDataModule or TDSDataModule options, as they provide a design surface on which to place components. If your DataSnap server is data-aware, as this one is, these components will be associated with connecting to a database and executing queries. Figure 1 shows how my DataSnap server methods data module looks like in Delphi's designer. Note that some of the components on this data module, such as the TFDStanStorageBinLink and the TFDStanStorageJSONLink, are there to support FireDACJSON Reflect, and not necessarily required by a DataSnap REST server.
Fig. 1: The server methods data module in the designer
36
MAGAZINE
{ Public declarations } function EchoString(Value: string): string; function ReverseString(Value: string): string; function EchoStringRaw(Value: string): string; function ReverseStringRaw(Value: string): string; function GetCustomerCDSRaw: string; end;
EchoString and ReverseString are the sample methods generated by the DataSnap Server wizard, and they return a JSON result. The other methods are custom methods whose names ends with Raw. Those methods return a custom string that does not necessarily wrap the result in a JSON object.
REST = REpresentational State Transfer; JSON = JavaScript Object Notation I don't want to focus too much on the implementation of these methods, instead permitting you to learn more about them by
DELPHI
examining the source code from the download I will reference later in this article. However, permit me to show two methods: EchoString, and EchoStringRaw, so that you can see the basic difference between how Delphi's default server returns data (EchoString) and how you can take control over the returned content. function TServerMethods1.ReverseString(Value: string):
Since the path to these files must be defined before the server starts, I insert a reference to the certificate files upon creation of the data module that holds the DataSnap-enabling components. This class is referred to as the server container unit, and the relevant code is shown in the following code segment. {$DEFINE UseAuthentication}
string; begin Result := System.StrUtils.ReverseString(Value);
var AppDir: string;
end; procedure TServerContainer1.DataModuleCreate(Sender: TObfunction TServerMethods1.ReverseStringRaw(Value: string):
ject);
string;
begin AppDir := ExtractFilePath(ParamStr(0)) + 'keys\';
begin //Must use the DBXPlatform unit for GetInvocationMetadata
DSCertFiles1.CertFile := AppDir + 'MyDataSnap.pem';
GetInvocationMetadata().ResponseCode := 200;
DSCertFiles1.KeyFile := AppDir + 'MyDataSnap.key';
GetInvocationMetadata().ResponseContent :=
{$IFDEF UseAuthentication}
System.StrUtils.ReverseString(Value); end;
DSHTTPService1.AuthenticationManager := DSAuthenticationManager1; {$ENDIF} end;
GetInvocationMetadata is discussed later in this article. DataSnap Servers and Security This DataSnap server implements security through secure socket layer and, optionally, through authentication. Since both of these features impose requirements for any REST client application, permit me to spend a moment explaining this in more detail. Secure socket layer, or SSL, is implemented in DataSnap using OpenSSL. OpenSSL is an open source technology used to provide encrypted communications between a server (which is an HTTP server in this case) and an HTTP client. The HTTP client could potentially be any client, such as a Delphi application, a Web browser, or a mobile application employing JavaScript.
As you can see from this code, there is a conditional define that can be used to turn on or off authentication. This allows me to easily enabled or disable authentication, and then show how doing so affects the client applications. When authentication is turned on, the first attempt by a client to connect to the DataSnap server will be challenged for a username and password. This is handled by the OnUserAuthenticate event handler associated with the TDSAuthenticationManager component. In my simple demonstration I am only requiring the user to enter the password Delphi, as you can see from the following event handler. procedure TServerContainer1.DSAuthenticationManager1UserAu-
Note: If you are using OpenSSL on your server, you should ensure that you are using a recent version of the OpenSSL libraries (libeay32.dll and libssl32.dll). Older versions of OpenSSL contain a vunerability named heartbleed For this demonstration, I created an SSL certificate using OpenSSL. This process is described by Paweł Głowacki, Embarcadero's European Technical Lead for Delphi and RAD Studio technologies, in his blog found at: http://blogs.embarcadero.com/pawelglowacki/2013/10/16/40089. When you download and install OpenSSL, and then run the batch file provided by Pawel in his blog, you can generate a certificate that is suitable for testing, but not for deployment. In order to create a certificate for deployment, you need to purchase one from a trusted certificate authority, such as Symantec, Thawte, or GoDaddy. In order to simplify your use of the DataSnap server demo, I have included a directory containing the certificate files that I generated.
thenticate( Sender: TObject; const Protocol, Context, User, Password: string; var valid: Boolean; UserRoles: TStrings); begin valid := Password = 'Delphi'; end;
Because the primary concern of this article is about REST clients, I have described as much as I intend to about the DataSnap server. REST Clients As mentioned earlier, REST clients come in a variety of flavors. Let's begin by using one of the more ubiquitous, the everyday web browser. Making REST Calls using a Browser To begin with, you need to run the DataSnap server. In this first demonstration, the UseAuthentication define is commented out, meaning that only SSL encryption is used. Let's start by calling the ReverseString method. Since my server is listening on port 8081, and I am using the default DSContext and RESTContext properties of the TDSHTTPService component in the server container unit, and my server methods class name is TServerMethods1, I can call ReverseString, passing the string "Delphi," using the following URL: https://localhost:8081/datasnap/rest/tservermethods1/ReverseString/Delphi
magazine voor software development 37
DELPHI
Since I have used a custom (some would say phoney) SSL certificate, Internet Explorer balks at my attempt to go to this URL, instead warning me of a potential problem, as shown in Figure 2.
Fig. 5: A username and password is requested prior to connecting to the DataSnap server Fig. 2: IE warns that the custom certificate was not issued by a trusted certificate authority Since I know that there is no threat, I click Continue to this website. So long as the browser is open, this is the last time I am going to have to verify that I want to go to this URL. Having accepted the risk, IE now shows the value returned by the call to ReverseString, as shown in Figure 3. The value shown in Figure 3 is a JSON object containing a single name/value pair. As you can see, the name is result. The value part is a JSON array, and this is where all of the data returned by a REST call to a DataSnap server will appear, by default. In some cases, such as when you return a data set, this array can contain a great deal of data.
Authentication happens the first time you touch a given DataSnap server from a given client. Authorization, by comparison, happens upon each and every REST method invocation. You use authorization to implement role-based permissions, either permitting or denying a particular user the right to invoke the method they are trying to call. A further discussion of authorization is beyond the scope of this article. Calling REST Methods Using the REST Debugger Introduced in Delphi XE5, Delphi's REST Debugger is a stand alone application that permits you to test calls to REST services. In it's simplest form, you enter a URL with a correctly formed REST invocation into the REST Debugger and then click Send Request. Figure 6 shows how the REST Debugger looks after sending the same request used in Figure 3 to the DataSnap server. In this figure, the Body tab of the Response pane is selected, displaying a formatted view of the returned JSON.
Fig. 3: The JSON object returned by DataSnap There might be some cases where you do not want to use the default format employed by DataSnap. In that case you can use a technique like that shown in the implementation of the ReverseStringRaw method. There I've used the TDSInvocationMetadata object returned by the GetInvocationMetadata function to return a string without wrapping it in a JSON object. This permits me to create my own string, even one that represents a JSON object using a different format. Figure 4 shows the text returned by the call to ReverseStringRaw, which is simple text in this case.
Fig. 4: You can return custom formats using a TDSInvocation Metadata object Things are a little different if we invoke our methods with authentication enabled. In that case, the first time we invoke one of the methods on the DataSnap server, in other words, the first time we touch the DataSnap server through HTTP, we are challenged for a username and password, as shown in Figure 5. Since my implementation of the OnUserAuthenticate event handler only requires a password of Delphi, so long as I provide the password Delphi (a case-sensitive string), the method being invoked will return its value. If I do not pass a valid username/password pair, the browser will display an error, and the call to the REST method will fail.
38
MAGAZINE
Fig. 6: The REST Debugger executes the same URL as shown in Fig.3. Entering the full URL for the invocation of the REST method in the URL field of the Request tab of the Request pane is convenient. However, when you later move to the REST client components in Delphi it is better to partition the pieces of the request URL between the base URL and the specific method invocation segment. Specifically, all of the methods from the DataSnap server being used in this sample have the same base URL, as shown here: https://localhost:8081/datasnap/rest/tservermethods1
DELPHI
The remainder of the URL specifies the method to invoke and any required parameters. The REST Debugger can accept the method name and its parameters in a property it calls the resource, where the resource specifies the method to be invoked, and, if the method requires one or more parameters, defines named placeholders, one for each parameter. With respect to the ReverseString method being invoked in Figure 6, this resource looks something like this: ReverseString/{Value}
In this resource, ReverseString specifies the method to be invoked, and the single required parameter is represented by a name within curly braces. The actual name used for a particular parameter is irrelevant, just so long as it is unique within the resource. Specifically, that I've used the name Value in the resource has nothing to do with the fact that the formal parameter name of the single parameter of the ReverseString method is called Value. I could have used something else.
resource and parameter value assignments are combined with the base URL defined on the Request tab (this base URL is set to the string shown earlier in this section). The REST call shown in Figure 6 was performed against the DataSnap server using SSL, but not authentication. (Since this DataSnap server only permits HTTPS calls (SSL), a call using HTTP would fail. If you have downloaded the code samples, you can test this for yourself.) If your REST server requires authentication, you use the Authentication tab of the Request pane to provide the require information before clicking Send Request. Figure 8 shows a username and password entered into the Authentication tab, and the resulting response from the server. The password is masked in the figure, but trust me that I entered Delphi. I've used BASIC authentication in this case, which inserts the username and password into the HTTP header. This is how the DataSnap server is expecting to receive this data when authentication is implemented. There are three additional authentication methods. SIMPLE passes the user name and password in a manner similar to how you would pass a username and password field from an HTML form. The last two, OAUTH and OAUTH2, use the corresponding protocol for OAuth. OAuth is an open standard for delegated authorization, permitting a site to accept access tokens from a third party service, for example, authorizing access to a site using the user's Facebook or Google account. The REST Client Library In addition to the REST Debugger, the release of Delphi XE5 also saw the introduction of the REST Client Library, a set of cross-platform components that you can use from any of Delphi's supported platforms. In this section I will focus on four of these: TRESTClient, TRESTRequest, and TRESTResponse. I will also talk about the authentication components, but only in passing.
Fig. 7: You use the Parameters tab of the Request pane to define the resource and assign values to your named parameters If you enter a base URL in the URL field of the Request tab of the Request pane, you use the Parameters pane to enter the resource, after which you assign a value to each of the parameter placeholders appearing in the resource. This can be seen in the Figure 7, where the
At a minimum, a REST request requires that you use a TRESTClient and a TRESTRequest. The TRESTClient takes responsibility for the HTTP communication to the REST server, and also holds the REST service end point, or base URL. Most applications need only one TRESTClient for each REST service to which it will connect. In most applications you will have one TRESTRequest for each method you want to execute. A given TRESTRequest object holds the resource definition for the corresponding method using the format described in Figure 7, as well as any parameters, which are used to associate values with each of the names that appear in the resource. The Client property of each TRESTRequest must point to a properly configured TRESTClient component. The use of TRESTResponse is optional. You use this component if you want to persist any data returned from a TRESTRequest. The TRESTRequest in question is the one whose Response property points to the TRESTResponse. If you execute a TRESTRequest, and its Response property does not point to a TRESTResponse, a TRESTResponse is created on-the-fly, and you can access it using the Response property of the TRESTRequest any time after the successful execution of the TRESTRequest and prior to freeing the TRESTRequest or clearing its content by calling ResetToDefaults.
Fig. 8: With Authorization turned on, you need to pass a user name and password to the server
The use of TRESTClient and TRESTRequest is demonstrated in the RESTClientDemo project, whose main form is shown in Figure 9. This project invokes three of the methods exported by the DataSnap REST server (the methods being invoked should be pretty obvious). There is a single TRESTClient, which points to the base URL of the DataSnap
magazine voor software development 39
DELPHI
server. In addition, there are three TRESTRequest objects, one for each of the methods that are invoked.
RRGetCustomerCDS.Execute; cds.XMLData := RRGetCustomerCDS.Response.Content; DataSource1.DataSet := cds; end;
Figure 10 shows the running application. In this figure, both the ReverseString and Get Customer Data buttons have been pressed.
Fig. 9: The main form of RESTClientDemo In this particular project there was no need to employ a TREST Response component, since the returned data is already being persisted in the application's user interface. For the ReverseString and ReverseStringRaw REST calls, the data is being stored in a memo. The value returned by GetCustomerCDSRaw is being stored in a ClientDataSet. There is an additional REST client component on this form, the TRESTBasicAuthentication component. This component, and its proper configuration, is required if your REST service implements authentication. Here are the three event handlers, each one associated with one of the buttons that appear on the left side of this form. Each event handler assigns values to the named parameters in the associated TRESTRequest.Resource properties, with the exception of Get CustomerCDSRaw, which has no parameters. procedure TForm1.ReverseStringBtnClick(Sender: TObject);
Fig. 10: The running RESTClientDemo application You can download the code sample for this article from the following URL: http://www.JensenDataSystems.com/sdnmag_rest.zip Summary In this article I have introduced the REST Debugger and several of the components of the REST Client Library. In the next issue of the SDN Magazine I will demonstrate more capabilities of the REST debugger, as well as show how to use the REST Debugger and REST Client Library on REST services other than DataSnap. •
Cary Jensen
begin RRReverseString.Params.ParameterByName('ValueToReverse').Valu e := ValueToReverseEdit.Text; RRReverseString.Execute; ResponseMemo.Lines.Text := RRReverseString.Response.Content; end; procedure TForm1.ReverseStringRawBtnClick(Sender: TObject); begin
Cary Jensen is Chief Technology Officer of Jensen Data Systems. Since 1988 he has built and deployed database applications in a wide range of industries. Cary is an Embarcadero MVP, a best selling author of more than 20 books on software development, and holds a Ph.D. in Engineering Psychology, specializing in humancomputer interaction. His latest book is Delphi in Depth: ClientDataSets 2nd Edition. You can learn more about this book at http://www.JensenDataSystems/cdsbook2.
RRReverseStringRaw.Params.ParameterByName('ValueToReverse').Value := ValueToReverseEdit.Text; RRReverseStringRaw.Execute; ResponseMemo.Lines.Text := RRReverseStringRaw.Response.Content; end; procedure TForm1.GetCustomerDataBtnClick(Sender: TObject);
OPROEP!
var cds: TClientDataSet; begin if DataSource1.DataSet <> nil then DataSource1.DataSet.Free; cds := TClientDataSet.Create(Self);
40
MAGAZINE
Lijkt het je leuk een bijdrage te leveren aan (het volgende) SDN magazine? We nodigen je van harte uit om een artikel te schrijven over je vakgebied, over ontwikkelingen en/ of achtergronden. Stuur je kopij naar
[email protected], er zit een auteur in ons allemaal!
TFS
Wouter de Kort
Ken jij Microsoft Test Manager? At SDN's Software Development Conference in Papendal this December I presented a session on DataSnap and REST using FireDAC. In that presentation I demonstrated a DataSnap server that used FireDAC FDMemTables to create special data streams that could be delivered to client applications written in Delphi, and from which specialized streams containing a user's updates to the data could be returned. Importantly, the client/server communication made use of HTTP (hypertext transfer protocol) requests and JSON (JavaScript Object Notation), two elements central to a distributed application style typically referred to as REST (REpresentational State Transfer). DevOps, Application Lifecycle Management, Agile. Het zijn termen die we allemaal kennen. Maar hoe past een tester binnen dit verhaal? We weten allemaal dat Microsoft voor developers erg goede tooling heeft. Teams gebruiken vaak versie beheer, build servers en project management tooling in TFS. Sommige teams gaan echt al richting continuous deployment door bijvoorbeeld Release Management te gebruiken. Maar hoe zit het met testers? Worden zij ook ondersteund? Vaak zie ik testers hun test cases nog bijhouden in Excel. Of ze gebruiken totaal andere tooling van bijvoorbeeld HP of Tosca zonder verder echt te integreren met de ontwikkelaars. Testers zijn veel tijd kwijt aan het handmatig uitvoeren van test cases en het bijhouden van voortgang. Maar als je echt naar continuous delivery wilt, kan een niet efficiënt test proces een steeds groter probleem worden.
Fast forwarding van tests In plaats van Excel lijstjes te gebruiken laat MTM testers hun tests bijhouden, organiseren en delen met het team als een echt onderdeel van TFS. Figuur 1 laat een test case zien zoals die er in MTM uitziet.
Eén van de best bewaarde geheimen van de Microsoft ALM tooling is Microsoft Test Manager (MTM). MTM is voor testers wat Visual Studio voor ontwikkelaars is. Door testers MTM te laten gebruiken integreren ze helemaal in het ALM proces. In dit artikel wil ik een paar van de mogelijkheden van MTM bespreken die mij enthousiast hebben gemaakt en die jou kunnen helpen om met testers binnen je organisatie in gesprek te gaan. Fig. 1: Een test case in MTM Ontmoet Microsoft Test Manager Als ontwikkelaars gebruiken we Visual Studio. Project managers gebruiken de web-interface van TFS en Excel. Testers gebruiken Microsoft Test Manager. MTM is speciaal gemaakt voor testers. De applicatie is een stuk eenvoudiger te gebruiken dan Visual Studio en helpt testers echt om hun werk gedaan te krijgen.
MTM is een onderdeel van Visual Studio Test Professional. Je kunt een gratis 90 dagen trial downloaden op http://www.visualstudio.com/products/visual-studio-testprofessional-with-msdn-vs
Hier zie je een test case met een aantal stappen en het verwachte resultaat. Als een tester deze test case nu gaat draaien verschijnt de interface in Figuur 2 bij de tester op zijn scherm. Tijdens het afspelen van de test kan de tester hierin direct bijhouden welke stappen goed gaan, eventueel commentaar toevoegen of direct een bug inschieten in TFS. Terwijl de tester zijn test case uitvoert, helpt MTM door de acties van de tester op te nemen. Stel bijvoorbeeld dat je een wizard test waarbij je verschillende velden moet invullen om door te kunnen naar de volgende stap. MTM helpt je door het invullen van de velden op te nemen en de volgende keer dat je deze test case uitvoert kun je automatisch doorspoelen en worden alle velden automatisch voor je ingevuld. Stel je eens voor hoeveel tijd dit een tester bespaart. In plaats van iedere keer handmatig alle stappen herhalen kan de tester de minder belangrijke stappen nu doorspoelen en zich focussen op de stappen die echt interessant zijn.
magazine voor software development 41
TFS
Fig. 2: Uitvoeren van een test case
Dit soort opnames zijn dan weer de basis voor volledig geautomatiseerde testen die bijvoorbeeld door de build server of tijdens een automatische deployment gedraaid kunnen worden zodat er nog meer tijd bespaart wordt.
plan tot je beschikking. In plaats daarvan ga je naar eigen inzicht door de applicatie heen terwijl ondertussen MTM alles bijhoud wat je doet. Vind je dus een bug, dan kun je rechtstreeks vanuit je Exploratory Testing sessie een bug aanmaken met daaraan gekoppeld de stappen die je hebt gedaan en eventueel weer info zoals een video opname, Event Log, System Information of IntelliTrace data.
Data Collection Naast dat MTM de acties die een tester uitvoert kan bijhouden, kan er nog veel meer data automatisch verzameld worden. Standaard wordt er bijvoorbeeld bijgehouden op wat voor systeem de tester zijn werk doet zoals Windows versie, gebruikte browser en systeem specificaties. Maar zoals Figuur 3 laat zien is er veel meer mogelijk. Met één simpel vinkje kun je hier bijvoorbeeld een video opname maken van het scherm van de tester en eventueel zelfs audio opnamen. Of wat dacht je van IntelliTrace data, event logs en code coverage info? Al deze data wordt gekoppeld aan het test result en toegevoegd aan bugs die de tester inschiet. Dus als ontwikkelaar heb je nu een stappenplan van wat de tester heeft gedaan samen met allerlei data waaronder zelfs een video opname.
Als je naar Figuur 4 kijkt zie je een bug die is aangemaakt vanuit een Exploratory Testing sessie. Als je kijkt naar de Steps To Reproduce zie je dat MTM precies heeft bijgehouden welke acties de gebruiker heeft uitgevoerd. De andere tabs geven extra info die allemaal in TFS wordt opgeslagen.
Fig. 4: Bug vanuit Exploratory Testing MTM is cool! Dit zijn maar een paar features van MTM waar ik enthousiast van werd. Maar er zijn er nog veel meer. Denk bijvoorbeeld aan het gebruik van parameters in test cases, rapportages over je voortgang, het gebruik van verschillende systeem configuraties voor testen (bijvoorbeeld Windows 7 en 8, of IE en Chrome) en nog veel meer. Beginnen met MTM is eenvoudig. Download gewoon de trial en koppel deze aan een gratis Visual Studio Online account zodat je meteen kunt beginnen. Als je wat gerichter met MTM aan de gang wilt kun je ook de Brian Keller Virtual Machine downloaden compleet met Hands On Labs die je alles van MTM laten zien. •
Fig. 3: Data Collectors Een andere optie die zeker interessant is, is Test Impact analysis. Als je je test omgevingen ook koppelt aan TFS, is TFS instaat om te analyseren welke code er tussen verschillende builds is gewijzigd en welke test cases daar dan weer bij horen. Op deze manier krijgt een tester dus een overzicht van de test cases die het belangrijkste zijn om te draaien voor een nieuwe versie van de applicatie. Exploratory Testing Tot nu toe hebben we vooral gekeken naar het gebruik van vooraf geschreven test cases. Maar wat nu als je in een Agile proces deze test cases nog niet hebt gemaakt? Of wat als je als ontwikkelaar of stakeholder gewoon even door de applicatie heen wilt gaan om te kijken of bepaalde dingen werken? En natuurlijk wil je dan, dat als het mis gaat je ook nog kunt reproduceren waar de fout zit. Dit is waar je Exploratory Testing voor gebruikt. Als je een Exploratory Testing sessie begint vanuit MTM, heb je geen voor gedefinieerd test
42
MAGAZINE
Wouter de Kort Wouter begon met software ontwikkeling toen hij 7 was. Hij werkt nu als Lead Microsoft ALM Consultant bij Ordina waar hij leiding geeft aan een team van ALM Consultants. Wouter helpt organisaties om voorop te blijven met alle ontwikkelingen op de Microsoft Stack. Hij richt zich vooral op Application Lifecycle Management en software architectuur. Hij houdt er van om complexe problemen op te lossen en anderen nieuwe dingen te leren. Wouter heeft een paar boeken geschreven, is een Microsoft Certified Trainer en ALM Ranger. Je kunt hem vinden op Twitter (@wouterdekort) en op zijn blog http://wouterdekort.blogspot.com
CLOUD
Marcel Meijer
API Management Het is voor leveranciers van producten bijna onmogelijk om voor ieder platform mobiele applicaties te maken. Natuurlijk kun je dan als leverancier zorgen voor een goede responsieve mobiele website. Het nadeel van deze manier is dat je de capaciteiten en mogelijkheden van een mobiel device niet volledig uit nut. Daarom zijn er ook leveranciers die hun backoffice via API’s beschikbaar stellen aan de wereld. Meestal wil je dat niet zonder pardon doen en wil je er als leverancier wellicht geld aan verdienen. Dus je wil een Developer portal maken met verschillende groepen, help pagina’s, voorbeeldcode, monitoring, issue lijst, FAQ, maar ook malafide gebruikers/applicaties blacklisten. Kortom het vergt meer dan even het beschikbaar stellen van een paar webservicesje. Enige tijd geleden had ik ook zo’n droom. Ik wilde voor de SDN een evaluatie app maken. Bezoekers van een SDN event kunnen dan mobiel een evaluatie formulier invullen. Deze evaluatie data wordt in een data store op Azure bewaard. Uiteraard wil ik niet mijn tokens/ connectionstrings/passwords etc in mijn mobiele apps opslaan. En aangezien ik niet voor elk device zelf een applicatie kan schrijven, deze gegevens delen met wildvreemde developers. Dus bedacht ik dat ik een aantal Webapi services beschikbaar moest stellen. Maar zoals hierboven genoemd, had ik behoefte aan eer developers portal om mijn services uit te leggen en wat ze opleveren. Dat is veel werk voor zo’n API als dit. Dit is mijn landingspagina nu; http://sdnevalapp.azurewebsites.net/. Gelukkig is daar een oplossing voor op het Azure platform. De API management service (documentatie site). Als je de service gemaakt hebt, dan is er een aparte portal (https://marcelmeijer.portal.azure-api.net/ admin) waar je alle instellingen doet, waar je de metrics van je API ziet, de applicaties die aangemeld zijn, welke API het vaakst aangeroepen wordt etc.
Bij de settings kun je dan de webservices beschikbaar stellen. De verschillende operaties, welke http verb, welke responses er verwacht kunnen worden, welke URL, omschrijving en helpteksten. De URL naar de bron services kan ook on-premises gehost worden.
Uiteraard is het dan wel verstandig om de endpoints op deze URL te beveiligen met een Certificaten, UserName/Password combinatie of via OAuth. Dit is de management portal voor de beheerder van de API(https://marcelmeijer.portal. azure-api.net/admin), voor de ontwikkelaars is er een aparte portal (https://marcelmeijer.portal.azureapi.net/). Deze kan tot op zekere hoogte ook gestyled en aangepast worden. Deze Developer portal is redelijk compleet. Alle genoemde zaken zijn hier wel te vinden.
Zo is er een handig overzicht van de beschikbare API’s. Van de beschikbare API kun je de beschikbare endpoints zien. Je ziet dan de omschrijving en de URL om API aan te spreken. Om het endpoint te gebruiken moet je een subscription key meegeven. Het hele idee van deze portal is dan ook om gebruik te reguleren en met behulp van de subscription key is de API per applicatie/ontwikkelaar apart. Aangezien de endpoints aan de basis beveiligd zijn met Certificaten, Username/ Passwords of via OAuth, heeft het geen zin om rechtstreeks naar de bron te gaan. Op deze Developer portal kun je API methode ook uitproberen en de verschillende gedefinieerde HTTP acties uitvoeren. Je krijgt dan de trace en het resultaat te zien. Helemaal onderaan de pagina kun je per programmeertaal voorbeeldcode krijgen. Alles om de ‘klanten’ van je API te ondersteunen en te helpen. Door deze Azure service kun je je richten op het echte leuke en belangrijkste van de API, de functionaliteit. Waarom zou je het zelf doen, als je gebruik kunt maken van de expertise van andere. “You can reach further while standing on the shoulders of giants”. •
magazine voor software development 43