You are on page 1of 65

UNIVERZA

 V  LJUBLJANI  
Fakulteta  za  elektrotehniko  
 
 
 
 
 
 

Matjaž  Pečan  
 

SPLETNA  STORITEV  SINHRONIZACIJE  


KONTAKTNIH  PODATKOV  V  OBLAKU  
 
DIPLOMSKO  DELO  UNIVERZITETNEGA  ŠTUDIJA  
 
 
 
 
 
 
 
 
 
 
 
 
 
Mentor:  doc.  dr.  Boštjan  Murovec  
Ljubljana,  maj  2011    

 
 
   

 
 

Zahvala  
Zahvaljujem  se  mentorju  doc.  dr.  Boštjanu  Murovcu  za  pomoč,  podporo  in  potrpežljivost  
med  pisanjem  diplomskega  dela.    
 
Prav  tako  se  zahvaljujem  tudi  svojim  staršem,  ki  sta  me  podpirala  med  dolgim  študijem  
in  nikoli  nista  izgubila  upanja.  
 
Zahvala   gre   tudi   vsem   mojim   prijateljem   in   prijateljicam,   ki   so   mi   v   času   študija   dajali  
nasvete  in  mi  pomagali.  
   

 
   

 
Povzetek  
Diplomsko   delo   opisuje   razvoj   spletnega   servisa   za   sinhronizacijo   kontaktov   med  
spletno  storitvijo  Google  Kontakti  in  socialnim  omrežjem  Facebook.  Storitev  samostojno  
povezuje   uporabnikove   kontakte   in   prijatelje   na   Facebooku,   zatem   pa   sinhronizira  
dostopne  kontaktne  podatke.    
 
V  prvem  delu  je  podan  koncept  rešitve,  kjer  so  predstavljene  osnovne  ideje,  arhitektura  
in   utemeljitev   načina   povezovanja   kontaktov   s   prijatelji.   V   nadaljevanju   je   opisana  
platforma   Google   App   Engine,   na   kateri   je   bil   razvit   spletni   servis,   opisan   je   način  
dostopa  do  uporabnikovih  podatkov  s  protokolom  OAuth  in  uporabljene  knjižnice.  
 
V   drugem   delu   je   prikazana   struktura   baze   podatkov   in   njena   izvedba,   zatem   pa   je  
opisana  tudi  izvedba  servisa  z  strukturo  in  optimizacija  le-­‐tega.  Na  koncu  je  prikazana  še  
analiza  stroškov  povezanih  z  vzdrževanjem  storitve.  
 
Ključne   besede:   spletni   servis,   sinhronizacija,   Google   App   Engine,   avtorizacija,   OAuth,  
Google  Kontakti,  Facebook,  Java    
   

 
 
   

 
Abstract  
The   thesis   describes   the   development   of   a   web   service   for   the   syncronization   of   contact  
data   between   the   web   service   Google   Contacts   and   the   Facebook   social   network.   The  
service   automatically   matches   the   user's   contacts   with   his   friends   on   Facebook   and  
syncronizes  the  available  data.  
 
The  first  part  describes  the  conceptual  idea  of  the  service,  its  architecture  and  details  the  
way  contacts  and  friends  are  matched.  It  also  describes  the  Google  App  Engine  platform,  
on  which  the  service  was  created,  the  way  that  user  data  is  accessed,  the  use  of  OAuth  
and  the  libraries  used  in  the  service.  
 
The   second   part   details   the   structure   of   the   database   and   its   implementation,   the  
structure  of  the  service  itself  and  the  optimization  process.  In  the  end  a  cost  analysis  is  
made.    
 
Keywords:   web   service,   syncronization,   Google   App   Engine,   authorization,   OAuth,  
Google  Contacts,  Facebook,  Java  
 
   

 
 
 

 
Kazalo  
 

1.   UVOD  ...........................................................................................................................................  1  

2.   IDEJNA  ZASNOVA  STORITVE  ...............................................................................................  3  


2.1.   AVTENTIKACIJA  IN  AVTORIZACIJA  ......................................................................................................  5  
2.2.   PRIDOBIVANJE  IN  SHRANJEVANJE  PODATKOV  ..................................................................................  6  
2.3.   POVEZOVANJE  KONTAKTOV  IN  PRIJATELJEV  ....................................................................................  7  
2.3.1.   Ime,  priimek  in  rojstni  dan  .......................................................................................................  8  
2.3.2.   Ime,  priimek,  rojstni  dan  in  prijateljstvo  ...........................................................................  9  
2.3.3.   Enačenje  uporabniških  imen  .................................................................................................  10  
2.3.4.   Ročno  povezovanje  ....................................................................................................................  10  
2.4.   SINHRONIZACIJA  .................................................................................................................................  11  

3.   GOOGLE  APP  ENGINE  ..........................................................................................................  13  


3.1.   VARNOST  IN  ZANESLJIVOST  ..............................................................................................................  13  
3.2.   PROGRAMIRANJE  ZA  GAE  V  JEZIKU  JAVA  .......................................................................................  14  
3.3.   HRAMBA  PODATKOV  ..........................................................................................................................  14  
3.4.   GOOGLE  APP  ENGINE  APIJI  ..............................................................................................................  15  
3.4.1.   Users  API  ........................................................................................................................................  15  
3.4.2.   Memchache  API  ..........................................................................................................................  16  
3.4.3.   URL  Fetch  API  ..............................................................................................................................  16  

4.   DOSTOP  DO  PODATKOV  ....................................................................................................  17  


4.1.   PROTOKOL  OAUTH  ............................................................................................................................  17  
4.1.1.   Vloge  ................................................................................................................................................  18  
4.1.2.   Potek  avtorizacije  ......................................................................................................................  18  
4.1.3.   Različice  .........................................................................................................................................  20  
4.1.4.   Primer  izvedbe:  Facebook  ......................................................................................................  20  
4.2.   GOOGLE  CONTACTS  DATA  API  ........................................................................................................  22  
4.2.1.   Predložitev  podatkov  za  dostop  ..........................................................................................  22  
4.2.2.   Oblikovanje  zahtev  za  pridobitev  podatkov  ...................................................................  23  
4.2.3.   Izvedba  zahteve  in  vrnjeni  podatki  ....................................................................................  23  
4.2.4.   Zapisovanje  podatkov  ..............................................................................................................  24  
4.3.   KOMUNIKACIJA  S  SOCIALNIM  OMREŽJEM  FACEBOOK  ..................................................................  24  
4.3.1.   Predložitev  OAuth  podatkov  .................................................................................................  24  

  I  
4.3.2.   Zahteve  in  branje  podatkov  ...................................................................................................  25  
4.3.3.   FQL  zahteve  ..................................................................................................................................  25  
4.3.4.   Iskanje  .............................................................................................................................................  26  

5.   BAZA  PODATKOV  .................................................................................................................  27  


5.1.   STRUKTURA  .........................................................................................................................................  27  
5.2.   IZVEDBA  BAZE  PODATKOV  .................................................................................................................  28  
5.3.   TWIG-­‐PERSIST  .....................................................................................................................................  29  
5.3.1.   Uporaba  knjižnice  ......................................................................................................................  29  
5.3.1.1.   Primer  uporabe  označb:  ContactList.java  .............................................................................................  29  
5.3.1.2.   Shranjevanje  podatkov  ..................................................................................................................................  30  
5.3.1.3.   Nalaganje  in  iskanje  objetkov  .....................................................................................................................  31  
5.3.1.4.   Učinkovitost  .......................................................................................................................................................  32  

6.   IZVEDBA  SERVISA  ................................................................................................................  33  


6.1.   STRUKTURA  SERVISA  ..........................................................................................................................  33  
6.1.1.   Paketa  uporabniškega  vmesnika  ........................................................................................  33  
6.1.2.   Paket  ponavljajočih  se  opravil  .............................................................................................  34  
6.1.3.   Paket  opravil  v  ozadju  .............................................................................................................  36  
6.2.   UPORABNIŠKI  VMESNIK  .....................................................................................................................  38  
6.2.1.   Omejitve  uporabniškega  vmesnika  ....................................................................................  38  
6.2.2.   Komunikacija  med  uporabniškim  vmesnikom  in  strežnikom  ................................  38  
6.2.3.   Oblika  uporabniškega  vmesnika  .........................................................................................  39  
6.3.   OPTIMIZACIJA  SERVISA  ......................................................................................................................  40  
6.4.   ANALIZA  STROŠKOV  ............................................................................................................................  42  
6.4.1.   Shranjevanje  podatkov  ............................................................................................................  43  
6.4.2.   Prenos  podatkov  .........................................................................................................................  43  
6.4.3.   Procesorski  čas  ............................................................................................................................  43  
6.4.4.   Skupni  mesečni  strošek  ............................................................................................................  44  

7.   ZAKLJUČEK  .............................................................................................................................  45  


 
   

II    
Kazalo  slik  
 
Slika  2.1  -­‐  Prikaz  medsebojnih  povezav  procesov  v  spletnem  storitvi  .......................................  3  
Slika  2.2  –  Potek  avtentikacije  in  avtorizacije  ........................................................................................  5  
Slika  2.3  -­‐  Shema  procesa  pridobivanja  kontaktnih  podatkov  .......................................................  6  
Slika  2.4  –  Shema  procesa  povezovanja  kontaktov  in  uporabnikovih  prijateljev  ..................  7  
Slika  2.5  -­‐  Shema  procesa  sinhronizacije  ...............................................................................................  11  
Slika  4.1  -­‐  prikaz  poteka  OAuth  avtorizacije  ........................................................................................  19  
Slika  5.1  -­‐  Struktura  baze  podatkov  .........................................................................................................  27  
Slika  6.1  -­‐  Struktura  paketov  client  in  server  ......................................................................................  34  
Slika  6.2  -­‐  Proces  dodajanja  opravil  za  sinhronizacijo  .....................................................................  35  
Slika  6.3  -­‐  Časovni  in  zmogljivostni  potek  procesa  povezovanja  kontakta  .............................  40  
Slika   6.4   -­‐   Časovni   in   zmogljivostni   potek   procesa   povezovanja   kontaktov   (100  
kontaktov)  .................................................................................................................................................  41  
 
   

  III  
Kazalo  tabel  
Tabela  6.1  -­‐  Cenik  storitev  Google  App  Engine  ...................................................................................  42  
Tabela  6.2  -­‐  Podatki  testnih  uporabnikov  storitve  ...........................................................................  42  
Tabela  6.3  -­‐  Projekcija  stroškov  vzdrževanja  storitve  .....................................................................  44  
 
   

IV    
Seznam  uporabljenih  kratic  in  simbolov  
 
API  –  Aplikacijski  programski  vmesnik.  
GAE  –  Google  App  Engine,  aplikacijski  strežnik,  ki  ga  oskrbuje  podjetje  Google.  
HTML   –   HyperText   Markup   Language,   jezik   za   določitev   strukture   dokumentov,   ki   se  
prenašajo  po  spletu  in  pregledujejo  s  spletnimi  brskalniki.  
JSON  –  JavaScript  Object  Notation,  format  izmenjave  podatkov.    
Memcache   –   Mehanizem   za   pospešitev   izvajanja   programa   z   uporabo   dinamičnega  
pomnilnika.  
RPC  –  Remote  procedure  call,  klic  oddaljene  procedure.  
URL  –  Uniform  Resource  Locator,  internetni  naslov,  na  katerem  se  nahaja  vsebina.  
   

  V  
 
 

VI    
1. Uvod  
Živimo   v   času   mobilnih   naprav   in   komunikacij.   Na   razpolago   imamo   veliko   število  
naprav,   ki   nam   omogočajo   hiter   dostop   do   interneta   na   poti   in   doma.   Istočasno   ima  
čedalje   več   uporabnikov   večje   število   takih   naprav.   Vsaka   od   njih   se   povezuje   na  
svetovni   splet   in   izvaja   sinhronizacijo   z   strežniki   za   razne   namene,   naj   bo   to   e-­‐pošta,  
kontakti  ali  pa  koledar.  
 
Po  mnenju  uporabnikov  mobilnih  naprav,  je  med  najpomembnejšimi  lastnostmi  naprave  
čas   mobilnega   delovanja   [1],   torej   čas,   ko   je   naprava   v   delovanju   brez   zunanjega  
napajanja.   Sinhronizacija   z   različnimi   servisi   pomeni   izgubo   energije,   kar   morda   lahko  
upravičimo   pri   enem   servisu,   v   primeru,   da   jih   uporabljamo   več,   je   potrebna  
sinhronizacija  za  vsak  servis  posebej.  Pri  tem  ne  gre  le  za  podvajanje  podatkov,  težava  je  
v  dodatnih  podatkih  (ang.  overhead),  ki  so  potrebni  za  sinhronizacijo  zaradi  protokolov  
in   usklajevanja   aplikacij.   Ti   podatki   pomenijo   dodatno   obremenitev   procesorja   in  
komunikacijske   poti   z   zunanjim   svetom,   kar   vodi   v   izgubo   časa   delovanja   zaradi  
nepotrebne  porabe  energije.  
 
Sinhronizacijo  je  mogoče  izvrševati  v  oblaku  (ang.  cloud),  saj  so  storitve  v  oblaku  danes  
poceni.  Omogočajo  uporabo  strežniških  sistemov,  ki  so  sestavljeni  iz  tisočev  posameznih  
strežnikov  in  so  zaradi  tega  zmožni  obdelati  velike  količine  podatkov.  Sinhronizacija,  ki  
se   na   mobilni   napravi   izvaja   več   minut,   je   v   oblaku   opravljena   v   sekundah,   hkrati  
mobilna  naprava  prihrani  skoraj  toliko  minut  delovanja,  saj  je  ta  čas  v  mirovanju.  
 
Računalništvo  v  oblaku  je  internetna  tehnologija,  za  katero  je  značilno  deljenje  sredstev,  
programske  opreme  in  informacij  med  več  spletnimi  storitvami  [2].  Uporaba  naprav  in  
programske  opreme  se  v  oblaku  izvaja  na  zahtevo,  torej  ni  potrebno  imeti  zakupljenih  
zmogljivosti,   obračunajo   se   le   opravljene   storitve.   Ko   razvijamo   aplikacije   za   oblak,   se  
nam   ni   potrebno   ukvarjati   s   tehničnimi   podrobnostmi   storitev,   saj   so   le-­‐te   skrite   za  
oblaki.  
 

  1  
V   diplomskem   delu   prikazujemo   razvoj   sinhronizacijskega   sistema,   ki   povezuje   servis  
Google   Kontakti   [3]   in   socialno   omrežje   Facebook  [4].   Sistem   je   sestavljen   modularno   in  
vsebuje   dva   poglavitna   modula.   Prvi   modul   ugotavlja   povezave   med   razpoložljivimi  
kontakti  in  Facebook  prijatelji,  drugi  modul  pa  izvaja  sinhronizacijo.  
 
Zaradi   omejitev,   ki   jih   Facebook   uveljavlja   nad   uporabniškimi   podatki,   je   žal   mogoče  
sinhronizirati   le   rojstni   datum,   ime,   priimek   in   fotografijo,   a   sistem   bo   z   manjšimi  
spremembami   omogočal   sinhronizacijo   vseh   razpoložljivih   podatkov   v   trenutku,   ko   bo  
Facebook  omogočil  dostop  do  njih.    
 
Pri  izvedbi  smo  se  zaradi  cenovne  ugodnosti  in  visoke  zmogljivosti  odločili  za  uporabo  
servisa  Google  App  Engine  [5]  (v  nadaljevanju  GAE).  
   

2    
2. Idejna  zasnova  storitve  
V   sistemu   želimo   sinhronizirati   podatke   med   dvema   spletnima   servisoma,   spletnim  
omrežjem   Facebook   in   Google   Kontakti.   Na   sliki   2.1   so   prikazane   povezave   med   procesi,  
ki  se  izvajajo  v  spletni  storitvi.  Vrstni  red  izvajanja  procesov  je  ponazorjen  z  številkami  
od  1  do  4.    Proces  3  se  ne  more  izvesti  v  primeru,  da  se  še  nista  izvedla  procesa  1  in  2.  Na  
sliki   so   s   črtkano   črto   obkroženi   procesi,   ki   se   izvajajo   na   oddaljenih   strežnikih   in   nad  
njimi   nimamo   nadzora.   Polne   puščice   predstavljajo   prenos   oz.   zapisovanje   podatkov,  
medtem   ko   prazne   puščice   predstavljajo   izključno   prenos   podatkov,   potrebnih   za  
avtentikacijo.  

 
Slika  2.1  -­‐  Prikaz  medsebojnih  povezav  procesov  v  spletnem  storitvi  

Ker   so   podatki   izrazito   osebne   narave,   je   poskrbljeno,   da   so   uporabniki   ustrezno  


avtenticirani,   zaradi   dostopa   do   podatkov   se   izvede   tudi   avtorizacija,   pri   kateri  
uporabnik  spletni  storitvi  dodeli  dostop  do  svojih  podaktov.  
 

  3  
Ko   je   uporabnikova   istovetnost   preverjena   in   je   le-­‐ta   storitvi   dodelil   dostop   do  
podatkov,   se   prične   pridobivanje   podatkov,   ki   so   potrebni   za   nadaljne   izvajanje  storitve.  
Glavni   vir   podatkov   za   spletno   storitev   predstavljajo   kontaktni   podatki,   ki   jih   ima  
uporabnik   shranjene   v   spletni   storitvi   Google   Kontakti,   zato   storitev   le-­‐te   prenese   v  
lokalno   bazo   podatkov,   tako   da   so   potem   na   razpolago   za   nadaljnjo   obdelavo.   Pri   tem   se  
zavoljo   varovanja   podatkov   in   zmanjševanja   porabe   plačljivih   zmogljivosti   izpusti  
podatke,  ki  jih   spletna   storitev   ne   potrebuje   za   delovanje.   Sistem   naj  bo  postavljen  tako,  
da  se  podatki  po  prvem  prenosu  le  osvežujejo.  
 
Po   pridobitvi   podatkov   se   prične   povezovanje   uporabnikovih   kontaktov   z  
uporabnikovimi   prijatelji   (povezavami)   na   Facebooku.   Zato   so   potrebni   kriteriji,   ki  
povezovanje  omogočajo.  E-­‐poštni  naslov  vsakega  kontakta  je  edinstven,  kar  pomeni,  da  
je  le-­‐ta  z  njim  v  celoti  definiran.  V  primeru,  da  kontakt  ne  vsebuje  e-­‐poštnega  naslova,  ali  
z   naslovom   ni   mogoče   najti   kontakta   v   socialnem   omrežju   Facebook,   to   predstavlja  
problem  povezovanja  zapisov  (ang.  record  linkage)  [6].  
 
Ko   so   povezave   vzpostavljene   in   zapisane,   se   tisti   kontakti,   ki   so   zanesljivo   povezani,  
posodobijo  s  podatki,  ki  so  razpoložljivi  na  Facebooku.  Ker  na  omrežje  samo  ni  mogoče  
zapisovati  dodatnih  podatkov,  je  postopek  enosmeren.  
   

4    
2.1. Avtentikacija  in  avtorizacija  
Postopek   se   prične,   ko   uporabnik   naloži   stran   spletne   storitve.   Potrebno   je   ugotoviti  
istovetnost   uporabnika   in   v   primeru,   da   še   ni   prijavjen   v   storitev,   tudi   vpisati   v   bazo  
uporabnikov.   Na   sliki   2.2   je   prikazan   diagram   poteka   avtorizacije   in   avtentikacije.  
Procesi,  ki  so  obkroženi  s  prekinjeno  črto,  potekajo  na  oddaljenih  strežnikih  in  nad  njimi  
nimamo  nadzora.  
 
Ko  je  istovetnost  uporabnika  uspešno  ugotovljena  (1),  se  preveri  (2),  ali  je  le-­‐ta  storitvi  
dodelil  dostop  do  podatkov  pri  Google  Kontaktih  in  pri  Facebooku.  Če  uporabnik  tega  še  
ni   opravil,   ga   storitev   napoti   na   avtorizacijo   (3),   ki   se   izvede   na   oddaljenem   strežniku.   V  
primeru   uspešne   avtorizacije   (4)   se   zapišejo   podatki,   potrebni   za   dostop,   nakar   se  
ponovno  preveri  stanje  avtorizacije.  V  primeru  veljavne  avtorizacije  se  proces  zaključi  in  
uporabniku  servis  prikaže  stran,  ki  potrjuje,  da  je  uspešno  zaključil  nastavitev  storitve.  

 
Slika  2.2  –  Potek  avtentikacije  in  avtorizacije  

  5  
2.2. Pridobivanje  in  shranjevanje  podatkov  
Podatki,   brez   katerih   ni   mogoče   povezati   kontaktov   z   njihovimi   profili   na   Facebooku,   so  
e-­‐poštni   naslovi,   imena   in   priimki.   Zaradi   tega   se   ti   podatki   prenesejo   iz   Google  
Kontaktov   in   se   shranijo   v   bazo   podatkov.   Hkrati   se   shrani   tudi   podatek,   ki   kontakte  
enoznačno   definira,   v   tem   primeru   je   to   identifikacijski   naslov   kontakta   v   Google  
Kontakih.  Shema  procesa  je  prikazana  na  sliki  2.3.  
 
Proces   se   prične   s   sestavo   zahteve   (1),   ki   bo   poslana   (2)   na   oddaljeni   strežnik.   V  
primeru,  da  zahteva  vključuje  primerne  podatke  za  dostop,  oddaljeni  strežnik  lokalnemu  
strežniku  vrne  (3)  zahtevane  podatke,  v  nasprotnem  primeru  lokalnemu  strežniku  javi  
napako  avtorizacije  (4).  Podatki  se  na  lokalnem  strežniku  obdelajo  (5)  in  shranijo  v  bazo  
kontaktov  (6).    

 
Slika  2.3  -­‐  Shema  procesa  pridobivanja  kontaktnih  podatkov  

6    
2.3. Povezovanje  kontaktov  in  prijateljev    
S   podatki,   ki   so   na   rapolago,   servis   prične   postopek   povezovanja   kontaktov   in  
uporabnikovih   prijateljev   na   Facebooku.   Shema   procesa   je   predstavljena   na   sliki   2.4.  
Proces   se   prične   z   branjem   kontakta   (1),   katerega   je   potrebno   povezati,   iz   baze  
kontaktov.   S   podatki   se   pripravi   zahteva   (2),   ki   se   pošlje   na   oddaljeni   strežnik.   Na  
strežniku  se  preveri  veljavnost  avtorizacije  (3).  Podatki,  prejeti  z  oddaljenega  stežnika,  
se  obdelajo  v  algoritmu  za  povezovanje  (4).  V  primeru  uspeha  pri  iskanju  povezave  (5),  
se  kontakt  z  informacijo  o  povezavi  zapiše  (6)  v  bazo  kontaktov,  v  nasprotnem  primeru  
se  proces  neuspešno  zaključi  (7)  in  ne  zapiše  nobenih  podatkov.    

 
Slika  2.4  –  Shema  procesa  povezovanja  kontaktov  in  uporabnikovih  prijateljev  

Najbolj   preprost   algoritem   za   povezovanje   s   pomočjo   e-­‐poštnega   naslova   preverja,   ali  


obstaja   povezava   med   oddaljenim   računom   ter   kontaktom.   V   primeru,   da   e-­‐poštni  

  7  
naslov   ni   na   voljo,   ali   le-­‐ta   ne   predstavlja   povezave   med   kontaktom   in   oddaljenim  
računom,  moramo  poskusiti  najti  povezavo  na  drugačen  način.  

2.3.1. Ime,  priimek  in  rojstni  dan  


Ena   možnost   je   iskanje   kontakta   s   pomočjo   imena,   priimka   in   rojstnega   dne.     V   tem  
primeru   se   moramo   prepričati   ali   je   tako   iskanje   sploh   smiselno,   izračunati   moramo  
verjetnost,  da  obstajata  dve  osebi  pri  katerih  so  vsi  trije  podatki  enaki.      
Verjetnost  !(!),   da   imata   dve   osebi   rojstni   dan   na   isti   dan,   imenujemo   problem  
rojstnega  dne,  ta  je  približno  [7]:  
 
! ! =  1 − ! ! ≈ 1 − ! !!(!!!)/(!  ×  !"#)

Pri  čemer  n  predstavlja  število  oseb  ki  jih  obravnavamo.  


 
V   našem   primeru   upoštevamo   tudi   letnico   rojstva,   kar   število   možnih   stanj   poveča;  
modificirana  enačba  se  glasi:  
 
!! ! =  1 − ! ! ≈ 1 − ! !!(!!!)/(!  ×  !"#  ×  !)

Kjer  l  predstavlja  število  let,  ki  jih  privzamemo  kot  okvir  pri  izračunu.  
 
Sedaj   moramo   ugotoviti   še   število   oseb   n,   ki   jih   obravnavamo   v   povezavi   z   našim  
problemom.   Predpostavimo,   da   so   imena   in   priimki   nepovezane   spremenljivke,   zato  
lahko   iz   podatkov  [8]   Statističnega   Urada   Republike   Slovenije   za   najpogostejša   imena   in  
priimke   razberemo,   da   je   najpogostejše   ime   Marija,   s   69.314   ponovitvami.   Najpogostejši  
priimek  pa  je  Novak,  z  11.311  ponovitvami.  
 
Predpostavimo,  da  je  pogostost  imena  Marija  med  ljudmi  s  priimkom  Novak  enaka  kot  
za  celotno  prebivalstvo  Republike  Slovenije.  Potemtakem  je:  
 
69.314
! = 11.311× = 385,76 ≅ 386  
2.032.362
V   primeru,   da   to   uporabimo   v   enačbi   in   privzamemo   časovni   okvir   10   let,   dobimo  
verjetnost:  
 

8    
!!" 386 ≅  0,9999 = 99,99%  
 
Če  privzamemo  časovni  okvir  100  let  je  rezultat:  
 
!!"" 386 ≅  0,8694 = 86,94%  
 
Zaključimo,  da  je  verjetnost  enakosti  vseh  treh  podatkov,  v  primeru  Marije  Novak,  zelo  
visoka,  zaradi  česar  ti  podatki  niso  zadostni  za  enoznačno  določitev  osebe  v  Sloveniji.    
 
Ta   obravnava   sicer   predstavlja   najslabši   možni   izid,   ki   pa   je   v   našem   primeru  
najpomembnejši,   saj   moramo   biti   prepričani,   da   kontakt   in   povezava   na   socialnem  
omrežju  Facebook  predstavljata  isto  osebo.    

2.3.2. Ime,  priimek,  rojstni  dan  in  prijateljstvo  


Če   prejšnji   primer   pogledamo   ožje,   torej   mu   dodamo   še   zahtevo,   da   mora   oseba   biti  
uporabnikov   prijatelj   v   okviru   Facebooka,   lahko   ugotovimo,   da   se   verjetnost   močno  
spremeni.  
 
V  povprečju  ima  uporabnik  na  socialnem  omrežju  Facebook  120  prijateljev  [9].  Torej  se  
število   oseb,   ki   jih   moramo   obravnavati   v   enačbi   drastično   zmanjša.   Sedaj   ne  
obravnavamo   več   celotnega   prebivalstva   Slovenije.   V   primeru,   da   bi   predpostavke   glede  
imen  in  priimkov  uporabili  sedaj,  bi  ugotovili,  da  je  v  tem  primeru:  
 
11.311 69.314
!= × ×120 = 0,0227 ≅ 0  
2.032.362 2.032.362
 
Verjetnost,  da  se  med  našimi  prijatelji  nahaja  Marija  Novak  je  namreč  majhna.  
Zato   se   bomo   problema   rojstnega   dne   poslužili   drugače,   uporabili   ga   bomo   za   izračun  
števila  ljudi,  potrebnih  za  verjetnost  ponovitve  0,1  %.  Zato  uporabimo  enačbo  [7]:  

1
!(!; 365×!) ≈ 2×365×!× ln  
1−!

 
Kjer   n   predstavlja   število   ljudi,   l   predstavlja   letni   okvir,   p   pa   predstavlja   verjetnost.   V  
primeru  p=0,1%  je:  

  9  
 
! 0,001;  365×10 ≈ 2.7  
 
Torej  moramo  v  primeru  časovnega  okvira  10  let,  v  katerem  se  pojavljajo  rojstni  dnevi  
prijateljev,   imeti   skoraj   tri   prijatelje   z   enakim   imenom   in   priimkom,   zato   da   bi   bila  
verjetnost   enakosti   njihovih   podatkov   0,1%.   Ker   menimo,   da   to   predstavlja   dovolj  
majhno   verjetnost   ponovitve   pri   določanju   povezav   med   kontakti   in   prijatelji   na  
socialnem  omrežju  Facebook,  bomo  ta  princip  uporabili  tudi  v  našem  servisu.  

2.3.3. Enačenje  uporabniških  imen  


Poleg   predstavljenih   možnosti,   bi   lahko   povezavo   poskusili   določiti   tudi   z   enačenjem  
uporabniških  imen,  vendar  bi  morali  prej  izračunati  verjetnost,  da  uporabniško  ime  res  
predstavlja   isto   osebo  [6].   Ker   je   ta   problem   prekompleksen,   smo   se   odločili,   da   te  
metode  ne  bomo  vključili.    

2.3.4. Ročno  povezovanje  


Uporabniku  lahko  tudi  omogočimo,  da  ročno  postavi  povezave.  Pri  tem  mu  pomagamo  
tako,   da   poiščemo   spisek   prijateljev   na   socialnem   omrežju   Facebook,   ki   so   možne  
povezave   za   dani   kontakt.   Zatem   v   uporabniškem   vmesniku   omogočimo   uporabniku  
pregled  teh  kontaktov  in  vzpostavitev  povezav.  
   

10    
2.4. Sinhronizacija  
Ko   je   povezovanje   kontaktov   zaključeno,   se   lahko   prične   sinhronizacija.   Le-­‐ta   je  
enosmerna,   saj   podatkov   prijateljev   na   Facebooku   ni   mogoče   spreminjati.     Med  
sinhronizacijo   se   pridobijo   podatki   iz   Google   Kontaktov   in   iz   Facebooka.   Postopek   je  
prikazan   na  sliki   2.5.  Najprej  se  pripravita  podatkovni   zahtevi  (1)  za  oba  spletni  storitvi.  
Oddaljena   strežnika   preverita   istovetnost   zahtev   (2)   in   v   primeru,   da   so   zahteve  
istovetne,   vrneta   zahtevane   podatke   (3).   Preneseni   podatki   se   primerjajo   (4)   in   po  
potrebi   se   sproži   postopek   posodobitve.   V   okviru   postopka   posodobitve   se   pripravi  
zahteva  za  posodobitev  (5),  ki  se  pošlje  na  oddaljeni  strežnik  storitve  Google  Kontakti.  
Ta  potrdi  spremembo  (6)  in  proces  sinhronizacije  se  uspešno  zaključi.    

 
Slika  2.5  -­‐  Shema  procesa  sinhronizacije  

   

  11  
   

12    
3. Google  App  Engine  
Google   App   Engine   omogoča   pogon   spletnih   storitev   na   Google   infrastrukturi  [5].    
Storitve   je   mogoče   napisati   v   več   programskih   jezikih,   izmed   katerih   sta   najbolje  
podprta   Java   in   Python.   Z   uporabo   prevajalnikov   ali   interpreterjev,   ki   podpirajo  
izvajanje  na  JVM  (Java  Virtual  Machine)  [10],  je  mogoče  uporabiti  tudi  druge  jezike,  ki  se  
uporabljajo  za  razvijanje  spletnih  aplikacij:  JavaScript,  Ruby  ali  Scala.  
 
GAE   je   še   posebej   zanimiv   zaradi   nizkih   vstopnih   stroškov,   saj   so   osnovne   storitve   na  
razpolago   brezplačno   in   je   zaradi   tega   primeren   za   projekte   z   omejenimi   finančnimi  
sredstvi.  
 
Glavne  prvine  okolja  GAE  so:  
• dinamične  spletne  vsebine  s  podporo  za  večino  spletnih  tehnologij,  
• trajna  hramba  podatkov  s  poizvedbami,  razvrščanjem  in  transakcijami,  
• avtomatsko  skaliranje  sistema  in  prerazporeditev  obremenitev,  
• APIji   za   avtentikacijo   uporabnikov   z   uporabo   Google   računov   ter   pošiljanje   e-­‐
pošte,  
• lokalno  razvojno  okolje  za  simulacijo  GAE  na  osebnem  računalniku,  
• čakalne   vrste   opravil   (ang.   task  queues),   ki   omogočajo   izvajanje   opravkov  
neodvisno  od  spletnih  zahtevkov,  
• nastavljanje   ponavljajočih   se   opravil   (ang.   cronjobs),   ki   se   izvajajo   ob   želenih  
trenutkih.  
 

3.1. Varnost  in  zanesljivost  


Vse   GAE   aplikacije   delujejo   v   peskovniku   (ang.   sandbox),   torej   so   ločene   od  
operacijskega  sistema  na  katerem  tečejo.  Ker  je  aplikacija  ločena  od  strežnika,  je  mogoča  
tudi   dinamična   uporaba   večih   strežnikov   za   aplikacjio,   kar   pomeni   višjo   zanesljivost  
aplikacije  ob  velikih  zahtevah.  V  tem  pogledu  so  vse  GAE  aplikacije  virtualizirane.  
 
   

  13  
Tak  način  delovanja  prinaša  tudi  omejitve:    
• aplikacije   ne   morejo   neposredno   dostopati   do   podatkov   na   drugih   internetnih  
straneh,   temveč   so   primorane   za   to   uporabiti   APIje,   ki   so   na   razpolago   v   okolju  
GAE  (primer:  pridobivanje  podatkov  na  internetu  ter  pošiljanje  e-­‐pošte),  
• aplikacije  ne  morejo  zapisovati  podatkov  v  datotečni  sistem;  namesto  tega  lahko  
uporabljajo  storitev  za  zapis  podatkov  (datastore)  
• aplikacije  lahko  tečejo  samo  kot  odziv  na  spletno  zahtevo,  kot  opravilo  v  vrsti  ali  
pa   ponavljajoče   se   opravilo.   V   primeru   spletne   zahteve   se   mora   aplikacija   s  
podatki   odzvati   najkasneje   v   30  s,   medtem   ko   je   v   primeru   ostalih   opravil  
(opravila  iz  čakalnih  vrst  ter  ponavljajoča  opravila)  ta  omejitev  10  min  [11].  
 

3.2. Programiranje  za  GAE  v  jeziku  Java  


Izvedba  JVM  v  GAE  omogoča  uporabo  standardnih  Java  knjižnic,  torej  v  večini  primerov  
ni  potrebno  spreminjati  izvorne  kode,  če  prenašamo  obstoječe  spletne  aplikacije  na  GAE.  
Večja  težava  se  pojavi,  ko  želimo  aplikacijo,  ki  teče  na  običajnem  operacijskem  sistemu,  
prenesti  na  GAE.    
 
Sama   arhitektura   sistema   prisili   razvijalca   v   uporabo   spletnih   tehnologij   za   vse   procese,  
ki   jih   izvede   v   programski   kodi.   Zaradi   stabilnosti   sistema   so   postavljene   tudi   časovne  
omejitve   izvajanja   posameznih   operacij.   Operacije   ki   se   izvajajo   kot   posledica   spletne  
zahteve,  se  morajo  izvesti  v  največ  30  s,  medtem  ko  pa  se  lahko  operacije,  ki  se  izvajajo  
zaradi  klicev  APIja  za  opravila  (Tasks  API)  ali  pa  kot  ponavljajoča  se  opravila  (cronjobs),  
izvajajo  do  10  min  [11].  
 
Pri  programiranju  moramo  biti  pozorni  na  GAE  implementacijo  standarnih  Java  knjižnic,  
saj  se  ta  lahko  razlikuje  v  zmogljivostih,  kar  nam  lahko  oteži  izvedbo.  
 

3.3. Hramba  podatkov  


Podatki  se  shranjujejo  na  porazdeljenem  hrambenem  sistemu,  ki   je  izjemno  prilagodljiv,  
zaradi   česar   se   lahko   naša   aplikacija   hitro   odzove   na   povečane   zahteve,   pa   naj   bo   to  
obdelava   večje   količine   podatkov,   ali   povečano   število   uporabnikov.   Ker   potrebe   po  

14    
shranjevanju   podatkov   niso   pri   vseh   projektih   enake,   sta   omogočena   dva   principa  
shranjevanja  podatkov  [12]:  
• sistem  gospodar  /  suženj  (ang.  Master/Slave):  poudarek  je  na  razpoložljivosti  
podatkov,  do  njih  dostopamo  hitreje,  vse  to  pa  na  račun  zanesljivosti,  
• sistem   z   visoko   stopnjo   podvajanja   (ang.   high   replication   datastore):   poudarek   je  
na   zanesljivosti   hrambe   podatkov,   podatki   so   na   razpolago   tudi   med   izjemnimi  
razmerami,   a   je   ta   sistem   dražji   in   v   določenih   primerih   se   zahteve   počasneje  
izvajajo.  
Hramba   podatkov   je   izjemno   konsistentna   in   deluje   vzporedno,   pri   tem   pa   se   konflikti   v  
primeru   zapisa   v   isto   celico   rešujejo   z   optimističnim   nadzorom   večopravilnosti  [13]  
(ang.:  optimistic  concurrency  control  -­‐  OCC).  
Pri   OCC   predpostavljamo,   da   bo   pogostost   hkratnega   dostopa   do   podatkov   in  
spreminjanja   le-­‐teh   s   strani   večih   uporabnikov   majhna.   Zato   dostopa   do   podatkov   ne  
zaklepamo   in   omogočamo   vzporeden   dostop.   Zaradi   ohranjanja   konsistence   podatkov  
smo   primorani   zavrniti   zahtevo   po   zapisu   podatkov   s   strani   uporabnika,   če   je   bil  
podatek   spremenjen   med   časom,   ko   je   uporabnik   podatek   prebral,   in   časom,   ko   ga  
poskuša   zapisati.   To   je   največkrat   izvedeno   tako,   da   imamo   poleg   podatka   samega   še  
ključ,   ki   predstavlja   verzijo   podatka   in   ob   zapisu   preverimo   verzijo   podatka   ter  
zavrnemo  zapis  v  primeru,  da  obstaja  novejši  podatek.  

3.4. Google  App  Engine  APIji  


Na   razpolago   imamo   več   aplikacijskih   programskih   vmesnikov.   V   nadaljevanju   bomo  
opisali  tiste,  ki  smo  jih  uporabili  pri  izvedbi  sinhronizacijskega  servisa.  

3.4.1. Users  API  


GAE   omogoča   uporabo   Google   računov   za   avtentikacijo,   kar   omogoča   storitvam   hitro  
integracijo  z  drugimi  Google  storitvami,  predvsem  pa  razreši  težavo  shranjevanja  gesel,  
saj   celoten   postopek   izvaja   Google.   Hkrati   je   zaradi   globoke   integracije   GAE   z   Google  
računi   mogoče   omogočiti   dostop   do   administrativnih   delov   aplikacije   samo   skrbnikom  
aplikacije.    
Do  podatkov  o  uporabniku  dostopamo  preko  Users  API  [14],  pri  čemer  imamo  dostop  do  
enolične  identifikacijske  številke,  e-­‐poštnega  naslova  uporabnika  in  njegovega  vzdevka.    
 

  15  
3.4.2. Memchache  API  
Memcache  API  [15]  omogoča  shranjevanje  podatkov  v  delovni  pomnilnik,  kar  omogoča  
hitrejši   dostop   do   podatkov.   Memcache   je   v   Google   App   Engine   izveden   v   skladu   s  
specifikacijo   JSR   107  [16],   dostop   do   APIja   pa   je   mogoč   z   uporabo   knjižnice  
net.sf.jsr107cache.    
 
V   našem   projektu   je   dostop   do   Memcache   APIja   še   posebej   pomemben,   ker   v   njem  
uporabljamo   veliko   podatkov,   ki   so   shranjeni   v   trajnem   pomnilniku,   do   katerega   so  
dostopi   časovno   in   zmogljivostno   zahtevni,   z   uporabo   Memchache   funkcije   pa  
zmanjšamo   število   klicev   branja   trajnega   pomnilnika   tako,   da   podatke   preberemo  
enkrat  in  jih  shranimo  v  delovni  pomnilnik  za  kasnejši  dostop.  
 
Dinamični  pomnilnik  je  izveden  tako,  da  shranjeni  podatki  ostanejo  v  njem  dokler  je  to  
mogoče,   oz.   dokler   ne   prične   zmanjkovati   prostora   in   se   podatki   pričnejo   izločati   iz  
njega.   Zato   moramo   pred   vsakim   prevzemom   podatka   iz   dinamičnega   pomnilnika  
preveriti,  ali  podatek  še  vedno  obstaja.  V  nasprotnem  primeru  bomo  prisiljeni  podatek  
prebrati  iz  trajnega  pomnilnika.  
 

3.4.3. URL  Fetch  API  


URL   fetch   API  [17]   omogoča   prenos   podatkov   z   drugih   storitev   ali   strani   na   spletu.  
Dostop  je  izveden  s  pomočjo  java.net  knjižnice,  ki  ima  ozadje  izvedeno  z  nizkimi  Google  
App   Engine   funkcijami.   To   pomeni,   da   lahko   za   pridobivanje   podatkov   uporabimo  
izvorno  kodo,  ki  je  enaka  kot  v  običajnem  Java  okolju.  
 
Če   se   odločimo   za   to   pot,   izgubimo   dostop   do   določenih   funkcij,   ki   v   tej   izvedbi   niso  
dostopne.   Ne   moremo   namreč   preveriti,   kakšen   je   bil   odziv   spletnega   servisa,   do  
katerega   dostopamo.   Bolj   natančno,   z   uporabo   java.net   knjižnice   ne   moremo   ugotoviti,  
ali  je  bila  zahteva  izvedena  uspešno  (koda  odgovora  strežnika  2xx  [18]),  ali  je  prišlo  do  
napake   (v   našem   primeru   to   predstavlja   koda   odgovora   strežnika   400).   Zaradi   tega   smo  
v   našem   sistemu   uporabili   nizkonivojski   API   (ang.   low-­‐level   API),   ki   omogoča   večjo  
fleksibilnost  na  račun  višje  kompleksnosti  programa.  
   

16    
4. Dostop  do  podatkov  
Za  dostop  do  uporabnikovih  podatkov,  v  tem  primeru  so  to  podatki  Google  Kontaktov  in  
Facebooka,  je  potrebno  spletni  servis  pooblastiti  za  dostop.    
 
To   je   mogoče   izvesti   z   direktno   avtentikacijo   uporabnika   z   njegovim   uporabniškim  
imenom   in   geslom,   ki   ju   shranimo   v   svojo   bazo   podatkov.   Bolje   je,   če   uporabimo  
avtentikacijo   preko   protokola   OAuth  [19],   ki   nam   omogoča   dostop   do   podatkov  
uporabnika   brez   njegovega   gesla,   hkrati   pa   ima   uporabnik   vedno   možnost   ta   dostop  
preklicati,   ne   da   bi   zaradi   tega   bil   primoran   spremeniti   geslo   za   dostop   do   zunanje  
storitve.  

4.1. Protokol  OAuth  


V   tradicionalnem   modelu   avtentikacije   odjemalec-­‐strežnik,   lastnik   podatkov  
(uporabnik)   potrdi   svojo   istovetnost   z   uporabniškim   imenom   in   geslom.   V   primeru   da  
potrebuje   dostop   do   teh   podatkov   odjemalec   podatkov   (namizna   aplikacija,   spletni  
servis,   itd.),   je   v   tem   modelu   lastnik   podatkov   primoran   svoje   dostopne   podatke,   torej  
uporabniško   ime   in   geslo,   predati   odjemalcu   podatkov,   ki   jih   shrani   za   nadaljno  
uporabo.  Tak  model  prinaša  mnoge  težave:  
• odjemalci   podatkov   so   primorani   hraniti   uporabnikove   dostopne   podatke,  
praviloma  v  nešifrirani  obliki,  
• za   avtorizacijo   z   geslom   so   potrebni   dodatni   strežniki,   kljub   temu   da   tak   način  
avtorizacije  ni  varen,  
• odjemalci   praviloma   pridobijo   širši   dostop   do   uporabnikovih   podatkov,   kot   je  
potrebno  za  delovanje  aplikacije  –  v  našem  primeru  potrebujemo  dostop  samo  do  
storitve  kontaktov;  če  bi  uporabljali  uporabniško  ime  in  geslo,  bi  pridobili  dostop  
do  vseh  uporabnikovih  podatkov,  
• lastniki  podatkov  ne  morejo  preklicati  dostopa  do  le-­‐teh  za  posamično  aplikacijo,  
primorani  so  preklicati  dostop  za  vse  aplikacije  s  spremembo  gesla.  
 
Protokol   OAuth   rešuje   te   težave   z   uvedbo   novega   avtorizacijskega   nivoja   in   strogo  
ločitvijo  vloge  lastnika  podatkov  in  odjemalca,  ki  do  podatkov  dostopa.  V  zahtevi  OAuth  
odjemalec   zaprosi   za   dostop   do   podatkov   in   v   ta   namen   prejme   podatke   za   dostop,   ki   se  
razlikujejo  od  uporabnikovih.  

  17  
 
Aplikacija   do   podatkov   uporabnika   ne   dostopa   z   geslom,   temveč   za   ta   dostop   zaprosi  
avtorizacijski   strežnik   za   žeton   za   dostop   (ang.   access   token),   v   obliki   tekstovnega  
zapisa,   v   katerem   so   zapisani   trajanje   veljavnosti   žetona,   njegov   namen   in   drugi  
dostopni  podatki.  Izdajo  tega  žetona  uporabnik  potrdi  in  na  ta  način  aplikaciji  omogoči  
dostop  do  zahtevanih  podatkov.  

4.1.1.  Vloge  
Protokol   OAuth   vpeljuje   štiri   vloge,   ki   skupaj   omogočajo   dostop   do   zaščitenih   podatkov,  
ki  zahtevajo  avtorizacijo  za  dostop:    
• lastnik  podatkov:  subjekt,  ki  ima  pravico  dodeliti  dostop  do  zaščitenih  podatkov,  
• podatkovni  strežnik:  strežnik,  ki  hrani  zaščitene  podatke,  
• odjemalec:   aplikacija   ali   storitev,   ki   zahteva   zaščitene   podatke   v   imenu  
uporabnika,  
• avtorizacijski  strežnik:  strežnik,  ki  dodeli  odjemalcu  žeton  za  dostop  po  uspešni  
avtentikaciji  lastnika  podatkov  in  avtorizaciji  dostopa.  

4.1.2. Potek  avtorizacije  


 
Slika  4.1  prikazuje  potek  OAuth  avtorizacije  in  interakcije  med  štirimi  vlogami:  
a) odjemalec   zaprosi   za   avtorizacijo   s   strani   lastnika   podatkov.   Zahteva   se   lahko  
izvede   neposredno   z   lastnikom   podatkov,   zaželjeno   pa   je,   da   se   avtorizacija  
izvede  preko  avtorizacijskega  strežnika,  
b) odjemalec   prejme   potrditev   avtorizacije,   ki   predstavlja   avtorizacijo   s   strani  
lastnika  podatkov.  Tip  potrditve  zavisi  na  metodi,  ki  je  bila  uporabljena  s  strani  
odjemalca  in  je  podprta  s  strani  avtorizacijskega  strežnika,  
c) odjemalec   zahteva   žeton   za   dostop   s   tem,   da   izvede   avtentikacijo   z  
avtorizacijskim   strežnikom   z   uporabo   podatkov   odjemalca   (le   ti   so   bili  
pridobljeni   vnaprej)   in   hkrati   predloži   potrditev   avtorizacije   s   strani   lastnika  
podatkov,  
d) avtorizacijski   strežnik   ugotovi   istovetnost   odjemalčevih   podatkov   in   potrditve  
avtorizacije  ter  v  primeru,  da  so  le-­‐ti  veljavni,  izda  žeton  za  dostop,  
e) odjemalec  zahteva  zaščitene  podatke  od  podatkovnega  strežnika  in  se  predstavi  z  
žetonom  za  dostop,  

18    
f) podatkovni  strežnik  preveri  istovetnost  žetona  za  dostop  in  v  primeru,  da  je  le-­‐ta  
veljaven,  dovoli  dostop  do  podakov.  
   

(a)   avtorizacijska  zahteva   lastnik  

(b)   potrditev  avtorizacije   podatkov  

potrditev  avtorizacije  
(c)   avtorizacijski  
odjemalec   in  podatki  odjemalca  
(d)   žeton  za  dostop  
strežnik  

(e)   žeton  za  dostop   podatkovni  


(f)   zaščiteni  podatki   strežnik  

Slika  4.1  -­‐  prikaz  poteka  OAuth  avtorizacije  

  19  
4.1.3. Različice  
Protokol  OAuth  je  specifikacija,  ki  jo  razvija  IETF  (Internet  Engineering  Task  Force)  [20]  
(v   okviru   Internet   Society  [21]).   Specifikacija   še   ni   dokončna,   v   času   pisanja   tega   dela   se  
nahaja   v   13.   verziji  [19]   (izdani   16   februarja   2011).   Tudi   zato   se   izvedenke,   ki   se  
pojavljajo   v   uporabi,   med   seboj   razlikujejo.   Izvedenki,   ki   ju   uporabljata   Google   in  
Facebook,  temeljita  na  10.  verziji  specifikacije.  Obe  izvedbi  imata  dobro  dokumentacijo,  
pri  Google  izvedbi  pa  je  na  razpolago  obširen  API,  kar  zelo  poenostavi  izvedbo.  Facebook  
je   prenehal   s   podporo   svojemu   Java   APIju   maja   2008,   zaradi   tega   smo   OAuth  
avtentikacijo  morali  izvesti  sami.    

4.1.4. Primer  izvedbe:  Facebook  


Avtorizacijski  postopek  pričnemo  tako,  da  uporabnika  preusmerimo  na  naslov  [22]:  
 
Če  
https://www.facebook.com/dialog/oauth?client_id=154494971275090
&redirect_uri=http://symple-sync.appspot.com/facebookCallback podrob
&scope=email,offline_access,friends_birthday no  
analizir
amo  povezavo,  vidimo,  da  je  sestavljena  iz  več  delov:  
• začetni   del   https://www.facebook.com/dialog/oauth   je   naslov   avtorizacijskega  
strežnika,  
• del  za  vprašajem  je  zahteva,  v  kateri  so  zapisani  podatki  o  odjemalcu:  
o  identifikacijska  številka  aplikacije:  client_id=154494971275090,  
o povratna  povezava:  redirect_uri=http://symple-
sync.appspot.com/facebookCallback   je   naslov,   na   katerega   Facebook  
preusmeri  uporabnika  po  uspešni  avtentikaciji  in  avtorizaciji,  
o scope=email,offline_access,friends_birthday   opisuje   pravice   [23],   ki   jih  

želimo  pridobiti  z  avtorizacijo:  


§ email:  pravica  branja  uporabnikovega  e-­‐poštnega  naslova,  

§ offline_access:  pravica  do  dostopa  do  podatkov  tudi  ko  uporabnik  ni  

vpisan  v  Facebook,  
§ friends_birthday:   pravica   do   dostopa   do   datumov   rojstnih   dni  
prijateljev.  
   

20    
Naslednji   korak   je,   da   Facebook   preusmeri   uporabnika   na   naslov,   ki   je   bil   podan   v  
zahtevi.  V  primeru,  da  je  uporabnik  zahtevo  potrdil,  na  konec  naslova  doda  še  zahtevo,  ki  
se   glasi   ?code=KODA_GENERIRANA_NA_STREŽNIKU.     Če   uporabnik   zahteve   ne   potrdi,   se  
odgovor   konča   z    
?error_reason=user_denied&error=access_denied&error_description=The+user+de
nied+your+request, v  tem  primeru  se  postopek  zaključi  neuspešno.  
 
Kodo,   ki   nam   jo   strežnik   vrne,   v   primeru   potrditve   avtorizacije   s   strani   uporabnika,  
uporabimo  v  zahtevi  naslovljeni  na:  
https://graph.facebook.com/oauth/access_token?client_id=154494971275090&red
irect_uri= http://symple-sync.appspot.com/facebookCallback
&client_secret=SKRIVNA_KODA&code=KODA_GENERIRANA_NA_STREŽNIKU
 
Strežnik   nam   v   primeru,   da   je   naša   SKRIVNA_KODA   pravilna,   vrne   žeton   za   dostop,   v  
primeru  da  je  prišlo  do  napake,  pa  vrne  HTTP  kodo  400  in  odgovor  v  obliki:  
{"error": {"type": "OAuthException", "message": "Error validating
verification code."}}
 
Ko   uspešno   pridobimo   žeton,   nadaljujemo   s   korakoma   E   in   F,   ki   pa   ju   izvedemo  
vsakokrat,  ko  želimo  pridobiti  podatke.  
 
Ker  smo  ob  začetku  avtorizacije  zahtevali  pravico  do  dostopa,  ko  uporabnik  ni  prijavljen,  
naš  žeton  velja  do  preklica  s  strani  uporabnika  ali  do  trenutka,  ko  uporabnik  spremeni  
geslo.   V   nasprotnem   primeru   bi   naš   žeton   prenehal   veljati   po   kratkem   časovnem  
intervalu.    
   

  21  
4.2. Google  Contacts  Data  API  
Z   avtorizacijo   preko   OAuth   smo   pridobili   žeton   za   dostop,   ki   nam   omogoča   dostop   do  
podatkov,   ki   so   na   razpolago   v   spletnem   servisu   Google   Kontakti.   Do   servisa   smo  
dostopali  preko  Google  Contacts  Data  API  [27].  
Vsa   komunikacija   z   Google   servisi   poteka   preko   formata     Atom   (Atom   Syndication  
Format).   Format   Atom   definira   obliko   XML   dokumentov,   ki   se   uporabljajo   kot   viri   v  
komunikaciji   z   različnimi   storitvami.   Ti   dokumenti   imajo   strukturo,   določeno   s  
standardom   RFC   4287  [28],   standard   pa   omogoča   tudi   razširitve,   ki   jih   lahko   servis  
doda.   Zato   se   format   Atom   uporablja   za   strukturiranje   širokega   spektra   podatkov,   od  
novic  na  internetnih  straneh  do  podatkov,  ki  jih  shranjujemo  na  osebnih  računalnikih.  

4.2.1. Predložitev  podatkov  za  dostop  


Za  dostop  do  podatkov  moramo  najprej  izvesti  zadnja  dva  koraka,  opisana  v  protokolu  
OAuth.   Podatkovnemu   strežniku   moramo   predstaviti   naš   žeton   za   dostop   ter  
identifikacijske  podatke  naše  aplikacije.  V  primeru  servisov  Google  imamo  na  razpolago  
dve  možnosti  [29]:  
• algoritem  HMAC-­‐SHA1  [30]  (Hash-­‐based  Message  Authentication  Code  –  Secure  
Hash  Algorithm),  ki  ne  kodira  zahtev,  a  smo  zaradi  tega  primorani  ob  pridobitvi  
žetona   za   dostop   shraniti   tudi   geslo,   ki   je   vezano   nanj.   Sicer   je   osnovna  
nastavitev  tega  bolj  preprosta,  a  je  varnost  nižja  
• algoritem   RSA-­‐SHA1  [31],   pri   katerem   moramo   na   Google   strežnike   najprej  
naložiti   javni   certifikat   (ang.   public   certificate),   ki   smo   ga   za   ta   namen   generirali.  
Pri  tem  je  varnost  višja,  saj  so  vse  zahteve  šifrirane  z  našim  ključem.  
 
Odločili  smo  se,  da  bomo  uporabili  algoritem  RSA-­‐SHA1,  saj  je  tako  varnost  zahtev  višja  
in  je  postopek  pridobivanja  podatkov  varnejši.    
 
Za   predložitev   podatkov   za   dostop   ob   zahtevi   je   treba   inicializirati   in   pripraviti   objekt  
tipa   GoogleOAuthParameters,   ki   vsebuje   podatke   o   odjemalcu   ter   dostopne   podatke,   v  
primeru   uporabe   algoritma   RSA-­‐SHA1   pa   tudi   objekt   tipa   OauthRsaSha1Signer,   ki  
omogoča  varno  podpisovanje  zahtev,  ki  se  pošiljajo.  
 
Primer:  

22    
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(“KLJUČ_SERVISA”);
oauthParameters.setOAuthConsumerSecret(“SKRIVNA_KODA_SERVISA”);
oauthParameters.setOAuthToken(“UPORABNIKOV_ŽETON”);
mySigner = new OAuthRsaSha1Signer(ZASEBNI_KLJUČ_SERVISA);

Ti   objekti   se   nato   uporabijo   pri   inicializacji   objekta   ContactsService   kot   parametri,   ki  


omogočijo  kasnejšo  izvedbo  zahtev:  

myService.setOAuthCredentials(oauthParameters, mySigner);
 

4.2.2. Oblikovanje  zahtev  za  pridobitev  podatkov  


Zahteve   za   pridobitev   podatkov   pripravimo   s   pomočjo   objekta   Query,   ki   je   opisan   v  
knjižnici   com.google.gdata.client  [32].   Vsaka   zahteva   mora   vsebovati   naslov   vira,   do  
katerega   želimo   dostop.   V   primeru   Google   Kontaktov   je   to  
https://www.google.com/m8/feeds/contacts/default/full,   ki   prestavlja   splošni   naslov   ne  
glede  na  uporabnika,  v  imenu  katerega  dostopamo  do  vira.  Primer  sestave  zahteve:  

URL feedURL = new URL(


"https://www.google.com/m8/feeds/contacts/default/full");
Query myQuery = new Query(feedURL);
myQuery.setMaxResults(2000);
   
V   primeru   lahko   vidimo,   da   najprej   ustvarimo   objekt  feedURL,   ki   predstavlja   povezavo  
do   vira,   do   katerega   dostopamo.   Zatem   ustvarimo   objekt   myQuery,   ki   predstavlja  
poizvedbo.     Poizvedbi   lahko   nastavimo   mnoge   dodatne   kriterije,   ki   omejujejo   število  
vrnjenih  objektov  (setMaxResults),  ali  pa  zahtevajo  samo  nove  objekte  (setUpdatedMin).  
Na  ta  način  preprečimo  prenos  nepotrebnih  kontaktov.    

4.2.3. Izvedba  zahteve  in  vrnjeni  podatki  


Po  pripravi  zahteve  se  ta  izvede  in  pridobljeni  podatki  se  obdelajo.  Zahteve  izvaja  objekt  
ContactsService,   ki   predstavlja   vmesnik   med   servisom   in   Google   strežniki.   Tega   smo  
predhodno  inicializirali  in  mu  podali  podatke,  potrebne  za  OAuth  avtentikacijo  .    
 
Servis   vrne   podatke   v   objektu   tipa   ContactFeed,   le-­‐ta   pa   predstavlja   zbirko   vseh  
podatkov,  ki  so  bili  zahtevani  in  so  bili  na  razpolago.  Do  kontaktnih  podatkov  v  objektu  
razreda  ContactFeed  se  dostopa  preko  lastnosti    getEntries()  v  obliki  List<ContactEntry>:  

  23  
resultFeed = myService.getFeed(myQuery, ContactFeed.class);
List<ContactEntry> contactList = resultFeed.getEntries();
 
V  nadaljevanju  se  podatki  obdelajo.  Pri  tem  se  preveri  ali  vsi  podatki  sploh  obstajajo,  kar  
je   mogoče   opraviti   z   uporabo   lastnosti   ContactEntry   objekta,   ki   se   začnejo   z   has,   npr.  
hasName(),   hasEmailAddresses()   in   hasBirthday(),   tu   so   navedene   tiste   lastnosti,   ki   so  
uporabljene  v  našem  servisu.  
 

4.2.4. Zapisovanje  podatkov  


Kontaktni   podatki,   zapisani   v   obliki   ContactEntry,   se   obdelajo   in   se   pošljejo   storitvi   z  
zahtevo   za   zapis   kontakta.   To   se   opravi   s   klicem   metode   objekta  
ContactsService.update(ContactEntry).   Klic   ne   bo   uspel   v   primeru,   da   je   bil   med   časom,  
ko  smo  prevzeli  kontakt  in  časom,  ko  je  bila  zahteva  za  zapis  oddana,  ta  spremenjen.  V  
primeru,   da   se   to   dogodi,   bo   servis   odgovoril,   da   je   bila   zahteva   neuspešna   in   bomo  
primorani  kontakt  ponovno  prenesti  in  obdelati.  
 

4.3. Komunikacija  s  socialnim  omrežjem  Facebook  


Ker   je   Facebook   prenehal   s   podporo   svojemu   Java   API   maja   2008,   moramo,   če   želimo  
dostopati  do  podatkov  na  Facebooku  z  jezikom  Java,  uporabiti  kakšno  od  odprtokodnih  
rešitev,   ki   so   na   razpolago.   Tri   med   njimi   so   restFB  [33],   batchFB   in   facebook-­‐java-­‐api.    
restFB   omogoča   preprost   dostop   do   podatkov,   hkrati   pa   je   prilagoditev   programa,   v  
primeru   da   želimo   uporabiti   hitrejši   batchFB,   manjša.   Prav   tako   je   velika   prednost  
knjižnice  restFB,  da  ni  odvisna  od  zunanjih  knjižnic,  zaradi  česar  se  hitreje  naloži  in  je  
programsko  manj  zahtevna.  

4.3.1. Predložitev  OAuth  podatkov  


V   tem   primeru   je   predložitev   dostopnih   podatkov   zelo   preprosta,   saj   je   potrebno  
predložiti  le  žeton  za  dostop,  ki  ga  je  servis  prejel  ob  avtorizaciji.  Ta  preprosta  uporaba  
je   hkrati   tudi   največja   slabost   te   rešitve,   saj   smo   prisiljeni   žeton   skrbno   varovati,   saj  
lahko   z   njim   kdorkoli   dostopa   do   podatkov,   ki   smo   jih   zahtevali.   To   se   razlikuje   od  
sistema,   ki   ga   uporablja   Google,   kjer   mora   storitev   ali   aplikacija   vedno   predložiti   tudi  
svoje  podatke.  
 

24    
Objekt   za   komunikacijo   s   Facebookom   je   tipa   FacebookClient,   ki   ob   inicializaciji   sprejme  
vrednost  žetona  za  dostop  kot  argument:  

FacebookClient facebookClient = new DefaultFacebookClient(ŽETON);

Na  ta  način  smo  identificirali  uporabnika  in  storitev  hkrati.  

4.3.2. Zahteve  in  branje  podatkov  


Za   branje   posameznih   objektov   se   lahko   poslužimo   funkcije  
facebookClient.fetchObject(arg1,   arg2).   Z   njo   izvedemo   zahtevo,   s   katero   pridobimo  
točno  določen  objekt.  Tako  lahko  pridobimo  podatke  o  uporabniku:  

User user = facebookClient.fetchObject("me", User.class);

Objekt  User  je  predefiniran  v  knjižnici  in  predstavlja  dekodirano  obliko  objekta  JSON,  ki  
ga  prejme  knjižnica  kot  odgovor  na  zahtevo.  Objekte  lahko  definiramo  tudi  sami  in  tako  
vežemo  podatke  direktno  na  objekte,  ki  jih  že  uporabljamo.  To  izvedemo  z  označbami,  ki  
predpisujejo,  katera  polja  objekta  odgovarjajo  poljem  v  objektu  JSON.  Označbe  so  oblike:  
@Facebook(“ime_polja”).  

4.3.3. FQL  zahteve  


Pomemben   del   socialnega   omrežja   so   povezave,   ki   jih   ima   uporabnik.   Te   lahko  
predstavljajo   prijatelje,   fotografije,   dogodke   in   drugo.   Za   pridobivanje   podatkov  
prijateljev,   ki   ustrezajo   specifičnim   kriterijem,   je   potrebno   izvesti   FQL   zahtevo.     Zahteve  
se   izvajajo   s   poizvedbami   FQL  [34],   ki   so   primerljive   s   poizvedbami   SQL,   a   v   Facebook  
kontekstu.  V  izvedbah  se  uporabljajo  ukazi  kot  so  SELECT,  FROM  in  WHERE,  ki  so  enaki  
kot   tisti,   ki   se   uporabljajo   v   poizvedbah   SQL.   Razlika   je   v   tem,   da   so   polja,   na   katerih  
poizvedbe   izvajamo,   definirana   vnaprej   s   strani   Facebooka.   Primer   poizvedbe,   ki   vrne  
vse  prijatelje  uporabnika:  

SELECT uid, name, pic_square


FROM user
WHERE uid IN
(SELECT uid2
FROM friend
WHERE uid1 = me())
 
Polja,   ki   so   zapisana   za   zahtevo  SELECT   so   polja,   ki   jih   želimo   pridobiti.   S   FROM   izrazom  
omejimo  poizvedbo  na  določen  tip  objekta,  v  našem  primeru  je  to  uporabnik.    WHERE  pa  

  25  
predstavlja  pogoje,  katerim  morajo  objekti  ustrezati.  V  našem  primeru  želimo,  da  so  to  
User  objekti,  ki  so  povezani  z  našim  uporabnikom.  

4.3.4. Iskanje  
Z   knjižnico   restFB   nam   je   preprosto   omogočeno   tudi   iskanje   po   socialnem   omrežju  
Facebook.   Iskalne   zahteve   sestavimo   in   izvedemo   s   pomočjo   metode   fetchConnection  
(del  objekta  FacebookClient).  Metodi  kot  prva  dva  parametra  podamo  tip  iskanja  in  tip  
izhodnega   objekta,   zatem   pa   lahko   dodamo   poljubno   količino   paramerov,   ki   jih  
sestavimo   z   metodo   Parameter.with(arg1,  arg2).   Primer   takega   iskanja   v   našem   servisu,  
ki  poskuša  poiskati  uporabnika  z  danim  e-­‐poštnim  naslovom:  

facebookUser = fbClient.fetchConnection("search", User.class,


Parameter.with("q", email), Parameter.with("type", "user"));
 
Tu   iščemo   objekt   tipa   User,   kjer   mora   biti   e-­‐poštni   naslov   tega   objekta   enak   zapisu   v  
spremenljivki  email.  
   

26    
5. Baza  podatkov  

5.1. Struktura  
Bazo  podatkov  strukturiramo  na  osnovi  dveh  glavnih  zahtev:  
• shranjevanje  najmanjše  možne  količine  osebnih  podatkov,  ki  še  vedno  omogočajo  
brezhibno  delovanje  storitve,  
• vsebovanje  čim  manjše  količini  vezanih  podatkov,  da  jih  ni  potrebno  nalagati.  
Baza   je   sestavljena   iz   dveh   poglavitnih   objektov.   Struktura   objektov   je   vidna   na   sliki   5.1.  
Poglavitna   objekta   predstavljata   uporabniške   podatke   (UserData)   in   zbirko   kontaktov  
(ContactList).   Primarni   ključ   je   pri   obeh   enak,   vrednost   tega   je   edinstvena  
identifikacijska  številka  uporabnika  iz  sistema  Google  Računov.    

 
Slika  5.1  -­‐  Struktura  baze  podatkov  

Na   objekt   ContactList   smo   vezali   kontaktne   objekte   (GoogleContact),   katerih   primarni  


ključ   je   edinstvena   identifikacijska   alfanumerična   vrednost,   ki   je   definirana   v   servisu  
Google  Kontakti.  
 

  27  
Na  ta  način  smo  omogočili  nalaganje  uporabniških  podatkov,  ne  da  bi  nalagali  tudi  vse  
vezane   kontakte.   Sicer   nam   to   oteži   dostop   do   podatkov,   saj   moramo   vezavo   objektov  
izvesti  sami,  a  s  tem  prihranimo  veliko  časa  in  plačljivih  zmogljivosti.  
 

5.2. Izvedba  baze  podatkov  


Za  izvedbo  baze  podatkov  je  na  rapolago  več  rešitev.  Osnovna  rešitev,  ki  jo  omogoča  GAE  
sam,   je   uporaba   Java   Data   Objects  (JDO)  [24]/Java   Persistence   API  (JPA)  [25]   vmesnikov  
Java,   ki   pa   so   v   GAE   izjemno   togi.   Ker   sta   JDO/JPA   standardna   vmesnika   do   trajno  
hranjenih   podatkov   v   jeziku   Java,   ne   vključujeta   mnogih   zmogljivosti,   ki   nam   jih   GAE  
ponuja.    Zaradi  kompleksne  uporabe  in  nefleksibilnosti  smo  se  odločili  pregledati  druge  
možne  rešitve,  ki  omogočajo  shranjevanje  podatkov  na  trajen  način.  
 
Na  razpolago  imamo  tri  vmesnike,  ki  poenostavljajo  uporabo  storitve  GAE  Datastore,  to  
so   Objectify,   SimpleDS   in   twig-­‐persist.   Medtem   ko   nam   prva   dva   omogočata  
poenostavljeno   shranjevanje   objektov   in   vsebujeta   veliko   funkcij,   ki   nam   lajšajo   delo   z  
storitvijo  GAE  Datastore,  ne  poenostavita  pa  nalaganja  in  shranjevanja  objektov,  saj  smo  
še  vedno  prisiljeni  v  uporabo  ključev,  ki  jih  moramo  sami  kodirati  in  vzdrževati.    
 
V   primeru   vmesnika   twig-­‐persist   so   ključi   abstraktirani,   torej   ni   potrebno   vzdrževati  
zbirke  ključev  in  lahko  objekte  uporabljamo,  kot  vse  ostale  običajne  objekte.  Zaradi  teh  
prednosti  smo  se  odločili,  da  bomo  v  našem  servisu  za  shranjevanje  podaktov  uporabili  
vmesnik  twig-­‐persist.  
   

28    
5.3. Twig-­‐persist  
Twig-­‐persist  [26]   je   vmesnik   za   trajno   shranjevanje   objektov,   zgrajen   z   osnovnimi  
funkcijami  GAE  Datastore  API,  ki  nima  mnogih  omejitev,  ki  so  prisotne  v  JDO/JPA-­‐GAE  
implementaciji  trajnega  shranjevanja.    
 
Twig-­‐persist  omogoča:  
• paralelne  asinhrone  klice,  
• združevanje  večih  poizvedb,  
• modele  Java  objektov,  ki  niso  odvisni  od  datastore  storitve.  

5.3.1. Uporaba  knjižnice    


Za   uporabo   knjižnice   najprej   prilagodimo   tiste   Java   razrede,   ki   jih   želimo   z   njo  
shranjevati.   V   ta   namen   uporabimo   posebne   označbe   (ang.   annotations),   s   katerimi  
določimo  pomen  polj  v  našem  modelu.  Označbe  so  oblike  @Označba.    
 
Pozorni  moramo  biti,  da  je  mogoče  vsa  polja,  ki  jih  uporabljamo,  serializirati  –  pretvoriti  
v   tok   podatkov   (ang.   serialize),   saj   se   vsi   objekti   med   shranjevanjem   pretvorijo   v  
serializirano  obliko.  

5.3.1.1. Primer  uporabe  označb:  ContactList.java  


Za   primer   vzemimo   Java   razred,   poimenovan   ContactList,   ki   predstavlja   spisek  
kontaktov  določenega  uporabnika.    

package com.nemesis.symple_sync.data;

import com.google.code.twig.annotation.*;

public class ContactList implements Serializable {


// Identifikacija uporabnika
@Id
private String userID;
// Spisek uporabnikovih kontaktov
@Activate(2)
@Child
private List<GoogleContact> googleContacts;
// Čas zadnje posodobitve
@Embedded
@Index
private DateTime lastUpdate;

}
 
 

  29  
Najprej  uvozimo  vse  razrede,  ki  opisujejo  uporabljene  označbe.  Ti  razredi  se  nahajajo  v  
knjižnici  com.google.code.twig.annotation.  

V  našem  primeru  imamo  štiri  različne  označbe:  


• @Id:   ključ,   s   katerim   identificiramo   naš   objekt.   Ta   ključ   mora   biti   edinstven   za  

vsak  objekt  našega  razreda,  lahko  pa  se  ponovi  v  drugih  razredih,  
• @Child:  spisek  podrejenih  objektov,  

• @Embedded:   predpis,   da   se   objekt   shrani   v   okviru   matičnega   objekta   in   ne   kot  

posamična  entiteta,  
• @Activate(2):   predpis,   v   katerih   nivojih   naj   se   podrejeni   objekt   aktivira,  
oziroma,  kdaj  naj  se  podrejeni  objekt  naloži  iz  baze  podatkov.  V  našem  primeru  
se  objekt  aktivira  samo,  če  izberemo  aktivacijski  nivo  višji  ali  enak  2.  Na  ta  način  
lahko   prevzamemo   objekte,   ki   imajo   nase   vezane   velike   količine   drugih   objektov,  
ne  da  bi  podrejene  objekte  naložili,  
• @Index:  predpis  indeksiranja  za  polje,  ki  ga  označuje.  

 
Poleg  naštetih  označb  je  potrebno  omeniti  še  označbo @Parent,  ki  predstavlja  nadrejeni  
objekt.   Uporaba   te   označbe   sicer   ni   nujna,   a   si   zaradi   nje   laže   predstavljamo   strukturo  
naših  podatkov.  

5.3.1.2. Shranjevanje  podatkov  


Najprej   je   potrebno   inicializirati   objekt,   ki   predstavlja   podatkovno   hrambo  
(AnnotationDataStore):  

AnnotationObjectDatastore dataStore =
new AnnotationObjectDatastore(false);
 
Konstruktorju  dodamo  parameter  false,  kar  povzroči,  da  podatkovna  hramba  indeksira  
samo  tista  polja,  ki  so  označena  z  označbo  @Index.  Na  ta  način  prihranimo  veliko  količino  
zmogljivosti.  
 
   

30    
Objekte  shranjujemo  ali  prepisujemo  z  ukazoma  

dataStore.store(objekt); // Shranjevanje objekta


dataStore.update(objekt); // Prepisovanje objekta
 

5.3.1.3. Nalaganje  in  iskanje  objetkov  


Objekte  lahko  nalagamo  direktno  s  ključem,  če  je  ta  znan:  

currentData = dataStore.load(UserData.class, userID);

Tu  se  obstoječi  objekt  currentData  tipa  UserData  nadomesti  z  objektom,  ki  se    naloži  iz  
baze  podatkov,  katerega  primarni  ključ  je  enak  vrednosti  userID.  
 
V   veliko   primerih   je   treba   najti   objekte,   ki   ustrezajo   določenim   zahtevam.     Uporabo  
prikazuje  naslednji  primer  iz  servisa:  

int unmatchedContacts = dataStore.find().type(GoogleContact.class)


.ancestor(currentContactList)
.addFilter("matched", FilterOperator.EQUAL, false)
.addFilter("tenativeMatches", FilterOperator.EQUAL, false)
.returnCount().now();
 
Iskalno  zahtevo  lahko  razdelimo  na  pomembnejše  dele:  
• type:  predpisuje,  kakšen  je  razred  objekta,  ki  je  iskan,  
• ancestor:  predpisuje,  kateri  objekt  je  nadrejen  iskanemu  objektu,  v  tem  primeru  
je  to  currentContactList,  
• addFilter:   ta   ukaz   sprejme   tri   parametre,   prvi   predstavlja   polje,   po   katerem  
želimo  iskati  (“matched”),  drugi  predstavlja  tip  operacije,  ki  jo  izvedemo,  tretji  pa  
predstavlja  vrednost,  s  katero  bomo  polje  primerjali,  
• zahtevo   zaključimo   z   zaključnimi   ukazi,   ki   predpisujejo   kaj   nam   iskanje   vrne,   v  
tem  primeru  je  to  število  objektov,  ki  ustrezajo  našemu  iskanju,  kar  je  zahtevano  
z  returnCount(),  z  now()  pa  je  zahtevano,  da  se  podatki  prevzemajo  sinhrono.  
   

  31  
•  

5.3.1.4. Učinkovitost  
Pri  uporabi  twig-­‐persist  in  drugih  implementacij  vmesnikov  s  hrambo  podatkov  v  GAE  
moramo   biti   zelo   pozorni   na   učinkovitost   operacij.   Stremeti   moramo   k   najmanjšemu  
možnemu  številu  klicev  DataStore  APIja,  saj  so  ti  zahtevni  in  počasni.  Prav  tako  moramo  
zaradi   načina   shranjevanja   podatkov   v   bazo   podatkov   v   svoji   aplikaciji   preprečevati  
hkratno   pisanje   v   isto   polje,   saj   v   nasprotnem   primeru   lahko   prihaja   do   neuspešnih  
operacij,  ker  je  bil  DataStore  prisiljen  v  zavrnitev  vpisa  zavoljo  vzdrževanja  konsistence  
podatkov.  
   

32    
6. Izvedba  servisa  
Storitev   je   izvedena   v   jeziku   Java,   s   specifičnimi   rešitvami,   ki   jih   omogoča   Google   App  
Engine.   Storitev   je   zato   sestavljena   iz   mnogih   servlet-­‐ov  [38],   objektov   programskega  
jezika  Java,  ki  omogočajo  odgovarjanje  na  HTTP  zahteve  in  obdelovanje  le-­‐teh.  

6.1. Struktura  servisa  


Servis  je  razdeljen  v  pet  poglavitnih  paketov.  Ti  so  razdeljeni  smiselno,  glede  na  namen  
objetkov,  ki  se  v  njih  nahajajo.  Enega  od  paketov,  data,  smo  že  opisali  v  poglavju  o  bazi  
podatkov.  V  tem  paketu  se  nahajajo  vsi  potrebni  razredi  za  shranjevanje  in  prevzemanje  
podatkov.   Ostali   paketi   vsebujejo   procese,   ki   omogočajo   delovanje   ozadja   in  
uporabniškega  vmesnika  spletne  storitve.  
 

6.1.1. Paketa  uporabniškega  vmesnika  


Uporabniški   vmesnik   je   sestavljen   iz   dveh   paketov,   paket   client   vsebuje   razrede  
uporabniškega   vmesnika,   ki   ga   uporabnik   vidi   v   svojem   brskalniku,   medtem   ko   paket  
server   vsebuje   podporne   razrede,   ki   uporabniškemu   vmesniku   omogočajo   komunikacijo  
s  strežniškim  delom  spletne  storitve.    
 
Struktura   paketov   je   prikazana   na   sliki   6.1.   Glavni   razred   paketa   client  je   Symple_sync,   ki  
skrbi  za  postavitev  uporabniškega  vmesnika.  Ob  obisku  spletne  strani  se  izvede  glavna  
metoda   (onModuleLoad()),   ki   preko   vmesnika   LoginServiceAsync   s   klicem   RPC   zahteva  
preverbo,   ali   je   uporabnik   prijavljen   v   sistem.   Ta   klic   na   strežniku   povzroči   izvajanje  
razreda  LoginServiceImpl,  ki  izvede  preverbo  uporabnika  in  vrne  uporabniške  podatke,  v  
primeru   da   ti   obstajajo,   v   nasprotnem   primeru   vrne   spletni   naslov,   na   katerega   je  
potrebno   napotiti   uporabnika,   da   se   le-­‐ta   lahko   prijavi.   Vrnjeni   podatki   se   v   razredu  
Symple_Sync   obdelajo   in   uporabniku   se   prikaže   primerna   vsebina;   v   primeru  
prijavljenega   uporabnika   je   to   glavna   stran   (metoda   sympleSync()),   v   nasprotnem  
primeru  se  prikaže  stran,  ki  uporabnika  poziva  k  prijavi  (metoda  loadLogin()).  

  33  
 
Slika  6.1  -­‐  Struktura  paketov  client  in  server  

V   primeru   uspešne   prijave   sta   med   podatki,   ki   jih   strežnik   vrne   uporabniškemu  
vmesniku   tudi   podatka   o   veljavnosti   avtorizacij   za   Google   Kontakte   in   Facebook.   Če  
avtorizaciji   nista   veljavni,   vmesnik   uporabniku   prikaže   povezavo,   s   katero   se   prične  
postopek   za   avtorizacijo.   V   primeru,   da   sta   obe   avtorizaciji   veljavni,   vmesnik   prikaže  
zahvalno  sporočilo.  
 
Preostali   del   uporabniškega   vmesnika   je   namenjem   administratorju   in   prikazuje  
uporabnike   in   statistiko   ter   omogoča   brisanje   uporabnikov   ali   uporabniških   podatkov.  
Te  operacije  so  izvedene  s  pomočjo  razreda  AdminServiceImpl.    

6.1.2. Paket  ponavljajočih  se  opravil  


Ime   paketa   ponavljajočih   se   opravil   je   cron.   V   njem   se   nahajajo   vsi   razredi,   ki  
predstavljajo  opravila,  za  katera  zahtevamo,  da  se  ponavljajo  ob  vnaprej  določenih  urah.  
V  našem  servisu  so  to  naslednji  razredi:  
• ContactFetcher:   zažene   opravila   za   pridobivanje   podatkov   o   uporabnikovih  
kontaktih,  
• ContactMatcher:     zažene   opravila   za   povezovanje   uporabnikovih   kontaktov   z  
uporabnikovimi  prijatelji  na  Facebooku,  
• ContactSync:   zažene   opravila   za   sinhronizacijo   podatkov   uporabnikovih  
kontaktov  s  podatki,  razpoložljivimi  na  Facebooku.  

34    
• StatisticsCron:   opravilo   vodi   dnevno   statistiko   o   uporabnikih,   beleži   število  
kontaktov,   število   prijateljev,   število   povezanih   kontaktov   in   število   možnih  
dodatnih  povezav  
 
Z   izjemo   razreda   StatisticsCron   ti   razredi   ne   opravljajo   obdelave   podatkov,   temveč   le  
predpišejo  obdelavo  opravilom  iz  Java  razredov  v  paketu  tasks.    
Primer   takega   delovanja   si   lahko   ogledamo   na   sliki   6.2.   Ponavljajoče   opravilo  
sinhronizacije   (ContactsSync)   postavi   v   čakalno   vrsto   n   opravil   za   polnjenje   čakalne  
vrste  (SyncQueuer),  kjer  n  predstavlja  število  uporabnikov.    

 
Slika  6.2  -­‐  Proces  dodajanja  opravil  za  sinhronizacijo  

Opravilo   za   polnjenje   čakalne   vrste   za   vsak   kontakt,   ki   je   povezan   z   uporabnikovim  


prijateljem   na   Facebooku,   predpiše   opravilo   za   sinhronizacijo   (SyncTask).   Tako   se   ob  
vsaki  sinhronizaciji  ustvari  o  opravil:  
!

! =   !!  
!!!

 
   

  35  
Poenostavljena  izvedba  opravila  razreda  ContactSync  v  izvorni  kodi:  

Iterator<UserData> userData = dataStore.find().type(UserData.class)


.now();
while (userData.hasNext()) {
UserData currentData = userData.next();
if (currentData.isFacebookAuthorizationValid()
&& currentData.isGoogleAuthorizationValid()) {
queue.add(withUrl("/symple_sync/tasks/syncQueuer"
).param("userID", currentData.getUserID()));
currentData.setLastSync();
dataStore.update(currentData);
}
}

Najprej   se   iz   podatkovne   baze   pridobijo   uporabniški   podatki,   s   katerimi   se   doda  


opravilo  za  polnjenje  čakalne  vrste.  Pri  tem  je  zahteva  sestavljena  tako,  da  je  navedena  
povezava,   na   kateri   se   nahaja   opravilo   in   parameter   userID,   ki   predstavlja   edinstveno  
identifikacijsko   število   uporabnika.   Nadaljnje   operacije   so   v   domeni   paketa   opravil   v  
ozadju  (tasks).  

6.1.3. Paket  opravil  v  ozadju  


Paket  opravil  v  ozadju  (tasks)  vsebuje  razrede,  ki  predstavljajo  opravila  in  se  opravljajo  
na  klic  opravil  iz  paketa  cron.    Ti  razredi  so:  
• ContactFetcher:  na  zahtevo  opravila  razreda  cron.ContactFetcher,  pridobi  podatke  
o  uporabnikovih  kontaktih,  
• MatcherQueue:  na  zahtevo  opravila  razreda  cron.ContactMatcher,  napolni  čakalno  
vrsto  z  opravili  razreda  MatcherTask,  z  namenom  povezovanja  kontaktov,  
• MatcherTask:  izvede  povezovanje  kontaktov  in  uporabnikovih  prijateljev,    
• SyncQueuer:  na  zahtevo  opravila  razreda  cron.ContactSync,  napolni  čakalno  vrsto  
sync-­‐queue  z  opravili  razreda  SyncTask,  
• SyncTask:  izvede  sinhronizacijo  podatkov  uporabnikovega  kontakta  s  podatki  na  
Facebooku.  
   

36    
Poenostavljena  izvedba  opravila  razreda  SyncQueuer  v  izvorni  kodi:    

ContactList currentContactList =dataStore


.load(ContactList.class, userID);
List<GoogleContact> matchedContacts =dataStore.find()
.type(GoogleContact.class).ancestor(currentContactList).
addFilter("matched", FilterOperator.EQUAL, true)
.returnAll().now();
for (GoogleContact currentContact : matchedContacts) {
dataStore.activate(currentContact);
cache.put(currentContact.getContactID(), currentContact);
String contactID = currentContact.getKey();
queue.add(withUrl("/symple_sync/tasks/syncTask")
.param("userID", userID)
.param("contactID", contactID));
}
 
Iz   baze   podatkov   se   naloži   spisek   uporabnikovih   kontaktov   (ContactList).   Zatem   se  
izvede   poizvedba,   v   kateri   so   zahtevani   uporabnikovi   kontakti,   ki   smo   jih   povezali   z  
uporabnikovim   prijateljem   na   Facebooku.   Opravilo   obdela   vse   kontakte   in   za   vsakega  
posebej   v   vrsto   sync-­‐queue   vstavi   opravilo   za   sinhronizacijo   (SyncTask),   istočasno   z  
ukazom  cache.put(ključ,  kontakt)  v  dinamični  pomnilnik  shrani  podatke  o  kontaktu.  
 
Opravilo   SyncTask   zamenja   fotografijo   kontakta   s   tisto,   ki   je   na   razpolago   na   Facebooku,  
preveri  se  pravilnost  zapisa  imena  in  priimka  kontakta  ter  v  primeru,  da  je  na  razpolago  
rojstni   datum   na   Facebooku,   le-­‐tega   doda   h   kontaktu   na   Google   Kontaktih,   če   ta   še   ni  
prisoten.  
   

  37  
6.2. Uporabniški  vmesnik  
Uporabniški   vmesnik   je   v   primeru   spletnega   servisa   spletna   stran,   ki   jo   prikažemo   v  
uporabnikovem   brskalniku.   Ker   v   našem   primeru   uporabljamo   v   ozadju   programski  
jezik   Java,   smo   se   odločili   za   uporabo   le-­‐tega   tudi   v   uporabniškem   vmesniku.   Za   to  
imamo   na   razpolago   veliko   število   ogrodij   AJAX   (Asynchronous   JavaScript   And   XML  
[35]),  med  drugimi  GWT  (Google  Web  Toolkit  [36]).  
 
Ogrodja   AJAX   omogočajo   prilagajanje   uporabniškega   vmesnika   brez   ponovnega  
prevzemanja   celotne   spletne   strani   s   strani   uporabnika.   Statični   del   strani   ostaja   enak,  
medtem   ko   se   dinamični   deli   prosto   spreminjajo   in   prilagajajo   trenutnim   podatkom   in  
zahtevam.    

6.2.1. Omejitve  uporabniškega  vmesnika  


Ker   uporabniški   vmesnik   teče   v   okviru   brskalnika,   smo   omejeni   na   uporabo   razredov   in  
metod,   ki   jih   je   mogoče   prevesti   v   AJAX   metode   in   klice.   Vse   procesiranje,   ki   ga   izvajamo  
v   uporabniškem   vmesniku,   mora   biti   izvedeno   z   knjižnicami   ogrodja   GWT,   ki   so   za   to  
predvidene.  Zaradi  tega  je  potrebno  večino  operacij  izvesti  na  strežniku,  ta  omejitev  pa  
prinaša   tudi   prednosti,   praviloma   je   to   hitrejši   odziv   uporabniškega   vmesnika,   ker   se  
operacije  izvajajo  asinhrono  v  ozadju.  

6.2.2. Komunikacija  med  uporabniškim  vmesnikom  in  strežnikom  


Komunikacija   poteka   preko   klicev   RPC   (Remote   Procedure   Call   [37]),   ki   prenašajo  
podatke   med   strežnikom   in   brskalnikom.     Klici   RPC   omogočajo   abstrakcijo  
komunikacijskega  vmesnika  in  tako  zelo  poenostavijo  programiranje,  saj  se  ni  potrebno  
posvečati  vmesnikom,  ki  podatke  prenašajo.  
 
Klice  RPC  delimo  na  dva  tipa:  
• sinhroni:  klicatelj  čaka  na  odgovor  in  medtem  se  izvajanje  na  uporabniški  stani  
ustavi,  
• asinhroni:  klicatelj  v  zahtevi  definira  funkcijo  za  vračilo  podatkov  in  nadaljuje  z  
izvajanjem  na  uporabniški  strani.  
V   ogrodju   GWT   so   mogoči   samo   asinhroni   klici   RPC.   Tako   vmesnik   izvede   klic   RPC   in  
nadaljuje  s  prikazovanjem  že  pridobljenih  podatkov,  medtem  ko  se  na  strežniku  izvaja  
proces   obdelave   podatkov.   Ko   se   proces   zaključi,   strežnik   vrne   rezultat   zahteve  

38    
uporabniškemu   vmesniku,   ki   rezultat   prikaže   uporabniku.   V   tem   času   ima   uporabnik   na  
razpolago  odziven  vmesnik,  kljub  izvajanju  zahteve.  

6.2.3. Oblika  uporabniškega  vmesnika  


Uporabniški  vmesnik  oblikujemo  s  pomočjo  datotek  CSS  (Cascading  Style  Sheet)  na  enak  
način   kot   običajno   statično   spletno   stran.   Razlika   je   predvsem   v   tem,   da   so   objekti  
definirani   v   programskem   jeziku   Java   in   niso   del   statične   strani.   Vsak   objekt   ima   že   v  
osnovi   definirane   oznake,   na   katere   lahko   vežemo   lastnosti   v   datotekah   CSS,   hkrati   pa  
imamo  možnost  objektom  dodati  svoje  lastne  oznake  in  tako  dodatno  prilagoditi  videz  
strani.  

   

  39  
6.3. Optimizacija  servisa  
V   GAE   je   potrebno   plačevati   za   prenos   podatkov,   procesorski   čas   in   shranjevanje  
podatkov.  V  našem  primeru  sta  najbolj  kritična  procesorski  čas  in  prenos  podatkov,  saj  
je   količina   shranjenih   podatkov   na   uporabnika   minimalna.   Sistem   GAE   nam   javlja  
porabo  procesorskega  časa  v  milisekundah,  ki  predstavlja  ekvivalent  računskih  ciklov,  ki  
jih  v  tem  času  opravi  procesor  1,2  GHz  Intel  x86.    
 
Prve  izvedbe  servisa  so  uporabljale  opravilne  vrste  za  vse  procese  tako,  da  se  je  vsak  del  
procesa  razbil  na  najmanjšo  možno  enoto  in  se  izvedel  v  svojem  opravilu.  Tako  se  je  v  
primeru   povezovanja   kontaktov   za   vsak   kontakt   posebej   ustvarilo   po   eno   opravilo.  
Proces   je   bil   zelo   počasen,   hkrati   je   bilo   v   administratorskem   vmesniku   GAE   aplikacije  
videti,   da   servis   zahteva   velike   količine   plačljivih   zmogljivosti   že   v   primeru   enega  
samega  uporabnika.  
Z   uporabo   AppStats  [39]   za   GAE,   smo   ugotovili   kateri   del   procesa   je   najpočasnejši.  
Posnetek   poteka   enega   opravila,   ki   poskuša   povezati   en   kontakt,   lahko   vidimo   na  
sliki  6.3.  Modri  pravokotniki  predstavljajo  čas,  ki  ga  zahteva  porabi  za  izvedbo,  medtem  
ko  rdeči  pravokotniki  predstavljajo  uporabljene  plačljive  zmogljivosti  (procesorski  čas).  
Kot   vidimo   se   proces   v   realnem   času   hitro   izvede,   a   se   pri   tem   porabi   velika   količina  
plačljivih   zmogljivosti.   Prav   tako   vidimo,   da   je   največja   poraba   pri   dostopu   do   baze  
podatkov  (klici  datastore_v3.Get).    

   
Slika  6.3  -­‐  Časovni  in  zmogljivostni  potek  procesa  povezovanja  kontakta  

Rešitev   za   ta   problem   je   seveda   v   tem,   da   do   baze   podatkov   dostopamo   čim   manjkrat,  


oziroma  do  nje  dostopamo  tako,  da  objekte  obdelujemo  v  skupinah  in  ne  posamično.  

40    
 
Opravilo   smo   zato   preuredili   tako,   da   hkrati   povezuje   po   100   kontaktov.   Število  
kontaktov  smo  morali  omejiti,  saj  se  lahko  v  nasprotnem  primeru  dogodi,  da  dosežemo  
omejitev   dolžine   izvajanja   procesa   (10   min).   Dostop   do   baze   podatkov   v   tem   primeru  
zahteva  približno  150%  plačljivih  zmogljivosti,  s  tem  da  smo  obdelali  100  kontaktov  in  
ne   enega,   kar   je   razvidno   iz   slike   6.4.   Slika   predstavlja   potek   opravila   pri   povezovanju  
100   kontaktov,   potrebno   pa   je   poudariti,   da   je   vmesni   del   poteka   zaradi   nazornosti  
izpuščen.   Ponovno   predstavljajo   modri   pravokotniki   realni   čas,   porabljen   za   izvedbo  
opravila,   rdeči   pravokotniki   pa   predstavljajo     porabo   plačljivih   zmogljivosti.   Iz   slike   je  
razvidno,   da   je   dostop   do   podatkov   pri   enem   kontaktu   približno   tako   zahteven   kot   pri  
stotih.    

 
Slika  6.4  -­‐  Časovni  in  zmogljivostni  potek  procesa  povezovanja  kontaktov  (100  kontaktov)  

Podobno   težavo   smo   imeli   pri   sinhronizacijskem   opravilu,   saj   je   dostopalo   do   vsakega  
podatka   posebej   in   tako   uporabljalo   velike   količine   plačljivih   zmogljivosti.   Opravilo   smo  
optimizirali   tako,   da   smo   ob   klicu   opravila   SyncQueuer,   ki   vstavlja   opravila   za  
sinhronizacijo  v  vrsto,  v  dinamični  pomnilnik  vstavili  objekt,  ki  predstavlja  kontakt.  Na  
ta   način   podatek   preberemo   iz   baze   podatkov   le   enkrat,   kasnejši   dostopi   pa   uporabijo  
podatke,   ki   so   shranjeni   v   dinamičnem   pomnilniku.   To   smo   lahko   izvedli   tako,   ker   pri  
sinhronizaciji  kontakta  ne  zapisujemo  nobenih  podatkov  v  bazo.    

  41  
6.4. Analiza  stroškov  
Če   bi   želeli   spletni   servis   tržiti,   bi   morali   najprej   vedeti,   kakšen   je   strošek   le-­‐tega   na  
enega  uporabnika.  Sicer  nam  Google  pri  uporabi  GAE  podaja  brezplačne  kvote,  a  so  te  za  
upravljalca  v  primeru  velike  količine  uporabnikov  zanemarljive.    
 
Trenutno   veljavni   cenik   (uveljavljen   24   februarja   2009  [40])   vsebuje   naslednje   cene  
(vrednosti  v  €  prepračunane  po  tečajni  listi  Banke  Slovenije  dne  29.04.2011  [41])  :  
 
Plačljiva  zmogljivost   Enota   Cena  enote   Brezplačna  kvota  
Odhodni  prenos  podatkov   gigazlog   0,08  €  (0,12  $)   1  GB  /  dan  
Dohodni  prenos  podatkov   gigazlog   0,067  €     1  GB  /  dan  
(0,10  $)  
Procesorski  čas   ura   0,067  €     6,5  ur  /  dan  
(0,10  $)  
Shranjeni  podatki   gigazlog  /  mesec   0,10  €     1  GB  
(0,15  $)  
  Tabela  6.1  -­‐  Cenik  storitev  Google  App  Engine  

Za  preizkus  storitve  smo  pridobili  7  uporabnikov,  katerih  podatki  so  naslednji:  


število   število   število  povezanih   število  možnih  
uporabnik  
kontaktov   prijateljev   kontaktov   povezav  
1   989   471   239   196  
2   245   235   93   43  
3   1073   646   232   315  
4   1014   705   291   286  
5   244   132   58   40  
6   203   485   62   23  
7   390   608   84   96  
povprečje   628   445   162,5   150,5  
Tabela  6.2  -­‐  Podatki  testnih  uporabnikov  storitve  

Naši  uporabniki  imajo  od  200  do  preko  1000  kontaktov  in  od  130  do  700  prijateljev  na  
Facebooku.   Za   izračune   privzamemo,   da   povprečne   vrednosti   naših   uporabnikov  
predstavljajo  povprečnega  uporabnika  in  izračunamo  približen  strošek  na  uporabnika.  

42    
 

6.4.1. Shranjevanje  podatkov  


Poraba   podatkov   s   sedanjimi   uporabniki   in   količino   kontaktov   se   giblje   okrog   0,02   GB  
pri  skupnem  številu  kontaktov  4158.  Povprečna  poraba  podatkov  na  kontakt  je  torej:  
0,02  GB
= 5  kB/kontakt  
4158
Z   upoštevanjem   povprečnega   števila   kontaktov   na   uporabnika   lahko   izračunamo  
zahteve  za  shranjevanje  podatkov  na  uporabnika:  
5×628 = 3167  kB   ≅ 0,003  GB    
Torej  je  mesečni  strošek  na  uporabnika  za  shranjevanje  podatkov:  
0,003×0,1  € = 0,0003  €  

6.4.2. Prenos  podatkov  


Odhodni   in   dohodni   prenos   podatkov   je   odvisen   predvsem   od   količine   povezanih  
kontaktov   in   števila   dnevnih   sinhronizacij.   V   trenutni   izvedbi   servisa   se   sinhronizacija  
izvede   6-­‐krat   dnevno.     Pri   trenutnih   uporabnikih   to   pomeni   sinhronizacijo   1059-­‐ih  
kontaktov,  torej  se  mora  sinhronizacija  dnevno  izvesti  6354-­‐krat.  Če  upoštevamo,  da  je  
trenutni   dnevni   odhodni   prenos   0,09   GB   in   dohodni   dnevni   prenos   0,06   GB,   lahko  
določimo  da  je  približna  cena  prenosa  na  sinhroniziran  kontakt:  
0,09  GB 0,06  GB
×0,08  € +   ×0,067€   ≅ 1,7×10!! €  
6354 6354
Torej  je  približni  mesečni  strošek  na  uporabnika  pri  šestih  dnevnih  sinhronizacijah:  
1,7×10!!  €  ×  162,5  ×  6  ×  30 = 0,0516  €  

6.4.3. Procesorski  čas  


Največ   procesorskega   časa   porabimo   za   povezovanje   kontaktov   in   njihovo  
sinhronizacijo.  Hkrati  je  to  tudi  edina  vrednost,  ki  jo  lahko  direktno  merimo  s  pomočjo  
orodij,   ki   jih   imamo   na   razpolago.   Za   povezovanje   100   kontaktov   se   v   sedanji   izvedbi  
porabi  približno  15  s.  Torej  teoretično  za  en  kontakt  porabimo  150  ms.    
Tu   preverjamo   samo   kontakte,   ki   jih   še   nismo   povezali.   V   našem   primeru   je   povprečje  
nepovezanih   kontaktov   na   uporabnika   cca.   300,   če   to   vrednost   uporabimo   za   izračun  
potrebujemo  za  obdelavo:  
0,150  s  ×  300   = 45  s = 0,0125  h  

  43  
Sinhronizacija   zahteva   v   povprečju   80   ms   na   kontakt   za   sinhronizacijo.   V   povprečju   ima  
uporabnik   162,5   povezanih   kontaktov   in   je   torej   zahtevana   količina   procesorskega   časa,  
pri  šestih  sinhronizacijah  na  dan:  
0,08  s  ×  162,5  ×  6 = 78  s = 0,0216  h  
Skupno  torej  potrebujemo  mesečno  na  uporabnika:  

0,0125  h + 0,0216  h  ×  0,067 ×  30 = 0,0687  €  
h

6.4.4. Skupni  mesečni  strošek  


Mesečno  bomo  torej  na  uporabnika  potrebovali  približno:  
0,0003  € + 0,0516  € + 0,0687€ ≅ 0,123  €    
Mesečni  strošek  pri  različnih  številih  uporabnikov  torej  znaša:  
Število  uporabnikov   Mesečni  strošek   Mesečni  strošek  
pri  upoštevanju    
brezplačne  kvote  
100   12,30  €   0  €  
1000   123,00  €   55,81  €  
10000   1  230,00  €   1133,10  €  
100000   12  300,00  €   11989,55  €  
  Tabela  6.3  -­‐  Projekcija  stroškov  vzdrževanja  storitve  

Če  sedaj  upoštevamo  količino  brezplačno  rapoložljivih  zmogljivosti,  lahko  ugotovimo,  da  


nas   omejuje   predvsem   procesorski   čas,   saj   lahko   z   brezplačno   procesorsko   močjo  
vzdržujemo   približno   190   uporabnikov,   v   primeru   prenosa   podatkov   se   ta   številka  
povzpne   na   1400,   prostora   za   hrambo   podatkov   pa   je   dovolj   za   330   uporabnikov,   če  
zahteve  ostanejo  enake.  

   

44    
7. Zaključek  
V   okviru   spletnega   servisa   smo   izpolnili   vse   zahteve,   ki   so   bile   postavljene   v   okviru  
naloge.  Servis  samostojno  ugotavlja  povezave  med  uporabnikovimi  kontakti  in  prijatelji  
na   Facebooku,   povezane   kontakte   pa   tudi   uspešno   sinhronizira.     Sinhronizirajo   se  
kontaktni   podatki,   do   katerih   je   mogoče   dostopati   v   okviru   Facebooka,   servis   je   izveden  
tako,   da   bo   v   prihodnosti   mogoče   omogočiti   sinhronizacijo   dodatnih   podatkov,   do  
katerih  bi  bil  kasneje  omogočen  dostop.  
 
Ocena   mesečnih   stroškov   na   uporabnika   v   okviru   storitve   kaže,   da   bi   bili   stroški   v  
primeru   javne   dostopnosti   servisa   sprejemljivi   in   bi   bilo   mogoče   storitev   za   veliko  
število   uporabnikov   vzdrževati   z   minimalnimi   stroški.   Prav   tako   bi   bilo   mogoče   v  
primeru   večjega   števila   uporabnikov   optimizirati   algoritem   za   povezovanje   kontaktov,  
kjer   bi   lahko   povezave,   ki   bi   jih   ugotovili,   shranili   v   bazo   in   jih   uporabili   pri   več  
uporabnikih.  
 
Pri   testnih   uporabnikih   in   v   sedanji   izvedbi   spletna   storitev   samostojno   poveže   25%  
uporabnikovih  kontaktov  s  prijatelji  na  Facebooku,  hkrati  pa  najde  možne  povezave  še  
za   20%   kontaktov.   Največje   težave   se   pojavljajo   pri   dostopanju   in   iskanju   podatkov   v  
okviru   Facebooka,   saj   se   vmesniki   za   dostop   do   podatkov   spreminjajo   večkrat   letno,  
praviloma   tako,   da   programska   oprema   brez   sprememb   v   izvorni   kodi   po   spremembi  
preneha   delovati.   Prav   tako   je   problem   v   pridobivanju   podatkov,   saj   so   pravila,   ki   jih  
postavlja   Facebook,   praviloma   nedorečena   in   v   večini   primerov   ne   veljajo   za   vse  
aplikacije.    
 
Spletno   storitev   je   mogoče   izboljšati   z   dodatkom   uporabniškega   vmesnika   za   ročno  
povezovanje  kontaktov.  Izboljšave  so  še  vedno  možne  tudi  na  področju  optimizacije,  kjer  
bi   lahko   z   bolj   agresivnim   shranjevanjem   podatkov   v   dinamični   pomnilnik   prihranili  
dodatna   sredstva   in   servis   tudi   pospešili.   Sinhronizacija,   ki   se   sedaj   izvaja   za   vse  
kontakte   ob   vsakem   klicu,   bi   se   lahko   izvajala   samo   za   spremenjene   kontakte,   prav   tako  
bi  lahko  ustvarili  sistem,  ki  bi  sinhronizacijo  izvajal  odzivno,  t.j.  kot  odziv  na  spremembo  
namesto,   da   se   izvaja   sinhronizacija   ob   določenih   časovnih   terminih.   Izboljšave   bi   bile  
možne   tudi   z   dodajanjem   drugih   spletnih   storitev   v   sinhronizacijo,   vstavljanje   rojstnih  
dni  v  koledar,  sinhronizacija  z  drugimi  socialnimi  omrežji.    

  45  
   

46    
Literatura  
[1]   Matti   Haverila,   What   do   we   want   specifically   from   the   cell   phone?   An   age   related  
study,  Telematics  and  Informatics,  vol.  In  Press,  Corrected  Proof.  
[2]    Jure   Vrščaj,   Razvoj   aplikacij   na   platformi   Google   App   Engine,   Diplomska   naloga,  
2011.  
[3]    Google  Inc.,  Google  Contacts  ,  http://www.google.com/contacts/,  8.  april  2011.  
[4]   Facebook  ,  https://www.facebook.com/,  8.  april  2011.  
[5]   Google   App   Engine   -­‐   Google   Code   ,   http://code.google.com/appengine/,   8.   april  
2011.  
[6]    Daniele   Perito,   Claude   Castelluccia,   Mohamed   Ali   Kaafar,   in   Pere   Manils,   How  
Unique  and  Traceable  are  Usernames?,  1101.5578,  jan.  2011.  
[7]   Birthday   problem   -­‐   Wikipedia,   the   free   encyclopedia   ,  
http://en.wikipedia.org/wiki/Birthday_problem,  9.  april  2011.  
[8]   Statistični   urad   RS   -­‐   Prebivalstvo,   Slovenija,   1.   januar   2010   ,  
http://www.stat.si/novica_prikazi.aspx?id=3088,  9.  april  2011.  
[9]    Inc.,   Maintained   Relationships   on   Facebook   ,  
http://www.facebook.com/note.php?note_id=55257228858&ref=mf,  9.  april  2011.  
[10]    Tim   Lindholm   in   Frank   Yellin,   Java(TM)   Virtual   Machine   Specification,   2.   izd.,  
Prentice  Hall,  1999.  
[11]   Google   App   Engine   Blog:   App   Engine   team   appearances   Winter   2011   ,  
http://googleappengine.blogspot.com/2011/01/app-­‐engine-­‐team-­‐appearances-­‐
winter-­‐2011.html,  9.  april  2011.  
[12]   Choosing   a   Datastore   (Java)   -­‐   Google   App   Engine   -­‐   Google   Code   ,  
http://code.google.com/appengine/docs/java/datastore/hr/,  8.  april  2011.  
[13]    Rod   Johnson,   Expert   one-­‐on-­‐one   J2EE   design   and   development,   Indianapolis     IN:  
Wrox,  2003.  
[14]   Users   Java   API   Overview   -­‐   Google   App   Engine   -­‐   Google   Code   ,  
http://code.google.com/appengine/docs/java/users/overview.html,  9.  april  2011.  
[15]   Memcache   Java   API   Overview   -­‐   Google   App   Engine   -­‐   Google   Code   ,  
http://code.google.com/appengine/docs/java/memcache/overview.html,   8.   april  
2011.  
[16]   The   Java   Community   Process(SM)   Program   -­‐   JSRs:   Java   Specification   Requests   -­‐  
detail  JSR#  107  ,  http://jcp.org/en/jsr/detail?id=107,  9.  april  2011.  
[17]   URL   Fetch   Java   API   Overview   -­‐   Google   App   Engine   -­‐   Google   Code   ,  
http://code.google.com/appengine/docs/java/urlfetch/overview.html,   9.   april  
2011.  
[18]   HTTP/1.1:   Status   Code   Definitions   ,  
http://www.w3.org/Protocols/rfc2616/rfc2616-­‐sec10.html,  8.  april  2011.  
[19]    Network   Working   Group,   draft-­‐ietf-­‐oauth-­‐v2-­‐13   -­‐   The   OAuth   2.0   Authorization  
Protocol  ,  http://tools.ietf.org/html/draft-­‐ietf-­‐oauth-­‐v2-­‐13,  8.  april  2011.  
[20]    IETF,  Internet  Engineering  Task  Force  ,  http://www.ietf.org/,  8.  april  2011.  
[21]   Internet  Society  (ISOC)  ,  http://www.isoc.org/,  9.  april  2011.  
[22]    Facebook,   Authentication   -­‐   Facebook   Developers   ,  
https://developers.facebook.com/docs/authentication/,  8.  april  2011.  
[23]   Permissions   -­‐   Facebook   Developers   ,  
https://developers.facebook.com/docs/authentication/permissions/,  8.  april  2011.  
[24]   Java  Data  Objects  (JDO)  -­‐  Home  ,  http://db.apache.org/jdo/,  14.  april  2011.  

  47  
[25]   The   Java   Persistence   API   -­‐   A   Simpler   Programming   Model   for   Entity   Persistence   ,  
http://www.oracle.com/technetwork/articles/javaee/jpa-­‐137156.html,   14.   april  
2011.  
[26]   twig-­‐persist   -­‐   Object   Datastore   for   Google   App   Engine   -­‐   Google   Project   Hosting   ,  
http://code.google.com/p/twig-­‐persist/,  9.  april  2011.  
[27]   Google   Contacts   Data   API   -­‐   Google   Code   ,   http://code.google.com/apis/contacts/,  
10.  april  2011.  
[28]    Network  Working  Group,  M.  Nottingham,  Ed.,  in  R.  Sayre,  Ed.,  RFC  4287  -­‐  The  Atom  
Syndication  Format  ,  http://tools.ietf.org/html/rfc4287,  8.  april  2011.  
[29]   OAuth  in  the  Google  Data  Protocol  Client  Libraries  -­‐  Google  Data  Protocol  -­‐  Google  
Code  ,  http://code.google.com/apis/gdata/docs/auth/oauth.html,  8.  april  2011.  
[30]    Hugo  Krawczyk,  Ran  Canetti,  in  Mihir  Bellare,  HMAC:  Keyed-­‐Hashing  for  Message  
Authentication  ,  http://tools.ietf.org/html/rfc2104,  3.  maj  2011.  
[31]    A.  Shamir  in  L.  Adleman,  A  method  for  obtaining  digital  signatures  and  public-­‐key  
cryptosystems,  Communications  of  the  ACM,  vol.  21,  1978,  str.  120–126.  
[32]   Developer’s   Guide:   Java   -­‐   Google   Contacts   Data   API   -­‐   Google   Code   ,  
http://code.google.com/apis/contacts/docs/3.0/developers_guide_java.html,   9.  
april  2011.  
[33]   RestFB   -­‐   A   Lightweight   Java   Facebook   Graph   API   and   Old   REST   API   Client   ,  
http://restfb.com/,  13.  april  2011.  
[34]   Facebook   Query   Language   (FQL)   -­‐   Facebook   Developers   ,  
http://developers.facebook.com/docs/reference/fql/,  13.  april  2011.  
[35]   Java   Ajax   Frameworks   -­‐   Ajax   Patterns   ,  
http://ajaxpatterns.org/Java_Ajax_Frameworks,  1.  maj  2011.  
[36]   Google   Web   Toolkit   -­‐   Google   Code   ,   http://code.google.com/webtoolkit/,   1.   maj  
2011.  
[37]    Robert   Thurlow,   RPC:   Remote   Procedure   Call   Protocol   Specification   Version   2   ,  
http://tools.ietf.org/html/rfc5531,  1.  maj  2011.  
[38]    Rajiv  Mordani,  Sun  Microsystems  Inc.  Java  Transaction  API  (JTA),  dec.  2009.  
[39]   Appstats   for   Java   -­‐   Google   App   Engine   -­‐   Google   Code   ,  
http://code.google.com/appengine/docs/java/tools/appstats.html,  1.  maj  2011.  
[40]   Google   App   Engine   Blog:   New!   Grow   your   app   beyond   the   free   quotas!   ,  
http://googleappengine.blogspot.com/2009/02/new-­‐grow-­‐your-­‐app-­‐beyond-­‐free-­‐
quotas.html,  1.  maj  2011.  
[41]   Tečajnica   Banke   Slovenije   -­‐   referenčni   tečaji   ECB   -­‐   Banka   Slovenije   ,  
http://www.bsi.si/podatki/tec-­‐bs.asp,  1.  maj  2011.  
 
   

48    
 
   

  49  
   

50    
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Izjava  
 
Izjavljam,  da  sem  diplomsko  delo  izdelal  samostojno  pod  vodstvom  mentorja  doc.  dr.  
Boštjana  Murovca,  univ.  dipl.  inž.  el.  Izkazano  pomoč  drugih  sodelavcev  sem  v  celoti  
navedel  v  zahvali.    
 
 
Matjaž  Pečan  
 

  51  

You might also like