Пример #1
0
        public async Task <ActionResult> Benchmarks()
        {
            var cache   = new CacheProviderMongoDB();
            var results = await cache.PerformPOIQueryBenchmark(10, "bounding");

            return(View(results));
        }
Пример #2
0
        public ActionResult Benchmarks()
        {
            CacheProviderMongoDB cache = new CacheProviderMongoDB();
            var results = cache.PerformPOIQueryBenchmark(10, "distance");

            return(View(results));
        }
Пример #3
0
        public async Task <JsonResult> RefreshPOIMirror(string mode)
        {
            MirrorStatus status = new MirrorStatus();

            if (HttpContext.Application["_MirrorRefreshInProgress"] == null || (bool)HttpContext.Application["_MirrorRefreshInProgress"] == false)
            {
                HttpContext.Application["_MirrorRefreshInProgress"] = true;
                var mirrorManager = new CacheProviderMongoDB();

                try
                {
                    if (mode == "repeat")
                    {
                        status = await mirrorManager.PopulatePOIMirror(CacheProviderMongoDB.CacheUpdateStrategy.Incremental);

                        while (status.NumPOILastUpdated > 0)
                        {
                            System.Diagnostics.Debug.WriteLine("Mirror Update:" + status.LastUpdated + " updated, " + status.TotalPOI + " total");
                            status = await mirrorManager.PopulatePOIMirror(CacheProviderMongoDB.CacheUpdateStrategy.Incremental);
                        }
                    }
                    else
                    if (mode == "all")
                    {
                        status = await mirrorManager.PopulatePOIMirror(CacheProviderMongoDB.CacheUpdateStrategy.All);
                    }
                    else
                    {
                        status = await mirrorManager.PopulatePOIMirror(CacheProviderMongoDB.CacheUpdateStrategy.Modified);
                    }
                }
                catch (Exception exp)
                {
                    status.TotalPOI    = 0;
                    status.Description = "Cache update error:" + exp.ToString();
                    status.StatusCode  = System.Net.HttpStatusCode.InternalServerError;
                }

                HttpContext.Application["_MirrorRefreshInProgress"] = false;
            }
            else
            {
                status.StatusCode  = System.Net.HttpStatusCode.PartialContent;
                status.Description = "Update currently in progress";
            }

            return(Json(status, JsonRequestBehavior.AllowGet));
        }
Пример #4
0
        public ActionResult CheckPOIMirrorStatus()
        {
            var mirrorManager = new CacheProviderMongoDB();
            var status        = mirrorManager.GetMirrorStatus();

            if (status == null)
            {
                status             = new MirrorStatus();
                status.StatusCode  = System.Net.HttpStatusCode.NotFound;
                status.Description = "Cache is offline";
            }
            else
            {
                if (HttpContext.Application["_MirrorRefreshInProgress"] != null && (bool)HttpContext.Application["_MirrorRefreshInProgress"] == true)
                {
                    status.Description += " (Update in progress)";
                }
            }
            return(View(status));
        }
Пример #5
0
 public ActionResult Benchmarks()
 {
     CacheProviderMongoDB cache = new CacheProviderMongoDB();
     var results = cache.PerformPOIQueryBenchmark(10, "distance");
     return View(results);
 }
Пример #6
0
        /// <summary>
        /// For given query/output settings, return list of charge points. May be a cached response.
        /// </summary>
        /// <param name="settings"></param>
        /// <returns></returns>
        public List<Model.ChargePoint> GetChargePoints(APIRequestParams settings)
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            bool cachingConfigEnabled = bool.Parse(System.Configuration.ConfigurationManager.AppSettings["EnableInMemoryCaching"]);
            if (cachingConfigEnabled == false) settings.EnableCaching = false;

            string cacheKey = settings.HashKey;
            List<Model.ChargePoint> dataList = null;

            if ((HttpContext.Current != null && HttpContext.Current.Cache[cacheKey] == null) || settings.EnableCaching == false)
            {
                bool enableNoSQLCaching = bool.Parse(System.Configuration.ConfigurationManager.AppSettings["EnableNoSQLCaching"]);
                if (enableNoSQLCaching && settings.AllowMirrorDB)
                {
                    try
                    {
                        dataList = new CacheProviderMongoDB().GetPOIList(settings);
                    }
                    catch (Exception exp)
                    {
                        //failed to query mirror db, will now fallback to sql server if dataList is null
                        //TODO: send error notification
                        if (HttpContext.Current != null) AuditLogManager.ReportWebException(HttpContext.Current.Server, AuditEventType.SystemErrorAPI, "POI Cache query exception:"+exp.ToString());
                    }
                }

                //if dataList is null we didn't get any cache DB results, use SQL DB
                if (dataList == null)
                {
                    int maxResults = settings.MaxResults;
                    this.LoadUserComments = settings.IncludeComments;
                    bool requiresDistance = false;

                    if (settings.Latitude != null && settings.Longitude != null)
                    {
                        requiresDistance = true;
                        //maxResults = 10000; //TODO find way to prefilter on distance.
                    }

                    dataList = new List<Model.ChargePoint>();
                    var dataModel = new OCMEntities();
                    dataModel.Configuration.LazyLoadingEnabled = true;
                    dataModel.Configuration.AutoDetectChangesEnabled = false;
                    ((IObjectContextAdapter)dataModel).ObjectContext.CommandTimeout = 180; //allow longer time for query to complete

                    //if distance filter provided in miles, convert to KM before use
                    if (settings.DistanceUnit == Model.DistanceUnit.Miles && settings.Distance != null)
                    {
                        settings.Distance = GeoManager.ConvertMilesToKM((double)settings.Distance);
                    }

                    bool filterByConnectionTypes = false;
                    bool filterByLevels = false;
                    bool filterByOperators = false;
                    bool filterByCountries = false;
                    bool filterByUsage = false;
                    bool filterByStatus = false;
                    bool filterByDataProvider = false;
                    bool filterByChargePoints = false;

                    if (settings.ConnectionTypeIDs != null) { filterByConnectionTypes = true; }
                    else { settings.ConnectionTypeIDs = new int[] { -1 }; }

                    if (settings.LevelIDs != null) { filterByLevels = true; }
                    else { settings.LevelIDs = new int[] { -1 }; }

                    if (settings.OperatorIDs != null) { filterByOperators = true; }
                    else { settings.OperatorIDs = new int[] { -1 }; }

                    if (settings.ChargePointIDs != null) { filterByChargePoints = true; }
                    else { settings.ChargePointIDs = new int[] { -1 }; }

                    //either filter by named country code or by country id list
                    if (settings.CountryCode != null)
                    {
                        var filterCountry = dataModel.Countries.FirstOrDefault(c => c.ISOCode.ToUpper() == settings.CountryCode.ToUpper());
                        if (filterCountry != null)
                        {
                            filterByCountries = true;
                            settings.CountryIDs = new int[] { filterCountry.ID };
                        }
                        else
                        {
                            filterByCountries = false;
                            settings.CountryIDs = new int[] { -1 };
                        }
                    }
                    else
                    {
                        if (settings.CountryIDs != null && settings.CountryIDs.Any()) { filterByCountries = true; }
                        else { settings.CountryIDs = new int[] { -1 }; }
                    }

                    if (settings.UsageTypeIDs != null) { filterByUsage = true; }
                    else { settings.UsageTypeIDs = new int[] { -1 }; }

                    if (settings.StatusTypeIDs != null) { filterByStatus = true; }
                    else { settings.StatusTypeIDs = new int[] { -1 }; }

                    if (settings.DataProviderIDs != null) { filterByDataProvider = true; }
                    else { settings.DataProviderIDs = new int[] { -1 }; }

                    if (settings.SubmissionStatusTypeID == -1) settings.SubmissionStatusTypeID = null;

                    //compile initial list of locations
                    var chargePointList = from c in dataModel.ChargePoints.AsNoTracking()
                                          where
                                              (c.AddressInfo != null && c.AddressInfo.Latitude != null && c.AddressInfo.Longitude != null && c.AddressInfo.CountryID != null)
                                              && ((settings.SubmissionStatusTypeID == null && (c.SubmissionStatusTypeID == null || c.SubmissionStatusTypeID == (int)StandardSubmissionStatusTypes.Imported_Published || c.SubmissionStatusTypeID == (int)StandardSubmissionStatusTypes.Submitted_Published))
                                                    || (settings.SubmissionStatusTypeID == 0) //return all regardless of status
                                                    || (settings.SubmissionStatusTypeID != null && c.SubmissionStatusTypeID == settings.SubmissionStatusTypeID)
                                                    ) //by default return live cps only, otherwise use specific submission statusid
                                              && (c.SubmissionStatusTypeID != (int)StandardSubmissionStatusTypes.Delisted_NotPublicInformation)
                                              && (settings.OperatorName == null || c.Operator.Title == settings.OperatorName)
                                              && (settings.IsOpenData == null || (settings.IsOpenData != null && ((settings.IsOpenData == true && c.DataProvider.IsOpenDataLicensed == true) || (settings.IsOpenData == false && c.DataProvider.IsOpenDataLicensed != true))))
                                              && (settings.DataProviderName == null || c.DataProvider.Title == settings.DataProviderName)
                                              && (settings.LocationTitle == null || c.AddressInfo.Title.Contains(settings.LocationTitle))
                                              && (filterByCountries == false || (filterByCountries == true && settings.CountryIDs.Contains((int)c.AddressInfo.CountryID)))
                                              && (filterByOperators == false || (filterByOperators == true && settings.OperatorIDs.Contains((int)c.OperatorID)))
                                              && (filterByChargePoints == false || (filterByChargePoints == true && settings.ChargePointIDs.Contains((int)c.ID)))
                                              && (filterByUsage == false || (filterByUsage == true && settings.UsageTypeIDs.Contains((int)c.UsageTypeID)))
                                              && (filterByStatus == false || (filterByStatus == true && settings.StatusTypeIDs.Contains((int)c.StatusTypeID)))
                                              && (filterByDataProvider == false || (filterByDataProvider == true && settings.DataProviderIDs.Contains((int)c.DataProviderID)))
                                          select c;
                    if (settings.ChangesFromDate != null)
                    {
                        chargePointList = chargePointList.Where(c => c.DateLastStatusUpdate >= settings.ChangesFromDate.Value);
                    }

                    if (settings.CreatedFromDate != null)
                    {
                        chargePointList = chargePointList.Where(c => c.DateCreated >= settings.CreatedFromDate.Value);
                    }

                    //apply connectionInfo filters, all filters must match a distinct connection within the charge point, rather than any filter matching any connectioninfo
                    chargePointList = from c in chargePointList
                                      where
                                      c.Connections.Any(conn =>
                                            (settings.ConnectionType == null || (settings.ConnectionType != null && conn.ConnectionType.Title == settings.ConnectionType))
                                            && (settings.MinPowerKW == null || (settings.MinPowerKW != null && conn.PowerKW >= settings.MinPowerKW))
                                            && (filterByConnectionTypes == false || (filterByConnectionTypes == true && settings.ConnectionTypeIDs.Contains(conn.ConnectionType.ID)))
                                            && (filterByLevels == false || (filterByLevels == true && settings.LevelIDs.Contains((int)conn.ChargerType.ID)))
                                             )
                                      select c;

                    System.Data.Entity.Spatial.DbGeography searchPos = null;

                    if (requiresDistance && settings.Latitude != null && settings.Longitude != null) searchPos = System.Data.Entity.Spatial.DbGeography.PointFromText("POINT(" + settings.Longitude + " " + settings.Latitude + ")", 4326);

                    //compute/filter by distance (if required)
                    var filteredList = from c in chargePointList
                                       where
                                       (requiresDistance == false)
                                       ||
                                       (
                                           (requiresDistance == true
                                               && (c.AddressInfo.Latitude != null && c.AddressInfo.Longitude != null)
                                               && (settings.Latitude != null && settings.Longitude != null)
                                               && (settings.Distance == null ||
                                                        (settings.Distance != null &&
                                           // GetDistanceFromLatLonKM(settings.Latitude, settings.Longitude, c.AddressInfo.Latitude, c.AddressInfo.Longitude) <= settings.Distance
                                                           c.AddressInfo.SpatialPosition.Distance(searchPos) / 1000 < settings.Distance
                                                        )
                                               )
                                           )
                                       )
                                       select new
                                       {
                                           c,
                                           //    DistanceKM = GetDistanceFromLatLonKM(settings.Latitude, settings.Longitude, c.AddressInfo.Latitude, c.AddressInfo.Longitude)
                                           DistanceKM = c.AddressInfo.SpatialPosition.Distance(searchPos) / 1000
                                       };

                    if (requiresDistance)
                    {
                        //if distance was a required output, sort results by distance
                        filteredList = filteredList.OrderBy(d => d.DistanceKM).Take(settings.MaxResults);
                    }
                    else
                    {
                        filteredList = filteredList.OrderByDescending(p => p.c.DateCreated);
                    }

                    //query is of type IQueryable
            #if DEBUG
                    string sql = filteredList.ToString();

                    //writes to output window
                    System.Diagnostics.Debug.WriteLine(sql);
            #endif
                    var additionalFilteredList = filteredList.Take(maxResults).ToList();

                    stopwatch.Stop();

                    System.Diagnostics.Debug.WriteLine("Total query time: " + stopwatch.Elapsed.ToString());

                    stopwatch.Restart();

                    foreach (var item in additionalFilteredList) //.ToList
                    {
                        //note: if include comments is enabled, media items and metadata values are also included
                        Model.ChargePoint c = Model.Extensions.ChargePoint.FromDataModel(item.c, settings.IncludeComments, settings.IncludeComments, settings.IncludeComments, !settings.IsCompactOutput);

                        if (requiresDistance && c.AddressInfo != null)
                        {
                            c.AddressInfo.Distance = item.DistanceKM;
                            if (settings.DistanceUnit == Model.DistanceUnit.Miles && c.AddressInfo.Distance != null) c.AddressInfo.Distance = GeoManager.ConvertKMToMiles(c.AddressInfo.Distance);
                            c.AddressInfo.DistanceUnit = settings.DistanceUnit;
                        }

                        if (settings.IsLegacyAPICall && !(settings.APIVersion >= 2))
                        {
                            //for legacy callers, produce artificial list of Charger items
            #pragma warning disable 612  //suppress obsolete warning
                            if (c.Chargers == null || c.Chargers.Count == 0)
                            {
                                if (c.Connections != null)
                                {
                                    var chargerList = new List<Common.Model.ChargerInfo>();
                                    foreach (var con in c.Connections)
                                    {
                                        if (con.Level != null)
                                        {
                                            if (!chargerList.Exists(l => l.ChargerType == con.Level))
                                            {
                                                chargerList.Add(new Common.Model.ChargerInfo() { ChargerType = con.Level });
                                            }
                                        }
                                    }
                                    chargerList = chargerList.Distinct().ToList();
                                    c.Chargers = chargerList;
                                }
                            }
                        }

            #pragma warning restore 612

                        if (c != null)
                        {
                            dataList.Add(c);
                        }
                    }

                    //cache results (if caching enabled)
                    if (settings.EnableCaching == true && HttpContext.Current != null)
                    {
                        HttpContext.Current.Cache.Add(cacheKey, dataList, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0), System.Web.Caching.CacheItemPriority.AboveNormal, null);
                    }
                }
            }
            else
            {
                //TODO: pass caching context instead of trying to access HttpContext.Current as not available during async
                if (HttpContext.Current != null)
                {
                    dataList = (List<Model.ChargePoint>)HttpContext.Current.Cache[cacheKey];
                }
            }

            System.Diagnostics.Debug.WriteLine("POI List Conversion to simple data model: " + stopwatch.Elapsed.ToString());

            return dataList.Take(settings.MaxResults).ToList();
        }
Пример #7
0
        public Model.ChargePoint Get(int id, bool includeExtendedInfo, bool allowDiskCache = false, bool allowMirrorDB = false)
        {
            if (allowMirrorDB)
            {
                var p = new CacheProviderMongoDB().GetPOI(id);
                if (p != null)
                {
                    return p;
                }
            }

            try
            {
                var dataModel = new OCMEntities();
                var item = dataModel.ChargePoints.Find(id);

                if (allowDiskCache)
                {
                    var poiCache = GetFromCache(id);
                    if (poiCache != null && poiCache.POI.DateLastStatusUpdate == item.DateLastStatusUpdate)
                    {
                        //found a cached version of POI which is up to date
                        return poiCache.POI;
                    }
                }

                var poi = Model.Extensions.ChargePoint.FromDataModel(item, includeExtendedInfo, includeExtendedInfo, includeExtendedInfo, true);

                if (allowDiskCache && poi != null)
                {
                    //cache results
                    CachePOIDetails(poi);
                }
                return poi;
            }
            catch (Exception)
            {
                //POI not found matching id
                return null;
            }
        }