Transcription
PDF
SOFTWARE DEVELOPMENT NETWORK MAGAZINE IN DIT NUMMER O.A.: Introduction to Razor Syntax < Duet Enterprise < Building a Custom Health Rule < Best practices bij het vervangen van een SCOM Gateway Server < Nummer 108 februari 2011 SDN Magazine verschijnt elk kwartaal en is een uitgave van Software Development Network 108 www.sdn.nl advertorial NjdsptpgufoBdinfb;tusbufhjtdifqbsuofstcjkefpouxjllfmjohwboWjtvbmTuvejp3121 ÒBdinfbxjmsb{foetofm lvoofojotqfmfopq pouxjllfmjohfojoefnbsluÓ Foto: Hans Barten Bdinfbjtffoxbbsefwpmmftusbufhjtdif qbsuofswboNjdsptpgu/Ejucmjklupoefsnffsvju ifugfjuebuefwfs{flfsbbsiffgunffhfebdiu cjkefpouxjllfmjohwboNjdsptpguWjtvbmTuvejp 3121/ÒNjdsptpgucftdipvxupotbmtffowboef nfftujoopwbujfwfwfs{flfsbbstufsxfsfmeÓ- {fhuBdinfbÕtqsjodjqbmbsdijufduBmfyUijttfo/ Afgelopen zomer was Achmea’s 2010 en de ‘Application Lifecycle Alex Thissen een week lang te gast Management omgeving’ Team bij het Windows Communication Foundation Server 2010) was Foundation team op Microsofts Achmea in een vroeg stadium hoofdkantoor in het Amerikaanse betrokken, vertelt Thissen. “We Redmond. “Er zijn op de hele wereld hebben ideeën en suggesties aan- maar zes bedrijven die daarvoor geleverd en Microsoft gewezen werden uitgenodigd, dus ik beschouw op bugs en verbeterpunten, zoals het wel als een eer dat Achmea deel bijvoorbeeld bij het berekenen uitmaakt van dit selecte groepje. van de burnrate van code. Dat is Microsoft luistert echt naar Achmea, nuttig voor ons én nuttig voor ze beschouwen ons als een bedrijf Microsoft.” dat voorop wil lopen. We spraken Voor Achmea is Visual Studio bijvoorbeeld over Microsofts onder- Team System belangrijk bij het daarop onder andere hun bloeddruk en body mass steuning van IBM Websphere MQ, ontwik kelingen van software index meten en sportieve prestaties vergelijken met waarvoor wij andere communicatie- aan de voorkant, zoals webappli- die van topsporters.” patronen mogelijk wilden maken. caties en mobiele applicaties, en Maar ook de koppeling tussen voor integratie-oplossingen met Agile Sharepoint en SAP was onderwerp behulp van webservices. “Voor Daarnaast draagt de Microsoft-software bij aan de van gesprek.” Achmea wordt het internet steeds toenemende vraag naar transparantie en voorspel- Microsoft-topman Scott Guthrie, belangrijker, niet alleen om schades baarheid, vindt Thissen. “Team Foundation Server alias ‘Scott Gu’, was onlangs te gast te melden of verzekeringen af te houdt alle stappen in het ontwikkelproces bij, vast- op de Achmea-burelen. Thissen: “Ja, sluiten, maar ook voor allerlei gelegd in hiërarchische workitems. Zo bieden wij dat zijn inspirerende sessies. In mijn zaken op het gebied van preventie. onze klanten – de mensen in de business van Achmea vakgebied heeft hij de status van Zo hebben we in opdracht van – optimaal inzicht in het proces.” een popster, dus je begrijpt dat het Zilveren Kruis Achmea de game Last but not least is Thissen tevreden met MSF Agile, geweldig sparren is met zo’n man.” ‘Mep je fit’ ontwikkeld voor Micro- het processjabloon dat Visual Studio Team System Alex Thissen: “Microsoft luistert echt naar Achmea.” softs ‘computertafel’ Surface. voert. “Dat betekent dat we snel en flexibel kunnen Mep je fit Ook tijdens de Olympische Winter- bouwen, in korte iteraties met de klant. Dat is precies Bij de ontwikkeling van Visual spelen hadden we in het Holland wat we nodig hebben, want Achmea wil razendsnel Studio Team System (bestaande uit Heineken House een gezondheids- kunnen inspelen op nieuwe ontwikkelingen die zich ontwikkelomgeving Visual Studio installatie staan; bezoekers konden voordoen in de markt.” Colofon Uitgave: voorwoord Software Development Network Negentiende jaargang No. 108 • februari 2011 Bestuur van SDN: Remi Caron, voorzitter Rob Suurland, penningmeester Marcel Meijer, secretaris Beste SDN magazine lezer, Redactie: Remi Caron en Marcel Meijer (redactie@sdn.nl) Aan dit magazine werd meegewerkt door: Aan dit magazine werd meegewerkt door: Roel Hans Bethlehem, Christiaan Heidema, Bob Swart, Stefan Kamphuis, Peter Donker, Maarten van Stam, Alexander Meijers, Remi Caron, Marcel Meijer en natuurlijk alle auteurs! Listings: Zie de website www.sdn.nl voor eventuele source files uit deze uitgave. Vormgeving en opmaak: Reclamebureau Bij Dageraad, Winterswijk www.bijdageraad.nl ©2011 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. Het jaar is al weer een tijdje bezig. Inmiddels hebben we het eerst event EngineerWorld (georganiseerd samen met Sogeti) alweer achter de rug. Het volgende reguliere SDN event staat gepland vrijdag 18 maart. Dit event staat weer bol van de content. Sessies over AppFabric, ALM voor Azure projecten, SharePoint Document management, Blend for Developers, Claimbased security, Delphi XE, Intraweb, Razor, DNN RadEditor en DNN in combinatie met Entity Framework. Traditioneel zal er tijdens dit event ook de Algemene Leden vergadering. Dit is nog maar een kleine greep. Kijk op de website voor meer informatie. Let op, ons tijdschema is veranderd. We beginnen om 9:30 en eindigen rond half vijf. Met het nieuwe jaar zijn er ook een aantal wijzigingen in de organisatie. Sandra de Ridder van de UX track heeft ons verlaten. Ze kon de werkzaamheden voor de SDN niet meer goed combineren met haar werk en prive leven. Marcel van Kalken van de Delphi track heeft ook zijn taken neergelegd. Beide danken wij hartelijk voor hun inzet de afgelopen jaren en wensen ze succes voor de toekomst. De organisatie is daarentegen ook uitgebreid met Alexander Meijers voor de Information Worker track en Roel Hans Bethlehem voor de Architecture track. Alexander en Roel Hans welkom bij de club, we gaan er een mooie tijd van maken. Ook hebben we dit jaar twee nieuwe corporate sponsoren IBM en Compuware. Daar zullen we de komende tijd veel meer over horen en van zien. Dit magazine staat bol van de artikelen. Van het Nieuwe werken tot SCOM en twee artikelen over Razor. Kortom wederom een magazine waar je je kennis mee kan verbreden. De volgende magazines gaan we meer richten op 4 standaard categorieen (Cloud, Mobile, Client apps en Web apps), natuurlijk blijven Delphi en DotNetNuke het hele palet compleet maken. We zijn altijd op zoek naar leuke artikelen van een tot twee pagina’s. Mocht je interesse hebben, meldt je dan bij redactie@sdn.nl. Wij kunnen je ook helpen met schrijven. Veel leesplezier! Groeten Marcel Meijer Adverteerders Achmea 4DotNet Sogeti Bergler Triple A Uniface Barnsten/Embarcadero Microsoft Macaw 2 6 8 18 23 29 34 51 52 Adverteren? Informatie over adverteren en de advertentietarieven kunt u vinden op www.sdn.nl onder de rubriek Magazine. magazine voor software development 3 Agenda 2011 Inhoud 03 Voorwoord Tech-Ed Middle East 2011 . . . . . .8 maart Marcel Meijer Tweede WAZUG meeting . . . . . .17 maart 04 04 05 SDN Event maart + ALV . . . . . . .18 maart Anky Persoons 07 CodeCamp / . . . . . . . . . . . . . . . . . . . . . . SharePoint Saturday . . . . . . . . .26 maart 09 SharePoint Conference 2011 . .3 oktober Introduction to Razor Syntax Introduction to the Delphi Open Tools API Wat is er zo moeilijk aan een mobiele applicatie? Jaap van Ekris Drag and Drop deel 2: Bestanden slepen naar de Windows Explorer Eric Roosendaal 20 Mixing Scrum and Smart Sander Hoogendoorn 24 SDN Event December 2011 .9 december Azure VM Role Cary Jensen 19 SDN Event juni 2011 . . . . . . . . . . .17 juni Leer Het Nieuwe Werken van een ZZP’er! Andrew Nurse 16 SDN Magazine 109 . . . . . . . . . . . .20 mei Agenda Marcel Meijer 12 DevDays 2011 . . . . . . . . . . . . . . .28 april Inhoudsopgave Introduction to the code coverage tooling in Rational Application Developer Paul Klicnik 30 Duet Enterprise Christian Siegers en Mark IJsselstein 32 Historie en toekomst van Database Change Management Ben Suurmeijer 36 Webservices en transacties Michiel van Otegem 38 Building a custom Health Rule Anita Boerboom 42 “Nieuw” in Nederland: NLDeveloper Robert Blom 43 Best practices bij het vervangen van een SCOM Gateway Server Mark Wolzak 46 De uiterste houdbaarheidsdatum van requirements Sander Hoogendoorn 47 DotNetNuke supports Razor Charles Nurse 50 Reflection loops of Agile Joachim Nilsson IW Anky Persoons Leer Het Nieuwe Werken van een ZZP’er! Steeds meer bedrijven stappen over op Het Nieuwe Werken. Vaak richten ze zich bij de invoering ervan sterk op de praktische aspecten (ICT, HR, facilitair). Wat ze vaak uit het oog verliezen is de cultuuromslag die nodig is om deze verandering succesvol te laten verlopen. Op dat vlak kunnen ze veel leren van ZZP’ers, die bij het werken als ondernemer hebben moeten leren omgaan met vrijheid, verantwoordelijkheid en het zoeken naar balans. Méér dan leuke ICT-tooltjes Er is veel te doen over Het Nieuwe Werken (HNW). Eind 2010 was er zelfs “De Week van Het Nieuwe Werken” en in 2011 zullen we er alleen maar meer over horen. Iedereen heeft het erover, wil het graag (of juist niet), moet het van zijn baas, vindt er iets van, of vindt het niks. In de pers worden steeds weer dezelfde praktijkvoorbeelden aangehaald: Microsoft, Interpolis. Is HNW een hype of het begin van een tijdperk waarin mensen anders omgaan met hun werk, hun tijd, het samenwerken met anderen en hun werk-privébalans? Worden we beter presterende, meer tevreden werkers of is het vooral een marketingterm waarmee ICT-bedrijven hun oplossingen verkopen, HRM-adviseurs hun uren en interieurarchitecten hun adviezen? Verantwoordelijkheid nemen Veel mensen denken dat Het Nieuwe Werken betekent dat je hetzelfde werk blijft doen, maar dat je zelf bepaalt wanneer en waar je dat doet. In de praktijk is het echter niet zo eenvoudig. Het is meer dan thuiswerken, communiceren met nieuwe slimme ICT-middelen, geen vaste werkplek meer hebben op kantoor en zelf je tijd kunnen indelen. Dat zijn eigenlijk maar bijkomende verschijnselen, die echter vaak de aandacht trekken en het zicht vertroebelen op waar HNW echt over gaat. In de kern gaat HNW over zelf verantwoordelijk zijn voor je werk In de kern gaat HNW over zelf verantwoordelijk zijn voor je werk. Dat werk bestaat uit opdrachten met een duidelijk omschreven eindresultaat, een deadline en tussentijdse evaluaties. Een medewerker heeft geen inspanningsverplichting meer, maar een resultaatverplichting. Dit heeft nogal wat gevolgen voor de werknemer en voor de manier waarop hij samenwerkt met managers, collega’s en ondergeschikten. En voor de balans tussen werk en privé. Want die zakelijke telefoontjes komen ook gewoon binnen als je net je kind uit school hebt gehaald. Werknemers hebben dus nieuwe vaardigheden nodig: zelfsturing, ondernemendheid, planning, grenzen bewaken. Het nieuwe managen Ook de rol van de manager verandert. Als niemand nog een 40-urige werkweek heeft, hoe stuur je dan je team aan? Je moet leren om te beoordelen op resultaat, niet meer op aanwezigheid. Vertrouwen neemt de plaats in van controle. Je zult meer aandacht moeten besteden aan de synergie in het team en aan de onderlinge communicatie en uitwisseling van informatie. Misschien hebben de ZZP’ers HNW wel uitgevonden Kortom, HNW vraagt om een cultuuromslag. Een omslag van eenrichtingsverkeer naar een dialoog, van delegeren naar coachen, en van werk of privé naar werk én privé. Dan krijgen medewerkers de ruimte om mee te denken, beslissingen te nemen en productiever te zijn. ZZP’ers werken al heel lang “Nieuw” Terwijl bedrijven en hun medewerkers hun best doen om HNW onder de knie te krijgen, vergeten we met zijn allen dat er een grote groep werkers is die al veel langer met dit bijltje hakt. HNW is eigenlijk niets nieuws onder de zon. Dat is het wel voor mensen die in loondienst werken en gewend zijn om 9 uur te starten en om 5 uur weer uit te klokken, om vervolgens op dezelfde snelweg weer in dezelfde file te gaan staan, net als hun collega’s. Maar niet voor de Vrije Werkers, Zelfstandige Professionals of - zoals ze meestal genoemd worden ZZP’ers. Voor velen van hen was de wens om op deze manier te kunnen werken zelfs een belangrijke reden om uit loondienst te gaan en “voor eigen rekening en risico” aan de slag te gaan. Misschien hebben de ZZP’ers HNW wel uitgevonden. Ga maar na: veel zelfstandige professionals wisselen het werken in hun thuiskantoor af met werken bij de klant en met besprekingen op verschillende locaties met mede-ZZP’ers en andere samenwerkingspartners. Ze doen overdag een boodschap, gaan sporten of halen de kinderen uit school, en werken dan ’s avonds of in het weekend nog een paar uur. In drukke tijden maken ze wat meer uren, in rustige tijden kan het even een tandje lager. Er is vaak één PC voor zakelijke en privéaangelegenheden. Ze doen hun eigen acquisitie en voeren voor hun klanten vaak projectmatige werkzaamheden uit, waarbij een vooraf afgesproken resultaat op een bepaalde datum moet worden opgeleverd. Deze professionals hebben de strijd om de werk-privé balans al gestreden. En vaak niet zonder moeite: zeker ondernemers zijn (in het begin) geneigd meer te werken dan goed is voor henzelf en de privésituatie. En ze vormen dus uitstekende rolmodellen en vraagbaken voor medewerkers die HNW onder de knie moeten krijgen. magazine voor software development 5 IW De ZZP’er als voorbeeld van ondernemerschap Toch hebben managers in HNW-bedrijven juist vaak moeite om de ingehuurde ZZP’ers het vertrouwen te geven dat bij HNW hoort. Ze hebben ze het liefst zichtbaar om zich heen, en niet thuiswerkend. Ze zijn immers per uur ingehuurd en dan wil je ook zien dat die uren allemaal gemaakt worden. Als ZZP’er kan ik medewerkers coachen in het wennen aan HNW Wat een gemiste kans! Want is HNW eigenlijk niet gewoon: ondernemerschap onder de vleugels van de werkgever? Het is werken met meer vrijheid en verantwoordelijkheid, zonder de risico's van het echte ondernemen te dragen. Wie kan er dan beter kennis en ervaring hierover delen dan een ZZP-‘er? medewerkers, die dan ook niet goed de stap durven maken naar locatie-onafhankelijk werken.” Terwijl het voor Gary heel gewoon is om resultaatgestuurd te werken. Als ZZP’er werkt hij immers zowel op uurbasis als op projectbasis. “Ik ben gewend om zelf mijn tijd in te delen en flexibel samen te werken met andere teamleden, of dat nu vaste of tijdelijk ingehuurde medewerkers zijn, of medewerkers van een externe leverancier. Als teamlid met HNW-ervaring kan ik de andere teamleden tussen de bedrijven door begeleiden bij het wennen aan HNW en ze suggesties geven over beschikbaarheid, balans, communicatie met collega’s en omgaan met vrijheid en verantwoordelijkheid.” Veel ZZP’ers delen Gary’s ervaringen. Wanneer zij de ruimte krijgen zodat ook zij optimaal kunnen functioneren kunnen zij op een natuurlijke manier in de dagelijkse werksituatie optreden als “rolmodel” en de andere teamleden laten zien hoeveel winst Het Nieuwe Werken kan opleveren. Voor het bedrijf, maar zeker ook voor de medewerkers.• Een ZZP’er die ervaring heeft opgedaan met HNW bij opdrachtgevers is Gary Wenneker. Hij werkt als zelfstandig SharePoint specialist en komt al jarenlang “bij de klanten thuis”. Hij vertelt: “Sinds een paar jaar zie ik in steeds meer bedrijven Het Nieuwe Werken opkomen. De meeste medewerkers vinden die nieuwe vrijheid prettig, maar het maakt mensen ook onzeker. Hoe bereikbaar moet je zijn? Moet je niet vaker je gezicht laten zien op kantoor? Wanneer kun je je collega’s wel, of juist niet, bellen?” Daarnaast ervaart Gary ook dat managers worstelen met HNW. “Zeker als het gaat over tijdelijk ingehuurde krachten. Die moeten toch eigenlijk wel gewoon op kantoor werken. Dat betekent dan voor die manager dat hij zelf ook veel op kantoor aanwezig is om de voortgang in het oog te houden. Zodat hij niet een goed voorbeeld is voor zijn Ankie Persoons Ankie Persoons is directeur van ICTProfessionals, een maatschap van zelfstandige ICT-ers die de afstand tussen werken in loondienst en zelfstandig werken verkleint. Ze heeft brede communicatie-ervaring in de ICT-branche en is Social Mediaconsultant en trainer. The one-stopcompany companyfor for.NET .NETdevelopment development The one-stop Maak uwuw dromen waar! Maak dromen waar! Kijk voor alle belevenissen op www.4dotnet.nl Heeft u altijd al willen rijden in een Ferrari of een keer zweefvliegen? Boek dit voorjaar een training bij 4DotNet en krijg een unieke belevenis van ons cadeau! Lees alles over deze droomactie op www.4dotnet.nl Een keer rijden in een Ferrari of zweefvliegen. actie is geldig t/m 30 juni 2011 Wie droomt daar nou niet van? Boekt u voor 31 maart een training bij 4DotNet dan krijgt u van ons een unieke belevenis cadeau! TEST CENTER 6 4DotNet bv t Paradijsweg 2 t 7942 HB Meppel t t. 0522-24 14 48 t info@4dotnet.nl t www.4dotnet.nl TEST CENTER MAGAZINE 4DotNet bv Paradijsweg 2 7942 HB Meppel t. 0522-24 14 48 info@4dotnet.nl www.4dotnet.nl CLOUD Marcel Meijer Azure VM Role Veel standaard ASP.NET webapplicaties kunnen in principe redelijk eenvoudig naar de Azure Cloud gebracht worden. Uiteindelijk is de Azure Cloud een Microsoft .NET platform met nagenoeg dezelfde omgelijkheden1. Maar als je applicatie heb die niet is op het Microsoft .NET platform, dan is de Azure VM Role een goede mogelijkheid. Je legacy applicatie moet dan wel te gebruiken zijn op Windows 2008 server. Op dit moment het enige mogelijke Operating system voor de VM Role. Een VM voor de VM Role moet natuurlijk op een bepaalde manier opgebouwd zijn. Op deze site wordt dat keurig stap-voor-stap uitgelegd. http://msdn.microsoft.com/en-us/library/gg433125.aspx. Een dergelijke VM kan gemaakt worden op een Windows 2008 R2 server met Hyper-V. Tijdens de installatie van deze VM kun je dan je “legacy” applicatie installeren.In een van de stappen moet je Windows Azure VM Role Integration Components installeren. Deze software installeert ook iets om te connecten met de storage. Nadat je de VM dan gesysprepd hebt, dan kun je deze uploaden naar Azure. Ook deze stappen staan op bovenstaande site uitgelegd. In het kort komt het erop neer, dat je een Windows Azure SDK command prompt in Administrator mode starten. Dan moet je met het CSUPLOAD tool de connectionstring vast leggen, dat zie je in het eerste deel. Daarna begint de daadwerkelijke upload. Bij het preparen worden er twee tijdelijke bestanden aangemaakt. Eentje met de extensie .PREPED en eentje met de extensie .DIGEST. Tijdens deze upload actie zie je dan op het Windows Azure portaal de status PENDING. Als de upload klaar is, dan zie je op de command line en op het Windows Azure portaal het volgende. Als je de VM dan geupload hebt, dan is er geen mogelijkheid om de VM te starten. In Visual Studio moet je een Virtual Machine role toevoegen aan je project. Daarbij kies je dan de geuploade VHD. Dit kan pas als de upload daadwerkelijk klaar is Dit moment moet de VM en de applicatie nog in hetzelfde zone staan. Dit zal wel te maken hebben met de beta fase waarin de VM role verkeerd. Je krijgt een foutmelding tijdens het deployen als dit niet klopt.• Zoals uit het figuur blijkt, begon het tool CSUPLOAD gewoon met het voorbereiden van de upload. Maar toen het feitelijk uploaden moest beginnen, kwam onderstaande foutmelding. In de cirkel zie je dat ik inderdaad “Anywhere Europe” gekozen had, dat is per definitie geen single location . 1 Uiteraard is dit niet altijd zomaar waar en zitten hier soms nog een paar haken en ogen aan. Marcel Meijer Gelukkig is het tool wel handig opgezet. Het hele preparing gedeelte hoeft niet nog een keer te gebeuren, hij begint nu met het feitelijk uploaden. Dit duurt wel een tijdje. Marcel Meijer werkt als Software Developer / Solution Architect bij VX Company. Hij is .NET track owner en bestuurslid bij de SDN en MVP. magazine voor software development 7 Als het een ICT-er is, zit hij bij Sogeti. Wat kun je? Die vraag stelt ieder bedrijf met een vacature. Wie ben je? Die vraag stelt Sogeti ben je dan aan het juiste adres. Ruim 100 ervaren meteen daarna. We vinden het belangrijk dat je bij ons past. Want een ICT-er van Sogeti is Javanen werken bij Sogeti aan het realiseren van geen gemiddelde ICT-er. Het is er een met uitgesproken eigenschappen. complexe en innovatieve oplossingen voor haar Gedreven. Resultaatgericht. En niet snel tevreden. Natuurlijk: plezier hoort erbij. Maar we gaan op de eerste plaats voor de inhoud. Zo kennen klanten ons. Zo kennen we elkaar. klanten. Aangezien vakmanschap bij Sogeti hoog in het vaandel staat, wordt er veel tijd geïnvesteerd in het vergroten van kennis en de persoonlijke ontwikkeling van de Java professionals. Het behalen Microsoft-specialisten meest gecertifi ceerde organisaties in de branche. van Java certificeringen is daar onlosmakelijk mee Stel, je hebt een passie voor Microsoft. Je bent een Qua omgeving kun je denken aan ALM, VSTS 2010, verbonden. Sogeti heeft dan ook niet voor niets de kei in applicatieontwikkeling en -architectuur. En je .NET4.0, Offi ce 2010, SharePoint 2010, Azure en best gecertificeerde Java Community van Nederland. wilt verder in je vakgebied. Dan is Sogeti het bedrijf BPOS. Terwijl de projecten enorm gevarieerd zijn. voor jou. Met 700 Microsoft-professionals behoren Van BizTalk-implementaties en end-user BI-oplos- Wil jij met jouw kennis en ervaring onze Microsoft we tot de grootste Microsoft-communities van singen tot de omvangrijkste integratie ooit van Community of Java Community versterken? Nederland. Bovendien verwachten onze klanten SharePoint in Dynamics CRM. Neem dan gerust contact met ons op of kijk op werkenbijsogeti.nl. innovatie, zodat je echt al je kennis inzet. Wat ons betreft wordt die kennis steeds breder en dieper; JAVA-specialisten we dagen je uit om het maximale uit jezelf te halen. Als je passie hebt voor het Java vakgebied, dan Bijvoorbeeld door je cursussen en opleidingen wil je natuurlijk ook werken bij het bedrijf met de aan te bieden. We zijn niet voor niets een van de beste Java Community van Nederland. Bij Sogeti .NET Andrew Nurse Introduction to Razor Syntax Since about 1996, writing websites on the ASP.Net platform has involved working with the “angle-bracket percent” (<%) syntax (sometimes called “WebForms syntax”) I’m sure we’re all familiar with. From Classic ASP right up to ASP.Net 4.0, if you worked with the Microsoft Web Platform, you probably worked with this syntax. However, with the release of the MVC framework in 2009 (more than 13 years after Classic ASP 1.0), the community started to explore new languages and new ways of writing web pages. Last year, we started investigating ways in which we could revamp the ASP.Net syntax, and the result of that process is Razor. In this article, I will describe the motivations behind developing Razor, and give an overview of the syntax. What is Razor? When we started designing Razor, we took a simple snippet of pseudo-code as an example: <ul> href=”/Products/@product.Id”>@product.Name</a></li> } </ul> Listing 3: The @ at work. foreach(var product in Products) { <li><a href=”/Products/product.Id”>product.Name</a></li> } </ul> Listing 1: What the developer means This is what the developer means; what they want their code to do. However, in most web languages, like the traditional ASP.Net syntax, you have to write something like this: <ul> <% foreach(var product in Products) { %> However, Razor does more than just cut down on extra characters. The magic of Razor lies in how it unifies two languages, the serverside code and the client-side markup. Razor has a fairly deep understanding of C#, VB and HTML and it uses that understanding to cut back on the extra syntax users need to write. For example, in Listing 3, you’ll notice that there are @ characters indicating where we switch to code, but nothing to indicate that we’ve gone back to markup. The Razor parser understands that immediately after the first @, there’s a foreach statement, so it assumes that when that statement is finished, you’re ready to go back to markup. Similarly, the parser is able to detect the <li> tag and treat it’s contents as markup. Razor also allows continued nesting of markup within code and vice-versa. <li><a href=”/Products/<%=product.Id%>”><%=product.Name%></a></li> <% } %> </ul> Getting Started with Razor To get started with Razor, you can download Microsoft WebMatrix from http://www.microsoft.com/web/webmatrix/. Everything you need is installed as part of that package. Listing 2: What the developer has to write, in WebForms syntax. So, we stripped all the extra control characters out and started again, back to the first example. We wanted to find a way to blend server-side code and client-side markup with as few characters as possible. The answer was a single character. The answer was a single character What makes Razor so different from other languages is that it only has one major control character, the at-sign (@). Going back to the earlier example, writing it in Razor would require only 3 control characters instead of 18 control characters: <ul> @foreach(var product in Products) { Razor files have one of two extensions, indicating which language the server-side code is written in. If you are using C#, the file extension is CSHTML. If you are using VB.Net, the file extension is VBHTML. For the most part, the server-side languages work the same way in Razor, but there are a few cases where one language works a little differently than the other. I’ll highlight those cases when we get to them. A Razor Document A Razor document starts with HTML. Until you need to start inserting some server-side code, a Razor file is just like a plain HTML file. When you’re ready to go in to code, you start a code block. Code Blocks Code Blocks in Razor are started with a single @, followed immediately by a C# or VB block construct (like foreach, or If). If you want code that isn’t within the body of a block statement (for example, you want to declare some variables or calculate some values), you can create a generic code block using @{ in CSHTML, or @Code in VBHTML. <li><a magazine voor software development 9 .NET @{ var foo = GetFoo(); } @<text>This is also valid, and it won’t have any tags <p>This is just regular markup!</p> around it!</text> @if(foo != null) { foo.Bar(); } <text>This is still NOT valid!</text> Dim p = <p>This is actually an XML Literal, and not considered markup!</p> Listing 4a: C# - Code Blocks Dim p = <text>Same for this!</text> @Code } Dim foo = GetFoo() End Code Listing 5b: VB - Mixing Markup and Code <p>This is just regular markup!</p> @If foo IsNot Nothing foo.Bar() End If Listing 4b: VB - Code Blocks Notice that there are no Razor constructs necessary in order to mark the end of a code block, the code block ends when it would naturally be expected to end. Mixing Code and Markup On the web, code isn’t very useful unless it can be used to control the output of client-side markup. In Razor, any code block can contain markup blocks within it. In fact, those markup blocks can then contain further code block which can contain further markup blocks. You can nest them as deeply as you need! In CSHTML, mixing markup in to your code is as easy as just typing some HTML! However, there are two rules to keep in mind. First, markup is only allowed at the start of a C# statement, you can’t place markup in the middle of a statement. Second, you must start your markup with a tag and all the tags must have a matching closing tag (or be self closed, like <br/>). For those cases where you don’t want to have an outer tag (like <p>) rendered around your text, you can use a special tag called <text>. The <text> tag is only used to define the boundaries of your markup, and it will not actually be rendered. Once inside the tag, everything until the matching close tag is considered HTML, including additional tags. You can also use the @ character to start another code block. This is why it’s so essential to close your tags. If you don’t, the parser can’t determine where the markup block ends, so it doesn’t know when to switch back to code. Unfortunately, this is also one place where CSHTML and VBHTML differ. Due to the complexity of the VB language, and the XML literals feature, we aren’t able to be quite as smart when parsing VB. So in VBHTML, when you want to switch from Code back to markup, you must use the @ character again. You can still use the <text> tag as before and The following example shows some valid and invalid ways of putting markup inside C# and VB code: @if(foo) { Partials, Layouts and Sections Often, when writing a web application, you will find it necessary to extract out common view logic into a component. In ASP.Net WebForms, these are called UserControls and in ASP.Net MVC and WebPages, we call them Partials. Razor supports rendering partials using the RenderPage method. For example, consider a partial like the following (shown only in C#, but the VB code is similar): The current time is @PageData[0] Listing 6: _Time.cshtml Partial Page Let’s note a few things about this file. First, the file-name starts with an “_”. In both ASP.Net WebPages and MVC, this indicates to the Razor engine that the file cannot be served on it’s own. With traditional ASP.Net syntax, UserControl have a different file extension (ascx) which prevents them from being served. However, all Razor pages written in the same language have the same extension, so we use the “_” to denote pages which are not to be served on their own. Second, is the PageData collection. When rendering a partial page, this collection will contain all of the extra arguments that were provided to the RenderPage method. So to use this partial, we would write code like this: <p>@RenderPage(“_Time.cshtml”, DateTime.Now)</p> Listing 7: Using the Time Partial The first argument to RenderPage is the virtual path to the page we want to render, and the remaining arguments are passed on to that page. One of the most popular features of ASP.Net is master pages. Razor has a concept similar to master pages, called layout pages. A layout page is a template, much like a master page, which has placeholders where each specific page’s content will be rendered. As with partial pages, layout pages are not directly requested, they are linked to a content page. When the user requests the content page, the Razor engine runs the page and collects up all the content to be rendered. It then checks to see if the page defines a layout page and if so, passes the content to that page and renders it. Here’s a simple example of a content page: @{ <p>This is valid</p> <text>This is also valid, and it won’t have any tags around Layout = “_Layout.cshtml”; } it!</text> string p = <p>This is NOT valid!</p>; @section Header { string p = <text>Nor is this!</text>; } This is the header } @section Footer { This is the footer Listing 5a: C# - Mixing Markup and Code } @If Foo This is the body @<p>This is valid</p> <p>This is NOT valid</p> 10 MAGAZINE Listing 8: Content Page – Content.cshtml .NET Let’s review this code from the top. First, we need to attach a layout page to our content page. We do this by simply setting the Layout property in a code block. You can use any code you want to set this property, even load it from config files or a database. Next, we define a Header section. Just like master pages allow for multiple content placeholders, Razor content pages can define multiple sections, as well as a special “body” section. Each named section is defined using the @section keyword (in both C# and VB). In C#, we use “{“ and “}” to delimit the boundaries of the section. In VB, the “End Section” keyword is used, much like existing VB constructs like “If”. Any content which is not contained in a section is considered part of the “body”, which is a special unnamed section. Then, after our header section, we define some body content and then a footer section. There are also some cases where it doesn’t make sense to have a body. For example, if you have a three column layout, you may want to have three sections “Col1”, “Col2” and “Col3” and no body. In Razor, as long as you have at least one @section block, you can omit the body completely. Now that we have a content page, let see what the layout page would look like: End Function End Functions The time is: @CurrentTime() Listing 9b: VB - Functions Block It is also often necessary to import classes and types from other namespaces into your Razor pages, and for this we provide the @using/@Imports keyword: @using System.IO @{ // Now I can use FileStream! Stream s = new FileStream(); } Listing 10a: C# - Using Statement @Imports System.IO @Code <html> ‘ Now I can use FileStream! ... Dim s as Stream = New FileStream() <body> End Code <div id=”header”>@RenderSection(“Header”)</div> <div id=”body”>@RenderBody()</div> Listing 10b: VB – Imports Statement <div id=”footer”>@RenderSection(“Footer”, required: false)</div> </body> </html> Finally, Razor also includes its own server-side commenting feature. This allows you to write comments in both code and markup block, as well as comment out chunks of Razor code. This syntax is the same in both languages: Listing 9: Layout Page - _Layout.cshtml This will be rendered! The layout page contains all the outer HTML markup we need to define our page, then it uses the RenderSection and RenderBody methods to render the sections defined by our content page. The RenderSection method injects the section with the specified name, and the RenderBody method injects the content which was not part of a section. Here, we’ve also specified that the footer section is not required. Normally, if we try to render a section the content page does not define, we get an run-time error, but by setting the “required” parameter to false, we tell the run-time that this section is optional. Layout pages can also be nested, so our _Layout.cshtml file above could have specified a further layout page simply by setting the Layout property. Other Bits of Syntax Sometimes it is necessary to define common functions that will be used throughout the page. For this purpose, Razor has a “functions” keyword which allows you to insert C# or VB function declarations. For example: @functions { @* But this will not, because it is a comment *@ Listing 11: Razor Comments Conclusion This is by no means a complete review of the features of Razor, there are a few more cool features to check out, so I recommend you check out the http://www.microsoft.com/web/webmatrix site and click the Learn tab to learn more about Razor, ASP.Net WebPages and WebMatrix. I hope you’re as excited to use Razor as we were to write it. We really believe this is a revolutionary new syntax and hope that you find it useful! • Andrew Nurse Andrew is a developer on the ASP.Net team at Microsoft and works on the Razor parser. public DateTime CurrentTime() { return DateTime.Now; } } The time is: @CurrentTime() Listing 9a: C# - Functions Block @Functions Public Function CurrentTime() as DateTime Return DateTime.Now magazine voor software development 11 DELPHI Cary Jensen Introduction to the Delphi Open Tools API In a recent article in this magazine I wrote about how you can add custom key bindings to Delphi's editor. In response, I received a number of questions about the mechanisms that permit Delphi developers to access something as internal as the code editor. This mechanism is called the open tools API, or OTA for short. It's been around since the very earliest days of Delphi, and it’s one of the more powerful, and least exploited areas of Delphi development. This is the first in a two part series on Delphi's open tools API. In this article I provide you with an overview of the OTA, and provide an example of a project that adds menu items to Delphi's menu. In the next article in this series, I will discuss a more complicated OTA implementation. Specifially, I will show you how to write a wizard that you can install into the Object Repository. deprecated, and the OTA is now entirely based on interfaces. And, with the release of the Galileo IDE (initially available in the now defunct C#Builder), the reliance of the OTA on pure interface definitions is complete. Overview of the Delphi Open Tools API Since Delphi 1, the Delphi IDE has provided developers with access to some of its most internal features. It is through this mechanism that tools such as CodeSite, CodeRush, and GXperts, and the like, have been able to extend the capabilities of Delphi beyond those implemented by the Delphi team. A Brief Overview of Interfaces Because they are so central to Delphi's open tools API, let's take a brief look at interfaces and their implementation. To begin with, an interface is a definition of public methods and properties. Interfaces serve as a sort of template for classes, defining the methods and properties that a class which implements the interface must support. In that sence, an interface defines a contract that a class must observe, without defining how that contract must be implemented. In the early days of Delphi, the open tools API was based on virtual, abstract base classes that provided templates for the features exposed through the OTA. In those days, you descended a custom class from one of these abstract classes, or one of their partially concrete descendants. One of the crucial features of an interface is that it provides for polymorphism without relying on common class ancestors. In other words, two classes that implement the same interface are assignment compatible with respect to that interface, regardless of what classes they descend from. It was a little clumsy in the early days. Even adding a single new component to the component palette required a complete re-compilation of the installed visual component library (VCL). Nonetheless, it was a groundbreaking capability. As far as the open tools API is concerned, these interfaces play two distinct roles. On the one hand, these interfaces define the collection of methods and properties that must be implemented in the classes that you create to implement your OTA features. (Well, that's not entirely accurate. The OTA also includes several interfaces, such as IOTAProjectWizard, that define no methods or properties. These interfaces are identifiers, and are used to signal to Delphi something about what roles the implementing object plays.) There have been many changes to the Delphi language over the years, and the open tools API has evolved along with it. Two of the major enhancements to Delphi that have had a profound influence on the open tools API was the introduction in Delphi 3 of packages and interfaces. With design-time packages, it became possible to easily install OTA extensions without re-compiling the entire VCL. On the other hand, some of the OTA extensions didn't actually require additions to the VCL. Instead, some of them, such as Object Repository wizards, were added to Delphi by compiling your Wizard class in a DLL. Delphi loaded that DLL based on entries that you made to the Windows registry. The second role of these interfaces is to define the methods and properties that are available for your use in objects that the OTA supplies for you. Specifically, there are numerous objects that you can use to do such things as manipulate Delphi's menus, toolbars, and glyphs. Similarly, there are objects that the OTA provides so that you can interact with the debugger, the code editor, the Object Repository, the Message pane, code completion, and much more. While packages made the installation of OTA classes easier, the introduction of interface support in the Delphi language had a much more profound influence on the architecture of the OTA. While interfaces were used sparingly when first introduced, they have grown exponentially more important in defining the application programming interface of the OTA. Indeed, the abstract classes of old are long These interfaces are actually divided into two groups, the native tools API (NTA) and the open tools API (OTA). The NTA is used to access the Delphi IDE objects, such as the menus and toobars. The NTA is defined by a single interface, INTAServices. By comparison, the OTA is a collection of interfaces that represent various facilities that the OTA makes available to you. 12 MAGAZINE DELPHI These include IOTACodeCompletionServices, IOTADebuggerServices, and IOTAKey BindingServices, to name just a few. (x86)\Embarcadero\RAD Studio\8.0\lib\win32\release (omit the (x86) if you are using a 32-bit operating system). The objects provided you by the NTA and OTA are accessed through a single interface, IBorlandIDEServices. The object that implements this interface is assigned to a global variable named BorlandIDE Services that is declared in the ToolsAPI unit. To access a service of the NTA or OTA you cast BorlandIDEServices to the appropriate interface. Actually, a better way to put this is that you should first ask whether or not BorlandIDEServices implements an object that implements the service you are interested in, and if so, then perform the cast. The Supports function, defined in the SysUtils unit, is the preferred technique for performing this task. For example, consider the following code var MessageService: IOTAMessageServices; begin if Supports( Fig 1: Configuring the package to be a design time package BorlandIDEServices, IOTAMessageServices, MessageService) then begin //CustMessage is a class that //implements IOTACustomMessage MessServ.AddCustomMessage(CustMessage.Create); end; Actually, this little code sample is a good representation of just how you approach the open tools API. Specifically, you use the Delphi provided object that implements the IOTAMessageServices interface to add a message to the Message pane (in this particular example). However, the method, AddCustomMessage, takes a single argument of the type IOTACustomMessage. That interfaces is one that you must implement in an object that you define. Next, we will add a unit in which we will define a class that implements the IOTAMenuWizard interface. To do this, use the following steps: 1. Select File | New | Unit. 2. Add the following units to the interface section uses clause: ToolsAPI, SysUtils, Menus, Dialogs. 3. Add a class that descends from TNotifierObject and implements the IOTAWizard and IOTAMenuWizard interfaces. In addition, add a declaration of a no-parameter procedure named Register. The interface section of this unit should now look like the code that appears in Listing 1. 4. Next, implement the methods of the TMenuDemo class and the Register procedure as shown in Listing 2. interface uses ToolsAPI, SysUtils, Menus, Dialogs In other words, Delphi provides some of the implementations of OTA (and NTA) interfaces, while you will supply additional objects that implement OTA interfaces, when necessary. type TMenuDemo = class( TNotifierObject, IOTAWizard, IOTAMenuWizard A Simple OTA Demonstration In the following project I am going to show you how to add your own menu items to Dephi's main menu using both the OTA and NTA. One of these menu items is added by implementing the IOTAMenuWizard interface, which you can use to add a single menu item to Delphi's Help menu. ) procedure MenuClick(Sender: TObject); constructor Create; { IOTAWizard } //Basic information about the wizard function GetIDString: string; function GetName: string; The second technique is more general, in that you can add one or more menu items to any of Delphi's menus. This second technique makes use of the NTA (and also requires greater care on your part, as you can seriously damage the Delphi IDE if you make mistakes). function GetState: TWizardState; procedure Execute; { IOTAMenuWizard } //Implement this interface to add an item //to the Help menu To begin with, you start with a design time package. Use the following steps to begin the project 1. From Delphi's main menu, select File | New| Package. 2. Right click the newly created package in the Project Manager and select Options. 3. From the Description page of the Project Options dialog box, set Usage options to Designtime only. 4. Right-click the project in the Project Manager and select Add Reference. Add the designide.dcp package to the project. In Delphi XE, this project is located by default in C:\Program Files function GetMenuText: string; end; procedure Register; Listing 1 implementation procedure Register; begin magazine voor software development 13 DELPHI RegisterPackageWizard(TMenuDemo.Create); end; item created by the implementation of IOTAMenuWizard. Similarly, you will find the Custom Menu Item menu item at the bottom of Delphi's Project menu, as shown in Figure 2. { TMenuDemo } constructor TMenuDemo.Create; var NTAServices: INTAServices; MainMenu: TMainMenu; Menu1, NewMenu: TMenuItem; begin if Supports( BorlandIDEServices, INTAServices, NTAServices) then begin MainMenu := NTAServices.MainMenu; Menu1 := MainMenu.Items.Find('Project'); if Menu1 <> nil then begin NewMenu := TMenuItem.Create(MainMenu); NewMenu.Caption := 'Custom Menu Item; Fig. 2: A custom menu item appears in Delphi's Project menu NewMenu.OnClick := MenuClick; Menu1.Add(NewMenu); end end;end; procedure TMenuDemo.Execute; Conclusion This article has given you a basic introduction to using Delphi's open tools API as well as its native tools API. In the next article in this series, we will take a look at a more complicated OTA project, one that adds a new custom wizard to Delphi's Object Repository. • begin ShowMessage('Your OTA object is executing'); end; Cary Jensen function TMenuDemo.GetIDString: string; begin Result := 'JDSI.MenuDemo'; end; function TMenuDemo.GetMenuText: string; begin Result := 'Select Me'; end; function TMenuDemo.GetName: string; begin Result := 'Simple Menu Demo'; end; Cary Jensen is President of Jensen Data Systems, Inc., a training and consulting company that won the 2002 and 2003 Delphi Informant Readers Choice Awards for Best Training. He is an award-winning author of 20 books, including Advantage Database Server: A Developers Guide (2007, Sybase), Building Kylix Applications (2001, Osborne/McGraw-Hill), JBuilder Essentials (1998, Osborne/ McGraw-Hill), and Delphi in Depth (1996, Osborne/McGraw-Hill). For information about onsite training or consulting services, you can contact Cary at cjensen@JensenDataSystems.com or visit his web site at www.JensenDataSystems.com. function TMenuDemo.GetState: TWizardState; begin Result := [ToolsAPI.wsEnabled]; end; procedure TMenuDemo.MenuClick(Sender: TObject); begin ShowMessage('This is where your new menu ' + 'item will do something cool'); DELPHI TIP: end; IntraWeb XI in Delphi XE Listing 2 The final step is to save your project and then install it. After saving your project, right-click the project in the Project Manager and select Install. Once it has been installed, you will find two new menu items added to Delphi's menu. On the Help menu you will find the Select Me menu 14 MAGAZINE De "bundled" versie van IntraWeb bevat niet langer alle features en mogelijkheden. Zo is o.a. ISAPI Deployment tegenwoordig uitgesloten van de gratis bundled features. Zie http://www.atozed.com/intraweb/featurematrix.aspx voor een overzicht van de versies en wat het kost om naar IntraWeb XE Ultimate over te stappen met daarin alle features. SDN > Update De bekende quote Premature Optimization is the root of all evil van Donald Knuth uit 1974 (http://pplab.snu.ac.kr/courses/adv_pl05/ papers/p261-knuth.pdf) is ook vandaag nog een bekend anti-pattern. Als programmeur probeer je van te voren al in gedachten je programma te optimaliseren. In 97% van de gevallen is de bedachte optimalisatie zo klein dat het (bijna) niets oplevert. Vandaar dat vaak wordt aangeraden om het programma eerst laten werken, leesbare code produceren, tests schrijven en dan als je ervaringscijfers hebt, dan te optimaliseren. Ik heb zelf gevoetbald en was noch een Sneijder noch een Robben. Wou altijd mooi scoren maar miste net doel. In ons collectieve geheugen staat Nederland - Spanje, Robben dribbel op Casillas gegrift. Ik zag die bal er al in gaan en droomde van een weeklang feest. Die teen van Casillas stond echt niet in het design, effectief was het zeker want het Spaanse doel bleef leeg. premature optimization is the root of all evil Zet een club van software architecten bij elkaar en iedereen optimaliseert vanuit zijn invalshoek. Geeft regels mee voor de bouw vanuit zijn gedachtenwereld. Hoe groter de organisatie, hoe meer acrchitectuur regels, design authorities, wijzigings advies commissies en andere ballotages je door moet. Zelf heb ik al een paar projecten meegemaakt waar het budget op ging in de architectuur fase door de constante drang naar optimalisaties vanuit verschillende hoeken. Erger nog het kan leiden tot een verlamming als je je het doel uit het oog verliest. Samen denken we na over academische oplossingen voor een praktisch probleem van de klant zonder aandacht voor het probleem van de klant zelf. Nu vraag je je vast af hoe Robben en Casillas in premature optimization passen. Soms moet je gewoon springen en kijken hoe ver je komt, tegen het gras of de bal wat meer hoogte geven, niet nadenken gewoon doen. Die terrabytes in je hoofd en de ervaring die je hebt laten de software wel werken. Schrijf het duidelijk op en maak het testbaar. De optimalisatie komt dan vanzelf want de code is test- en leesbaar en toegankelijk voor je collega’s die je bij de optimalisatie kunnen helpen. In 2012 worden we kampioen! Roel Hans Bethlehem • magazine voor software development 15 MOBILE Jaap van Ekris Wat is er zo moeilijk aan een mobiele applicatie? Mobiele applicaties zijn helemaal hot. Eigenlijk tel je als bedrijf niet mee als je geen mobiele app levert aan je klanten. Niet alleen de usual suspects als Nederlandse Spoorwegen en OV9292 maar ook Albert Heijn, TNT Post, QPark en Rabobank proberen actief een plekje te verwerven op het meest private stukje electronica wat we kennen: onze telefoon. Technisch is het ook niet zo moeilijk: er zijn voor Apples iOS, Googles Android en Microsofts Windows Phone zeer goede ontwikkelstudio’s beschikbaar. Het is geen drag-and-drop ontwikkelwerk, maar het scheelt erg weinig. De applicaties zijn functioneel vaak geen rocketscience. Feit is dat als je voor de desktop kunt ontwikkelen je ook voor de telefoon kunt ontwikkelen. Toch zit er wel een voetangel. Een groot deel van de gedownloade applicaties blijft ongebruikt. Slechts 25% van de gebruikers koopt ooit een applicatie. Dus er zijn wel degelijk een hoop applicaties die bij nader inzien gewoon “rommel” zijn in de ogen van de gebruiker. In dit artikel gaan we in op wat de rommel van de top-applicaties onderscheidt. We beginnen met het uitleggen van het meest fundamentele verschil tussen desktop en mobiele applicaties: de gebruikerscontext. Daarna kijken we naar de impact hiervan op de user-interface en gebruikte techniek. Gebruikerscontext De gebruiker en zijn context is zonder twijfel het grootste verschil tussen desktop en mobiele applicaties. De desktop gebruiker zit in het algemeen relaxed op een vertrouwd plekje zijn werk met zijn computer te doen. Kern hiervan is dat hij de omgeving vertrouwt en dat hij bezig is met zijn werk op de computer. De mobiele gebruiker is bezig in een onvertrouwde omgeving en heeft zijn telefoon nodig om hem te helpen beslissingen te nemen in die omgeving. Kern hiervan is dat de gebruiker in een onvertrouwde (wellicht zelfs onbetrouwbare of potentieel vijandige) omgeving bezig is beslissingen te nemen waarbij zijn telefoon hem moet helpen. De mobiele gebruiker moet, in tegenstelling tot de desktop gebruiker, real-life beslissingen nemen en wil eigenlijk helemaal niet bezig zijn met die applicatie. De mobiele applicatie is voor de gebruiker is slechts een noodzakelijk kwaad om zijn omgeving beter te begrijpen. Doordat de mobiele applicatie slechts een middel is tot een hoger gebruikersdoel, ontstaat er een soort ongeduld bij de gebruiker. Als de applicatie te traag is of teveel aandacht opeist zal hij de applicatie terzijde schuiven en gewoon “blind” beslissingen gaan nemen zoals hij vroeger ook deed: op een gegeven moment moet je als gebruiker gewoon die trein gaan pakken, in plaats van uitzoeken welke van de vele opties de meest optimale is. De wereld om de applicatie gaat door en de gebruiker dus ook, met of zonder applicatie. Gek genoeg is de benaderingswijze van veel software ontwikkelaars er een van het laten krimpen van een desktop-applicatie. Men heeft te veel informatie in de applicatie, de user interface is te complex en er wordt vaak geen rekening gehouden met technische beperkingen van mobiele toestellen. 16 MAGAZINE Keep it simple Een van de belangrijkste basisprincipes is “hou het simpel”. Dat klinkt makkelijk, maar de praktijk wijst uit dat het ontzettend moeilijk is een applicatie eenvoudig te maken voor de gebruiker: het vereist de moed om keuzes te maken. Een van de belangrijkste keuzes is het beperken van de applicatie tot één heel specifieke taak van de gebruiker. Een mobiele applicatie dient een bepaald doel en daar moet dus niet teveel franje in komen, omdat dat domweg in de weg gaat zitten bij gebruik. Een interessant voorbeeld hiervan is bijvoorbeeld de NS Reisplanner Xtra, die geen enkele informatie bevat over de prijs van een reis. Hij is puur bedoeld om mensen treinreizen efficient te laten plannen. Overigens moet ook bij deze applicatie wel een kritische kanttekening worden gezet: er is een deel in de applicatie gereserveerd voor marketing-acties, wat kostbare ruimte in de navigatiebalk kost. Als men dergelijke informatie zou willen bieden, zou je eigenlijk moeten overwegen een tweede applicatie te bouwen. SPB Traveller doet dit structureel: alle onderdelen (vluchtplanning, currency-converter, woordenboek, etc.) worden ook als losse applicatie geinstalleerd, zodat er vlot genavigeerd kan worden. User interface Een belangrijk onderdeel van de applicatie is de user interface. Belangrijk is om te onthouden dat de niet de tijd, zin of aandacht heeft om precieze handelingen uit te voeren. Ook moet informatie zeer overzichtelijk zijn om snel te kunnen analyseren. Dit betekent dat de applicatie hier ook op ingericht zijn. Dit uit zich op verschillende vlakken: het visuele deel van de de user interface maar ook de page-flow en de informatie die ingevuld moet worden in de interacties. Een belangrijke wake-up call voor GUI ontwerpers is dat mensen hun applicatie ook gebruiken, maar dan ook echt overal. Onderzoek laat zien dat veel mensen hun telefoon gebruiken als ze in bed liggen of op de WC zitten. Maar ook treinstations en bushaltes zijn vaak favoriete plekken om even wat te gaan doen. Dit laatste brengt nogal wat uitdagingen, zeker in Nederland en noord Europa. Mensen hebben ’s winters handschoenen aan of zijn onnauwkeurig door de koude. Kleine controls op zo’n telefoonscherm zijn dan ook volstrekt uit den boze, gewoon omdat het niet te bedienen is. Een scherm moet goed te bedienen zijn met een dikke handschoen aan of koude handen. Ook mensen die meer bezig zijn met hun omgeving zitten nog wel eens een paar milimeter mis. Grote knoppen met duidelijke gevolgen zijn dan ook essentieel. Daar faalt eigenlijk de iPhone GUI al een beetje: daar staan eigelijk al te kleine knoppen op. MOBILE Bedenk ook dat een gebruiker veelal informatie in een oog-opslag moet kunnen interpreteren, zonder al teveel analyse van zijn kant. In de desktop wereld kun je probleemloos informatie op een visueel aantrekkelijke, maar onoverzichtelijke, manier presenteren: de gebruiker moet er toch nog zijn eigen analyse op los laten. Een mobiele gebruiker wil graag snel hapklare informatie hebben die zijn beslissing in de wereld zal gaan beinvloeden. Je eindigt dan al snel in tabelgeorienteerde vormgeving. Visueel wellicht niet de mooiste oplossing, maar vaak wel de meest effectieve. Soms moet je een hele andere aanpak kiezen: file-informatie moet je wellicht niet als lijst van files weergeven (wat een behoorlijke wissel trekt op de topografische kennis van de gebruiker), maar meer als kaart van Nederland met rood snelwegen of gekleurde gebieden. Denk ook aan het minimaliseren van “vereisten” van een huisstijl. Bijvoorbeeld de NS heeft in haar NS Reisplanner Xtra een plaatje zitten die bijzonder veel ruimte inneemt. Ruimte die anders door nuttige informatie gebruikt zou kunnen worden. Maar ook zaken als logo’s, beeldelementen en standaard icoontjes kunnen op een klein scherm wel eens zeer veel ruimte kosten of erg onduidelijk overkomen. Het is verstandiger om te kijken hoe de applicatie het beste uit de verf komt, en dan pas een huisstijl hier passend in te krijgen, dan de huisstijl leidend te laten zijn. Page-flow is een volgend punt van aandacht. Die moet niet te complex zijn, maar zeker ook niet te lang. Een gebruiker raakt snel afgeleid, en de vraag “waar was ik ook al weer” is foutgevoelig en helpt niet bij het vlot uitvoeren van de dingen die hij snel wilde doen. Idealiter bestaat een handeling uit maximaal 3 tot 4 verschillende schermen die erg duidelijk maken waarmee de gebruiker bezig is. Denk ook over de gevolgen van de pageflow na: de gebruiker is bijzonder doelgericht en zal alles doen om die taak te volbrengen. Het beste voorbeeld hiervan is het navigatiepakket van de ANWB, wat niet toeliet dat de gebruiker de bestemming invoerde of wijzigde als de auto bewoog. Doel van de ANWB was om veiliger weggedrag te stimuleren. Gevolg was echter dat de gebruiker met enige vorm van creativiteit de GPS deactiveert en vervolgens alsnog zijn bestemming ingeeft/wijzigt. Gevolg is dus een agressievere en veel meer afgeleide bestuurder dan de bedoeling van de ANWB was. Ongemerkt zitten dit soort zaken in elke applicatie: een tunnelvisie van hoe het gebruiksscenario verloopt is handig, maar zeker niet altijd de realiteit. Ingevoerde informatie is een verhaal apart. Veel devices kennen een on-screen toetsenbord of zelfs een (klein) fysiek toetsenbord. Veel ontwikkelaars zien dit als een excuus om dit ook te gebruiken. Het gebruik van zo’n toetsenbord is alles behalve comfortabel: er zijn zelfs specifieke RSI-varianten voor dit soort gebruik ontdekt. Een paar tekens is vaak nog te doen, maar grotere stukken tekst zijn voor gebruikers vaak erg vervelend. Soms is het een bruikbaar scenario om complexe informatie via een website in te voeren en dan naar het toestel te syncen. Zo werken de reisschema’s van TripIT bijvoorbeeld. Voorkomen dat een gebruiker veel informatie moet invoeren is belangrijk omdat het afleid van het primaire doel van de gebruiker: zijn omgeving managen. Technische mogelijkheden en beperkingen Ook technische mogelijkheden en beperkingen spelen een sterke rol bij de kwaliteit van een mobiele applicatie. Het is voor een gebruiker zeer vreemd als technische mogelijkheden onbenut blijven of als je ingaat tegen technische beperkingen. Een smartphone heeft zeer veel technische mogelijkheden. Technisch gezien zijn ze bijna gelijk aan laptops van 3 jaar terug met office volledig geinstalleerd. Maar een smartphone weet tegenwoordig ook zijn eigen locatie en heeft een camera. Het is voor gebruikers dan ook zeer vreemd als je als applicatiebouwer daar geen gebruik van maakt. Het zou bijvoorbeeld bijzonder vreemd zijn als je bij de NS Reisplanner de startlocatie handmatig zou moeten ingeven. Hoogstwaarschijnlijk is dat het dichtsbijzijnde station. Maar ook verwacht de gebruiker bijvoorbeeld dat Appie, de Albert Heijn boodschappenlijst, gewoon automatisch het juiste filiaal selecteert. Maar de gebruiker verwacht ook integratie met de agenda en contactpersonen. Gewoon omdat het technisch mogelijk is en hem veel complex werkt bespaart. Maar de smartphone kent ook zijn technische beperkingen: met name de accu is een van de belangrijkste. Als je als applicatie de accuduur significant verkort, door veel van de GPS, CPU of internet-verbinding te vragen, dan pak je figuurlijk de telefoon van de gebruiker af. Je verkort de bruikbare tijd van een telefoon voor de gebruiker. Dus veel energie gebruiken door intensief energie-slurpende hardware te gebruiken is niet verstandig. Dat is de manier om slechte reviews te krijgen met de opmerking “battery drain”. Een ander punt is de internetverbinding. De telecom-operators willen ons erg graag laten geloven dat hun netwerk overal aanwezig is met voldoende bandbreedte. Dit is niet het geval: de dekking door hun netwerken valt in de praktijk gewoon erg tegen. Zelfs al zou je goede dekking hebben, valt de kwaliteit daarvan vaak tegen door verstoringen door gebouwen of warmtewerende beglazing. Bovendien raken netwerken erg snel overbelast: een grote storing op Utrecht Centraal en je krijgt in de wijde omtrek geen data-verbinding meer. Een volledige afhankelijkheid van internet is dus iets wat je als ontwikkelaar moet zien te vermijden als het mogelijk is. Conclusie is dus dat het bij mobiele applicaties veel minder over de harde techniek van API-calls en code gaat, maar veel meer nadenken over hoe de applicatie gaat functioneren in de context van een gebruiker die iets wil realiseren. Bij mobiele applicaties gaat het veel meer om hoe de gebruiker snel zijn beoogde taak kan realiseren, en dat vergt speciale aandacht voor wat de functionaliteit is, hoe de GUI er uit ziet en de oplossing technisch wordt opgezet. • Jaap van Ekris Jaap van Ekris (Det Norske Veritas) is een Microsoft Most Valuable Professional, gespecialiseerd in Mobiele applicaties, hoe ze passen in het levensritme van hun gebruikers en de business modellen achter applicaties. SDN Event 18 maart 201 1 aanmelden v ia www.sdn.nl/sd e magazine voor software development 17 ((1%((7-(,7(5 ,6(,*(1%$$6 =RJDDWGDWWHJHQZRRUGLJ%HQMHHHQPDDOHUYDUHQJHQRHJLQGH,&7GDQNLHVMHYRRUHHQEHVWDDQ DOV]HOIVWDQGLJRQGHUQHPHU:HUNJHQRHJ'XL]HQGHQIUHHODQFHUVJLQJHQMHYRRU+HWHQLJHPLQ SXQWMHDDQKHWRQGHUQHPHUVFKDSLVKHWJHPLVDDQ]HNHUKHGHQGLHYDQ]HOIVSUHNHQG]LMQYRRUHHQ ZHUNQHPHU:DQWHHQYDNEHNZDPHHQDPELWLHX]H,&7HULVQLHWSHUGHÀQLWLHHHQFRPPHUFLsOH GXL]HQGSRRWRIKRXGWHUQLHWYDQRPHHQXLWJHEUHLGHDGPLQLVWUDWLHWHYRHUHQHQRSHQVWDDQGH IDFWXUHQQDWHEHOOHQ'HZDUPHGHNHQYDQHHQYDVWGLHQVWYHUEDQGKHHIWRRNYRRUGHOHQ 'HVFKRHQZULQJW %HUJOHU&RZHHWZDDUGHVFKRHQZULQJW$OVIUHHODQFHUYHUGLHQMHLQGHUHJHOPppU'HORNURHS LVQDXZHOLMNVWHZHHUVWDDQ'DDURPNULMJMHYDQRQVHHQGHUGHRSWLHZDDULQGHYULMKHLGYDQ IUHHODQFHQVDPHQYDOWPHWGH]HNHUKHLGYDQHHQYDVWGLHQVWYHUEDQG'HVOHXWHOYDQGHIRUPXOH LVGDWMH²QDDVWKHWEDVLVVDODULVYRRUHHQJURRWGHHO]HOIGHKRRJWHYDQMHLQNRPHQEHSDDOW %HWHUYRRUMRXEHWHUYRRU%HUJOHU&R -LM FRQFHQWUHHUW DOOH DDQGDFKW RS KHW SURMHFW %HUJOHU &R QHHPW RQGHUWXVVHQ GH YHUDQW ZRRUGLQJYRRUDFTXLVLWLHHQDOOHSULPDLUHHQVHFXQGDLUHDUEHLGVYRRUZDDUGHQ'DDUPHHEHQMH %HUJOHU1HGHUODQG%9 RQPLGGHOOLMNHQGHÀQLWLHIYHUORVWYDQMHHLJHQDGPLQLVWUDWLHYRHUHQHQRQGXLGHOLMNKHGHQURQG %LMVWHU$ YHU]HNHULQJHQDXWRHQSHQVLRHQRSERXZ'DDUNRPWQRJELMGDWMHPHWHHQYDNJHULFKWHWUDLQLQJHQ +;%UHGD HQRSOHLGLQJHQRSPDDWNXQWYROJHQ'DWLVEHWHUYRRUMRXHQEHWHUYRRU%HUJOHU 7 ) S]#EHUJOHUFRQO (HQEHHWMH,7HUZHUNWELM%HUJOHU %HUJOHU &R PDDNW GHHO XLW YDQ %HUJOHU ,&7 'H]H RQGHUQHPLQJ LV DO GHUWLJ MDDU DFWLHI LQ VRIWZDUHRQWZLNNHOLQJ:LM]LMQRS]RHNQDDUHUYDUHQVSHFLDOLVWHQRSKHWJHELHGYDQ0LFURVRIW 9HVWLJLQJHQ 1(7-DYD-((HQWHVWHQGLHRSNRUWHWHUPLMQLQ]HWEDDU]LMQ:LOMLMHHQEHHWMHHLJHQEDDVHQ %UHGD$PVWHUGDP HHQEHHWMH%HUJOHUNLMNGDQRSRQ]HZHEVLWHEHUHNHQMHWRHNRPVWLJHVDODULVHQQHHPFRQWDFW 5RWWHUGDP$SHOGRRUQ RSPHWHHQYDQRQ]HYHVWLJLQJHQ0DLOHQNDQRRNS]#EHUJOHUFRQO .NET Eric Roosendaal Drag and Drop deel 2: Bestanden slepen naar de Windows Explorer Laten we om te beginnen aannemen dat u een ListBox hebt, gevuld met filenamen, zoals hieronder. } } Nu moet het Draggedeelte nog daadwerkelijk worden ingevuld. Het eerste gedeelte is eenvoudig: de ListBox heeft een property Selected Items die alle geselecteerde items bevat. Doorloop deze collectie en verzamel alle geselecteerde items in een generic List van strings. List<string> list = new List<string>(); foreach (var x in listBox1.SelectedItems) { list.Add(x.ToString()); } Maar dan moet de data nog meegegeven worden bij DoDragDrop, en daarvoor is een speciaal object nodig. Zo’n object heet een Data Object. Dit moet nieuw worden gemaakt en bovendien moet er bij worden aangegeven, dat het een object moet worden voor het verslepen van bestanden. Daarvoor is een speciaal formaat nodig en dat heet DataFormats.FileDrop. Tenslotte wordt het object gevuld met de inhoud van de List die dan eerst moet worden omgezet in een string-array. De code ziet er dan zo uit: DataObject data = Hoe kunt u nu een aantal van deze bestanden verslepen naar de Windows Explorer? Omdat het handiger is om meer bestanden tegelijk te kunnen slepen stellen we de SelectionMode van de ListBox in op MultiExtended. Het implementeren van bestanden slepen is redelijk straightforward De code voor het starten van een Dragactie via het MouseMove Event is al in deel 1 aan de orde geweest. De code luidde als volgt (voor het waarom precies verwijzen we gaarne naar deel 1): if ( isdragstart ) { if( Math.Abs(e.Location.X - dragstartposition.X) > SystemInformation.DragSize.Width / 2 || Math.Abs(e.Location.Y - dragstartposition.Y) > SystemInformation.DragSize.Height / 2) { isdragstart = false; // perform the drag new DataObject(DataFormats.FileDrop, list.ToArray()); listBox1.DoDragDrop(data, DragDropEffects.Copy); U zult nu merken dat u bestanden van de ListBox naar een folder kunt slepen. • Eric Roosendaal Eric Roosendaal is trainer bij Compu'Train. Hij is afgestudeerd in Scheikunde, maar eind jaren '80 geswitcht naar IT, met name naar Development. Sinds medio jaren '90 in dienst van Compu'Train als specialist voor alle programmeertalen, de laatste jaren met name .NET (VB en C#). Hij is Microsoft Certified Trainer, gecertificeerd sinds 1995. Eric is te bereiken via eroosendaal@computrain.nl. magazine voor software development 19 ARCHITECTURE Sander Hoogendoorn A recipe for enterprise agile. Mixing Scrum and Smart To cut to the chase, those of you who have worked on enterprise or service oriented projects before already know this. These types of projects are characterized by a large number of organizational, functional and technically complicating factors. Enterprise software development projects are surrounded by a large number of complicating characteristics and challenges: • Many different stakeholders Projects have many different parties in the organization that are involved. Often such projects realize goals for different departments or divisions in the organization. As an example I once coached a project that served 22 different departments. Quite often these departments or division try to achieve overlapping or even contradicting goals. • Business processes In general enterprise projects (re-)implement (parts of) business processes that are key to the organizations success, rather than building a straightforward web application. • Complex software architectures Most likely, enterprise projects implement business processes in a complex IT landscape or architectures. Think of landscapes that host many different applications all tied together. • Many external dependencies Often, such complex IT landscapes contain components that are 20 MAGAZINE outside of the organization. Services that run outside the corporate firewall, with other parties. A well-known issue to agile projects is that of availability. We need the new version of the service in this iteration, but the other party runs a waterfall project that will not deliver this year. • Changing requirements In enterprise projects, requirements change continuously. Either by changing insights during the project, but more often due to changing legislation or regulations. • Many different types of deliverables Traditionally these projects count many different types of deliverables. Think of service description, user interface, process models, non-functional requirements, workflow, project plans, test plans and many, many others. • Multiple roles Large organizations have many different roles that are involved in projects. There are business analysts, enterprise architects, information analysts, testers, release managers, SAP developers, web developers, SAP functional consultants, Thus these projects often become a mission impossible, and fail in large numbers. Such projects are difficult to estimate, therefore hard to plan. For developers it’s tough to build the software, often with many new techniques and technologies, and even worse for testers, these projects are sheer impossible to test well. This is where a structured agile approach should come to the rescue. Being agile in enterprise projects Independent of the approach that is applied, or the agile process that is followed, being successful in agile projects follows a number of key principles: • Multi-disciplinary teams Instead of different roles such as analysts, designers, developer and testers working in consecutive stages in a project, all roles collaborate in implementation individual work items from heads to tails. • Short iterations Project work in short time boxes, in most cases 2, 3 or 4 weeks. During such an iteration, a number of work items is planned, completed and evaluated – with different terminology in use with different agile processes. • A small standardized unit of work Projects require a small unit of work, to be able to deliver a number of them in a single iteration. Large work items such as traditional use cases therefore do not apply well. • Testing from day one Testing is an important discipline during agile projects. Testers are involved from the very first iteration, when the first work items are realized. Note that testing in most projects goes way beyond the obvious unit testing – which is actually a developer technique. ARCHITECTURE • Continuous measurement Successful agile projects continuously measure their progress. Since they are always delivering individual work items, measurement in agile projects is easy. • Continuous (process) improvement At the end of each iteration not only the realized work items are evaluated, but also the project approach itself is evaluated, leading to highly effective project approaches. Scrum in a nutshell When organizations first start with agile projects Scrum is often the process of choice. At this point in time, Scrum is by far the most popular and best known agile approach. Scrum is a straightforward lightweight agile process that offers a collection of highly applicable principles and techniques for short iterative projects and is easy to understand. It also specifies a remarkable terminology with scrums, sprints and user stories. In a nutshell, Scrum is characterized as follows: • Sprints Projects are divided into iterations, called sprints. In general these are 2 to 4 weeks. • Backlogs Work items still to be done during a project reside in a so called project backlog. At the start of each sprint items from the backlog are placed in the sprint backlog. These are the worked items to be realized. • Sprint cycle All iterations follow the same simple process, with an iteration kickoff, actual work and a retrospective workshop for evaluation. • User stories The main unit of work is usually the user story, although this is not mandatory. This rather informal requirements technique is shared with the agile process extreme programming. • Planning In general the project and sprint planning is visualized in task boards, which usually are put up on a wall using post-its. Progress is monitored by using burn down charts, a straightforward diagram that on a daily basis displays the number of points still to realize. A trend line in the burn down chart extrapolated from the points identifies the likely project end date. Again this technique is shared with a number of other agile processes, including Smart and extreme programming. • Delivery Every iteration or sprint results in fully delivered products, software or otherwise. Scrum has proven to be a successful approach in many (smaller scale) web projects. In larger, more complex, service or cloud oriented and enterprise projects, I think Scrum needs to be augmented to fit the project and its environment. Let me explain. Beyond lightweight agile When applying Scrum or other lightweight agile processes such as Crystal Clear or the set of lean principles (applied to software development that is) to more complex projects of all sorts, you might recognize a number of shortcomings: • Business goals It is often unclear how the work items in such projects (in most cases user stories) link back to business goals, stakeholders and business processes to implement. • Analysis and design. Although many people in the so-called agile community will now think I’m promoting a waterfall approach, in most agile approaches there are hardly any analysis or design activities or deliverables defined. For instance, it is undefined how the backlog in a Scrum project is assembled. Let me assure you, in more complex projects some analysis and design is required, albeit not in big-upfrontdesign mode. • Architecture The same argument goes for software architecture. Most agile approaches lack decent software architectural activities and deliverables. Architecture is often assumed as-is. If you’re implementing business processes that run through a systems landscape of over 40 collaborating systems, you will definitively need to design your architectures, but again this need not be in big-upfront-architecture mode. • Roles Scrum and extreme programming describe a very limited set of roles that, although looking slick, in most projects does not adhere to the standing organization. There’s often enterprise architects, information analysts, business analysts, middleware developers, application management, testers, release manager. How will a project work with all those roles? There’s a bit more to it than just saying they are allowed to participate in the daily scrum. • Testing Apart from the obvious (developer) techniques such as unit testing, the role of testing more specifically – which is essential in larger agile projects – is not very well described in lightweight agile approaches. • User stories Although very flexible, user stories are a highly unstructured unit of work, despite efforts in epics or story maps. Applying such an unstructured unit of work may result in low re-use, non-repeatable estimation, difficult to standardize development, testing and measurement beyond the individual projects. In a multi-project environment user stories will block progress and reuse (of for instance metrics and code). • Delivery cycle Scrum does not specify the organization of delivery of the products to different environments such as test, acceptance and (pre)production (so called OTAP). When executing large, more complex, service oriented or enterprise projects, I therefore strongly recommend to overcome these limitations by augmenting Scrum and the likes with additional techniques. Smart accelerators In my personal experience in enterprise projects I have had very good experiences with mixing the agile process Scrum with the best magazine voor software development 21 ARCHITECTURE practices from another agile process called Smart to overcome the drawbacks of the aforementioned approach. Smart originated from the Netherlands in 1998 and was originally designed to implement best practices for DSDM, an iterative approach that was popular in those days. Later Smart grew out to a stand-alone agile approach that particularly combines well with other more basis agile approaches such as Scrum and extreme programming, but also aligns well with PRINCE2. More specifically Smart puts accents on aspects in project that are only marginally highlighted in other agile approaches. As an example Smart adds the following accelerators to projects: • Preliminary iterations Preliminary iteration types Propose and Scope is where work items are added to the backlog such as a modeling business processes, modeling smart use cases, creating an estimate, creating a costbenefit analysis, writing a project plan (not that obvious it seems), first-cut software architecture set-up, development environment set-up, project kick-off, team education and first-cut user interface guidelines. • Smart use cases Next to the more “non-functional” work items mentioned above, Smart introduces the well-known smart use cases requirements technique. Smart use cases not only model the needs of the user, but also identify workflow and reusable back-end services. This technique allows for identifying re-use, repeatable and reliable estimation, and very good traceability between requirements, architecture and code, great functional testing capabilities. An absolute must in enterprise projects. • Estimates Estimation of size and complexity of a project is estimated and measured in smart use case points, defined on a scale from 1 to 10. Smart use case points of course come from estimating the size or complexity of smart use cases, and is a highly pragmatic and repeatable technique.. • Work item life cycle Where Scrum’s work item life cycle contains to-do, working and done, in Smart, work items are delivered through a slightly more structured life cycle, that allows for all roles in enterprise projects to be maximally involved in a collaborative manner. Due to the life cycle, work items need not be broken down in tasks, a cumbersome and highly unstructured element of Scrum. In Smart work items simply move through the stages of the life cycle (in most cases in one or two days), the progress of which can be shown easily on a dashboard. • Designing During the daily stand-up meeting, it is decided whether or not a design session is required. This time-boxed design session addresses the design or a single smart use case. Most project will 22 MAGAZINE organize this design session directly after the daily stand-up. On a typical time scale, if the stand-up runs from 10:00 to 10:15, the design session runs from 10:15-11:00. During such sessions all roles that need to deliver input to this particular use case participate. Of course also the developer and tester are present, so all roles create a homogeneous view of the smart use case at hand. • Smart testing Working with user stories will normally not result in a very efficient test approach, as user stories do not add structure to the project. Smart describes a standardized approach on functional testing in agile projects of course based on smart use cases. • Stabilizing iteration Usually the last iteration of a Smart project or the last one to an upcoming release is used to round off remaining work items, build issues, bugs, and remaining features. This iteration is merely used to stabilize the solution. In Smart this iteration type if referred to as Finalize. Blending Scrum and Smart Besides defining an obvious project life cycle, these best practices from Smart blend in really well with the more lightweight approach of Scrum and extreme programming. This leads to the following best practices: • Initial backlog The initial backlog of the project is filled with the work items Smart recommends, rather than assuming a user story filled backlog. When prioritizing work items for the first sprint in a mixed Scrum and Smart project, it is very likely that these are picked. As a result, after one or two iterations, a project plan for the remainder of the project is produced, containing at least an estimate, based on the smart use cases that are also defined during these iterations (of course without any analysis or design, just the diagrams, the ovals and the actors). • Iteration kick-off After the initial work-items are cleared from the backlog, the smart use cases become the primary work item type in the project. During sprint kick-off a number of smart use cases is picked to implement in the next sprint. • Dashboard The traditional Scrum task board is replaced by Smart’s agile dashboard, containing columns for the stages in the work item life cycle – In Iteration, Designing, Working, Testing, Rework, Accepted. If appropriate additional columns can be added, e.g. when testing is split up in Developer Testing and Customer Testing. • Points The progress in the project is not measured in story points, but rather in smart use case points. ARCHITECTURE very well aligned with the organizations release calendar. This approach of mixing best practices, techniques and tools from Scrum, Smart over the past 12 years has proven to be very successful in a variety of projects and project types, including larger Java and .NET projects. service oriented projects, business intelligence projects, and even packaged implementations. Moreover, when augmented with more technical best practices from extreme programming, such as refactoring, continuous integration, pair programming, and test driven development (smart use cases are a very good unit for unit testing code) projects are aligned to deliver ontime, on-budget, and with just-enough documentation and fitting (reusable) features. As former US president Bush used to say: failure is not an option. • • Scrum meeting The focus of the daily scrum meeting shifts a bit as it is also used to answer the question: what still needs to be done on the smart use case(s) we’re currently working on to get them accepted? • Design Host the design sessions as Smart recommends, preferably right after the daily scrum meeting. • Testing As the work item life cycle clearly stipulates, functional testing, often done manual is all in a days work. The role of the testers here becomes imminent in the project. • Finalize Projects have to decide when to apply a Finalize iteration to stabilize the solution and round up loose ends. Depending on the type of project, these iteration can be the very last sprint, but also can be Sander Hoogendoorn Principal Technology Officer and Agile thought leader Capgemini www.smartusecase.com www.sanderhoogendoorn.com The Triple A Company = SharePoint. Ruim 11 jaar verzorgen wij de implementatie van Microsoft SharePoint voor organisaties uit diverse markten. Daar zijn we trots op en we willen graag dat je in die trots gaat meedelen. Ter uitbreiding van het team zijn wij per direct op zoek naar een: SharePoint Managing Consultant M/V Als Managing Consultant kun je jouw team van SharePoint Consultants stimuleren en richting geven. Je zorgt er voor dat planningen gemaakt en gehaald worden. Je begeleidt projecten en springt in als het moeilijk wordt. Functie-eisen: Universitair/HBO werk- en denkniveau. Minimaal vier jaar ervaring met SharePoint implementaties en managementprojecten. Hoge mate van zelfstandigheid. Projectmanagement en coaching is een tweede natuur. Over The Triple A Company: The Triple A Company is informeel, kenmerkt zich door ͞ĂůůĞƐŵĂŐƚĞŶnjŝũŚĞƚǀĞƌďŽĚĞŶŝƐ͕͟ĞŶŬĞŶƚĞĞŶƉůĂƚƚĞhiërarchie. We zijn een flexibel, innovatief en een vooruitstrevend bedrijf met een sterk concurrerend en onderscheidend vermogen in de markt, experts. Interesse? Herken je jezelf in het profiel en wil je deze uitdaging aangaan? We ontvangen je Curriculum Vitae samen met je motivatie graag voor 31 maart 2011 op werken@triplea.net of per post t.a.v. Dhr. A.M.C. Deibel, 5301 LJ, Zaltbommel. Voor meer informatie verwijzen wij u naar onze website www.triplea.net. Voor aanvullende informatie kunt u contact opnemen met Dhr. A.M.C. Deibel op: 0418 -510 570. CORE SYSTEMS Paul Klicnik Introduction to the code coverage tooling in Rational Application Developer Code coverage is an important aspect of software testing, and can be considered fundamental to the overall system testing of a component. The motivation behind coverage tooling is simply to give you (as a developer or tester) more insight into the areas of code that are being exercised by a set of test cases. This information is useful because you can then use it to devise new test cases to achieve adequate coverage. The IBM® Rational® Code Coverage feature is a tool that integrates with IBM® Rational® Application Developer. You can use it to generate and analyze coverage statistics for your Java applications. The tooling generates statement coverage statistics for the application under test (that is, the number or percentage of lines in your application that have been executed). Instrumentation In order to properly analyze the coverage statistics in the Rational Code Coverage feature, it is important to understand the technology used behind the scenes. Rational Code Coverage uses an instrumentation engine to manipulate the bytecode of a class and inject custom calls to the coverage data collection engine. Figure 1 provides a high-level overview of the process: By definition, a basic block is a set of instructions that cannot be branched into or out of. The key idea here is that when the first instruction runs, all of the subsequent instructions in that block are guaranteed to be executed without interruption. It follows that a basic block can be conceptually considered a single group or block of instructions. In general, basic blocks end on branch, call, throw or return statements. An executable unit begins at the start of every basic block and at any instruction that corresponds to a line of source code that is different than the previous instruction. What differentiates an executable unit from a basic block is the condition that triggers the end of the executable unit. For example, the divide instruction is not considered to be the end of an executable unit despite the fact that it can throw an exception. The instrumentation engine in Rational Code Coverage is used to inject custom code at the start of every executable unit. Consequently, you can customize the Rational Code Coverage feature to report statistics down to the executable unit level of granularity (in other words, block coverage). Figure 2 provides an overview of how the instrumentation engine modifies the bytecode to support code coverage. Fig. 1: Overview of the Rational Code Coverage execution environment Fig. 2: Overview of the bytecode instrumentation Basic blocks versus executable units The instrumentation engine operates on units of bytecode called executable units. The definition of executable unit is slightly different than the traditional definition of basic block, but the differences are important to take into account when the results are analyzed. 24 MAGAZINE Generating coverage statistics in RAD One of the major advantages of the Rational Code Coverage feature is that you can enable it on any Java project in RAD by navigating to the Code Coverage panel in the project Properties, as shown in Figure 3. CORE SYSTEMS Fig. 4: UML diagram for the sample application Fig. 3: Code Coverage panel in the project Properties While in the Java perspective in RAD, you can start the TestCar.java test by right-clicking TestCar.java and selecting Run As > JUnit test. The results of the JUnit test will appear in the JUnit view as normal. The coverage results are integrated into the RAD UI, and you can analyze them by switching back to the Package Explorer. Figure 5 displays a sample result set for the TestCar.java test. Select the Enable code coverage check box in Figure 3 to enable code coverage for the project, and to instrument the classes in your project under the covers. You can also use this panel to customize acceptable coverage levels for each step of granularity. The supported levels of granularity are described following: • Type coverage: the percentage of types covered in a class • Method coverage: the percentage of methods covered in a class • Line coverage: the percentage of lines covered in the class file • Block coverage: the percentage of blocks covered in a class file. Note that a block refers to an executable unit (as described previously) You can also specify custom filters, and they are used to control what gets instrumented in your project. By default, all of the classes in your project are instrumented, but you can create custom filters to exclude target packages or specific types, if there is a need to restrict the results. Package Explorer After you enable code coverage on a project, coverage statistics will be generated the next time that the application is launched. Note that statistics will not be generated for all types of launch configurations automatically. Table 1 displays the launch types that are supported from within RAD. Launch Type Java Applet OSGi Framework JUnit JUnit Plug-in Test Java Application Eclipse Application Standard Widget Toolkit (SWT) Application Table 1. Supported launch configurations A sample application has been provided (see link at the bottom of this article) and will be used throughout this article. The application is a simple representation of different vehicles (car, van, motorcycle, and so on) and the various parts associated with each vehicle. The UML diagram outlining the structure of this application is displayed in Figure 4. There are two JUnit tests already defined in the project: TestCar.java and TestCarImproved.java. As the names suggest, these tests target the Car.java class. Fig. 5: Coverage results for TestCar.java displayed in the Package Explorer By default, the UI is annotated with only the line coverage information; however, you can change this in the workbench Preferences, and optionally choose to include coverage for packages, types, and blocks. The percentage beside each Java item is a breakdown of the line coverage for the last execution. You can drill down into the various Java artifacts (for example, classes, types, and methods) in the Package Explorer to get coverage statistics at a lower level of granularity. The results are color-coded depending on the success rate: by default, red indicates that the acceptable coverage level has not been met while green indicates that the appropriate coverage level was achieved. Naturally, the goal of the test is to reach an acceptable coverage level on the classes of interest. magazine voor software development 25 CORE SYSTEMS Based on the results shown in Figure 5, the first test was inadequate: the Car class (and abstract parents AbstractFourWheelVehicle and Vehicle) did not reach appropriate coverage level. Luckily, you have a second attempt to execute: TestCarImproved.java. Again, you can execute the test as a normal JUnit and the results are automatically updated in the Package Explorer (Figure 6). was not covered. There is a slight advantage in viewing the results in the Java Editor because it also indicates the partially covered lines. Partially covered lines can occur when there is more than one executable unit on a line of source code, but only one of them has been executed. As an example, look at the first line of code in the setTargetSpeed(int speed) method shown in Figure 7: the first executable unit is the if statement, and the second executable unit is the return statement. By default, a partial line is colored in yellow. Generating reports You can compile the code coverage results into reports and view them in RAD, or save them to the file system for future analysis. You can generate two different types of reports: Workbench reports (Eclipsebased) and HTML reports. To generate a report, select Run > Code Coverage > Generate Report. Figure 8 shows the report generation dialog. Fig. 6: Code coverage results for TestCarImproved.java displayed in the Package Explorer Java editor Line coverage results are also displayed and marked in the Java editor, and you can use it to give a more precise indication of which lines are covered in each class. After coverage statistics have been generated, you can open any class in your project with the Java editor, and the left ruler bar in the editor shows the coverage information. Figure 7 displays the results for Vehicle.java: Fig. 8: Report generation dialog You can create and view a report in RAD using the Quick View option on the dialog, or save it to the file system using the Save Report option. Fig. 7: Coverage results displayed in the Java editor The color indicators are the same as they are in the Package Explorer. That is, by default a green line was covered and a red line 26 MAGAZINE Workbench reports The workbench reports (also known as Eclipse-based reports) provide a consolidated view of all of the coverage statistics for your project, and contain coverage information for all of the classes in your project at execution time. Figure 9 shows a populated Eclipse-based report. Workbench reports have the added advantage of being integrated in RAD, so you can use them as a quick tool to provide insight into the parts of your code that require improved test coverage. As Figure 9 shows, the statistics in a workbench report contain coverage information for all levels of granularity: from a package to a method. Right-clicking any of the Java artifacts displays a pop-up menu with two additional actions: Show in Package Explorer and Open in Java Editor. These are useful tools for identifying and investigating areas of code with low coverage, because they highlight the elected area of code by opening it in the appropriate viewer or editor. CORE SYSTEMS A quick overview of the expected parameters is outlined in Table 2. Both approaches to instrumentation will output a baseline file. A baseline file is a notion specific to the Rational Code Coverage feature. The baseline file contains an index of all of the classes in your project, and maintains additional metadata about each class. Fig. 9: Coverage results in an Eclipse-based report HTML reports HTML reports display the same type of information provided in the Eclipse-based report, but in HTML format. These reports are particularly useful when saved to the file system, because they provide a way for the coverage results to be analyzed independently of RAD, shared with team mates, or published to a Web site for viewing. Generating statistics outside of the workbench One of the major features of the Rational Code Coverage tool is its ability to generate statistics outside of RAD. This provides extra flexibility and enables you to customize your environment to take advantage of the Rational Code Coverage feature in your systems. For example, one natural combination would be to set up a nightly build environment and generate statistics with JUnit tests on the nightly driver. You can integrate the Rational Code Coverage feature into your environment by performing the following three steps: instrumentation, execution, and report generation. Step 1. Instrumentation There are two different approaches that you can use to instrument your application. The first is to use the instrument.bat/sh script provided in the <RAD_HOME>/plugins/com.ibm.rational.llc. engine_ <date>/scripts directory. This article does not focus on this script, but you can reference the RAD documentation for more information if necessary. The second approach is to use the instrumentation Ant task provided by the Rational Code Coverage feature. Listing 1 shows an example usage of the instrument task configured to target the sample application in this article. <target name="instrument"> <taskdef name="instrument" This file is used at the reporting step (Step 3) to determine which classes in your application were not covered. This step is necessary because the Rational Code Coverage data collection engine is only notified of a class when it is loaded by Java™ Virtual Machine (JVM), and so a list of the classes that were not executed cannot be determined without additional metadata. If the baseline file is not present at reporting time, the classes that were not loaded will be absent from the report. Parameter Description The path to the project on the file system outputDir (Optional) The output directory of the instrumented project. If not specified, the classes in the buildPath will be instrumented in place. baseLineFile (Optional) The output location of the baseline project index file. See the following paragraph for more information on this file. saveBackups (Optional) Set to true if the original class files should be backed up before instrumenting. buildPath Table 2: Input parameters for instrumentation tasks Step 2. Execution In order to execute the instrumented classes, the Java environment must be configured correctly at launch. The two specific parameters needed for execution are explained below: • -Dcoverage.out.file=<absolute path to output file>: the file specified by this JVM argument is the output location of the coverage statistics • Add the <Rational Application Developer HOME>/plugins/ com.ibm.rational.llc.engine_<date>/RLC.jar to the classpath: because the code has been instrumented with callbacks to the the Rational Code Coverage data collection engine, the RLC.jar file needs to be on the classpath at runtime. These parameters can be supplied to a JUnit Ant task. Listing 2 provides example usage. classname="com.ibm.rational.llc.engine.instrumentation. anttask.InstrumentationTask" classpath="{path to com.ibm.rational.llc.engine plugin}"/> <instrument saveBackups="true" baseLineFile="project.baseline" buildPath="VehicleProject" outputDir="VehicleProjectInstr"/> </target> <target name="run"> <junit showoutput="true" fork="yes"> <jvmarg value="-Dcoverage.out.file={absolute path to the output file}"/> <classpath> <pathelement location="{absolute path to the <Rational Application Developer HOME>/plugins/com.ibm.rational.llc.engine_<date> Listing 1: Example usage of instrument Ant tasks on the sample application in this article /RLC.jar file}"/> <pathelement location="{path to the project classes}"/> <pathelement path="{absolute path to the junit.jar}" /> </classpath> magazine voor software development 27 CORE SYSTEMS <test name="com.ibm.vehicles.tests.TestCar" outfile="TestCar" /> </junit> </target> Listing 2: Example of how to specify the the Rational Code Coverage feature arguments in an Ant launch Step 3. Report generation You can generate reports using another Ant task provided by the Rational Code Coverage feature. This task uses the reporting functionality provided by the BIRT Eclipse.org project, and thus requires that you download the BIRT V2.3.2 Reporting Engine standalone offering. This can be done by navigating to http://www.eclipse.org/birt/ download, select the V2.3.2 release and downloading the Report Engine offering. Note that this Ant task can only produce HTML reports. Listing 3 provides sample usage of the reporting Ant task. Note that, as input, it requires the coveragedata file generated in Step 2 and (optionally) the baseline file generated in Step 1. Fig. 10: Coverage results in an HTML report • <target name="generate-report"> Paul Klicnik <path id="lib.path"> <pathelement location="{absolute path to the <Rational Application Developer HOME>/plugins/ com.ibm.rational.llc.common_<date>.jar plugin}"/> <pathelement location="{absolute path to the <Rational Application Developer HOME>/plugins/ com.ibm.rational.llc.report_<date> plugin}"/> <pathelement location="{absolute path to the <Rational Application Developer HOME>/plugins/ org.eclipse.equinox.common_<date>.jar plugin}"/> <fileset dir="{absolute path to the BIRT ReportEngine directory}\lib" includes="*.jar"/> </path> Paul Klicnik is a Software Developer at IBM Toronto lab in Markham Ontario. He has worked on Code Coverage since 2008, and worked in the general area of performance and testing tools since 2006. Paul has worked on several key IBM products, including IBM Rational Performance Tester and IBM Rational Application Developer, as well as the Eclipse Test and Performance Tools Project (TPTP) project. <taskdef name="code-coverage-report" classname="com.ibm.rational.llc.report.birt.adapters.ant. ReportGenerationTask" classpathref="lib.path"/> <code-coverage-report outputDir="{absolute path to the report output directory}" TIP: coverageDataFile="{absolute path to the coveragedata file generated in step 1}" baseLineFiles="{absolute path to the baseline file generated in step 1}"/> </target> Listing 3: Example usage of the report generation Ant task on the sample application in this article An example HTML report is displayed in Figure 10. Generating HTML reports using the Ant task provides a means by which users can view the statistics generated in an Ant environment independently of RAD. Try it out! The downloads section of this article at http://www.ibm.com/developerworks/rational/library/10/introtocodecoveragetoolinrationalapplicationdeveloper/ provides sample scripts and build files for an Ant environment that can be used to instrument, execute, and generate reports on the sample application. If you're interested in testing this environment out, refer to the README file in the Standalone.zip file. 28 MAGAZINE Windows Azure gebruik Azure kost geld voor het verbruik van Rekenkracht (CPU), Storage en Netwerk verkeer. Bij een MSDN account kun je Azure subscription instellen. Deze subscription heeft een aantal services zonder kosten, zoals 750 Small compute uren per maand, 10 Gb Storage, 3 SQL Azure web databases en nog een paar. Ruime voldoende voor wat development en probeersels. Als je over je budget heen gaat, dan moet je als nog betalen. Tegenwoordig krijg je een mail Microsoft Online Services als boven een bepaald percentage van je basis eenheden zit. Erg handig, zo hou je de extra kosten een beetje in de hand. Microsoft heeft daar iets aan veranderd. Vorige week kreeg ik een mail van de Microsoft Online Services met de mededeling ik dat ik 75% van mijn basis eenheden zat. ZZZLFXFRP )5(( &ORVLQJ.H\QRWH$GGUHVVDQG4$ %UHDNRXW6HVVLRQVDQG4$ %UHDNRXW6HVVLRQVDQG4$ 2SHQLQJ.H\QRWH$GGUHVVDQG4$ ARCHITECTURE Christian Siegers en Mark IJsselstein Duet Enterprise Duet is het product dat door SAP en Microsoft samen is ontwikkeld om business oplossingen te bieden die gebruik maken van software van beide leveranciers. Vaak hebben bedrijven SAP producten voor backend processen en Microsoft producten voor werkplekken (Windows, Office, eventueel SharePoint). Duet is een oplossing om de sterke punten van beide platforms met elkaar te combineren. In de huidige versies van Duet wordt een aantal standaard scenario’s geleverd, die met geringe configuratiemogelijkheden enigszins aangepast kunnen worden aan de klant. Duet biedt geen ondersteuning om nieuwe scenario’s te ontwikkelen, dus als de benodigde functionaliteit niet aanwezig is zal een andere oplossing gekozen moeten worden. SAP en Microsoft komen nu met een nieuwe versie, namelijk Duet Enterprise Niet zozeer een nieuwe versie van Duet maar een compleet nieuw ontwikkelplatform. Duet Enterprise biedt out-of-the-box een toolset waarmee je zelf business scenario’s kunt realiseren. Er is gekozen om zoveel mogelijk gebruik te maken van de bestaande producten van beide leveranciers en dus zo min mogelijk nieuwe tools en componenten te introduceren. Duet Enterprise draait als add-ons op SharePoint 2010 en SAP, waardoor de technische omgeving vele malen simpeler is geworden. Wat biedt Duet Enterprise aan functionaliteit In bovenstaande komt nog geen Duet Enterprise functionaliteit voor, deze integratie kan ook met SAP en SharePoint (dus zonder Duet Enterprise) worden gerealiseerd. De toegevoegde waarde is redelijk subtiel, maar zeker op de lange termijn (volgende versies) erg belangrijk. Duet Enterprise levert op hoofdlijnen de volgende functionaliteit: • Gateway aan de SAP zijde (IWF) • Workflow integratie • Technische integratie • Platform capabilities Gateway aan de SAP zijde Bedrijven hebben een divers SAP landschap, waarin meerdere SAP producten zitten en waarin meerdere versies van SAP tegelijk in gebruik zijn. Om te zorgen dat vanuit SharePoint geen rekening hoeft te worden gehouden met welk product, versie of technologie gebruikt wordt voor de verschillende SAP entiteiten, is gekozen om aan de SAP zijde een gateway te implementeren. Deze wordt de Information Worker Framework (IWF) genoemd. Hierin kun je entiteiten definiëren/samenstellen die je vanuit SAP beschikbaar wil maken voor 30 MAGAZINE SharePoint. Tevens geef je aan hoe deze entiteiten zich verhouden tot de verschillende bestaande SAP entiteiten uit het SAP landschap. Dus concreet welk SAP product, welke versie en welke technologie wordt gebruikt om de data te lezen en schrijven. Vervolgens wordt die entiteit op uniforme wijze aan SharePoint gepresenteerd middels webservices. Alle webservices die SharePoint nodig heeft om de entiteit te onderhouden worden beschikbaar gemaakt. Denk hierbij aan ‘selecteer één object’, ‘selecteer alle objecten’, ‘voeg object toe’, etc. Als een nieuwe versie van een SAP product in gebruik wordt genomen, dan hoeft alleen de definitie van de entiteiten in de IWF te worden aangepast en blijft de interface naar SharePoint gelijk. Workflow integratie Een andere feature die Duet Enterprise levert is workflow integratie. In SAP is het mogelijk meerdere soorten workflows te definiëren. De focus van Duet Enterprise ligt op goedkeuringsprocessen. Een voorbeeld is als iemand vakantie aanvraagt, dan moet de verantwoordelijke manager dit goedkeuren. Duet Enterprise levert de mogelijkheid om de goedkeuringsstappen te integreren met SharePoint en Outlook. Als een stap in SAP actief wordt, dan wordt voor deze stap een gelijkwaardige workflowstap in SharePoint gegenereerd. Per stap heeft de beslisser dan de keuze of hij de goedkeuring doet in SAP, SharePoint, Outlook of op z’n smartphone. Nadat een beslissing is genomen, worden de workflow in SAP en SharePoint automatisch met elkaar gesynchroniseerd. Voordeel is dat je hiermee alle collaboration features van SharePoint kan gebruiken. Je kan dan andere mensen om advies vragen, je goedkeuring aan een ander delegeren, je kan discussies voeren en documenten delen. Technische integratie De technische integratie wordt gerealiseerd door in SAP webservices beschikbaar voor SharePoint te maken. SharePoint gebruikt BCS (Business Connectivity Services) en BDC (Business Data Catalog) om de SAP webservices te consumeren. Hiermee kunnen SAP entiteiten in een ‘external list’ worden geladen. Een external list is een lijst in SharePoint met data die niet in SharePoint zelf is opgeslagen. Deze data kan vanuit de external list in een SharePoint site worden getoond en gewijzigd. ARCHITECTURE Platform capabilities Duet Enterprise zorgt voor onderliggende ontwikkelplatform functionaliteit, met name Single SignOn (SSO), traceability in de logging en error handling. Single SignOn SSO tussen SAP en SharePoint was tot nu toe technisch ingewikkeld. Duet Enterprise maakt gebruik van de SharePoint 2010 feature Security Token Service (STS) STS maakt gebruik van claims based authentication. STS maakt het mogelijk om op basis van een Windows login toegang te krijgen tot andere systemen door credentials van andere systemen te koppelen aan een Windows login. Met Duet Enterprise wordt binnen STS de Windows login van de gebruiker vertaald naar de SAP ID van die gebruiker. Gevolg is dat van alle acties die een gebruiker doet, wordt gevalideerd door SAP of die gebruiker daar de benodigde rechten toe heeft. Het enige wat nog moet gebeuren is de mappingtabel tussen Windows en SAP identiteit te vullen in SAP. Traceability Het is belangrijk om processen integraal te kunnen volgen voor auditing doeleinden en wanneer een fout optreedt. Auditing wordt bijvoorbeeld gebruikt om te kunnen achterhalen welke gebruiker bepaalde data heeft benaderd of aangepast of een beslissingstap heeft uitgevoerd. Als processen van SAP naar SharePoint lopen en weer terug, dan moeten de processtappen in SAP gerelateerd kunnen worden aan die in SharePoint. Duet Enterprise zorgt ervoor dat in de logging op basis van IDs terug is te vinden bij welk SAP proces een SharePoint proces hoort (en andersom). Error Handling Duet Enterprise zorgt ervoor dat fouten die optreden in SAP netjes en uniform worden teruggegeven aan SharePoint. Ontwikkelaars hoeven dus niet allerlei verschillende soorten foutafhandelingen te implementeren. Voordelen van het platform Het SAP-SharePoint en Duet Enterprise platform biedt de volgende voordelen. • Collaboration mogelijkheden rondom ‘SAP beslissingen’. Processen die voorheen binnen SAP plaatsvonden en waarover werd gecommuniceerd via email, losse documenten en ander communicatiemiddelen, worden nu ondersteund door een geïntegreerde omgeving. • Geïntegreerde zoekfunctionaliteit. Op basis van SharePoint Federated Search kun je tegelijk in SharePoint, SAP en eventuele andere systemen zoeken. Hierbij wordt rekening gehouden met de SAP rechten die de zoekende gebruiker heeft. • Outlook offline functionaliteit. In de 2010 versie van Outlook kun je data uit SharePoint lijsten offline beschikbaar maken. Hierbij wordt de gehele inhoud van de lijst lokaal in een database opgeslagen. Deze data kan worden gelezen en gewijzigd. Als je weer connectie hebt, worden de wijzigingen naar de server gepubliceerd. Deze functionaliteit werkt out-of-the-box en kan ook gebruikt worden voor lijsten met externe data zoals data uit een SAP systeem. De lokale data is ook door andere Office onderdelen te gebruiken, dus bij het maken van een offerte in Word kunnen de klantgegevens automatisch worden ingevuld door het selecteren van een klant uit het SAP systeem, ook als je offline bent. • No-code customization. Er is veel effort gestopt om te zorgen dat de scenario’s kunnen worden gemaakt zonder dat hiervoor gecodeerd hoeft te worden. Bijna alles kan door configuratie worden gerealiseerd. Conclusie Duet Enterprise is een oplossing om Microsoft SharePoint en daarmee Office te integreren met SAP systemen. Het bouwt voort op de reeds aanwezige functionaliteit van deze producten. Hierdoor is het voor zowel eindgebruikers, ontwikkelaars en beheerders vertrouwd terrein. Duet Enterprise is niet nodig voor het realiseren van één enkele technische interface tussen SharePoint en SAP. Als een bedrijf kiest om bedrijfsprocessen met SAP te ondersteunen en het SharePoint/Office platform kiest voor de gebruikersinterface, dan moeten de technische beginselen als SSO en auditing goed geregeld zijn. In dat geval is Duet Enterprise de enige logische keuze voor de toekomst. • Christian Siegers Christian Siegers is werkzaam bij Capgemini als Managing Consultant. In projecten wordt Christian ingezet als Solution Architect. Christian richt zich voornamelijk op de Microsoft technologie en heeft zijn roots in de integratie liggen. Het integreren van Microsoft technologieën met de cloud als het integreren van een Microsoft platform met een SAP platform hoort tot Christian’s specialiteiten. Mark IJsselstijn Mark is an architect with 11 years of experience working mostly with Microsoft-related technology. magazine voor software development 31 DATABASES Ben Suurmeijer Historie en toekomst van Database Change Management Sinds tientallen jaren halen veel organisaties voordeel uit het gebruik van geaccepteerde en bewezen Software Change Management (SCM) principes. Processen zoals “file locking”, “check in / check out”, “compare and merge” en “rollbacks” stellen organisaties in staat om op een productieve en gecontroleerde manier wijzigingen aan te brengen in hun applicaties. Echter, binnen de database wereld werkt het hele principe van SCM niet bijzonder goed. De belangrijkste reden is dat databases totaal anders zijn gestructureerd dan traditionele programma code (zoals Java en .NET), en om die reden kunnen de traditionele SCM producten, zoals bijvoorbeeld IBM Rational of Subversion, niet gebuikt worden in de databasewereld. Het gevolg is een enorme kloof tussen SCM en database ontwikkelactiviteiten. De problematiek van database veranderingen Een database is, in tegenstelling tot een softwareprogramma bijvoorbeeld, geen verzameling bestanden, en door het filesysteem wordt een database meestal gezien als één groot bestand. Bij veranderingen in het programma code, wordt er een kopie van het programmabestand gemaakt en vindt de ontwikkeling van code plaats op deze lokale kopie. Een database is echter geen verzameling bestanden, maar een centraal middel waar iedereen toegang tot heeft en waar ontwikkelaars tegelijkertijd wijzigen in aan kunnen brengen. Er worden zelden kopieën gemaakt voor elke individuele ontwikkelaar. In situaties waar dit wel gebeurt, moet er nagedacht worden over hoe deze verschillende kopieën van de database voordurend gesynchroniseerd kunnen worden om databaseconsistentie te garanderen. Een lastig probleem. Verder moet er rekening gehouden worden met versiebeheer, en bestaat er geen zogenaamde “debug” omgeving. Ook een gestructureerd proces van ontwikkeling, waarbij aanpassingen door van de ontwikkelafdeling door worden gegeven aan QA (Quality Assurance), integratie en vervolgens productie, stuit bij database ontwikkeling op problemen. Bij de ontwikkeling van program- 32 MAGAZINE macode omvat dit proces weinig meer dat het simpelweg kopiëren en registreren van individuele bestanden. Echter, het verplaatsten van database objecten is niet zo eenvoudig. Het is niet zonder meer mogelijk een gewijzigde tabel vanuit ontwikkeling in productie want dan gaat alle productiedata verloren. In tegenstelling tot een software ontwikkelaar, die gebruik maakt van een SCM oplossing, waarbij een gedetailleerde registratie van alle veranderingen wordt bijgehouden, moeten database ontwikkelaars vaak handmatig een lijst bijhouden met alle database wijzigingen. Geloof het of niet maar, maar ik heb wel eens een database ontwikkelaar gezien die alle modificaties bijhield op gele Post-It briefjes die verspreid waren over zijn bureau en beeldscherm. Met andere woorden, database ontwikkeling is een totaal andere tak van sport dan traditionele programmacode ontwikkeling. Als gevolge van de enorme verschillen tussen software ontwikkeling en database ontwikkeling, is een geautomatiseerd proces voor Database Change management (DCM) á la SCM nooit echt van de grond gekomen, en wordt er noodgedwongen gebruik gemaakt van een breed scala van handmatige processen en work-arounds. DATABASES Een work-around: DDL export De meest bekende work-around is de database definition language (DDL) te exporteren om een databasestructuur te definiëren, en deze vervolgens als bestanden veilig te stellen binnen een traditionele SCM oplossing (zie diagram). Echter, dit proces is verre van waterdicht. Niemand kan namelijk verwachten dat ontwikkelaars daadwerkelijk consequent dit proces volgen voor iedere veranderingen die ze aanbrengen in een database. En wat gebeurt er als iemand alleen maar de database aanpast, en niet de bijbehoorde SCM bestanden? Hoe wordt er omgegaan met deze inhoudelijke veranderingen? Een veranderde waarde van een parameter (in bijvoorbeeld een lookup of metadata tabel), kan invloed hebben op het gedrag van een applicatie programma en moet goed beheerd worden. De vraag is alleen hoe? In dat geval moet er handmatig code geschreven worden om de wijzigingen in de databasestructuur mogelijk te maken zonder verlies van data. Dit is niet alleen erg tijdrovend, maar ook er foutgevoelig. Bovendien is deze handmatige code geen deel van een zogenaamd application lifecycle management (ALM) proces, en volgt hierdoor niet de zelfde regels en voorwaarden als bij normale programmacode. De eerste generatie database change management De eerste generatie database change management producten zijn in principe geautomatiseerde “vergelijk en synchroniseer” oplossingen die het mogelijk maken verschillende databaseomgevingen met elkaar te vergelijken. Dit type oplossingen genereert rapporten die de verschillen aangeven, waarna er automatisch code gegenereerd kan worden om de verschillen te compenseren. Dit type oplossingen biedt een belangrijke verbetering in het database change management proces. Door het geautomatiseerde karakter wordt het aantal fouten als gevolg van handmatig handelen in belangrijke mate gereduceerd. Echter, veel change management problemen worden met de eerste generatie van database change management producten nog steeds niet geadresseerd: • Wat gebeurt er bijvoorbeeld als er veranderingen in de testomgeving worden aangebracht? Dan kan het gebeuren dat de referentieomgeving niet langer identiek is, en wijzigingen kunnen verloren gaan. • Een andere vraag is wat er precies gebeurt tijdens een ontwikkelcyclus? Welke stappen zijn in deze cyclus genomen. Er was geen informatie beschikbaar over hoe het uiteindelijke resultaat is bereikt. • Kan iedereen die toegang heeft tot een database wijzigingen aanbrengt in de database? • Welke veranderingen zijn door wie, wanneer gemaakt? • Is database ontwikkeling effectief gesynchroniseerd met de software ontwikkeling? • Hoe te handelen bij gedeeltelijke distributie van de veranderingen? Bijvoorbeeld de noodzaak een applicatie aanpassing te distribueren zonder een andere, minder stabiele aanpassing? In vergelijk tot moderne SCM oplossingen, biedt de eerste generatie database change management producten weinig meer dan “vergelijk en synchroniseer”. Ze bieden zeker niet de complete functionaliteit van moderne SCM oplossingen, zoals bijvoorbeeld de mogelijkheid veranderingen terug te draaien (rollback), check in / check out, file locking, baseline settings, code merging en veranderingsrapporten voor auditing en regelgeving. Omdat deze eerste generatie database change management producten nog steeds niet in staat is naar tevredenheid veranderingen te managen, is het wellicht beter deze producten te categoriseren als database development management in plaats van database change management producten. database veranderingen te beheren, in principe een oplossing die dezelfde functionaliteit kan bieden als traditionele SCM oplossingen: 1. Het afdwingen van formele, gedisciplineerde database change management processen en workflows 2. Het werk van verschillende database ontwikkelteams synchroniseren en coördineren 3. Het ondersteunen van de volledige database ontwikkelcyclus, vanaf ontwikkeling via Q&A, naar integratie en tenslotte productie. 4. Beheren en volgen van veranderingen 5. Het bieden van een goede, stabiele centrale opslag (repository) voor het opslaan van een veranderingshistorie voor auditing doeleinden 6. Het koppelen van database veranderingen met traditionele SCM projecten 7. Database veranderingen distribueren door middel van SCM taken Om dit te realiseren, moeten de nieuwe generatie database change management oplossingen het complete palet van software change management functionaliteit in een database wereld gaan ondersteunen. In tegenstelling tot de eerste generatie oplossingen, welke zoals we hebben gezien niet meer biedt dan een “vergelijk en synchroniseer” product, moeten moderne database change management oplossingen vandaag de dag een uitgebreid scala aan functionaliteiten kunnen bieden waaronder object locking, check in / check out, baseline setting, samenvoegen van code en een rollback van veranderingen. In plaats van het foutgevoelige en handmatige proces waar database ontwikkelaars vandaag de dag noodgedwongen gebruik van maken om aanpassingen in de database te maken, hebben ontwikkelaars een dwingende behoefte aan een manier wijzigingen direct en effectief aan te kunnen brengen in de structuur van de database. Maar, ook de nieuwe generatie database change management oplossingen is niet geheel zonder uitdagingen. Een moet bijvoorbeeld een nieuw type centrale opslag (repository) worden gecreëerd die zowel speciale attributen, database objecten als ook database inhoud kan opslaan. Verder is er het probleem van het beheren en coördineren van de centrale resources en de gekopieerde resources. Een veranderingsproces moet worden gedefinieerd en worden afgedwongen, en de activiteiten van de diverse ontwikkelteams moet worden gesynchroniseerd. Database ontwikkeling moet worden gekoppeld met traditionele SCM componenten zoals versiebeheer, verandering sets (change sets) of activiteiten. Maar ondanks deze uitdagingen, biedt een succesvolle implementatie van de nieuwe generatie database change management oplossingen enorme voordelen. De crux is de juiste database change management oplossing te vinden, en de focus te houden op risico beheersing. Een goede database change management oplossing van de nieuwe generatie moet aan de volgende eisen voldoen: • • • • • • De nieuwe generatie database change management Vandaag de dag zijn database ontwikkelaars meer en meer op zoek naar een oplossing die hen in staat stelt het volledige proces van Procedures moeten worden afgedwongen zodat wijzigingen alleen via een SCM workflow doorgevoerd kunnen worden. Database ontwikkeling moet zodanig worden gedaan dat botsingen en conflicten voorkomen kunnen worden. Standaarden moeten gedefinieerd kunnen worden en worden afgedwongen via check in / check out en labels. Een compleet audit trail van alle veranderingen moet kunnen worden vastgelegd. Een automatische rollback van veranderingen, zowel in ontwikkel- als ook in productieomgevingen moet mogelijk zijn. De uitrol van verschillende databases moet volledige geautomatiseerd plaats kunnen vinden, met three-way comparison en analyse met gebruik maken van het samenvoegen van database code. magazine voor software development 33 DATABASES dbMaestro TeamWork Teamwork van dbMaestro maakt het mogelijk om database ontwikkeling een integraal onderdeel van een gedisciplineerd SCM proces te maken in plaats van een handmatig proces of, op zijn best, semigeautomatiseerd proces. TeamWork voldoet in alle opzichten aan de eisen voor een nieuwe generatie database change management oplossingen, en vergroot in belangrijke mate de voordelen voor organisaties die een SCM proces volgen voor zowel software ontwikkeling als ook database ontwikkeling. De database developer community heeft behoefte aan oplossingen met voordelen als object-locking en auditing, die een nauwere controle biedt van de ontwikkelprocessen binnen een team. Deze benadering biedt tevens de mogelijkheid tot het distribueren van veranderingen en versie beheer van database objecten en schema’s. Innovatieve volgende generatie database change management oplossingen, zoals dbMaestro TeamWork™, bieden al de hiervoor beschreven mogelijkheden, plus heel veel meer. • Veranderingen in databases kunnen nu op eenzelfde manier gevolgd worden als veranderingen in de software code, waardoor het complete ontwikkel project, inclusief database veranderingen, op een gecontroleerde, geregistreerde en gestandaardiseerde wijze uitgerold kan worden. Teamwork integreert met oplossing als IBM Rational. Ben Suurmeijer Ben Suurmeijer is ruim 17 jaar actief in de IT. Eerst als Unix systeembeheerder en Oracle DBA, later als pre sales bij onder andere Amerikaanse en Israëlische bedrijven, maar altijd op het gebied van IT Beheer. www.go-esi.com/blog / blog.dbmaestro.com Conclusie Programma code ontwikkelaars hebben meer dan 20 jaar de voordelen ervaren van het gebruik van SCM oplossingen. Het is nu tijd om een database change management proces naar hetzelfde niveau te tillen als een SCM proces, en database ontwikkelaars en DBAs dezelfde mate van eenvoud en procesmatige beveiliging te bieden bij database ontwikkeling. Integratie met bestaande, traditionele SCM producten biedt een homogeen ontwikkelproces, identiek voor programmacode ontwikkeling als ook voor de ontwikkeling van database objecten. ! uw Nie DB PowerStudio voor SQL Server Tot 31 maart 2011 extreem voordelig! Ga naar: www.barnsten.com Change Manager RapidSQL SQL Scripting, Query Building, Versiebeheer, ObjectManagement + Beheer alle veranderingen op alle databases (data, schema, config) www.barnsten.com 34 MAGAZINE SQL Optimizer + Ontdek, diagnosticeer en optimaliseer slechte code DBArtisan + Voor al je development & database tools. Alle beheertaken vanuit 1 scherm, DB migraties, user management 023 - 542 22 27 SDN > Update Delphi Nieuws De afgelopen maanden zijn er verschillende ontwikkelingen en technische publicaties op het gebied van Delphi geweest. Hierbij een overzicht van het meest in het oog springende en interessante nieuws. Delphi XE Starter Edition REST Servers in Delphi XE Using DataSnap Embarcadero is weer begonnen met een aantal RAD in Action white papers. De eerste is half januari gepubliceerd op de website van Embarcadero, en er zullen er meerdere volgen. REST Servers in Delphi XE using DataSnap geschreven door Marco Cantù kan gelezen worden te http://www.embarcadero.com/rad-in-action/datasnap-rest waar ook videos en voorbeeld code te vinden is. Andere RAD in Action white papers die zullen volgen zijn o.a. Delphi Prism XE for iPhone Development door Brian Long, en een Delphi XE DataSnap XE Case Study geschreven door Bob Swart (met een webinar gepland op woensdag 2 maart 2011). SDE 18 maart 2011 Het duurt nog even, maar over een paar weken staat de december SDE weer voor de deur. Het Delphi Development Network heeft een drietal sprekers gevonden die samen weer vier sessies zullen verzorgen. Pawel Glowacki Pawel Glowacki, de Embarcadero Technical Lead voor Delphi in EMEA, zal laten zien “What’s Cooking” in de labs voor de komende “Pulsar” release van Delphi, en zal daarbij ook het laatste nieuws delen m.b.t. Delphi en de ontwikkelingen voor en met Delphi. Voor eventueel nieuws over 64-bits en/of Mac is dit de sessie om niet te missen… Bob Swart Bob Swart zal de nieuwe mogelijkheden van IntraWeb XI in Delphi XE laten zien, en daar- Op 1 februari 2011 heeft Embarcadero een goedkoper Starter Edition uitgebracht van Delphi XE. Met een New User prijs van 199 Euro (ex.BTW) maar een “Upgrade van elke andere IDE (inclusief Notepad++)” prijs van 149 Euro (ex.BTW) is deze versie gericht op de hobbyist of de starter die met weinig budget toch met Delphi XE aan de slag wil. Er zitten wel enkele beperkingen in Delphi XE: zo is database toegang beperkt tot de BDE (dat wil je niet) of InterBase met IBX, en zitten er geen web, cloud of multi-tier zaken in (maar daar moet je dan ook de Professional of Enterprise versie voor kopen). Iedereen die Delphi XE Starter Editie koopt kan de PDF Delphi XE Starter Essentials gratis downloaden van de Registered Users pagina, of in paperback formaat kopen van Lulu.com via http://www.lulu.com/product/14723094 Ook zijn speciale upgrade prijzen naar Delphi XE Enterprise en RAD Studio XE Enterprise aangekondigd, geldig tot het einde van dit kwartaal. Zie http://www.delphixe.nl voor meer details. mee een introductie geven voordat Bruno Fierens er in zijn sessie dieper op in kan gaan met onder andere de IntraWeb iPhone controls. In deze sessie komen de verschillende edities van IntraWeb XI (personal, standard en ultimate) aan de orde – zowel de bestaande als nieuwe features. Deployment als standalone toepassing of ISAPI DLL zal gedemonstreerd worden, net als URL Mapping, de nieuwe Authentication en AJAX support voor snelle en interactieve web Applications. Bruno Fierens Bruno Fierens van TMS Software uit België zal een tweetal sessies voor ons verzorgen: Extending the Delphi IDE en Getting the most out of IntraWeb. In de eerste sessie zullen verschillende types van IDE extensies uitgelegd worden gerealiseerd aan de hand van de open tools API (OTAPI) Dit gaat van extensies op de Delphi repository, access van de project manager, custom toolpanels in the IDE toevoegen en access tot de Delphi code editor. De extensies worden geillustreerd door kleine voorbeelden en daarnaast worden ook een aantal gratis extensies gepubli- ceerd door TMS software gedemonstreerd. Voor performante en gebruiksvriendelijke web applicaties staan in IntraWeb client-events, asynchrone events en updates ter beschikking. In de sessie wordt gedemonstreerd hoe deze technieken aangewend worden in the TMS IntraWeb grids. Verschillende asynchrone en client-side features van de grids komen aan bod. Daarnaast komen ook de TMS IntraWeb iPhone controls aan bod die eveneens via veel async functionaliteit toelaten iPhone, iPad web applicaties te ontwikkelen met Delphi en IntraWeb. Erik van de Wetering Erik van de Wetering van Marik Computers zal een sessie doen over een Applicatie Framework met o.a. Datasnap in XE. De sessie start met een korte intro van het project Applicatie Framework, en laat o.a. zien hoe de dataset structuur opgebouwd wordt via datasnap tijdens runtime (server-side en clientside). Ook zien we een ClassForName functie van Java in Delphi, Firebird sql en views, en Delphi programma’s via Remote Applications van Win2008. magazine voor software development 35 .NET ASP Michiel van Otegem Webservices en transacties Transacties zijn bedacht om systemen consistent te houden en worden daarom ook al decennia gebruikt. De ondersteuning voor transacties is om die reden ook bedacht voor webservices in de vorm van de WS-AtomicTransaction standaard. Maar is dat wel een goed idee? Juval Löwy, verantwoordelijk voor de C# coding standards van IDesign en schrijver van onder andere Programming .NET Components en Programming WCF Services (beide uitgegeven door O’Reilly), heeft wel eens gezegd dat iedere applicatie die geen gebruik van transacties maakt speelgoed is (“Any application not using transactions is a toy”). Dit is natuurlijk wat gechargeerd, maar het is niettemin belangrijk om op z’n minst na te gaan of je applicaties transacties nodig heeft. Daarbij moet je bedenken hoe je het systeem consistent wilt houden. Een inconsistent systeem doet immers niet wat het moet doen, omdat het gegevens bevat die elkaar tegenspreken. Dit zelf oplossen is over het algemeen een heidens karwei, omdat de complexiteit snel oploopt. Bij vijf operaties in een transactie is het aantal permutaties 5! (=12), bij tien operaties 10! (=3.600.000). Transacties zijn daardoor vaak de beste oplossing. Het is niet voor niets dat .NET vanaf 2.0 uitstekende ondersteuning biedt voor transacties middels de TransactionScope (daarvoor al via System.EnterpriseServices), en dat technologieën als LINQ-to-SQL en het Entity Framework alle wijzigingen met SaveChanges automatisch in een transactie verpakken. Ook in Windows Communication Foundation is het eenvoudig om services te maken die transacties ondersteunen (of vereisen). Om te beginnen moet je in het operation contract aangegeven dat de betreffende service operation transacties ondersteunt. Dit doe je met het TransactionFlow attribuut, zoals in Listing 1. [OperationContract] [TransactionFlow(TransactionFlowOption.Allowed)] void MyServiceMethod(string someParam); ervoor kiest een Operation Behavior te gebruiken, zoals in Listing 2, zal een exception de transactie automatisch afbreken. Zonder exception wordt aangenomen dat de operatie geslaagd is. [OperationBehavior(TransactionScopeRequired=true, TransactionAutoComplete=true)] public void MyServiceMethod() { // Implementatie hier } Listing 2: Operation Behavior voor automatisch transactiebeheer. Dat we webserivces die over de hele wereld verspreid zijn in een enkele transactie kunnen betrekken betekent niet dat we dit ook moeten doen Om transacties mogelijk te maken, moet je wel een binding kiezen die transacties ondersteunt. De belangrijkste binding die dat niet doet is BasicHttp, maar voor de meeste andere bindings is dit geen probleem. Je moet deze binding daarnaast ook configureren om transacties te ondersteunen en dat doe je als volgt: Listing 1: Operation Contract met ondersteuning voor transacties. <binding name="MyBinding" transactionFlow="true" /> De complexiteit loopt bij transacties al snel op. Een transactie met 10 operaties kent 3.600.000 permutaties Andere waardes voor TransactionFlowOption zijn Mandatory (verplicht) en NotAllowed (niet toegestaan). Met de instelling Allowed zijn transacties toegestaan, maar kan een client de service ook aanroepen zonder een transactie te gebruiken. Uiteraard kan een service intern dan nog steeds wel een transactie gebruiken. Andere services die door de client aangeroepen worden zullen daarin echter niet meedraaien. Met de TransactionFlow goed ingesteld, moet je nog wel zorgen dat de operaties die je maakt aangeven of wat hun betreft de transactie geslaagd is. Dit kun je declaratie doen met een Operation Behavior of in code door expliciet OperationContext.Current.SetTransaction Complete() aan te roepen voordat de functie retourneert. Wanneer je 36 MAGAZINE In .NET is het kinderspel om een client te maken die een transactie gebruikt bij het aanroepen van een service die dit ondersteunt. De bindingconfiguratie wordt automatisch overgenomen uit de metadata en daardoor wordt een aanroep binnen een TransactionScope automatisch gedaan met een transactie. WCF kiest hierbij automatisch het meest optimale protocol voor de transactie, waarbij het kan kiezen uit OleTx en WS-AtomicTransaction (WSAT). OleTx is een Windows-only protocol dat uitstekend werkt binnen een lokaal netwerk. Zodra het echter nodig is om ook andere services te betrekken, zoals services gemaakt met Java’s WCF tegenhanger Web Services Interoperability Technology (WSIT), zal WCF automatisch schakelen naar WSAT. Dit kan ook als de transacties oorspronkelijk in OleTx gestart is. Dit is volledig transparant en je hoeft je hier dus niet om te bekommeren. Met WS-AtomicTransaction is het in principe mogelijk om webservices die over de hele wereld verspreid zijn te betrekken in een enkele transactie. Dat we dat kunnen betekent echter niet meteen dat we dat ook moeten doen. WS-AtomicTransaction werkt op basis van 2-phase commit. Dit betekent dat de zogenaamde Transaction Co-ordinator (TC), de regisseur van de transactie, eerst aan alle deelnemers in een .NET ASP transactie vraagt of de transactie doorgang kan vinden. Wanneer alle deelnemers daarop bevestigend antwoorden, laat de TC de transactie doorgaan en moeten de wijzigingen definitief gemaakt worden door alle deelnemers. Deelnemers die in de eerste fase een OK gegeven hebben, kunnen hier niet op terugkomen. Dit systeem werkt uitstekend, maar geeft wel een nadeel: locking. Zolang de TC nog niet aangegeven heeft dat de transactie door mag gaan, houdt de transactie in principe een lock op resources die betrokken zijn bij de transactie. Deze resource, zoals een database record of een bestand, mogen in de tussentijd niet door andere operaties gewijzigd worden en (afhankelijk van het Isolation Level) mogen de wijzigingen ook nog niet zichtbaar zijn voor andere operaties. Dit geldt bijvoorbeeld ook als de TC na de eerste fase, maar voor de tweede crasht en een tijd uit de lucht is. In zulk soort situaties zijn resources zo lang geblokkeerd dat dit enorme problemen voor een systeem op kan leveren. Maar zelfs als alles goed gaat is het nog zo dat locks niet erg lang mogen duren. Meer dan een seconde kan al geweldige gevolgen hebben voor een systeem waar een hoop wijzigingen op gedaan worden. Binnen een applicatie en zelf binnen een lokaal netwerk is dit nog wel te realiseren, maar is een van de deelnemers bijvoorbeeld een webservice in Singapore, dan kan een enkele request-response al 10 seconden duren. Dan duurt een 2-phase commit in vergelijking een eeuwigheid. Afgezien van de technische implicaties is er ook nog een ander vraagstuk. Door een webservice aan te bieden aan een derde met ondersteuning voor transacties, geef je eigenlijk een deel van de controle over je eigen systeem uit handen. De gemiddelde systeembeheerder zal hier van gruwen, en terecht! Had er dan nooit een standaard als WS-AtomicTransactions moeten komen? Of had deze nooit in WCF en WSIT geïmplementeerd moeten worden? Dat is ook wel weer een brug te ver. Transacties hebben ook in de wereld van webservices hun waarde. Je moet alleen goed nadenken over wanneer je ze wel of niet moet gebruiken. Het beste is om hier binnen een organisatie richtlijnen voor op te stellen. Je kunt hierbij services bijvoorbeeld verdelen in categorieën op basis van hun functie en plek in een proces. Zo kun je bijvoorbeeld services onderscheiden die een bepaalde basisfunctie bieden, zoals het versturen van een email. Dergelijke “basisservices” worden altijd in de context van bedrijfslogica uitgevoerd en zijn dus een goede kandidaat om in een transactie mee te draaien. Services die deze services aanroepen zitten op een hoger niveau en daarvan zou je bijvoorbeeld kunnen bepalen dat ze niet deel mogen nemen in een transactie, maar er wel een mogen initiëren om de lager gelegen services te coördineren. Transacties buiten de grenzen van het eigen netwerk zijn meestal geen goed idee, dus je moet wel hele goede redenen hebben om dat toe te staan. Voor multi-nationals kan ook de latency een rol spelen in de richtlijnen. Persoonlijk vind ik het heel handig om de richtlijnen die je kiest vast te leggen in een duidelijk plaatje. Een plaatje kun je namelijk makkelijk ergens ophangen om mensen te herinneren aan de richtlijnen. Bovendien zijn plaatjes beter te onthouden dan regeltjes tekst. Afbeelding 1 laat een voorbeeld zien van een plaatje waarin de transactierichtlijnen gevat zijn. • Afbeelding 1, Voorbeeld transactiesrichtlijnen 26 maart 2011 CodeCamp TIP: Als je Google Chrome installeert kun je de standaard Search engine instellen. Daarvoor kun je kiezen uit: Google, Yahoo en Microsoft Bing. Dus zelfs in Chrome kun je bingen ;-) Op 26 maart 2011 zal SharePoint Saturday en de volgende CodeCamp in Nederland georganiseerd worden door de gezamelijke communities. Blijf op de hoogte via Twitter en vol http://twitter.com/ codecampnl E-Office (www.e-office.com) is platina sponsor en Macaw (www.macaw.nl) is gold sponsor. magazine voor software development 37 IW Anita Boerboom Building a custom Health Rule SharePoint 2010 and governance are tightly connected these days. Governance consists of policies, roles, responsibilities and processes to ‘avoid’ chaos in the SharePoint environment. Some of the possible policies implemented by an organization can be monitored by SharePoint itself by the new feature called SharePoint Health Analyzer. The Health Analyzer is rule based and the rules check the farm for potential problems. SharePoint has several out of the box rules, like ‘Drives are running out of disk space’ and ‘The server farm account should not be used for other services’. To make administrators aware of possible issues with the farm all errors are listed in the Health Reports list. To monitor additional items not available out of the box, custom health rules can be built. Functionality of the custom health rule Sandboxed solutions can be monitored a little bit better than SharePoint default provides. When the Microsoft SharePoint Foundation Sandboxed Code Service is started sandboxed solutions can be deployed and used. To monitor the resources consumed by the sandboxed solutions a couple of timer jobs measure and collect the consumed resources: • Solution Daily Resource Usage Update • Solution Resource Usage Log Processing • Solution Resource Usage Update It is possible to deploy sandboxed solution when the timer jobs are not running. In that case the resources consumed by the sandboxed solutions are not measured. This means when the sandboxed solutions are consuming a lot of resources the farm can get down in not a nice way. One of the strengths of sandboxed solutions is that they are hosted in a partially trusted context so they do not affect the rest of the SharePoint implementation... • • • • Summary - the title for the rule Explanation - displayed in the Health Reports list when the rule fails Remedy - displayed in the Health Reports list when the rule fails ErrorLevel - severity of the failure of the rule All rule definitions can be found in the rule definition list: Central Administration, Monitoring, Review rule definitions. The Health Reports list can be found in the Central Administration, Monitoring, Review problems and solutions. The Health Reports list explains the issue, failing servers and services and the remedy to the problem. The difference between the two lists is that the rule definition list displays all the existing rules; the Health Reports list displays the rules which cause problems in the farm. The rules are categorized in both lists. Code listing 1 lists the custom rule in the Configuration category. public override SPHealthCategory Category { get { Wouldn’t it be nice to be sure the timer jobs are running when the Sandboxed Code Service is running? return SPHealthCategory.Configuration; } One of the strengths of sandboxed solutions is that they are hosted in a partially trusted context so they do not affect the rest of the SharePoint implementation } Listing 1: Override the Category property The title of the rule can be set by overriding the Summary property as shown in code listing 2. public override string Summary { get { return "Verify the sandbox related jobs are started."; Build the rule To set up a health analyzer rule an empty SharePoint project is created. A class is added which inherits from SPHealthAnalysisRule. This is the class to implement the rule definition. The class can also be inherited from SPRepairableHealthAnalysisRule. This means the rule can repair the problem itself. When inheriting from SPRepairableHealthAnalysisRule the method Repair() has to be implemented as well. To define a rule some properties has to be overridden: • Category - rule definitions are grouped by Category in the default view 38 MAGAZINE } } Listing 2: Override the Summary property The Summary is shown in the rule definition list and the health reports list. The custom rule can be scheduled by overriding the AutomaticExecutionParameters property. In the get accessor a SPHealth AnalysisRuleAutomaticExecutionParameters object is returned. When the property isn’t overridden the rule can be scheduled IW manually by a farm administrator. public override SPHealthAnalysisRuleAutomaticExecutionParameters AutomaticExecutionParameters { get { The code in listing 4 checks if the Sandboxes Code Service is started. If the service is started, it checks if the timer jobs involved in measuring the resources consumed by the solutions are enabled. When the service isn’t started there are no running sandboxed solutions and no resources have to be measured. The AddJobTitle() method adds the title(s) of the disabled job(s) to a generic list of strings as stated in code listing 5. SPHealthAnalysisRuleAutomaticExecutionParameters private void AddJobTitle(SPJobDefinition job) parameter = new SPHealthAnalysisRuleAutomaticExecutionParameters(); { parameter.Schedule = SPHealthCheckSchedule.Hourly; if (job.IsDisabled) parameter.Scope = SPHealthCheckScope.Any; { jobTitleOfDisabledJobs.Add(job.Title); parameter.RepairAutomatically = false; } parameter.ServiceType = typeof(SPTimerService); } return parameter; } } Listing 5: Collection of titles of disabled jobs Listing 3: Overriding property SPHealthAnalysisRuleAutomatic ExecutionParameters The generic list is used at the Explanation property to inform the farm administrator exactly which job(s) aren't enabled. Code listing 6 overrides the Explanation property and returns an informative message including the titles of the jobs which aren’t enabled. In code listing 3 the rule is scheduled on an hourly basis and the scope is set to SPHealthCheckScope.Any. This means the rule will run on an hourly basis on the first available computer with the specified service. The code that identifies the real problem is the Check() method. The Check() method returns the outcome of the check: SPHeathStatus.Failed or SPHealthStatus.Passed. When SPHeathStatus.Failed is the result of the check, the rule will be displayed in the Health Reports list to make the administrator aware of the problem. public override string Explanation { get { string jobTitles = string.Empty; for (int i = 0; i < jobTitleOfDisabledJobs.Count; i++) { public override SPHealthCheckStatus Check() jobTitles += jobTitleOfDisabledJobs[i].ToString(); { if (i != jobTitleOfDisabledJobs.Count - 1) jobTitleOfDisabledJobs.Clear(); { SPUserCodeService userCodeService = } jobTitles += " / "; SPUserCodeService.Local; } if (userCodeService.IsEnabled) return "The Microsoft SharePoint Foundation Sandboxed { Code Service is started, but not all the " + using (SPSite site = new SPSite("your_site_url")) "timerjobs are: " + jobTitles; foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) } } { switch (job.Title) { Listing 6: Display an informative message in the Explanation property of the rule case "Solution Daily Resource Usage Update": AddJobTitle(job); break; case "Solution Resource Usage Log Processing": Besides explaining the issue in detail a message can be displayed to the administrator on how to act on the issue. Code listing 7 overrides the Remedy property. AddJobTitle(job); break; case "Solution Resource Usage Update": public override string Remedy { AddJobTitle(job); get break; { return "Start the timerjobs: Solution Daily Usage default: Update, Solution Resource Usage Log Processing break; and/or Solution Resource Usage Update."; } } } } if (jobTitleOfDisabledJobs.Count != 0) { Listing 7: Override the Remedy property return SPHealthCheckStatus.Failed; } } Code listing 8 overrides the ErrorLevel property and sets the severity of the issue to Warning. return SPHealthCheckStatus.Passed; } Listing 4: Implementation of the Check() method magazine voor software development 39 IW public override SPHealthCheckErrorLevel ErrorLevel } { } get catch (Exception ex) { { return SPHealthCheckErrorLevel.Warning; throw new Exception("There was an error removing } the health rule: " + ex.Message); } } } Listing 8: Override the ErrorLevel property Listing 9: Register and unregister the rule Deploy the rule The rule can be deployed by adding a farm level scoped feature to the solution, and add an event receiver to the feature. Code listing 9 overrides the FeatureInstalled and FeatureUninstalling to register and unregister the rule. After the deployment, the rule can be found in the rule definition list: Central Administration, Monitoring, Review rule definitions. Details of the rule are shown in Figure 1. public override void FeatureInstalled (SPFeatureReceiverProperties properties) { try { Assembly currentAssembly = Assembly.GetExecutingAssembly(); IDictionary<Type, Exception> exceptions = SPHealthAnalyzer.RegisterRules(currentAssembly); if (exceptions != null) { Fig. 1: The rule definition if (exceptions.Count == 0) { //ok } The default view of the rule definition list is showing all the defined rules EXCEPT the rules defined with the category ‘System’. Of course it's possible to create an additional view to show all the rules. else { //something went wrong, take appropriate action } } Run and test the rule By disabling for example the ‘Solution Daily Resource Usage Update’ job and the ‘Solution Resource Usage Update’ job the rule can be tested to fail. } catch (Exception ex) { throw new Exception("There was an error registering the health rule: " + ex.Message); } } public override void FeatureUninstalling The rule is scheduled to run every hour as defined in code listing 3 and shown in Figure 1. To speed things up the rule can be selected to run directly by pressing Run Now. The timer job which actually runs the Health Analyzer jobs, dependent of the schedule, is in this case Health Analysis Job (Hourly, Microsoft SharePoint Foundation Timer, Any Server). The job can be found in Central Administration, Monitoring, Review Job Definitions. By selecting the job title the details of the job are shown and the job can run immediately by selecting Run Now. (SPFeatureReceiverProperties properties) { The rule fails and shows up in the Health Reports list as shown in Figure 2. try { Assembly currentAssembly = Assembly.GetExecutingAssembly(); IDictionary<Type, Exception> exceptions = SPHealthAnalyzer.UnregisterRules(currentAssembly); Fig. 2: The rule fails if (exceptions != null) { if (exceptions.Count == 0) { The little yellow sign at the bottom of the icon in Figure 2 shows a visual representation of the ErrorLevel set in code listing 8. The Summary of the rule set in code listing 2 is displayed as the title of the rule. //ok } else { //something went wrong, take appropriate action } 40 MAGAZINE The details of the rule can be viewed by selecting the text in the Health Reports list. A dialog opens as shown in Figure 3. Note that the Explanation of the rule changes when different sandbox timer jobs are disabled or enabled and the rule is reanalyzed. The Explanation property displays exactly which timer jobs aren´t enabled. IW Keep in mind to attach the debugger to the timer services when debugging the rules: OWSTimer.exe process. DELPHI TIP: CD/DVD Drive Openen Soms is het handig om de CD/DVD driver van je computer of laptop te openen. Hier kunnen we de mciSendString functie uit de MMSystem unit gebruiken. Om de CD drive te openen moeten we de string “Set cdaudio door open wait” sturen, en om hem te sluiten de string “Set cdaudio door closed wait”. Om een specifieke drive X te openen kunnen we de string “X: Alias Drive_X type cdaudio” sturen om X: als alias voor Driver_X op te geven, gevolgd door “set Drive_X door open”. De volgende functie kan gebruikt worden om een willekeurige Drive te openen, of de default driver (als je #0 meegeeft als argument): function OpenDrive(DriveLetter: Char): LongInt; var ParamString: string; Fig. 3: Details of the failed rule begin if DriveLetter = #0 then Settings are not updated It is possible that a property like the category will change during development. A mistake is easily made and the rule has to move from the Configuration to the Performance category. Code listing 10 displays the minor change in code. begin ParamString := 'set cdaudio door open'; Result := mciSendString(PChar(ParamString),nil,0,0) end else begin public override SPHealthCategory Category ParamString := DriveLetter + ': Alias Drive_' + { DriveLetter get + ' Type CDAudio'; { Result := mciSendString(PChar('open ' + return SPHealthCategory.Performance; ParamString),nil,0,0); } if Result = 0 then } Result := mciSendString(PChar('set ' + 'Drive_' + DriveLetter Listing 10: Changing the Category of the rule definition After the deployment of the solution with the changed Category property the rule fails, but the rule shows up at the 'old' category Configuration. This is one of the possible 'issues' which can occur if the Timer Service Recycle timer job isn’t restarted. The job is like an iisreset, but for the timer service, it recycles the Timer Service to free resources. Conclusion It is a good practice to implement health rules to monitor the farm, be informed about issues and take the appropriate action. The rules are not that hard to program, but can be really useful to have an overview of issues.Whenever possible implement health rules that comply with the governance plan of the organization. It will be easier and maybe avoids chaos in the SharePoint environment. • Anita Boerboom Anita Boerboom is an independent SharePoint developer and consultant in The Netherlands. She combines programming knowledge with good communication skills and a high quality standard in all her projects. Anita has worked in several industries with focus on several knowledge areas within SharePoint. She's very fond of the jQuery library SPServices. + ' door open'),nil,0,0) end end; TIP: Het Windows Phone 7 product team heeft het boek over Programming the Windows Phone 7 van Charles Petzold beschikbaar gesteld aan de community. In dit boek kun je alles lezen, hoe je zelf applicaties kunt maken voor de Windows Phone 7. In principe heb je daarvoor geen toestel nodig en kun je alles uitproberen in de emulator. Het boek is te downloaden op: http://bit.ly/9PBQNr en de bijbehorende sources op: http://bit.ly/aB0N08. magazine voor software development 41 GENERAL Robert Blom “Nieuw” in Nederland: NLDeveloper De marktwaarde van elke software-ontwikkelaar wordt al jaren bepaald door de expertise die hij of zij meebrengt. Elke werkgever is tenslotte gebaat bij goed-functionerende software, of er nu sprake is van een detacherings-opdracht of het uitvoeren van projecten onder eigen dak. Het is daarom niet verwonderlijk dat er voortdurend wordt bijgeleerd: via cursussen, seminars, workshops, competence centers, fora etc. Een forum is al jaren een bekende ontmoetingsplaats om kennis te delen: de een vraagt, de ander antwoordt, weer een ander corrigeert of vult aan. Het succes van Wikipedia is hierop gebaseerd, duizenden auteurs bepalen het succes en de waarheidsgetrouwheid. In de wereld van software-ontwikkeling zijn er op internet vanzelfsprekend al verschillende fora te vinden. Het ene forum is populairder dan de ander of richt zich op één specifieke ontwikkelomgeving. En vaak is het antwoord op een brandende vraag in het buitenland en/of in een andere taal te vinden. Daarbij blijft Google een veelgebruikt vertrekpunt voor een prangende vraag. Een forum in je eigen moerstaal blijft toch het meest ideaal. Want wat is er nou handiger om via het forum nog even - in je eigen taal - contact met de vragensteller op te nemen of om via het forum een gezamenlijk probleem aan te pakken. Het onderwerp sfeer is daarmee een ‘hot issue’ geworden. Elke moderator probeert zijn (of haar!) forum uit te bouwen, veel leden te werven en qua inhoud en populariteit op internet tot een succes te maken. Wat dat betreft heeft NLDeveloper als kennistank, forum, blog of ‘ontmoetingsplaats’ niets nieuws te melden. NLDeveloper is daardoor altijd op de hoogte van de nieuwste ontwikkelingen; een voorsprong die natuurlijk ten goede komt aan de actieve leden van het forum. Op zowel de website als via Twitter, Facebook, LinkedIn en media besteden we aandacht aan nieuwe ontwikkelingen en technieken die de moderne software-ontwikkelaar helpt nog beter in zijn/haar werk te worden en te blijven. NLDeveloper komt niet zomaar uit de lucht vallen. In een tijd dat Cloud-computing en Social Media het gesprek van de dag zijn, zijn de moderators (en tevens initiatiefnemers) al jaren werkzaam in de wereld van software-ontwikkeling en hebben hun sporen op dit gebied al lang verdiend. Betekent dat dan een probleemloze start van het nieuwe forum? Mede-initiatiefnemer Robert Blom: “Welnee. Elke nieuwe site, forum, blog, concept of dienst op internet vraagt om voortdurende aandacht en waar nodig bijsturen. Natuurlijk, de site kan alleen een succes worden bij voldoende ‘verstandige’ vragen en ‘verstandige’ antwoorden. Ongeacht het kennisniveau van de bezoeker: men moet zich op NLDeveloper thuis (gaan) voelen. Tweerichtingsverkeer dus. Maar ook de artikelen, blogs, speciale aanbieden, berichtgevingen, aankondigingen moeten aantrekkelijk zijn én blijven. Waarbij ook de sfeer niet uit het oog verloren wordt.” NLDeveloper is dus nieuw. De mensen achter de website willen een modern, informatief en succesvol platform realiseren. Dit kan uitsluitend met de medewerking van lezers en leden. “Heb je vragen en/of opmerkingen, aarzel dan niet om contact met ons op te nemen of een vraag te stellen op ons forum. Alleen met elkaar kunnen we NLDeveloper voor elkaar een succes laten worden.” Meer weten? Kijk op www.nldeveloper.com. Wedden dat het klikt? • Robert Blom En toch is er wat nieuws onder de zon. NLDeveloper richt zich niet op één specifieke ontwikkeltaal! . En dat is handig voor leden, lezers én bedrijven als Microsoft (.Net, VB), Sun (Java/J2EE), Embarcadero (Delphi, Prism) en Oracle. Als lid van NLDeveloper blijf je op de hoogte van de nieuwste ontwikkelingen. Je maakt deel uit van een netwerk van professionele ontwikkelaars die elkaar op een professionele wijze te hulp staan. Hierdoor is er altijd een technische vraagbaak binnen handbereik waardoor je bij het oplossen van vraagstukken een aanzienlijke tijdwinst realiseert. Zowel formeel als informeel heeft het NLDeveloper uitstekende contacten met leveranciers. 42 MAGAZINE Robert Blom adviseert en produceert. Voegt de daad bij het woord. Met als resultaat: een lange reeks aan enthousiaste opdrachtgevers. Plus een lange reeks succesvolle brochures, websites en andere uitingen. Complete producten, van concept tot uitvoering - inclusief design, fotografie, copywriting, drukwerk en meer. Kortom, alles wat u nodig hebt om u met effect in de markt bekend te stellen. Zie ook www.RobertBlom.nl GENERAL Mark Wolzak Best practices bij het vervangen van een SCOM Gateway Server Bij het monitoren van agents binnen System Center Operations Manager (SCOM) 2007 R2 wordt gebruik gemaakt van Kerberos voor onderlinge authenticatie binnen de trust boundary van een domein. Buiten trust boundaries wordt gebruik gemaakt van certificaten. Sinds SCOM 2007 kan voor monitoring van agents buiten de trust boundary ook gebruik gemaakt worden van een Gateway server. De gateway server wordt geplaatst binnen de trust boundary van de agents en verzorgt authenticatie voor de agents met de managementgroup met behulp van een certificaat. Omdat de agents zich in dezelfde trust boundary bevinden als de gateway kunnen zij zich authenticeren bij de gateway met behulp van Kerberos en hebben hierdoor zelf geen certificaat nodig. Dit kan een aanzienlijke besparing opleveren in beheer van certificaten op het moment dat er veel agents in betreffende omgeving gemonitord moeten worden. Een ander voordeel is dat de agents zelf geen internetverbinding nodig hebben. Op den duur kan het noodzakelijk worden om een gateway server te vervangen, bijvoorbeeld doordat hardware verouderd is. De procedure die hiervoor is beschreven in de Operations Administrator’s Guide van Microsoft werkt echter niet altijd vlekkeloos. In dit artikel worden een aantal extra benodigde stappen besproken om tot het gewenste eindresultaat te komen. De procedure volgens Microsoft in praktijk gebracht De procedure zoals beschreven in de SCOM 2007 R2 Operations Administrators Guide1 is als volgt: 1. Log in op een managementserver (MS) met een account dat lid is van de Operations Manager Administrators groep en open de console; 2. Ga naar het Administration scherm en ga naar Administration > Device Management en klik ‘Agent Managed’; 3. Selecteer de Computers waarvoor de primary managementserver gewijzigd moet worden, doe rechtermuisklik en selecteer ‘Change Primary Management Server’; 4. De-installeer de gateway server software van de computer; 5. Verwijder de gateway server uit de groep. Met deze procedure bestaat er een kans dat de agents communicatie verliezen met de managementgroep. Vooral als agents niet geconfigureerd zijn met een failover managementserver. In principe zou nu het volgende moeten gebeuren: 1. De Root Management Server (RMS) verwerkt de aanpassing waardoor de ‘state cookies’ van Gateways (GTW) ‘A’ en ‘B’ en van ‘Agt X’ verlopen en deze een nieuwe configuratie nodig hebben; 2. Gateway ‘A’ controleert of zijn state cookie nog geldig is en vraagt de nieuwe configuratie op; 3. De nieuwe configuratie wordt overgebracht naar Gateway ‘A’ waarin is aangegeven dat ‘Agt X’ moet rapporteren aan Gateway ‘B’; 4. ‘Agt X’ controleert of zijn state cookie nog geldig is en vraagt de nieuwe configuratie op; 5. De nieuwe configuratie wordt overgebracht naar ‘Agt X’ waarin is aangegeven dat ‘Agt X’ moet rapporteren aan Gateway ‘B’; 6. Communicatie met Gateway ‘B’ wordt opgestart en ‘Agt X’ rapporteert voortaan met Gateway ‘B’. Op het moment dat de configuratie gewijzigd wordt volgens bovenstaande procedure zullen agents die niet geconfigureerd zijn met een failover managementserver, connectie met de managementgroep verliezen. De oorzaak hiervan ligt primair in de volgorde waarin de configuratie wordt ontvangen en de wijze waarop de managementservers hierop reageren. Omdat in stap 3 de configuratiewijziging aankomt bij Gateway ‘A’ zal deze server elke volgende communicatie met ‘Agt X’ weigeren. Volgens de configuratie van deze gateway communiceert ‘Agt X’ immers niet langer met Gateway ‘A’. Dit betekent dat de agent na stap 4 de communicatie met de managementgroup verliest. Symptomen bij verliezen communicatie De symptomen voor het verliezen van de communicatie zullen terug te vinden zijn in de console en in de ‘Operations Manager’ eventlogs van de agent en van de oude en de nieuwe gateway server. Console In de console zal een heartbeat failure te zien zijn waardoor de agent grijs weergegeven zal worden in de console. magazine voor software development 43 GENERAL Tevens zullen in de alertview de volgende errors te zien zijn Agent In de eventlog zal bij het maken van een connectie met de oorspronkelijke Gateway server een error met eventid 20070 met als source ‘OpsMgr Connector’ optreden. 1. Verwijder een gateway server pas (stap 5 in de procedure) op het moment dat alle agents succesvol communiceren met hun nieuwe managementserver; 2. Zorg ervoor dat agents, indien er een nieuwe primaire managementserver aangewezen wordt, de oorspronkelijke managementserver, al dan niet tijdelijk, als failover management– server toegewezen krijgen. Indien de oorspronkelijke gateway server niet meer ingezet kan worden, bijvoorbeeld doordat deze niet meer actief is, kan de configuratie van de agent ook handmatig aangepast worden. Naast de error in de eventlog is het probleem te zien in de configuratie van de agent in de registry onder ‘HKLM\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Agent Management Groups\[Managementgroup Name]\Parent Health Services\0’. Hier zal te zien zijn dat de genoemde managementserver (AuthenticationName en NetworkName), nog steeds de oude server betreft. Oorspronkelijke en nieuwe Gateway server In de eventlogs van de oorspronkelijke en de nieuwe gateway server zullen errors met respectievelijke EventId’s 20000 en 20022 van Source ‘OpsMgr Connector’ gelogd worden. Hierbij geeft de eerste aan dat een device welke geen lid is van de managementgroup heeft geprobeerd contact te maken. De tweede geeft aan dat de agent geen heartbeat heeft. Oorspronkelijke gateway server als failover aanwijzen Door het inzetten van de oorspronkelijke managementserver als failover management server is de agent geautoriseerd om contact op te nemen met de managementgroup via zijn oorspronkelijke primaire managementserver en wordt de agent in staat gesteld om de juiste configuratie op te halen van de managementgroup. Oplossen en voorkomen Het beschreven probleem kan het best opgelost en voorkomen worden door bij het vervangen van een gateway server een aantal regels aan te houden: De procedure kan uitgevoerd worden met behulp van onderstaande powershell script (uit te voeren via de operations manager shell): 01234567890123456789012345678901234567890123456789012 3456 44 MAGAZINE GENERAL $primaryMS = Get-GatewayManagementServer | where {$_.Name -eq 'ExtGWt02.clientx.local'} $failoverMS = Get-GatewayManagementServer | where {$_.Name -eq 'ExtGWt01.clientx.local'} $agent = Get-agent 7. Verifieer dat ‘Specify Management Group Information’ is aangevinkt en klik ‘Next’; 8. Onder ‘management server’ kan nu de juiste managementserver aangegeven worden. Klik ‘Next’ en klik ‘Install’. Na afloop van deze installatie zal de communicatie met de managementgroup hervat worden. | where {$_.Name -eq 'ExtADt01.clientx.local'} Set-ManagementServer -AgentManagedComputer: $agent -PrimaryManagementServer: $primaryMS -FailoverServer: $failoverMS In bovenstaand voorbeeld is ExtGWt01.clientx.local de originele managementserver (gateway) en ExtGWt02.clientx.local de nieuw in te zetten managementserver (gateway). Conclusie De procedure die door Microsoft is beschreven voor het vervangen van een Gateway server functioneert niet altijd vlekkeloos. Problemen die hieruit voortvloeien zijn echter niet onoverkomelijk en kunnen voorkomen worden door een paar eenvoudige regels te hanteren. • 1 http://download.microsoft.com/download/B/F/D/BFDD0F66-1637-4EA3- 8E6E-8D03001E5E66/OM2007R2_OperationsAdministratorsGuide.docx Na uitvoeren van het script zal communicatie met de managementgroup hersteld worden en kan, zodra de agent de nieuwe configuratie opgehaald heeft, de failover managementserver verwijderd worden uit de configuratie van de agent door onderstaande script via de operations manager shell uit te voeren: Mark Wolzak Ik ben 10 jaar werkzaam in de IT en als ontwerper infrastructuur / consultant werkzaam bij Info Support in Veenendaal. Ik werk onder andere met SQL Server, ISA/TMG, Exchange en System Center Virtual Machine manager, maar heb me gespecialiseerd in System Center Operations Manager waarvoor ik diverse implementaties heb verzorgd $primaryMS = Get-GatewayManagementServer | where {$_.Name -eq 'ExtGWt02.clientx.local'} $agent = Get-agent | where {$_.Name -eq 'ExtADt01.clientx.local'} Set-ManagementServer -AgentManagedComputer: $agent -PrimaryManagementServer: $primaryMS bij uiteenlopende klanten. .NET TIP: Welke .NET versie draai ik Als je wilt weten welke versie van het .NET framework je allemaal hebt geinstalleerd, kun je dat doen door in de registry te zoeken en de directories op je disk te controleren. Maar dit is er arbeidsintensief en niet geheel foutloos. Via twitter kwam deze link http://www.asoft.be/prod_netver.html. Handmatig aanpassen van de configuratie Indien de oorspronkelijke gateway server niet meer ingezet kan worden kan onderstaande procedure gebruikt worden om de configuratie aan te passen: 1. Stop de service ‘System Center Management’ op de server waar de agent draait; 2. Verwijder de inhoud van de directory ‘D:\Program Files\System Center Operations Manager 2007\Health Service State\Connector Configuration Cache\[Managementgroup name]’; 3. Open ‘Add/Remove programs’ (of ‘Programs and Features’ in server 2008) 4. Selecteer ‘System Center Operations Manager 2007 R2 Agent’ en klik ‘Change’; 5. Klik ‘Next’, selecteer ‘Modify’ en ‘Next’; 6. Selecteer ‘Modify Management Group’, selecteer de juiste managementgroup en klik ‘Next’; magazine voor software development 45 GENERAL De uiterste houdbaarheidsdatum van requirements Onlangs gaf ik – voor de zoveelste keer – training in het identificeren en modelleren van smart use cases. Dit keer bevond ik me in de hippe ruimtes van Meeting Plaza Utrecht, boven het altijd sfeervolle Hoog Catharijne. Tijdens de goed verzorgde lunch werd het onderwerp al snel bepaald door de uiterste houdbaarheidsdatum. Van levensmiddelen, maar meer nog, van requirements. Stickeren In de horeca is het al jaren een goed gebruik, het stickeren van levensmiddelen, zo weet ik van afzichtelijke televisieprogramma’s als Keuringsdienst Van Waren. Een eenvoudige sticker vertelt wanneer het product is opengemaakt, en tot wanneer het houdbaar is. Is deze uiterste houdbaarheidsdatum verstreken, dan wordt het product weggegooid, onbruikbaar voor consumptie. Tenminste dat hoop je dan. Maar dan. De uiterste houdbaarheidsdatum van requirements? Het onderwerp kwam ter tafel toen een van de cursisten vertelde op dit moment te werken aan de requirements van een request for change (RFC) die inmiddels twee jaar oud is. Twee jaar oude requirements? De kans is groot dat deze requirements inmiddels al behoorlijk beschimmeld zijn; wet- en regelgeving is gewijzigd en de wensen van de gebruikers zijn ontegenzeggelijk veranderd. Als tijdens een gemiddeld project de requirements al 20-25% wijzigen, hoe vergaat het dan requirements die ergens op een plank liggen te verstoffen? Requirements en kaas Welbeschouwd zijn requirements te vergelijken met kaas. Je hebt jonge requirements, net rijp genoeg om te consumeren, jong belegen requirements die eigenlijk al hadden moeten worden gerealiseerd, en dan oude requirements, die opzichtig beginnen te brokkelen. Tenslotte zijn alle ongebruikte requirements overjarig. Wellicht smaakvol, maar ze vallen al uit elkaar op het moment dat ze worden gehanteerd. En net als kaas die op een plank ligt te rijpen verdienen requirements dezelfde zorgzame aandacht willen ze na een of twee jaar nog consumeerbaar zijn. Ze moeten worden omgedraaid, geevalueerd en verzorgd. Gebeurt dit niet dan verschimmelen ze en moeten ze eenvoudigweg uit de handel worden genomen, ongeschikt voor comsumptie. Ik denk dan ook dat het een goed idee is ook requirements te stickeren, net als alle andere bederfelijke waar. Wanneer zijn ze aangemaakt, en belangrijker nog, wanneer dienen de requirements gerealiseerd te zijn voor ze definitief verschimmelen. Maar wanneer zijn onze requirements eigenlijk bedorven? Een kritisch agile luisteraar zal wellicht zeggen dat requirements beginnen met rotten zodra ze zijn opgeschreven. Immers, voortschrijdend inzicht begint direct te werken. Misschien is het een idee om een standaardtermijn voor bederf te hanteren – zeg een half jaar. En misschien zijn requirements voor de user interface wel nog sneller bedorven. Die krijgen dan een sticker van drie of vier maanden. En wanneer requirements over hun uiterste houdbaarheidsdatum heen zijn? Niet aarzelen. Gewoon weggooien! YAGNI Het is overigens goed mogelijk de uiterste houdbaarheidsdatum te rekken. Hier komt het bekende YAGNI-principe goed van pas. You aren’t gonna need it. Ofwel voorkom in projecten al het werk dat op dit moment (nog) niet nodig is. Doorvertaald naar requirements komt dit er op neer dat alhoewel het verstandig is aan het begin van een project vast te stellen welke requirements we graag willen implemeteren, de details van deze requirements pas echt nodig zodra de implementatie ervan begint. En dat is mogelijk pas veel later. Dit verklaart ook deels het succes van agile, kort-iteratieve projecten. De details (analyse en ontwerp) van een requirement worden pas bepaald zodra deze tijdens een van de iteraties daadwerkelijk wordt gebouwd. Zo wordt voorkomen dat er vroeg in een project veel werk in requirements wordt gestoken die nooit worden gerealiseerd, zoals in watervalprojecten nog wel eens het geval is. En bovendien, wanneer de details bijvoorbeeld pas na een half jaar worden onderzocht, is het voortschrijdend inzicht van dat half jaar automatisch geborgd. Om in de metafoor te blijven, zo zijn requirements altijd vers. Ik benieuwd overigens wat de uiterste houdbaarheidsdatum van deze column zal blijken te zijn. • 46 MAGAZINE DOT NET NUKE Charles Nurse DotNetNuke supports Razor On January 13th at CodeMash in Sandusky, Ohio, Microsoft introduced Razor - a new lightweight syntax for developing WebPages as part of its WebMatrix offering. In a separate article in this issue, Andrew Nurse, one of the developers who created Razor describes the motivations behind this new syntax and an overview of the syntax itself. In this article I will focus on how you can use Razor scripts in DotNetNuke 5.6.1. The Razor Host Module In addition to the new bits that are available as part of the WebMatrix suite, the Razor parser and the new WebPages Framework requires ASP.NET 4.0. As we still wish to retain compatibility with ASP.NET 3.5 we cannot directly integrate support for Razor scripts into the DotNetNuke core, as this will force all of our users to upgrade to ASP.NET 4.0. Therefore, our approach to providing support for Razor scripts is to provide a “Razor Host” module. If DotNetNuke users wish to use Razor scripts as part of their sites, they will need to install this module. A Beta of this module has been available since early December and was used as the basis for the recent Hackathon contest. However, DotNetNuke 5.6.1 will contain an initial release of the Razor Host module. Adding the Razor Host Module to a Page An instance of this module can be added to a DotNetNuke page in the usual way (see Figure 1). The resulting module looks pretty sparse (see Figure 2). The body of the module does not display anything - as no script is selected - and there is only a single Action – Edit Script - which allows Host users to create and edit scripts. Fig. 2: The Razor Host Module on a page Only Host Users can Create or Edit Razor Scripts It is very important to note that the only users who will see the “Edit Script” Action button or menu item are Host (or Super) Users. This is because you can do anything in Razor script, so only users with the highest level of access should be able to create Razor scripts. Configuring the Razor Host Module As with most modules in DotNetNuke the Razor Host module does have settings - actually a single setting - the ability to select a previously created Razor script (see Figure 3). Fig. 1: Adding an instance of the Razor Host module to a page Fig. 3: Setting the Razor Script to use magazine voor software development 47 DOT NET NUKE While editing and creating scripts can only be done by a Host User, any user with Edit permissions can select an existing script. In the example shown in Figure 3, selecting the PageInfo.cshtml script will result in the module displaying the content shown in Figure 4. The Text Area does not provide any Syntax Highlighting (or Syntax checking). But if you want some “Syntax Highlighting” you can use the WebMatrix IDE to modify the script files (Figure 6) or even Visual Studio 2010. Note that in the WebMatrix IDE the C# code has a different highlighting than the HTML. Hosting the Razor Engine So far we have seen how we can use the Razor Host Module, but how is this achieved? Razor can actually be thought of as a templating engine and if you are planning on building a module that requires templates you might want to consider Razor. So, by describing how we host the Razor Engine hopefully I will be able show how you might do that. Fig. 4: The Rendered Razor Script Creating and Editing Razor Scripts So selecting a previously created script is fairly easy, but how can we edit or create scripts. When logged in as a Host user, selecting the previously described “Edit Script” Action will bring up the “Edit Script” control (Figure 5). The WebPage Class The WebPage Class (actually WebPageBase) is the basis of the new WebPages Framework, in the same way that the “Page” class is the basis of the WebForms Framework. Essentially the approach we use in our “Razor Host” module is as follows. 1. Identify the Razor script file (e.g. Twitter.cshtml) 2. Call BuildManager.GetType(scriptFile) to create an instance of WebPage. Note that the System.Web.WebPages assembly contains a special class - PreApplicationStartCode - that ensures that the extensions cshtml and vbhtml are registered with the BuildManager 3. Call the ExecutePageHierarchy method of the WebPage class and capture the rendered content. 4. Create a LiteralControl with the rendered content and add it to the control tree. In order to achieve this there are two new classes in a new assembly (DotNetNuke.Web.Razor.dll) which is distributed as part of the “Razor Host” Module. Fig. 5: Editing a Razor Script using the Edit Script control This control allows you to: • Add a new Script File • Choose a Script file to Edit • Modify the Script source in the Text Area • Set the current Script to be the Active Script (Is Active) - as an alternative to choosing the “Active” script in the Module Settings • Save the Modified Script. The script files are all stored in the “Scripts” sub-folder. 1. RazorModuleBase – this class implements IModuleControl by sub-classing ModuleUserControlBase 2. DotNetNukeWebPage – this class subclasses WebPageBase and provides some DNN specific enhancements. The RazorModuleBase Class The RazorModuleBase class is where everything comes together. All DNN Modules need to implement the IModuleControl Interface - this is how the module injection logic knows what to inject. RazorModuleBase is a new base class that implements IModuleControl and is used as the base class for the Razor Host Module. In the OnPreRender method of the class we first check if our script RazorScriptFile - exists. If it does we call the CreateWebPageInstance method to get an instance of the DotNetNukeWebPage. Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs) MyBase.OnPreRender(e) Try If File.Exists(Server.MapPath(RazorScriptFile)) Then Dim instance As Object = CreateWebPageInstance() If instance Is Nothing Then Throw New InvalidOperationException( _ String.Format( _ Fig. 6: Editing a Razor Script using the WebMatrix IDE 48 MAGAZINE CultureInfo.CurrentCulture, _ DOT NET NUKE "The webpage found at '{0}' was not created.", _ RazorScriptFile)) End If Private Function CreateWebPageInstance() As Object Dim type As Type = BuildManager.GetCompiledType(RazorScriptFile) Dim instance As Object = Nothing Dim webPage As DotNetNukeWebPage = TryCast(instance, DotNetNukeWebPage) If type IsNot Nothing Then instance = Activator.CreateInstance(type) End If If webPage Is Nothing Then Throw New InvalidOperationException( _ String.Format( _ Return instance End Function CultureInfo.CurrentCulture, "The webpage at '{0}' must derive from Listing 3: The CreateWebPageInstance method DotNetNukeWebPage.", RazorScriptFile)) End If Earlier in this article I mentioned that BuildManager knew to “build” a WebPage instance from a cshtml or vbhtml because of some code that exists in the WebPages Framework that registers the extension. webPage.SetContext(Me.ModuleContext) InitHelpers(webPage) Dim writer As New StringWriter webPage.ExecutePageHierarchy( New WebPageContext(HttpContext), writer, webPage) Controls.Add( New LiteralControl(Server.HtmlDecode So why do we get an instance of DotNetNukeWebPage rather than an instance of WebPage? The answer lies in the included web.config file (Listing 4) that sits in the same folder as the Razor Host Module. By default the Razor Engine will return an instance of WebPage, but this can be modified in the new system.web.webPages.razor section of web.config, where we have indicated that an instance of DotNetNukeWebPage should be returned. (writer.ToString()))) End If Catch ex As Exception ProcessModuleLoadException(Me, ex) End Try <system.web.webPages.razor> <pages pageBaseType="DotNetNuke.Web.Razor.DotNetNukeWebPage"> <namespaces> <add namespace="Microsoft.Web.Helpers" /> <add namespace="WebMatrix.Data" /> End Sub </namespaces> </pages> Listing 1: The OnPreRender method of the RazorModuleBase class We then set the WebPage’s module context by calling its SetContext method. This allows us to access the ModuleContext in Razor script. Finally we call the WebPage’s ExecutePageHierarchy method to get the rendered content, which we add as a LiteralControl to the Controls collection of the module. In the above description I glossed over two important points: the RazorScriptFile property and the CreateWebPageInstance property. The RazorScriptFile Property The RazorScriptFile property (Listing 2) returns the virtual path of a “default” script file. In the Razor Host module, we override this property and return the currently selected script, but the default behaviour in the base class is to return “MyScript.cshtml” if the current control is “MyScript.ascx”. Protected Overridable ReadOnly Property RazorScriptFile As String Get Return Me.AppRelativeVirtualPath.Replace("ascx", "cshtml") End Get End Property Listing 2: The RazorScriptFile property The CreateWebPageInstance Method The CreateWebPageInstance method (Listing 3) uses the RazorScriptFile property to create an instance of a DotNetNukeWebPage (Listing 3), calling BuildManager.GetCompiledType, which returns a Type and then calling Activator.CreateInstance to return an instance of the DotNetNukeWebPage. </system.web.webPages.razor> Listing 4: The Razor Host Module’s web.config file Conclusion Razor is an exciting addition to our list of technologies that we can use to create dynamic webistes. By hosting the Razor Engine in DotNetnuke, the Razor Host Module can be used to host Razor scripts in DotNetNuke 5.6.1. Take the opportunity to investigate Razor by installing the Razor Host Module and play with the included script files – or goto the DotNetNuke site (www.dotnetnuke.com) and download one of the Razor Hackathon entries. • Charles Nurse Since 2006 he has been Senior Architect for DotNetNuke Corporation the creators of the DotNetNuke Open Source Web Application Platform. Charles has been working with the .NET Framework since its first release, specializing in Web Applications using ASP.NET and he is a Microsoft MVP and an ASPInsider. He has spoken at many major conferences including the Software Developers Conference (SDC) (www.sdc.nl), DevConnections (www.devconnections.com), DevTeach (www.devteach.com) and Microsoft Tech Days, and he is a frequent speaker at local User Groups and Code Camps. magazine voor software development 49 GENERAL Joachim Nilsson Reflection loops of Agile The agile way of working has now come upon us with full strength; some projects with poor results and others with excellent results. Since the agile way includes elements of selfimprovement, any poor results should soon become good ones and finally excellent ones. As a Software Engineer, I really like this way to work since it provides me with some great tools. In the pre-agile world, I could sometimes feel that I and my team at times would drift away from the solution we were supposed to create. The time to market is putting pressure on the deliveries, and a complex technological surrounding forced us to work in a speed that left no time to correct bad input values in requirements. When thinking about this I also came to an insight that the agile practices that I have selected to work with, gives me a scheduled time to reflect. Reflection loop 1: Self Start by looking at Test Driven Development or TDD. When we implement this in both unit testing and automated functional testing, the practice will force us to reflect on and validate the requirements as a first step. So before starting to write a single line of code, we make sure that our requirements are testable since otherwise we cannot write our automated tests for the feature. The reflection is done by the test writer him- or herself and is done within a very short time frame. assumptions and limitations that need to be handled? The one thing I want to improve on is to hold demos more often, for any type of change that can be demonstrated: • Test cases - to verify with stakeholders that the requirements are interpreted correctly. • Architectural changes – to make our surrounding teams understand how the latest code works. • Working code – the normal demonstration Reflection loop 5: Retrospective We hold our retrospective once a sprint as normal. And this is the best practice of all because it allows our team to constantly improve in a pace that fits us. It also provides feedback and learning to the department in terms of how we can make all teams work more efficient. Reflection loop 2: The pair Pair programming is my next selected practice. It is seldom implemented to 100% since it appears to cut the production speed in half. And that is true! It is true - if all developers • …never write any poorly designed code • …never introduce any bugs • …and always are up to date with the architecture of the rest of the development department. If you have this situation in your teams: Congratulations! When pair programming actually is done, it will give the benefit of forcing the developer to reflect on the design and solution of the problem. If the design is incorrect or the solution seems unclear, the navigator or co-pilot will interrupt with a question. In order to answer, the developer must of course have a clear thought of the solution or think about it for a while. The reflection is done together with the team mate and perhaps a few times during the day. Reflection loop 3: Stand-up meeting When I look at the stand-up meeting with reflection in mind, I see that in order to get the reflective mindset in the team it is best if my team members are all focused on the same task. When they have different tasks, the interest between the team members decreases and I end up with sub tasks being forgotten or issues being missed. Done properly, with same goal in mind and with an attitude to help each other, I find that reflection is done in the whole team. Reflection loop 4: Demonstration When we do demonstrations from our team, we invite the product owners, the architects and the other teams that work in our product. It is an excellent way to get feedback on the completed task. Can we consider it done or not. Are there any issues that have arisen from our 50 MAGAZINE Summary To summarize, I find that the practices I have chosen to follow will allow me and my team to reflect in a number of ways, starting from the smallest feedback loop up to the largest. This is also a lesson that I think is worth sharing, to find reasons behind the agile practices that you choose to follow. Reasons are of course several, but bring them up to discussion within your own team and see that it will be a lot easier to follow practices since there is a common understanding of why you do the things you do. • Joachim Nilsson Joachim Nilsson is a consultant at Capgemini, Sweden. He has a M.Sc. in computer sciences from Lund institute of Technology and has been working in different roles of software development during the last 16 years. 0HOGXQXDDQRS 'HY'D\VQO .RPQDDU'HY'D\V 'HY'D\VLVKpWJURRWVWH0LFURVRIWHYHQWLQ 1HGHUODQGYRRUVRIWZDUHGHYHORSPHQWHQ VRIWZDUHDUFKLWHFWXXU/DDWXLQVSLUHUHQ HQVFKULMIXLQYRRU'HY'D\V 'RQGHUGDJHQYULMGDJ HQDSULO :RUOG)RUXPLQ'HQ+DDJ 7RSVSUHNHUV'HY'D\V 0LOHV0LNH 9LWRUULR%HU WRFFL5RE E%HDXFKHPLQ 7DXOW\%ULDQ.HOOHU%R VWHU,QJR5DPPHU 9D V HQ P OH & VL DV 0 WK %H URVLVHHQQRJ &KULVWLDQ:HLMHU-HVV3 V YHOHDQGHUHWRSVSUHNHU O 3UHFRQIHUHQFHVHVVLHVRSDSUL PELQHHUG $]XUH²LQGHSWKWUDLQLQJGDJJHFR LQJHHQ VWUDLQ LGLQJ UEHUH PHWHHQRQOLQHYRR QEHSHUNW HQR GDJ Q DVVH GDDJVH$]XUHS JHQ DLQLQ QHWU RQOL VLJKW WRHJDQJWRW3OXUDO RS² :LQGRZV3KRQH²KDQGVRQZRUNVK QH ERXZMHHHUVWH$SSYRRU:LQGRZV3KR ODFH UNHWS HQPDDNGH]HEHVFKLNEDDULQGHPD %HODQJULMNHRQGHUZHUSHQ &ORXGGHYHORSPHQWPHW:LQGRZV$]XUH :LQGRZV3KRQHGHYHORSPHQW :HEGHYHORSPHQWPHWRD09&5D]RU 5HVW2'DWD$631(76LOYHUOLJKWHQ+70/ $OOHVRYHU9LVXDO6WXGLRPHWRD/LJKW6ZLWFK ,QWHOOLWUDFH7)6HQ] 7HYHQVGLYHUVHVHVVLHVRYHU1(7)UDPHZRUN 6KDUH3RLQWGHYHORSPHQWHQ64/ 'D\VQO 0HOGXQXDDQRS'HY Wat W at doe jij vvolgende olgende maand? ::ŝũďŽƵǁƚĚĞŶŝĞƵǁĞǁĞďĂƉƉůŝĐĂƟĞǀŽŽƌĠĠŶǀĂŶĚĞƚŽƉĚƌŝĞǀĞƌnjĞŬĞƌĂĂƌƐŝŶEĞĚĞƌůĂŶĚ͕ ŝũďŽƵǁƚĚĞŶŝĞƵǁĞǁĞďĂƉƉůŝĐĂƟĞǀŽŽƌĠĠŶǀĂŶĚĞƚŽƉĚƌŝĞǀĞƌnjĞŬĞƌĂĂƌƐŝŶEĞĚĞƌůĂŶĚ͕ ǁĂĂƌŵĞĞŵĞŶƐĞŶƐŶĞůĞŶĞĞŶǀŽƵĚŝŐŽŶůŝŶĞŚƵŶǀĞƌnjĞŬĞƌŝŶŐĞŶŬƵŶŶĞŶĂĨƐůƵŝƚĞŶ͕ŝŶnjŝĞŶ ǁ ĂĂƌŵĞĞŵĞŶƐĞŶƐŶĞůĞŶĞĞŶǀŽƵĚŝŐŽŶůŝŶĞŚƵŶǀĞƌnjĞŬĞƌŝŶŐĞŶŬƵŶŶĞŶĂĨƐůƵŝƚĞŶ͕ŝŶnjŝĞŶ ĞĞŶďĞŚĞƌĞŶ͘:ĞnjĞƚũŽƵǁĐƌĞĂƟĞǀĞŝĚĞĞģŶŽŵŝŶƐůŝŵŵĞĐŽĚĞĞŶŐĞďƌƵŝŬƚĚĞŶŝĞƵǁƐƚĞ ŶďĞŚĞƌĞŶ͘:ĞnjĞƚũŽƵǁĐƌĞĂƟĞǀĞŝĚĞĞģŶŽŵŝŶƐůŝŵŵĞĐŽĚĞĞŶŐĞďƌƵŝŬƚĚĞŶŝĞƵǁƐƚĞ ͘͘EdƚĞĐŚŶŽůŽŐŝĞŽŵĨƌŽŶƚͲĞŶĚƐƚĞŵĂŬĞŶŵĞƚĚĞďĞƐƚĞŬŽƉƉĞůŝŶŐĞŶŶĂĂƌďĂĐŬŽĸĐĞĞŶ EdƚĞĐŚŶŽůŽŐŝĞŽŵĨƌŽŶƚͲĞŶĚƐ ď ďĞƚĂĂůƐLJƐƚĞŵĞŶǀĂŶĚĞŬůĂŶƚ͘ ĞƚĂĂůƐLJƐƚĞŵĞŶǀĂŶĚĞŬůĂŶƚ͘ :ŝũďĞŶƚŶĂŵĞůŝũŬĞĞŶƐƉĞĐŝĂůŝƐƚĚŝĞǁĞůƌĂĂĚǁĞĞƚŵĞƚ^W͘Ed͕η͘Ed͕^ŚĂƌĞWŽŝŶƚĞŶ^Y>͘ :ŝũďĞŶƚŶĂŵĞůŝũŬĞĞŶƐƉĞĐŝĂůŝƐƚĚ //ĞŵĂŶĚĚŝĞĂůƟũĚŽƉnjŽĞŬŝƐŶĂĂƌŶŝĞƵǁĞŬĞŶŶŝƐĞŶĂůƐĞĞƌƐƚĞŵĞƚĚĞƚĞĐŚŶŽůŽŐŝĞǀĂŶŵŽƌŐĞŶ ĞŵĂŶĚĚŝĞĂůƟũĚŽƉnjŽĞŬŝƐŶĂĂ ǁŝůǁĞƌŬĞŶ͕ŵĂĂƌŽŽŬŝĞŵĂŶĚĚŝĞŐĞŶŝĞƚǀĂŶŚĞƚƐƵĐĐĞƐĚĂƚĚĞŬůĂŶƚǀĂŶĚĂĂŐďŽĞŬƚŵĞƚũŽƵǁ ǁ ŝůǁĞƌŬĞŶ͕ŵĂĂƌŽŽŬŝĞŵĂŶĚĚ ŝŝŶŶŽǀĂƟĞǀĞŽƉůŽƐƐŝŶŐĞŶ͘ ŶŶŽǀĂƟĞǀĞŽƉůŽƐƐŝŶŐĞŶ͘ ::ŝũĚĞĞůƚŐƌĂĂŐũĞǀŝƐŝĞĞŶŬĞŶŶŝƐŵĞƚũĞŽŵŐĞǀŝŶŐ͕njŽǁĞůĨLJƐŝĞŬĂůƐŽŶůŝŶĞ͕ĞŶǁĞƌŬƚƐĂŵĞŶ ŝũĚĞĞůƚŐƌĂĂŐũĞǀŝƐŝĞĞŶŬĞŶŶŝƐ ŵĞƚĂŶĚĞƌĞĞǀĞůŽƉĞƌƐ͕ĞƐŝŐŶĞƌƐ͕ƌĐŚŝƚĞĐƚĞŶĞŶŶĂůŝƐƚĞŶĂĂŶĚĞďĞƐƚĞŽƉůŽƐƐŝŶŐĞŶǀŽŽƌ ŵ ĞƚĂŶĚĞƌĞĞǀĞůŽƉĞƌƐ͕ĞƐŝŐŶ ĚĞŬůĂŶƚ͘:ĞǁĞĞƚŚŽĞũĞǁĞƌŬĞŶƉƌŝǀĠǀůĞŬŬĞůŽŽƐŬƵŶƚĐŽŵďŝŶĞƌĞŶĞŶŽŶĂĬĂŶŬĞůŝũŬǀĂŶƟũĚ Ě ĞŬůĂŶƚ͘:ĞǁĞĞƚŚŽĞũĞǁĞƌŬĞŶ ĞĞŶƉůĂĂƚƐĚĞŽƉƟŵĂůĞďŝũĚƌĂŐĞůĞǀĞƌƚĂĂŶũĞƚĞĂŵ͘ ŶƉůĂĂƚƐĚĞŽƉƟŵĂůĞďŝũĚƌĂŐĞů Volgende Volgende de maand werk w jij bij Macaw. .NET Developer D DĂĐĂǁŝƐEĞĚĞƌůĂŶĚƐŐƌŽŽƚƐƚĞ͕ƵŝƚƐůƵŝƚĞŶĚŝŶDŝĐƌŽƐŽŌƚĞĐŚŶŽůŽŐŝĞŐĞƐƉĞĐŝĂůŝƐĞĞƌĚĞ͕/dĚŝĞŶƐƚǀĞƌůĞŶĞƌ͘KŶnjĞŬĞŶŶŝƐ ĂĐĂǁŝƐEĞĚĞƌůĂŶĚƐŐƌŽŽƚƐƚĞ͕ƵŝƚƐůƵŝƚĞŶĚŝŶDŝĐƌŽƐŽŌƚĞĐŚŶŽůŽŐŝĞŐĞƐƉĞĐŝĂůŝƐĞĞƌĚĞ͕/dĚŝĞŶƐƚǀĞƌůĞŶĞƌ͘͘KŶnjĞŬĞŶŶŝƐ ŝŝƐŐĞďƵŶĚĞůĚŝŶǀŝĞƌ^ŽůƵƟŽŶĞŶƚĞƌƐĚŝĞnjŝĐŚƌŝĐŚƚĞŶŽƉŚĞƚƌĞĂůŝƐĞƌĞŶǀĂŶĐŽůůĂďŽƌĂƟĞǀĞƉŽƌƚĂůĞŶ͕DƐLJƐƚĞŵĞŶ͕ ƐŐĞďƵŶĚĞůĚŝŶǀŝĞƌ^ŽůƵƟŽŶĞŶƚĞƌƐĚŝĞnjŝĐŚƌŝĐŚƚĞŶŽƉŚĞƚƌĞĂůŝƐĞƌĞŶǀĂŶĐŽůůĂďŽƌĂƟĞǀĞƉŽƌƚĂůĞŶ͕DƐLJƐƚĞŵĞŶ͕ ŝŶƚĞƌŶĞƚĞŶĐŽŵŵĞƌĐĞƐŝƚĞƐ͕ďƵƐŝŶĞƐƐƐŽůƵƟŽŶƐ͕ZDƐLJƐƚĞŵĞŶĞŶĂƉƉůŝĐĂƟĞďĞŚĞĞƌĞŶŚŽƐƟŶŐĚŝĞŶƐƚĞŶ͘ ŝŶƚĞƌŶĞƚĞŶĐŽŵŵĞƌĐĞƐŝƚĞƐ͕ďƵƐŝŶĞƐƐƐŽůƵƟŽŶƐ͕ZDƐLJƐƚĞŵĞŶĞŶĂƉƉůŝĐĂƟĞďĞŚĞĞƌĞŶŚŽƐƟŶŐĚŝĞŶƐƚĞŶ͘ ĞnjŽĞŬǀŽŽƌŵĞĞƌŝŶĨŽƌŵĂƟĞŽǀĞƌĚĞnjĞĞŶĂŶĚĞƌĞǀĂĐĂƚƵƌĞƐŽŶnjĞǁĞďƐŝƚĞwww.echtleukwerk.nlŽĨŶĞĞŵĐŽŶƚĂĐƚŽƉ ĞnjŽĞŬǀŽŽƌŵĞĞƌŝŶĨŽƌŵĂƟĞŽǀĞƌĚĞnjĞĞŶĂŶĚĞƌĞǀĂĐĂƚƵƌĞƐŽŶnjĞǁĞďƐŝƚĞwww.echtleukwerk.nlŽĨŶĞĞŵĐŽŶƚĂĐƚŽƉ ŵ ŵĞƚŽŶnjĞĂĨĚĞůŝŶŐZĞĐƌƵŝƚŵĞŶƚǀŝĂϬϮϬͲϴϱϭϬϱϭϬŽĨrecruitment@macaw.nl͘ ĞƚŽŶnjĞĂĨĚĞůŝŶŐZĞĐƌƵŝƚŵĞŶƚǀŝĂϬϮϬͲϴϱϭϬϱϭϬŽĨrecruitment@macaw w.nl͘
Similar documents
mijn CV - imagico.nl
ontoereikende interne en externe communicatie. Tegenwoordig moeten mensen zowel zakelijk, alsook privé kunnen omgaan met communicatieve druk. Om uzelf goed te leren presenteren, kalmte uit te stral...
More information