Att genomföra ett GDPR-projekt med full kontroll

Att genomföra ett GDPR-projekt med full kontroll

På IT informa har vi genomfört ett flertal projekt där regulatoriska krav är styrande. Det kan vara regulatoriska krav som PUL, Patientdatalagar i olika länder, etc., och nu även Dataskyddsförordningen (GDPR). Gemensamt för dessa projekt är att vi arbetar med en fungerande metod och verktyg för att säkerställa att vi når upp till rätt compliance-nivå, men även att vi bibehåller den under livscykeln.

Genomföra ett GDPR-projekt

Det finns vissa givna faser i ett projekt. Dessa faser går ut på att dokumentera befintligt nuläge samt vilket resultat vi vill uppnå. Därefter genomför vi de förändringar som behövs. När vi har nått det önskade resultatet sker förändringar hela tiden i verksamheten och i omvärlden som ställer krav på att lösningen anpassas till nya förutsättningar, en förvaltning av det önskade resultatet.

Förstudie

I förstudien är det viktigt att samla in och sammanställa så mycket information som möjligt kring den nuvarande compliance-nivån. Detta blir då den plattform vi utgår ifrån när vi senare beslutar om vilka steg som behöver utföras för att nå önskat resultat.

Vi tittar på flera organisatoriska faktorer, roller, processer och dokumentation som finns. Allt utifrån ett GDPR-perspektiv. Efterlever vi redan PUL idag och/eller t ex ISO 27000 har vi en kortare resa att genomföra. Vi kartlägger de dataflöden som finns för att identifiera vad som är persondata och hur den flödar genom processerna. Riskanalyser (PIA och DPIA) utifrån analyserna genomförs. När detta och mycket mer är genomfört finns det en plattform att utgå ifrån.

Som en av de sista aktiviteterna i förstudien tolkas artiklarna/lagen utifrån hur vi som organisation uppfattar att den berör oss. Vi identifierar vilka krav som ställs, men även vilka delar av GDPR som inte berör oss. Dessa tolkningar dokumenteras ned i ett verktyg, Cockpit GDPR, som ger oss en överblick och kontroll hur vi t ex beslutade kring en viss tolkning när vi utsätts för en audit/review.

När tolkningarna är genomförda kan vi enkelt samköra dessa mot det nuläge som vi har dokumenterat. Deltat blir då det som måste genomföras för att nå önskat läge, dvs ett antal aktiviteter. Dessa prioriteras och planeras in i en plan tillsammans med resurser och budget. Därefter har vi ett bra underlag att påbörja implementationen.

Samuel Persson

Senior Consultant
Samuel has worked as a consultant for 30 years in a variety of industries and business areas.

His professional network and his thorough knowledge are the basis for the several executive and board members roles he held.

Implementation

Implementationen kan med fördel delas upp i två faser beroende på verksamhetens art. Den första delen är att säkerställa att man når en beslutad nivå för att kunna fortsätta i samverkan med andra parter, t ex kunders eller leverantörers GDPPR-projekt. T ex om man är ett mjukvarubolag kan det finnas ett värde av att samköra vissa delar tillsammans eller parallellt med sina kunder.

Aktiviteter som genomförs dokumenteras hela tiden i Cockpit GDPR så att en spårbarhet finns mellan lagtexterna, tolkningarna och vad som har gjorts för att nå önskat resultat. Det ger oss en dokumentation och kontroll över vad som är gjort och vad som finns kvar att göra, tillsammans med estimat, relationer, etc. Vid en audit/review är det viktigt att kunna påvisa vilka tolkningar vi har gjort och vad som har genomförts för att nå dessa tolkningar. Är vi inte färdiga med implementationen är det en styrka att ha visa på vad som är gjort samt vad som är kvar samt när det beräknas vara klart. Därmed har vi redan smygstartat förvaltningen av vår GDPR compliance-nivå.

Förvaltning

Det räcker inte med att köra ett implementationsprojekt och nå GDPR compliance-nivå. Den måste bibehållas. Omvärlden förändras, likaså vår egen verksamhet och de tjänster/produkter vi levererar. Vid något tillfälle kommer det att finnas prejudikat som befäster en viss tolkning. Denna måste givetvis stämmas av mot vår tolkning och vår lösning. Då är det skönt att snabbt identifiera vilka delar av vår compliance-lösning det slår mot. Här hjälper Cockpit GDPR oss att ha kontroll.

Med viss periodicitet behöver vi utföra vissa uppgifter, t ex utbildning, uppdatera/verifiera dokumentation, kravställa nya system utifrån GDPR-perspektivet, etc. Cockpit GDPR hjälper oss att samla rutiner, dokumentation, aktiviteter, etc. samt påminna oss när det är dags att genomföra dessa.

Cockpit GDPR

Cockpit GDPR är ett verktyg som har varit ett bra stöd för oss när vi har hjälpt olika organisationer att genomföra projekt där kravställningar har bl a baserats på regulatoriska krav. Verktyget har därefter varit det verksamhetssystem som förvaltningen såväl som compliance-avdelningen ser som ett av sina viktigaste verktyg.

GDPR består idag av ett antal artiklar som den 25 maj 2018 kommer att övergå i lagtext i någon form. Utöver det finns det även beaktanden, utredningar, mm. Och när lagen väl har trätt i kraft kommer det så småningom även att finnas prejudikat. Allt detta finns i Cockpit GDPR från start.

Lag- och Artikeldatabas

Bild 1 visar innehållet av artikel 7, Villkor för samtycke i GDPR. Förutom texten finns även länkar till relaterade artiklar, beaktande och när så sker, även prejudikat. Dessa länkar är klickbara och användaren kan enkelt navigerar sig mellan dessa.

Bild 1. Artikel 7, Villkor för samtycke i Cockpit GDPR

Förutom innehållet finns det möjlighet att sätta metadata på varje artikel, tolkning och aktivitet. Out-of-the-box finns ett antal metadata fält, men även egna fält kan skapas utan programmeringsbehov. Fälten kan användas för att filtrera och skära innehållet i Cockpit GDPR på annan ledd. På så sätt kan vi ”zooma” in på t ex det området vi fokuserar på just nu.

Tolkningar och krav

Bild 2 visar en tolkning av Artikel 7 för en verksamhet. Detta är den dokumentation som görs i samband med t ex förstudien, hur vi som verksamhet har valt att förhålla oss till lagtexten. Att kunna påvisa våra beslut, samt vilka aktiviteter som genomförs för att nå denna nivå anser vi är extremt viktigt vid en eventuell audit. Detta signalerar och visar på att vi har kontroll.

Bild 2. Exempeltolkning i Cockpit GDPR

I Cockpit GDPR finns det några generella tolkningar, men vi anser att det är viktigt att den egna verksamhetens tolkningar måste genomsyra arbetet.

När tolkningen är gjord, beslutad samt dokumenterad är det möjligt att identifiera vilka aktiviteter som krävs för att nå det önskade resultatet. Dessa aktiviteter delas upp i två huvudgrupper, implementations- och förvaltningsaktiviteter.

 

Aktiviteter

I bild 3 nedan visas en samlingsaktivitet för de implementationsaktiviteter som är identifierade för tolkningen i Bild 2. För respektive implementationsaktivitet finns arbetsuppgiften beskriven. Den kan tilldelas en resurs, estimeras, etc. På själva aktiviteten kan tidrapportering ske och aggregeras upp till flera olika nivåer för att tydligt och enkelt presenteras i t ex en dashboard.

Bild 3. Implementationskativiteter i Cockpit GDPR

Cockpit GDPR – Vårt stöd i arbeteT

I vårt GDPR arbete ute hos kund använder vi med fördel Cockpit GDPR. Det är vårt verktyg för att dokumentera nuläget, tolkningarna samt aktiviteterna under förstudien.

Under implementationen använder vi cockpit för att dels uppdatera status, använd tid, delegering, m.m. på implementationsaktiviteter, men även för att snabbt hitta samband, uppdatera förändringar i tolkningar, etc.

I förvaltningsläget använder vi Cockpit GDPR för att ge oss stöd och påminnelse i de periodiska aktiviteterna som sker regelbundet framöver. Men det är också ett stöd när vi ska ta fram och implementera nya tjänster och produkter.

Och fram för allt, det är vårt stöd i audit/review tillfällen. Att snabbt kunna påvisa kontroll, struktur och fakta gör arbetet mycket enklare.

Hela tiden kan vi ta ögonblicksbilder som kan exporteras ut i ett antal olika format för vidare bearbetning. Till aktiviteterna skapar vi ett workflow så att en aktivitet enkelt kan dirigeras genom verksamheten beroende på status, tillhörighet, etc.

Det finns mycket mer att visa i Cockpit GDPR kring hur vi kan skapa och öka kontrollen över vår GDPR implementation och förvaltning.

Är du också nyfiken på hur du kan dra nytta av ett verktyg som vi har funnit mycket användbart, tveka inte att ta kontakt med oss.

GDPR

General Data Protection Regulation, GDPR, är en ny dataskyddsförordning som kommer att gälla inom EU från 25 maj 2018. Målsättningen med regelverket är att skyddet av den personliga integriteten ska stärkas så att denna grundläggande rättighet är i balans med andra grundläggande rättigheter och legitima samhällsintressen. Utöver den kommer även en ny dataskyddslag, som är svenska kompletteringar till GDPR.  

Business Analyst efter GDPR – uppgiftsminimering eller överinformation?

Business Analyst efter GDPR – uppgiftsminimering eller överinformation?

Erfarenheter från senaste halvårets GDPR arbete – Vissa företag har mycket kvar att göra andra har det mycket enklare. Alla känner till grundtankarna med PUL, få har kontroll på detaljinnehållet men vissa har väldigt god kontroll ändå medan andra får det att fungera mycket väl ändå. Oavsett så kommer införandet av GDPR att påverka företagen med väldigt stor sannolikhet.

Ett av de område som många företag har ”slarvat med”, är uppgiftsminimering och till vilket ändamål och syfte som informationen har samlats in. En konsekvens av detta är att det hos alla företag sparas mer information än vad som verkligen är nödvändigt för att dagens verksamhet ska rulla på.

I artikel 5.1b i Dataskyddsförordningen kan vi läsa följande:

Vid behandling av personuppgifter ska följande gälla: De ska samlas in för särskilda, uttryckligt angivna och berättigade ändamål och inte senare behandlas på ett sätt som är oförenligt med dessa ändamål”.

Läser vi vidare under 5.1c skriver man

De ska vara adekvata, relevanta och inte för omfattande i förhållande till de ändamål för vilka de behandlas (uppgiftsminimering)”.

Men alla behöver ju också tänka på morgondagen. Det är ofta här överinformationen kommer in i bilden – den används för att söka efter morgondagens affärsmöjligheter. Är det så illa att samla in information, anonymiseras till oigenkännlighet utan möjlighet att återskapa ursprunget? Syftet med GDPR är ju inte att försvåra affärsutvecklingen utan att förhindra kränkning av personlig integritet., hur stora är riskerna då?

I artikel 89.1 kan vi läsa följande:

Behandling för … statistiska ändamål ska omfattas av lämpliga skyddsåtgärder i enlighet med denna förordning för den registrerades rättigheter och friheter. Skyddsåtgärderna ska säkerställa att tekniska och organisatoriska åtgärder har införts för att se till att särskilt principen om uppgiftsminimering iakttas. Dessa åtgärder får inbegripa pseudonymisering, under förutsättning att dessa ändamål kan uppfyllas på det sättet. När dessa ändamål kan uppfyllas genom vidare behandling av uppgifter som inte medger eller inte längre medger identifiering av de registrerade ska dessa ändamål uppfyllas på det sättet.

Jan Wrangmark

Senior Consultant
Jan is an experienced manager with a great sense for quality. Jan has a broad knowledge of the financial sector with a strong connection to quality management, IT governance and operational risk management.

Vi kan alltså använda persondata för att hitta nya affärsmöjligheter. Men vi måste uppfylla de krav på skyddsåtgärder som beskrivs i 89.1 och vi måste ange ändamål och syfte med insamlingen. I vissa lösningar avseende säkerhet används beteende som en förstärkning av identifieringen – dvs vi samlar in hur du beter dig när du använder våra redskap inom vår domän. Fungerar det att samla in ett samtycke bestående av ospecificerade data för att söka efter framtida förbättringar och affärsmöjligheter? Som vi nämner ovan står det i Artikel 5.1b:

Vid behandling av personuppgifter ska följande gälla: De ska samlas in för särskilda, uttryckligt angivna och berättigade ändamål och inte senare behandlas på ett sätt som är oförenligt med dessa ändamål”.

Det gäller att ha koll på sin information, dvs var den finns och hur den hanteras. Brister i detta avseende förstör möjligheten att med trovärdighet argumentera för att samla på sig någon som helst information med ett ändamål som kan härledas till ett eventuellt framtida behov.

GDPR

General Data Protection Regulation, GDPR, är en ny dataskyddsförordning som kommer att gälla inom EU från 25 maj 2018. Målsättningen med regelverket är att skyddet av den personliga integriteten ska stärkas så att denna grundläggande rättighet är i balans med andra grundläggande rättigheter och legitima samhällsintressen. Utöver den kommer även en ny dataskyddslag, som är svenska kompletteringar till GDPR.  

GDPR och registerutdrag, blir det en skillnad mot idag?

GDPR och registerutdrag, blir det en skillnad mot idag?

Idag är det ett fåtal individer som begär ett utdrag från våra register. Förmodligen bara en bråkdel av promille av den totala mängd personuppgifter som vi hanterar. Men vad kommer att hända när den nya lagstiftningen har trätt i kraft? Kommer antalet förfrågningar att öka? I så fall, i vilken omfattning? Hur kan man hantera detta rationellt? Detta är många av frågeställningarna som flera av våra kunder ställer sig i samband med att den nya Dataskyddsförordningen kommer att gälla

Kravanspråk

I artikel 82.1 kan vi läsa följande:

”Varje person som har lidit materiell eller immateriell skada till följd av en överträdelse av denna förordning ska ha rätt till ersättning från den personuppgiftsansvarige eller personuppgiftsbiträdet för den uppkomna skadan.”

Den enskilda personen har i och med detta möjlighet att driva kravanspråk mot ditt företag om behandlingen av dess personuppgifter inte har skett i enlighet med Dataskyddsförordningen. Kommer detta vara en drivkraft? Kommer vissa individer att sätta detta i system? Kommer det skapas tjänster på marknaden som ger individen stöd i att driva frågan mot företaget som bryter mot dataförordningen? Med all säkerhet, men det är svårt att i dag uppskatta omfattningen.

Men för att komma dit måste en incident ha skett eller att personen kan visa på att Dataskyddsförordningen inte efterlevs. Ett verktyg för det senare är att kräva registerutdrag från företagets register och hitta de ställen där dessa bryter mot t ex det insamlade samtycket.

Hur länge dröjer det innan det finns automatiserade tjänster som kommer att utföra detta på uppdrag av personen? Idag finns t ex automatiserade tjänster för att kräva ersättningar vid t ex flygförseningar. Vi tror därför att förfrågan på registerutdrag kommer att öka i jämförelse mot idag.

Nya Effektiva processer

Artikel 12.3 tar upp hur snabbt vi ska reagera:

“Den personuppgiftsansvarige ska på begäran utan onödigt dröjsmål och under alla omständigheter senast en månad efter att ha mottagit begäran tillhandahålla den registrerade information om de åtgärder som vidtagits enligt artiklarna 15–22.”

Samuel Persson

Senior Consultant
Samuel has worked as a consultant for 30 years in a variety of industries and business areas.

His professional network and his thorough knowledge are the basis for the several executive and board members roles he held.

Artiklarna 15-22 tar upp personens rättigheter mot ditt företag, bl. a. rätten att bli informerad (registerutdrag), men även t ex rätt till rättelse, eller att bli bortglömd, etc. Så var även förberedd på att dessa anspråk kommer samt hur lagstiftningen kommer att se ut.

Vi tror därför att det är viktigt att företaget är beredda på en ökning av förfrågan på registerutdrag, men även att de har bra mallar och en eller flera effektiva processer för att hantera detta.

GDPR

General Data Protection Regulation, GDPR, är en ny dataskyddsförordning som kommer att gälla inom EU från 25 maj 2018. Målsättningen med regelverket är att skyddet av den personliga integriteten ska stärkas så att denna grundläggande rättighet är i balans med andra grundläggande rättigheter och legitima samhällsintressen. Utöver den kommer även en ny dataskyddslag, som är svenska kompletteringar till GDPR.  

Write your first Gradle plugin

A promise to hit the sweet spot

The Gradle build system promises to hit the sweet spot between Ant and Maven. It allows for convention over configuration build scripts (lesser code). The build scripts are highly readable and compact compared to its XML based cousins (looking at you Ant and Maven) thanks to its own groovy based DSL (domain specific language) .

Consistent and (fail-) fast builds are a key component to any successful Continuous Integration / Continuous Deployment (delivery) – process (from now on CI/CD). The build in itself is one of the most important parts of a modern CI solution. Gradle integrates well with Jenkins and Artifactory (binary storage). In a previous assignment I was tasked with replacing the old build system (Ant based), having worked with Gradle in the mobile world I began a journey to convert the old build to a new based on Gradle. The project to build was a Java EE application with several sub modules, here are the key points on why specifically Gradle was chosen:

  • Incremental build support (Gradle only builds files that has changed), checksums everything (both input and output files)
  • Parallel builds, Gradle utilizes all your cores if you have several Gradle sub-projects to build
  • Gradle has a daemon (a JVM running ready to build instantly), default enabled in Gradle 3
  • Fails fast (trust me it’s a good thing!). Builds are separated into three phases init, config and execute phases.
  • Groovy scripting support
  • Kotlin scripting support (as of Gradle 3.0), enables autocomplete for your build scripts in e.g. IntelliJ
  • Compact DSL: easy dependency declaration, a dependency needs one row of declaration
  • Support running Ant tasks from within Gradle (great for complicated legacy tasks from e.g. Ant, enables gradually rewrite of legacy tasks)
  • Debugging / profiling support, you can get a html report of where your build time is spent in the build process and also since Gradle runs in a JVM you can attach a debugger to the Gradle process itself
  • In a future release (targeted for 4.0, in 2017) there are plans for a distributed build cache. This means that same commit (branch) needs only to be built once and for any subsequent builds the artifacts can be fetched from the cache.

Magnus Borgström

Software Engineer
Magnus has a profile on stackoverflow: http://www-test.itinforma.se/member/magnus-borgstrom/

He is a strong believer in OSS and use several projects on a daily basis, in his spare time, he builds computers and explore IT related technologies such as container technology (docker, e.t.c.) / VM (VMware) and web technologies.


Gradle builds in action showing the powerful up to date checks that’s builtin in the tool

Part of the old Ant build was a JAXB generating task, converts XML schema definitions files to Java files that later consumes data (XML) to generate reports. The declaration in Ant for this was around 400 lines (most parts was specifying which XSD files to use while generating the Java ones). Four different modules were using the same JAXB generating code, which led me to the idea of reusing the code for generating the java files through JAXB. This is where Gradle plugins come in handy, since it promotes reusability and with Gradle’s powerful configuration injection makes the whole process a breeze. A complete rewrite of this part of the Ant build script was not planned.

A complete Gradle plugin

Below you’ll find the complete Gradle plugin for generating java files from xsd files. All the interesting stuff happens in the convert method. Most important is the call to project.ant here Gradle delegates a call to the Gradle built in Ant runtime with the XJC task target that takes in all the different parameters we set with the definitions inside BaseTask class, we set the parameters from the dynamically generated Gradle tasks, see later code snippet.

 

import org.gradle.api.DefaultTask
import org.gradle.api.Project

import org.gradle.api.tasks.TaskAction

// Base (holder) class
class BaseTask extends DefaultTask {
   String packageName;
   String packagePrefix = "com.name.xml";
   String packageSuffix = "generated";
   String partialPackageName;
   String schemaDir = "schemas";
   String schemaFile = "*.xsd";
   String targetDir = project.projectDir.toString();
}

class JaxbTask extends BaseTask {
   @TaskAction
   void convert() {
       // gets the jaxb configuration path (path to lib containing Ant task) 
       // from the build script
       def classpath = project.configurations.jaxb.asPath;

       println "Running xjc for packageName: $packageName, schemaDir: $schemaDir, schemaFile: $schemaFile"
       // perform ant actions

       project.ant {
           taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: classpath);

           // target property is renamed to destdir in jaxb lib versions > 2
           // package name decides where on the filesystem the generated files
           // will land, and schema property points to the XSD file
           xjc(target: targetDir, package: packageName) {
               schema(dir: schemaDir, includes: schemaFile);
           }
       }
   }
}

To use the above plugin in your Gradle build you need the following lines in your script:

buildscript {
   dependencies {
       // these depends on your version etc of the above groovy code
       classpath 'groovy.org.gradle:JaxbTask:1.0.2'
   }
}

class XSDHolder {
   String dirName;
   String packageName;
   String schemaFile;

   XSDHolder(String dirName, String packageName, String schemaFile) {
       this.dirName = dirName
       this.packageName = packageName
       this.schemaFile = schemaFile
   }
}

An array with holder data, example of one element:

new XSDHolder("order", "com.name.reports.order.generated.summary", "Report.xsd")

task jaxbGenerate() {
   for (XSDHolder xsdHolder : holders) {
       // TaskName is derived from Report.xsd -> [Report, .xsd]-> ReportJaxbTask
       String taskName = xsdHolder.getSchemaFile().split("\\.")[0] + "JaxbTask"
       // Dynamically creates several tasks (available as separate targets when
       // using Gradle from cli)
       task "${taskName}"(type: JaxbTask) {
           // Here we configure all the properties that our task should have
           // (executed during init phase, the task itself with the properties
           // set is executed during execution phase)
           schemaFile = xsdHolder.schemaFile
           description "Generates java classes for the $schemaFile schema"
           schemaDir = "schemas/" + xsdHolder.dirName
           packageName = xsdHolder.packageName
           targetDir = generatedSources
           // tracks the input files (for up to date checks)
           inputs.dir fileTree(dir: schemaDir, includes: ["**/${schemaFile}"])
           // tracks the output files (for up to date checks)
           outputDir = new File(generatedSources + "/" + packageNameToPath(packageName))
       }
   }
}
// The name of the dependency used by the groovy code to execute the jaxb task
configuration {
   jaxb
}
// The dependency for running the groovy jaxb code
dependencies {
   jaxb name: 'jaxb-xjc'
}

Our approach on regulatory requirements

How health- and biotech related experience of regulatory requirements can be applied on other industries

Being a consultant company, we often run into questions related to the Patient Data Act (PDA), General Data Protection Regulation (GDPR) or other regulatory requirements and principles. We have developed a method to address regulatory and other non-functional requirements.

Our company has worked with customers within health- and biotech industry for several years. One of our customers is a health provider with clinics in more than 20 countries. Because they reside in many countries, we have multiple PDA and other regulations to consider and to implement in their software, processes and organisation. But are there any differences when we working with other industries, e.g. food or finance?

Of course, there are different regulations depending on the industry. The model we address the regulatory requirements, and use them in our processes and critical software, should be similar no matter which sector we work in.

Identify the regulatory requirements

As you may know, to be compliant is not only about the software. How you work, your processes, your values, these are also parts of compliance. For this particularly customer, we collected the Patient Data Acts from all 20 countries and started to identify what requirements affected the software and what requirements affected the processes within the organisation. When we looked at the processes and the software from a holistic view, we quickly found out, many of the regulatory requirements could be treated as properties of the solution. 

So, what is the best model to handle this type of requirement?

As an example, in the financial sector there are a lot of discussions about regulatory requirements in regards to Risk Management. One well known set of requirements from ECB is called BCBS239 (RDARR). When we read through those principles it’s obvious, the requirements are high level properties on the solution.

Managing Requirements

The traditional way to analyse requirement is to break them down into sub requirements until each detailed requirement can be solved with a pretty straight forward solution. However, when we work with non-functional requirements e.g. regulatory requirements, this method could be a trap which leads us into an extremely fragmented solution where we lose our eagle eye perspective and the ability to maintain the solution.

 

Samuel Persson

Senior Consultant
Samuel has worked as a consultant for 30 years in a variety of industries and business areas.

His professional network and his thorough knowledge are the basis for the several executive and board members roles he held.

Regulatory requirement are properties of the solution

With a superior list of principles e.g. BCBS239, we think it is best to use another approach. The experience we have gained, we can address the requirements as properties of a solution. When we use this model, we will move our focus from a pile of requirements into a solution with a set of properties. When we shift focus, we will soon find it much easier to work with the requirements and make our systems and processes compliant. It’s still a lot of work to do, but our effort will be much smaller and we will gain control of the implementation process.

BCBS239 describes properties of the solution not functional requirements. We can recognise this model from other quality standards e.g. ISO9126 or ISO25010. We treat the principles in BCBS239 as properties of the same solution. The scope will be smaller and easier to manage. It will also be easier to demonstrate compliance against the principles. The illustration in this article shows how to look on the solution from different views, each view with a property as the focus point.

During the process of making a change in our system, we always return to this model to verify we are still compliant. We look at the changes through the different views of the solution, the properties. This will let us know in an early stage, if we eventually will make a change against any of the properties. Once again, using BCBS239 as an example, we should verify the change we implement is compliant with the requirements of: 

  • Principle 1 – will the change affect the Governance?
  • Principle 2 – will the change affect the IT Architecture?
  • Principle 3 – will the change interfere with the Accuracy and Integrity?
  • And so on…

When we design, and develop a solution, we work on the solutions in several layers before it is implemented. On the top layer, we design the solution on a conceptual level. The iterations will lead into a conceptual solution which can be verified against the different properties. Each layer has its own purpose, and the granularity is in more detail for each layer we pass through. At the bottom layer the solution is implemented and verified against the properties. This method helps us to secure we are compliant through the whole development process as well as the solution.

Compliant processes

A common error some companies tends to do is to only make their software compliant. It is important, but the IT architects who understands the regulatory requirements can do this easily. Compliant software doesn’t necessary make your organisation compliant and the risk to fail in an audit or review is much higher. The processes and work instructions are even more important and easy to forget. 

Conclusion

We use this model when we work with compliance and regulatory requirements. It helps us keep our focus on the requirements and the gain we receive is far beyond the effort. The model is not only applicable during an organizational change or during a development phase, but it is also applicable when the business is in normal operational state.

Our experience has shown the model is applicable cross-industry. Even if the requirements differ, the model to address them is the same.


Scanning your Java App with jQAssistant and Neo4j

Michael Hunger’s talk had an elegant solution to an actual, unsolved problem of mine

After attending a software development conference, you usually return back home with a bunch of new ideas and cool things you want to try out. But most of the time your ideas remain in experimental stage, since it’s often hard to find a problem that’s just right for all newfound solutions…

But returning from GeekOut 2014 was different – Michael Hunger’s talk “Using Ascii Art to Analyze Your Source Code with Neo4j and OSS Tools” had an elegant solution to an actual, unsolved problem of mine that had surfaced just a couple of weeks earlier.

 

Challenge

A system I am involved in as a developer relies on custom parsing of the source code to find all concrete subclasses of a particular class, excluding inner classes. These subclasses represent units for which user access can be configured. If this list is incomplete, the configuration will be incomplete, which in turn means missing user access. We had just seen our first case of generics showing up in this class hierarchy, and the parser couldn’t handle that properly.

Solution

The objective is to extract all concrete subclasses of a particular class into a custom format file, and this should be part of the build. This file serves as a template for access control configuration for the scanned rich client application.

If you have a Maven project, this can be done quite easily with jQAssistant and Neo4j. Here are the basic steps:

  1. Setup jQAssistant
  2. Build your Maven project
  3. Scan your compiled classes with jQAssistant to create a Neo4j representation of your code
  4. Query the database to extract the information you need
  5. Generate the result

The steps will be described in more detail below, using this sample project. It’s a real-world example, but the actual code scanned and the custom report plugin have been replaced with sample code.

Step 1 – Setting Up jQAssistant

To set up jQAssistant, make sure you have the following:

  • JDK 7
  • Maven 3 and access to Maven Central Repository
  • A Maven project

Add the following to your settings.xml, located in the .m2 folder of your home directory:

Mattias Olofsson

Senior Consultant
Mattias is a software developer with project management experience. He is a quick learner with excellent analytical, design and problem solving skills. He has long experience from design and development of technically challenging systems. He has also been involved in team and technical project management as well as architecture work. He is comfortable working independently or as part of a team and always strives to perform his best and deliver on time and in full.
<pluginGroups>
    <pluginGroup>com.buschmais.jqassistant.maven</pluginGroup>
</pluginGroups>

This makes it easier to run jQAssistant from the command line. Now you’re good to go.

Step 2 – Build Your Maven Project

Since jQAssistant scans bytecode, you need to build your Maven project.

mvn clean install

Step 3 – Scan Your Compiled Classes

Before you can scan your application, you need to add the jQAssistant Maven plugin to your POM:

<properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <jqassistant.version>1.0.0-M3</jqassistant.version>
</properties>


<build>
   <plugins>
      <plugin>
         <groupId>com.buschmais.jqassistant.scm</groupId>
         <artifactId>jqassistant-maven-plugin</artifactId>
         <version>${jqassistant.version}</version>
         <configuration>
            <reportProperties>
               <report.file>result.txt</report.file>
            </reportProperties>
         </configuration>
         <dependencies>
            <dependency>
               <groupId>com.buschmais.jqassistant.plugin</groupId>
               <artifactId>jqassistant.plugin.java</artifactId>
               <version>${jqassistant.version}</version>
            </dependency>
            <dependency>
               <groupId>com.mattias</groupId>
               <artifactId>report-writer</artifactId>
               <version>1.0-SNAPSHOT</version>
            </dependency>
         </dependencies>
      </plugin>
   </plugins>
</build>

This also includes configuration of the report writer described later, the file to which the result should be written.

Now you can scan your code using

mvn jqassistant:scan

Step 4 – Query the Neo4j Database

With your code scanned, it’s time to write your Cypher query. The Neo4j web interface is very useful for experimenting with queries, start it by executing

mvn jqassistant:server

Now you can browse to https://localhost:7474 and start writing and testing your queries.

Neo4j web interface

First, let’s locate the base class that we want to find concrete subclasses for. In the sample code we have a hierarchy of animals, with the base class Animal. So, to find that class, we can use the following query:

match
  (t:Type)
where
  t.name = 'Animal'
return
  t as Type

Executing that query in the web interface will return one node, the Animal class:

Now, if we extend the query a little bit we can get all subclasses instead.

match 
  (t:Type)<-[:EXTENDS*]-(sc:Type)
where 
  t.name = 'Animal'
return 
  sc as Type

Clicking the nodes will reveal that we now have found some animals, but also some abstract classes such as Fish and Insect. To get rid of those, we enhance the query:

match 
  (t:Type)<-[:EXTENDS*]-(sc:Type)
where 
  t.name = 'Animal'
  and sc.abstract is null
return 
  sc as Type

Now we only have concrete subclasses left. The final thing to get rid of is the inner class declared by GoblinShark.

match 
  (t:Type)<-[:EXTENDS*]-(sc:Type)
where 
  t.name = 'Animal'
  and sc.abstract is null
  and not sc:Inner
return 
  sc as Type

Now only we have a query that returns all concrete subclasses of Animal, inner classes excluded.

To stop the server, return to the console from where it was started and hit Enter.

Now it’s time to create a rule file to integrate the query into the build. Rule files are XML files located in the jqassistant folder.

<jqa:jqassistant-rules xmlns:jqa="https://www3.buschmais.com/jqassistant/core/analysis/rules/schema/v1.0">

    <concept id="my-rules:ExtractSubClassesOfAnimal">
        <requiresConcept refId="java:InnerType" />
        <description>Extracts subclasses of Animal</description>
        <cypher><![CDATA[
		  match
            (t:Type)<-[:EXTENDS*]-(sc:Type)
          where
            t.name = 'Animal'
            and sc.abstract is null
            and not sc:Inner
          return
            sc as Type
        ]]></cypher>
    </concept>

    <group id="default">
        <includeConcept refId="my-rules:ExtractSubClassesOfAnimal"/>
    </group>

</jqa:jqassistant-rules>

Step 5 – Generate the Result

Now that we have a query that do the extraction from the compiled code, we just need to put that in a file. In this example, we just want to write the fully qualified name for each class found by the query. To do that, we implement a custom report writer:

package com.mattias;

import com.buschmais.jqassistant.core.analysis.api.Result;
import com.buschmais.jqassistant.core.analysis.api.rule.Concept;
import com.buschmais.jqassistant.core.analysis.api.rule.Constraint;
import com.buschmais.jqassistant.core.analysis.api.rule.Group;
import com.buschmais.jqassistant.core.analysis.api.rule.Rule;
import com.buschmais.jqassistant.core.report.api.ReportException;
import com.buschmais.jqassistant.core.report.api.ReportPlugin;
import com.buschmais.jqassistant.plugin.java.api.model.TypeDescriptor;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Created by mattias on 2014-06-30.
 */
public class ReportWriter implements ReportPlugin {

    private String reportFile;

    @Override
    public void initialize() throws ReportException { }

    @Override
    public void configure(Map<String, Object> map) throws ReportException {
        this.reportFile = (String) map.get("report.file");
    }

    @Override
    public void begin() throws ReportException { }

    @Override
    public void end() throws ReportException { }

    @Override
    public void beginConcept(Concept concept) throws ReportException { }

    @Override
    public void endConcept() throws ReportException { }

    @Override
    public void beginGroup(Group group) throws ReportException { }

    @Override
    public void endGroup() throws ReportException { }

    @Override
    public void beginConstraint(Constraint constraint) throws ReportException { }

    @Override
    public void endConstraint() throws ReportException { }

    @Override
    public void setResult(Result<? extends ExecutableRule> result) throws ReportException {
        Rule rule = result.getRule();
        if ("my-rules:ExtractSubClassesOfAnimal".equals(rule.getId())) {
            try {
                BufferedWriter writer = new BufferedWriter(new FileWriter(reportFile));
                List<Map<String, Object>> rows = result.getRows();
                for (Map<String, Object> row : rows) {
                    TypeDescriptor type = (TypeDescriptor) row.get("Type");
                    writer.write(type.getFullQualifiedName() + "\n");
                }
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

When we plug in this report writer, the result from the query will be available in the Result parameter passed to the setResult method. The rows can be retrieved and written to a file in the desired format.

To let jQAssistant know about your plugin, create a file called jqassistant-plugin.xml and place it in the META-INF folder of your report writer project.

<jqa-plugin:jqassistant-plugin xmlns:jqa-plugin="https://www3.buschmais.com/jqassistant/core/plugin/schema/v1.0" name="Custom Report">
    <description>Example plugin defining a custom report.</description>
    <report>
        <class>com.mattias.ReportWriter</class>
    </report>
</jqa-plugin:jqassistant-plugin>

The final step is to let jQAssistant execute your query and generate the report, which is done by executing

mvn jqassistant:analyze

As simple as that.

Thanks to Michael Hunger for a great talk on jQAssistant and Neo4j at GeekOut 2014, and many thanks to Dirk Mahler for helping out, sharing knowledge and enhancing jQAssistant to allow plugging in your own custom report writer. Awesome.

For more details check out https://jqassistant.org where you’ll also find reference documentation and examples.

Future-proof your architecture with Aspects

Using Aspects you can safe-guard that the code will keep in a good state after refactoring

How do we safe guard that new features will comply with the new design? A refactoring needs to be looked after.

A refactoring aims to leave the code in a better state than before. But what happens after the dust is settled and it is time for some new development that must adhere to the new architecture. What can we do in order to avoid degeneration of the software architecture?

 

Documentation & training

All relevant documentation needs to be updated like, SAD, design documents etc. Also developers need to get hands on training to understand the refactoring.

Code-documentation. Adding of comments describing what an interface is doing so we know what to do when implementing.

This and other things are all done in order to keep code not deteriorating. But is it really enough? What happens for example if new developers join? How do we guarantee that they will acquire the knowledge needed?

More often developers code first and read documentation later. So what we need is a way of enforce our architectural refactoring (or any architecture for that matter) and convey that to the developer. Our answer is Aspects! First some background regarding Aspects.

Aspects is used to separate cross-cutting concerns, thus separating business logic from secondary functions like caching, logging etc. Aspects is defined in separate modules specifying what it should do and when it should be trigger at what point in the program. Using this approach you don’t have to concern yourself with coding logging or caching in every business object, the aspect will handle this.

For further reading regarding Aspects:

https://en.wikipedia.org/wiki/Aspect-oriented_software_development

Even though Aspects is great doing this, how does this relate to future-proof our architecture? Of course when defining our Aspects correct we will always have logging, caching, etc not worrying about if the programmer remembered to add it. But it will not check that that design patterns are followed correctly. We want to use it where it hurts for a programmer: at compilation time!

Daniel Svedberg

Senior Consultant
Daniel has extensive technical experience as a developer and software architect for large mission critical systems. He is responsible for designing and developing applications in multi-layered architecture. The solutions put high demands on scalability to handle large volumes of user and usability.

This can be done using the framework AspectJ. This is a extension used in the java programming language implementing the aspect model. It has all of the functionality mentioned above plus that you can use the point-cuts to add compiler time warnings and errors with the “declare:” statement. This can be a very efficient way of reinforcing architectural rule.

Further reading of AspectJ:

https://www.eclipse.org/aspectj/

Using the declare statements of AspectJ you can control that:

  • certain calls from specified classes are forbidden
  • Methods follows requested signatures
  • certain calls from specified
  • classes are mandatory
  • and more…

For example:

declare error : call(* org.xyz.model.*.*(..)) &&
!@within(Trusted)
: "Untrusted code should not call the model classes directly";

This means that the aspect will generate an compiler error when any this pattern is encountered (the trusted condition can be whatever you can define using Aspects).

You can also declare exception to the rules that certain classes/methods shall be excluded from the compile-time check etc. It is a powerful tool and you can almost specify any compilation rule you want to enforce.

Using Aspects you can safe-guard that the code will keep in a good state after refactoring. Separating concerns helps, with the addition of compiler time check we can take a step further. It is hard to ignore compilation errors.

The refactoring safety net

Your black box tests will give you the confidence and keep you safe

Don’t underestimate the value of keeping your unit tests in shape. When it’s time for refactoring, your black box tests will help you get the job done faster.

Unit Test

There are many good reasons why you should unit test your code, an important one is that if done right, they serve as a safety net when you do refactoring. Since no developer writes the ideal solution on the first go, refactoring is needed all the time. But to take advantage of your tests when refactoring, your design must allow changing the implementation without rewriting your tests.

The tests that are going to help you in the process are your black box tests, the ones that test your functionality without bothering about implementation details. Any white box tests you might have, that know about the internal structures of your components, will make your mission more risky not to mention painful – and no developer likes to change more code than necessary.

The less your tests know about the internal implementation of your components, the more useful they will be during refactoring. If you have to change your unit tests just as much as the rest of the code, you can’t use them to ensure that you still have the same behavior and quality.

Enforce a good design

When you develop a new component, your tests help you enforce good design. Developers who don’t like writing tests are quite good at coming up with excuses why they shouldn’t – “this can’t be tested, is too difficult”. Well, if it’s difficult to test, it’s probably difficult to use. Maybe it can be designed a bit differently, perhaps the business logic is in the wrong place, or there’s some static dependency that shouldn’t be there.

Coding against interfaces, keeping clear dependencies and loose coupling between components are all factors that simplify your testing quite a bit, and mocking will be a lot easier. Try to separate different concerns, avoid mixing code for transaction management and database access with your business rules. Usually, this also makes it easier to put the right code in the right place.

Getting inside the box

If you feel the urge to get inside the box and test a private method, access or set private fields, your class may be responsible for more than it should, perhaps it has unclear dependencies, or it could be too tightly coupled with other components.

Have a look at the design before bringing on test frameworks with capabilities for breaking encapsulation – save that for the cases when there is no other way out, or you really need to verify implementation details. In a well designed system with unit tests protecting the interface and functionality of each component, refactoring will be a lot faster – and your black box tests will give you the confidence and keep you safe.

Mattias Olofsson

Senior Consultant
Mattias is a software developer with project management experience. He is a quick learner with excellent analytical, design and problem solving skills. He has long experience from design and development of technically challenging systems. He has also been involved in team and technical project management as well as architecture work. He is comfortable working independently or as part of a team and always strives to perform his best and deliver on time and in full.

Lessons learned from a Redmine implementation project

Do not be afraid to change and re-change as experience grows

The most successful way can be summarized in three words – “just do it”. It is very important to be quick and not be afraid to change and re-change as experience grows.

Baby steps but very fast – The first review:

  • What kind of things will we track (trackers)? Start with a few and expand as you go. Do not be afraid to name incorrectly, the name can be changed.

 

  • What kind of states do we need per tracker (statuses)? There are good reasons to avoid too much reusing of statuses. Sometimes it is good to group statuses per tracker and actually create duplicate statuses to make sure that we have consistent and good workflows.

 

  • What kind of roles do we need? Start with basic roles and refine as you need. The main driver for a new role is the need to limit who can change an issue from one state to the other (workflow).

 

  • Basic workflows. This is where trackers/roles and statuses comes together. This is also the hardest part of the Redmine GUI. It is very hard to get a good overview of possible state-changes, so don’t be afraid to test and review several times.

 

  • Custom fields may be the most underestimated feature in Redmine. A simple drop-down custom field may enable any amount of useful filtering.

 

  • Filters. This is the key survival tool to handle data as soon as you pass the first 100 issues. A good naming convention, continuously updated to follow all the important views of issues is critical for Redmine usage. The RSS tracking based on saved filters is the icing on the cake. I might write another article just about filters and rss-feeds.

 

  • Time reporting. Using this from the start is probably the single most important driver for a successful implementation. I know that this is probably something most projects would like to postpone but it should really be viewed the other way around. The key driver for everyday use is to have some place to document time. When you require an issue before you can report time you’ll get the right incentive to add and keep issues up to date.

These are the main Redmine functionalities to address in the first quick steps. As the tool evolves there are a lot of other interesting and useful functions to explore.

Thomas Pihl

Senior Consultant
Thomas is working in leading or operative roles in different technical and business areas. He has experiences from a long range of change- and improvement projects. He has a true holistic approach to IT and an analytic and driving manner. Thomas is driven by a strong will to create real business value.