Google Spreadsheet API vanuit de Google AppEngine

 
18 juni 2010

Ik was bezig met een demo applicatie aan het schrijven voor de Google AppEngine. Om de applicatie wat interessanter te maken bedacht ik ook een export mogelijkheid om de gegevens uit de applicatie te exporteren naar Google Spreadsheets.
Dit is moeilijker dan men in eerste instantie zou denken.

Authenticatie
De eerste stap wat mij al voor een klein probleem zorgde wat de authenticatie die in Google Docs gebouwd zit. De techniek werkt wel mooi maar niet alles is te lezen in de documentatie.
Het voorbeeld op de website toont deze code:

String requestUrl = AuthSubUtil.getRequestUrl(
	"http://www.coolspreadsheetssite.com/welcome",
	"https://spreadsheets.google.com/feeds",
	false,
	true);

Pas later na een hoop zoeken en vloeken is dat de Google Spreadsheets API twee verschillende URL’s gebruikt. Voor deze URL’s zijn rechten nodig. Tevens staat in de API wel vermeld dat men met deze code gewoon meerdere URL’s kan meegeven om op de authenticeren.
Hoe was niet vermeld.
Na lang verschillende pogingen te hebben ondernomen bleek het volgende te werken:

String requestUrl = AuthSubUtil.getRequestUrl(
	request.getRequestURL().toString(),
	"http://spreadsheets.google.com/feeds/spreadsheets/private/full "
	+ "http://spreadsheets.google.com/feeds", false, true);

Oftewel: men moet het scheiden met een spatie.

De API
Zoals ik hierboven al vermeldde moet ik geauthenticeerd zijn op twee verschillende URL’s. Dit komt omdat ik gebruik maak van de API om een specifieke spreadsheet te zoeken met een specifieke naam. Wanneer ik die vind dan open ik deze en vul hem met de gegevens d.m.v. Spreadsheet ListEntry API. Deze blijkt een andere URL te gebruiken.
Dit wordt wel uitgelegd maar in een ander document.
De API document voor Java is wat ik doorlees om deze interface te kunnen benutten. Echter: vele details staan in de low-level protocol beschrijving.
Maar uiteindelijk is dat ook opgelost.

De AppEngine limitaties
Het volgende struikelblok komt door het gebruik van de Google AppEngine (ookwel GAE). Elke web request in de AppEngine mag niet langer duren dan 30 seconden. Na 30 seconden word de request simpelweg afgebroken.
Toen ik mijn export dus af had en alles wekte naar behoren had ik al in mijn achterhoofd dat dit niet zou werken met grote hoeveelheden.
Om te kijken of dit een probleem zou worden heb ik, met behulp van JMeter, ongeveer 1000 entiteiten in de applicatie gezet om te kunnen exporteren.
Lokaal in de bleek alles goed te gaan omdat de ontwikkeltools van de AppEngine deze 30 seconden limiet niet uitvoert, maar ik zag dat ik er duidelijk over heen ging. Mijn applicatie was ongeveer een minuut bezig om alles te exporteren. Dat gaat dus niet werken.

Andere aanpak
De Google AppEngine heeft in de 1.3 series de Task API toegevoegd. Dit maakt het mogelijk om een taak in de achter grond te laten uitvoeren. Nou blijkt dat de taken gewoon servlets die ook de 30 seconden limiet hebben. Dus één taak maken die alles exporteerd op de achtergrond gaat ook niet werken.
Uiteindelijk heb ik er maar voor gekozen om een servlet te schrijven die de opdracht voor exporteren start door voor elk object een losse taak in de queue te zetten. Elke taak wordt dus opgestart met een id van een object en een security token voor toegang tot de Google Spreadsheets API. Vervolgens exporteert de taak zijn ene object naar de spreadsheet en stopt. Het process zou eventueel geoptimaliseerd kunnen worden door meerdere object te exporteren per taak, men zou dan eerst moeten kijken hoeveel er ongeveer binnen 30 seconden geëxporteerd kunnen worden.

Omslachtig maar het werkt.


Werken met ?
Kijk dan bij onze mogelijkheden voor starters en/of ervaren IT'ers.


Categorieën: Development, Deployment, Java (EE)

Tags: , , , , , , , , ,