Akamai is well known CDN(content delivery network) provider. It provides content delivery features that are very widely used across popular websites. Besides CDN, Akamai provides additional features, but not everyone is aware of them. One of them is providing GeoIp data. In brief, how it works:
- Akamai maintains database of IP addresses
- When user requests your website under Akamai, Akamai is able to parse IP address of request on the fly and add information about user’s geographic location, network, connection speed, etc. to request header.
- You get X-Akamai-Edgescape request header on your server that contains a lot of information that could be used. E.g.: X-Akamai-Edgescape: georegion=263,country_code=US,region_code=MA,city=CAMBRIDGE,dma=50 6,pmsa=1120,areacode=617,county=MIDDLESEX,fips=25017,lat=42.3933,l ong=-71.1333,timezone=EST,zip=02138-02142+02238-02239,continent=NA ,throughput=vhigh,asnum=21399
- You are able parse this header and get more information about your visitor to show him relevant information on website
If you choose Akamai then you are able to find article that describes how to do it. That solution works properly for Sitecore 6.6 - 7.2, but doesn’t work on Sitecore 8+. Since some time Sitecore moved parsing GeoIp headers to separate thread:
if (orCreate.GeoIpResolveState == GeoIpResolveState.Unresolved) { GeoIpManager.StartResolvingThread(orCreate); }
That thread doesn’t know nothing about your context, that is why call of HttpContext.Current.Request.Headers["X-Akamai-Edgescape"] causes “Object reference not set to an instance of an object” exception. It means that only overriding of LookupManager will not work. I have managed to transfer data from Akamai header to Sitecore analytics context in next way:
- Disable Sitecore.Analytics.Pipelines.CommitSession.UpdateGeoIpData, Sitecore.Analytics.Pipelines.CreateVisits.UpdateGeoIpData and Sitecore.Analytics.Pipelines.EnsureClassification.UpdateGeoIpData processors
- Override Sitecore.Analytics.Pipelines.StartTracking.UpdateGeoIpData processor
using Foundation.Akamai.GeoIp; namespace Foundation.Akamai.Pipelines { public class UpdateGeoIpData { public void Process(object args) { var whois = new LookupProvider().GetInformationByIp(""); if(whois!=null) { Sitecore.Analytics.Tracker.Current.Interaction.SetGeoData(whois); } } } }
This approach works, because parsing header is quick operation that doesn’t need running separate thread. As I understand four UpdateGeoIpData processors in different pipelines were required to sync thread that get GeoIp information with main HttpRequest thread.
To get more details you can review my repository on GitHub or download package and try it by yourself.
No comments:
Post a Comment