Kunde: Ah, Sie zeigen uns in dieser Demo so ein Glossar. Ach, jaja, nett, das haben wir schon! Ich: Oh, und benutzen Sie persönlich das in Ihrem Unternehmen oft? Kunde: Nee, das ist veraltet. Da schaut keiner rein, weil das pflegt ja keiner richtig… Oder doch? Hm.
Unternehmen „wollen” Governance machen. Wir zeigen ihnen das kollaborative SAS Business Data Network (BDN). Und der Kreis der nickenden Kunden versteht: Da kann man Begriffe pflegen; das braucht man für Data Governance. Klar. Aber wie kriege ich die Governance der Governance hin? Wie weiß der Data Steward beispielsweise, dass der Term „Neukundenquote” seit drei Monaten vom faulen Herrn Mayer, dem ernannten Data Owner, nicht mehr aktualisiert wurde (obwohl er es hätte tun sollen), weil der gute Herr Mayer irgendwie keine Zeit hat – na, merkt ja keiner –, den lieb gemeinten & von oben verordneten Workflow auch „durchzuziehen”?!
Von Haus aus gibt es keine Standardberichte, die das auswerten. Klar, man kann’s Glossar mal durchblättern, das letzte Änderungsdatum begutachten und sich wundern, dass da keiner weiter dran arbeitet. Oder ein Term zwar mal bemüht „eingetippt” wurde, er im Workflow – warum auch immer – leider nie freigegeben, also zur Veröffentlichung kam. Merke: So ein Workflow-inklusives Tool ist an sich zwar toll; nur doof, wenn man drin steckenbleibt …
Also, da kann man was machen, sprich: bauen. Um zum Beispiel obigen SAS VA-Report zu füllen, aus dem bei jedem Term ersichtlich ist, wann er zuletzt geändert wurde. Und wer dafür verantwortlich ist. Und hier an dieser Stelle würden wir auch dem faulen Herrn Mayer auf die Schliche kommen. Denn wie heißt es so schön in der Überschrift? SAS BDN API zum Finden fauler Leute!
Denn Faulheit hat Vorbildfunktion. War in der Schule noch „cool“, bremst im Job aber herrlich all das aus, was Vorstand und Controlling ihren Mitarbeitern mitgeben möchten: Transparenz durch tragfähiges Hand-in-Hand beim gemeinsamen aktuellen Beschreiben von Prozessen und ihren Objekten. Kennt man aus wirren Meetings: drei Leute, fünf Kennzahlen und babylonische Verwirrung beim „Was misst der Kollege da eigentlich? Was meint der bloß mit ‚Neukundenquote‘?!“
Auch wenn das BDN keine solche Auswertung ab Werk bietet, halb so wild – die Daten sind ja da. Es hilft die Erkenntnis: Das BDN ist nur ein Weg, mit dem zugrunde liegenden PostgreSQL-Repository zu kommunizieren. Ein weiterer ist die eingebaute REST API: Dort gibt es in der Programmierschnittstelle eine Get_All_Terms-Methode. Nachteil: Das Ergebnis (eine Liste der meisten Attribute aller Terms) wird im XML-Format zurückgeliefert. Ist halt normal bei REST/SOAP-Calls (jene sogenannten Web-Services als „Esperanto“ im bunten Software-Markt), aber leider etwas unhandlich für die SAS Welt, in der man (ob Data Step, DataFlux oder VA) lieber Relationen, also Tabellen, mag anstatt Hierarchien in Form von XML oder JSON.
Nächster Schritt: die XML in eine SAS Datei transformieren. Zuvor sollte man noch die als Flatfile gespeicherte Datei aller Term-Inhalte nach ANSI umschlüsseln: nennt sich „Transcoding“ und geht leicht per ein Kommandozeilen-Tool wie beispielsweise Iconv: "C:\Program Files (x86)\iconv\bin\iconv.exe" -f utf-8 -t iso-8859-1 C:\temp\GetAllTerms.xml > C:\temp\GetAllTerms_Latin1.xml
Diese XML kann man nun als „normale Tabelle” einlesen, flugs lasr'n und im VA bunt färben. Das geht entweder im SAS Data Management Studio als Data Job (XML Input Transformation) oder klassisch per Base SAS (siehe unten).
Trickreich ist der hierzu notwendige Eigenbau einer passenden XML Map. Diese lässt sich aber mit dem SAS XML Mapper (Download-Link) durch etwas Knobeln erstellen. Oder: Der Autor dieses Blogs (Anwendungsentwickler im ersten Leben) schickt sie Ihnen auch gerne auf Anfrage, z. B. via Twitter @herrmann. Obacht: Die sollte dann generisch für „alle möglichen“ Term-Inhalte funktionieren – was aber nicht immer auf Anhieb hinhaut, Stichwort „Sonderzeichen im Text“.
Fazit: Die API ist eine mächtige Schnittstelle, um nach Belieben sogar neue Oberflächen auf dem Glossar- oder Lineage-Repository zu bauen. Und man kann mit ihr auch schreiben. Oder das SAS Glossar in Nicht-SAS Welten einbinden.
libname D1_TEST BASE "C:\temp";
%let SAS_USER=sasdmadm; * <<< ANPASSSEN! *;
%let SAS_PW=12345; * <<< ANPASSSEN! *;
%let REST_URL=http://myserver.com/SASBusinessDataNetwork/rest/terms/; * <<< ANPASSSEN! *;
filename request TEMP; * keine Parameter, daher Request notwendig *;
filename hdrin 'C:\temp\BDN_AllTerms_HEADER.txt'; * Header *;
filename response 'C:\temp\BDN_AllTerms_RESPONSE.xml'; * Response = Liste aller Terme als XML *;
filename SXLEMAP 'C:\temp\BDN31_GetAllTerms_Term.map'; * (selbstgebaute) XMLMap zum Parsen der XML *;
libname response xmlv2 xmlmap=SXLEMAP access=READONLY ; * Libname auf Response-XML mit XMLMap *;
* Header schreiben: user und pw base64-encodieren, XML (statt default JSON) als Ergebnis anfordern *;
data _null_;
file hdrin;
sas_user = urlencode("&SAS_USER.");
sas_pw = urlencode("&SAS_PW.");
encodedAccessToken = put( compress(sas_user || ":" || sas_pw),$base64x32767.);
put "Authorization: Basic " encodedAccessToken;
put "Accept: application/vnd.sas.collection+xml";
run;
* BDN REST API aufrufen *;
%let response=response;
proc http method="GET" in=request out=&response headerin=hdrin url="&REST_URL."
ct="application/x-www-form-urlencoded;charset=UTF-8";
run;
* Ergebnis-XML in SAS-Datei umwandeln *;
data D1_TEST.GetAllTerms;
set response.term;
format term_ageInDays 4.;
length term_id_link $100;
term_ageInDays=int(today()-term_updatedDate/86400);
term_id_link = '?_sasapp=Business+Data+Ntwk+3.1#termID='!!trim(left(put(
term_id,best.)))!!'&module=BusinessData';
run;