Täysautomatisoitu raportointiympäristö

Täysautomatisoitu raportointiympäristö
Joni-Petteri Paavilainen
Jani Alatalo
Miksi tähän ryhdyttiin?
Miten asiassa edettiin?
Vaatimuksia
• Reaaliaikaisuus n 15 min
• Hallitut käyttöoikeudet
– Raportin tekijöillä ei välttämättä näkyvyyttä koko
dataan
– Kukin näkee datasta vain sen mihin on oikeutettu
• Käyttöoikeuksien määrittelylle helppo prosessi
• Datan lisääminen järjestelmään helppoa ja
yksinkertaista
Visio
Tieto virtaa lähes reaaliaikaisesti
→Operatiivisista järjestelmistä tietokantaan
→ Tietokannasta SAS VA:n muistiin
→ Ei manuaalista ylläpitoa VA:n päässä
Lähes reaaliaikainen raportti kokoajan monitorilla
→ KPIt, jotka indikoivat paineen kasvua
→ Korjaavat toimet voidaan aloittaa ilmiön alkaessa
Tiimi
• Joni-Petteri Paavilainen, Elisa Appelsiini
• Niko Mäkelä, Elisa Appelsiini, Data
• Ville Kajatsalo, Tae Konsultointi, Data
•
•
•
•
•
•
•
Jaakko Marila, Javascript, Dashboard
Pasi Helenius, Dashboard
Jani Sassi, Tietoturva
Pertti Viitamäki, Data
Ilkka Maristo, Päivitys
Johannes Koskinen, Asennukset
Jani Alatalo, Tech lead
Toteutus
• Tietokanta
– Yksi rajapinta dataan
– Datalähteet suojassa
• SAS Visual Analytics
– Dashboardit monitoreilla
– Raportit
Performanssi toteutuksesta
• Tietokanta & AD
– Palomuuri
• SAS Visual Analytics
– Palomuuri
• Käyttäjät, Raportin tekijät
• Data, joka ihanasti virtailee
Varoitus!!
Code
var lastUpdate = 0;
var updateFrame = function() {
var iframe =
document.getElementById('dashboardFrame');
iframe.src = iframe.src;
};
var checkUpdateFile = function () {
var fileRequest = new XMLHttpRequest();
fileRequest.onreadystatechange = handleStateChange;
fileRequest.open("GET", "d1_updated.txt", true);
fileRequest.send();
• Esitys sisältää
– Koodia
– Teknisiä yksityiskohtia
– SAS akronyymejä
function handleStateChange() {
if (fileRequest.readyState === 4 && fileRequest.status ==
200) {
if (lastUpdate == 0) lastUpdate =
parseInt(fileRequest.responseText);
else if (parseInt(fileRequest.responseText) != lastUpdate) {
lastUpdate = parseInt(fileRequest.responseText);
updateFrame();
}
}
};
};
window.onload = function() {
var intervalId = setInterval(checkUpdateFile,
30000);
};
Täysautomatisoitu
•
•
•
•
Dataflow
Rivikohtainen tietoturva
Metadata rakenteet
Itsensä virkistävä raportti
Dataflow
1. Luetaan kannasta taulut
2. Luetaan lataussäännöt ohjaustaulusta
- jos uusi taulu, lisätään ohjaustauluun uusi rivi
3. Jokaista taulua kohden
1. Tarkistetaan onko uutta data
2. Jos on käynnistetään ohjaustaulun määräämä ajo
3. Luetaan muuttuneet tiedot kannasta (delta)
4. Tarkistetaan deltan rakenne
5. Jos sama, deltalataus (upsert)
6. Jos eri, täyslataus ja metadatan päivitys
7. Ehdolliset lukuoikeudet
Deltalataus
• Delta muistiin
• Päällekkäiset rivit pois taulusta
• Lisätään delta tauluun
proc imstat data=LASeRi.Kohdetaulu noprint;
where %delList ;
deleterows / purge;
run;
where;
set delta_taulu / drop;
quit;
Täyslataus
• Uusi kopio muistiin – apu
• Poistetaan taulu
• Luodaan uuden kaltainen
taulu tyhjänä
• Lisätään tyhjään tauluun
rivit apu taulusta
• Dropataan apu taulu
data LASeRi.t_Taulu;
set onDisk.Taulu;
run;
*Drop table from memory;
proc delete data=LASeRi.Taulu;
run;
*Create empty table;
data LASeRi.Taulu;
set onDisk.Taulu(obs=0);
run;
*append loaded table to empty and drop
temp table;
proc imstat data=LASeRi.Taulu;
set t_Taulu / drop;
run;
Rivikohtainen tietoturva
• Käyttövaltuutuksien hallinta AD:ssa
– Ryhmän nimet ja muuttujan sisältö 1:1
• Vain Read Metadata
• + Ehdollinen Read
data work.auth_call;
set authdata.lasr_table_authorizations;
length tname $ 200;
tname = "omsobj:PhysicalTable?@Name='"||Lasr_name||"'";
rc_remove = METASEC_SETAUTH('', tname, type, name, "Remove", permission, "");
rc_add = METASEC_SETAUTH('', tname, type, name, action, permission, condition);
run;
Metadatarakenteet
• AD:sta merkityt ryhmät Metadataan
• Ryhmiin kuuluvat käyttäjät
• AD Sync koodin jatkeella uusille ryhmille
– Kansiorakenne
– ACT + ACE suojaamaan sisältöä
actrc = METASEC_APPLYACT("", t_uri,
act_uri,0);
Itsensä virkistävä raportti
• Jaakko Marila
• HTML sivu
– Javascript
– iFrame
•
•
data _NULL_;
file
"xxx/yyy/ddd/htdocs/asia/d1_updated.txt";
length updateTime $20;
updateTime = put(datetime(), 20.0);
put updateTime;
run;
if (lastUpdate == 0) lastUpdate =
parseInt(fileRequest.responseText);
Data valmis
else if
→aikaleima web tiedostoon
(parseInt(fileRequest.responseText) !=
javaScript havaitsee päivityksen lastUpdate) {lastUpdate =
→iFramelle refresh
parseInt(fileRequest.responseText);
updateFrame();
Kehitysajatuksia
• Latauksiin tarkistukset ja hälytykset
• Kaksivaiheinen tunnistautuminen
Olemmeko visiossa?
Kysymyksiä?
[email protected]