/// <summary>
        /// Stores a list of OBA client stops in Azure Tables
        /// </summary>
        /// <param name="stops">list of stops</param>
        /// <param name="regionId">uniquely identifies the region that these stops belong to</param>
        /// <returns>task that stores the entities</returns>
        public async Task Insert(IEnumerable <OBAClient.Model.Stop> stops, string regionId)
        {
            // convert the input stops into stop entities
            List <StopEntity> stopEntities = new List <StopEntity>();

            foreach (OBAClient.Model.Stop stop in stops)
            {
                StopEntity stopEntity = new StopEntity
                {
                    Id         = stop.Id,
                    Lat        = stop.Lat,
                    Lon        = stop.Lon,
                    Direction  = stop.Direction,
                    Name       = stop.Name,
                    Code       = stop.Code,
                    RegionId   = regionId,
                    RecordType = RecordType.Stop.ToString(),
                    RowState   = DataRowState.Default.ToString(),
                    RawContent = stop.RawContent,
                };

                stopEntities.Add(stopEntity);
            }

            await this.Insert(stopEntities);
        }
Esempio n. 2
0
        public StopEntity UpdateStop(JObject entity, int id, int duration)
        {
            StopEntity existingStop = GetById(id);
            JToken     value;

            if (entity.TryGetValue("name", StringComparison.OrdinalIgnoreCase, out value) && (value.Type == JTokenType.String))
            {
                existingStop.Name = value.Value <string>();
            }
            if (entity.TryGetValue("departureTime", StringComparison.OrdinalIgnoreCase, out value) && (value.Type == JTokenType.Date))
            {
                existingStop.DepartureTime = value.Value <DateTime>();
            }
            if (entity.TryGetValue("arrivalTime", StringComparison.OrdinalIgnoreCase, out value) && (value.Type == JTokenType.Date))
            {
                existingStop.ArrivalTime = value.Value <DateTime>();
            }
            if (entity.TryGetValue("cityId", StringComparison.OrdinalIgnoreCase, out value) && (value.Type == JTokenType.Integer))
            {
                existingStop.CityId = value.Value <int>();
            }
            existingStop.Duration = duration;

            _context.Stops.Update(existingStop);
            _context.SaveChanges();

            return(existingStop);
        }
        /// <summary>
        /// Get a particular stop from table storage
        /// </summary>
        /// <param name="regionId">region Id</param>
        /// <param name="id">stop Id</param>
        /// <returns>stop entity</returns>
        public StopEntity Get(string regionId, string id)
        {
            StopEntity partialStop = new StopEntity {
                Id = id, RegionId = regionId, RecordType = Enum.GetName(typeof(RecordType), RecordType.Stop)
            };

            var retrievedStops = (from entry in this.Table.CreateQuery <DynamicTableEntity>()
                                  where entry.PartitionKey == partialStop.PartitionKey &&
                                  entry.RowKey == partialStop.RowKey &&
                                  entry.Properties["RecordType"].StringValue == RecordType.Stop.ToString()
                                  select entry).Resolve(AbstractEntityAdapter.AdapterResolver <StopEntity>).ToList();

            // return null if no records were retrieved
            if (retrievedStops == null || retrievedStops.Count == 0)
            {
                return(null);
            }

            // throw an exception if more than 1 record was received
            if (retrievedStops.Count > 1)
            {
                throw new Exception("Expected 1 record but retrieved " + retrievedStops.Count + " records.");
            }

            return(retrievedStops[0]);
        }
 public Stop MapToClass(StopEntity stopEntity)
 {
     return(new Stop(stopEntity.Latitude, stopEntity.Longitude)
     {
         Id = stopEntity.WayPointIndex
     });
 }
Esempio n. 5
0
        /// <summary>
        /// Delete a published stop from Embedded Social.
        /// The way we delete a stop is to simply indicate it as deleted
        /// in the Embedded Social topic title. That way, existing
        /// comments live on, and users who visit the topic will know
        /// that this stop is no longer valid.
        /// </summary>
        /// <param name="stop">stop that no longer exists</param>
        /// <returns>task that deletes the stop</returns>
        public async Task DeleteStop(StopEntity stop)
        {
            // check the input
            this.CheckInputEntity(stop);

            // update the topic title to indicate this has been deleted
            await this.UpdateTopic(this.TopicName(stop), DeletedTopicTitlePrefix + this.TopicTitle(stop), this.TopicText(stop), stop.RegionId);
        }
Esempio n. 6
0
        /// <summary>
        /// Publish an updated stop to Embedded Social
        /// </summary>
        /// <param name="stop">updated stop information</param>
        /// <returns>task that updates the stop</returns>
        public async Task UpdateStop(StopEntity stop)
        {
            // check the input
            this.CheckInputEntity(stop);

            // update the topic
            await this.UpdateTopic(this.TopicName(stop), this.TopicTitle(stop), this.TopicText(stop), stop.RegionId);
        }
Esempio n. 7
0
        /// <summary>
        /// Constructs the topic name for a stop
        /// </summary>
        /// <param name="stop">stop information</param>
        /// <returns>topic name</returns>
        private string TopicName(StopEntity stop)
        {
            string name = "stop_" + stop.RegionId + "_" + stop.Id;

            // Embedded Social's named topics can store only strings that are safe as an Azure Table key.
            name = name.StringToTableKey();

            return(name);
        }
 private WayPointDto MapToDto(StopEntity stopEntity)
 {
     return(new WayPointDto
     {
         Id = stopEntity.WayPointIndex,
         Latitude = stopEntity.Latitude,
         Longtude = stopEntity.Longitude,
     });
 }
        /// <summary>
        /// Updates a stop in Azure Tables
        /// </summary>
        /// <param name="stop">stop</param>
        /// <returns>task that updates the entity</returns>
        public async Task Update(StopEntity stop)
        {
            // note: this is dangerous because StopEntity is actually not a table entity.
            // hence it does not contain an Etag that would be used for concurrency control.
            ITableEntity entity = new EntityAdapter <StopEntity>(stop);

            entity.ETag = "*";
            TableOperation replace = TableOperation.Replace(entity);

            await this.Table.ExecuteAsync(replace);
        }
Esempio n. 10
0
        /// <summary>
        /// Publish a new stop to Embedded Social
        /// </summary>
        /// <param name="stop">new stop information</param>
        /// <returns>task that publishes a new stop and returns the topic name</returns>
        public async Task <string> CreateStop(StopEntity stop)
        {
            // check the input
            this.CheckInputEntity(stop);

            // publish the new topic
            string topicName = this.TopicName(stop);

            await this.CreateTopic(topicName, this.TopicTitle(stop), this.TopicText(stop), stop.RegionId);

            // return the topic name
            return(topicName);
        }
Esempio n. 11
0
        public Stop UpdateStop(JObject item, int id, int duration)
        {
            StopEntity stopEntity = _stopRepository.UpdateStop(item, id, duration);

            if (stopEntity != null)
            {
                return(_stopRepository.GetById(id).ToDomain());
            }
            else
            {
                return(null);
            }
        }
Esempio n. 12
0
        public int Insert(StopEntity entity)
        {
            using var transaction = _context.Database.BeginTransaction();
            try
            {
                _context.Stops.Add(entity);
                _context.SaveChanges();

                transaction.Commit();
                return(entity.StopId);
            }
            catch (Exception e)
            {
                transaction.Rollback();
                return(-1);
            }
        }
        /// <summary>
        /// Creates a stop entity with a random Id and name
        /// </summary>
        /// <param name="regionId">optional region Id; if not specified, one will be created</param>
        /// <returns>stop entity</returns>
        public static StopEntity FakeStopEntity(string regionId = null)
        {
            StopEntity stop = new StopEntity()
            {
                Id        = Guid.NewGuid().ToString(),
                Lat       = 0,
                Lon       = 0,
                Direction = Guid.NewGuid().ToString(),
                Name      = Guid.NewGuid().ToString(),
                Code      = Guid.NewGuid().ToString(),
                RegionId  = regionId == null?Guid.NewGuid().ToString() : regionId,
                                RecordType = RecordType.Stop.ToString(),
                                RowState   = DataRowState.Default.ToString(),
                                RawContent = string.Empty
            };

            return(stop);
        }
Esempio n. 14
0
        /// <summary>
        /// Constructs the topic text for a stop
        /// </summary>
        /// <param name="stop">stop information</param>
        /// <returns>topic text</returns>
        private string TopicText(StopEntity stop)
        {
            // in the common case, the topic text will be:
            //      Discuss the stop at Name (Direction)
            string text = string.Empty;

            if (!string.IsNullOrWhiteSpace(stop.Name))
            {
                text += "Discuss the stop at " + stop.Name;
            }

            if (!string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(stop.Direction))
            {
                text += " (" + stop.Direction + ")";
            }

            return(TopicUtils.RemoveHashtags(text));
        }
Esempio n. 15
0
        /// <summary>
        /// Constructs the topic title for a stop
        /// </summary>
        /// <param name="stop">stop information</param>
        /// <returns>topic title</returns>
        private string TopicTitle(StopEntity stop)
        {
            // in the common case, the topic title will be:
            //      Name (Direction)
            string title = string.Empty;

            if (!string.IsNullOrWhiteSpace(stop.Name))
            {
                title += stop.Name;
            }

            if (!string.IsNullOrWhiteSpace(title) && !string.IsNullOrWhiteSpace(stop.Direction))
            {
                title += " (" + stop.Direction + ")";
            }

            return(TopicUtils.RemoveHashtags(title));
        }
Esempio n. 16
0
 public static Stop ToDomain(this StopEntity stop)
 {
     if (stop != null)
     {
         return(new Stop
         {
             StopId = stop.StopId,
             CityId = stop.CityId,
             Name = stop.Name,
             Duration = stop.Duration,
             ArrivalTime = stop.ArrivalTime,
             DepartureTime = stop.DepartureTime
         });
     }
     else
     {
         return(null);
     }
 }
Esempio n. 17
0
 /// <summary>
 /// Checks a stop for validity before publishing to Embedded Social.
 /// Will throw an exception if invalid.
 /// </summary>
 /// <param name="stop">stop</param>
 private void CheckInputEntity(StopEntity stop)
 {
     if (stop == null)
     {
         throw new ArgumentNullException("stop");
     }
     else if (string.IsNullOrWhiteSpace(stop.Id))
     {
         throw new ArgumentException("stop id is null or whitespace", "stop");
     }
     else if (string.IsNullOrWhiteSpace(stop.RegionId))
     {
         throw new ArgumentException("stop region id is null or whitespace", "stop");
     }
     else if (string.IsNullOrWhiteSpace(stop.Name))
     {
         throw new ArgumentException("stop name is null or whitespace", "stop");
     }
 }
Esempio n. 18
0
        public void Delete(int id)
        {
            using var transaction = _context.Database.BeginTransaction();
            try
            {
                RouteStopEntity routeStop = _context.RoutesStops.FirstOrDefault(item => item.StopId == id);
                if (routeStop != null)
                {
                    _context.RoutesStops.Remove(routeStop);
                }

                StopEntity route = _context.Stops.FirstOrDefault(item => item.StopId == id);
                _context.Stops.Remove(route);

                _context.SaveChanges();
                transaction.Commit();
            }
            catch (Exception e)
            {
                transaction.Rollback();
            }
        }
Esempio n. 19
0
        public TourEntity MapToEntity(Tour tour)
        {
            var entity = new TourEntity
            {
                Id    = tour.Id,
                Stops = new List <StopEntity>()
            };

            for (int i = 0; i < tour.TourStops.Count; i++)
            {
                Stop stop       = tour.TourStops[i];
                var  stopEntity = new StopEntity
                {
                    Latitude      = stop.Latitude,
                    Longitude     = stop.Longitude,
                    Tour          = entity,
                    WayPointIndex = i
                };
                entity.Stops.Add(stopEntity);
            }
            return(entity);
        }
Esempio n. 20
0
 /// <summary>
 /// Resurrect a published stop from Embedded Social.
 /// The way we delete a stop is to simply indicate it as deleted
 /// in the Embedded Social topic title. To resurrect it, that
 /// text has to be removed from the topic title.
 /// </summary>
 /// <param name="stop">stop that has been restored</param>
 /// <returns>task that deletes the stop</returns>
 public async Task ResurrectStop(StopEntity stop)
 {
     await this.UpdateStop(stop);
 }
 /// <summary>
 /// Stores a stop in Azure Tables
 /// </summary>
 /// <param name="stop">stop</param>
 /// <returns>task that stores the entity</returns>
 public async Task Insert(StopEntity stop)
 {
     await this.Insert(new List <StopEntity>() { stop });
 }
Esempio n. 22
0
        public async Task ResurrectEntities()
        {
            // this test messes with the publish table so it should not be run on production accounts
            Assert.IsFalse(Utils.ProdConfiguration.IsProduction(TestConstants.AzureStorageConnectionString));

            string runId = RunId.GenerateTestRunId();

            // clean the publish table so that we are working with known state
            StorageManager publishStorage = new StorageManager(TestConstants.AzureStorageConnectionString, TableNames.TableType.Publish, runId);
            await TestUtilities.CleanPublishStorage(publishStorage);

            // setup download storage
            StorageManager downloadStorage = new StorageManager(TestConstants.AzureStorageConnectionString, TableNames.TableType.Download, runId);
            await downloadStorage.CreateTables();

            // create region
            RegionEntity region = TestUtilities.FakeRegionEntity();
            await downloadStorage.RegionStore.Insert(new List <RegionEntity>() { region });

            // create agency
            AgencyEntity agency = TestUtilities.FakeAgencyEntity(region.Id);
            await downloadStorage.AgencyStore.Insert(new List <AgencyEntity>() { agency });

            // create 1 route and 1 stop in download table that also exist in the publish table as deleted entities
            RouteEntity existingRoute = TestUtilities.FakeRouteEntity(region.Id, agency.Id);
            await downloadStorage.RouteStore.Insert(existingRoute);

            existingRoute.RowState = DataRowState.Delete.ToString();
            await publishStorage.RouteStore.Insert(existingRoute);

            StopEntity existingStop = TestUtilities.FakeStopEntity(region.Id);
            await downloadStorage.StopStore.Insert(existingStop);

            existingStop.RowState = DataRowState.Delete.ToString();
            await publishStorage.StopStore.Insert(existingStop);

            // setup diff manager
            DiffManager diffManager = new DiffManager(TestConstants.AzureStorageConnectionString, runId);
            await diffManager.InitializeStorage();

            // execute diff manager
            await diffManager.DiffAndStore();

            // sleep between the insert and the query otherwise Azure sometimes returns no records
            Thread.Sleep(TestConstants.AzureTableDelay);

            // query results
            StorageManager            diffStorage = new StorageManager(TestConstants.AzureStorageConnectionString, TableNames.TableType.Diff, runId);
            IEnumerable <RouteEntity> diffRoutes  = await diffStorage.RouteStore.GetAllRoutes(existingRoute.RegionId);

            IEnumerable <StopEntity> diffStops = await diffStorage.StopStore.GetAllStops(existingStop.RegionId);

            StorageManager            diffMetadataStorage = new StorageManager(TestConstants.AzureStorageConnectionString, TableNames.TableType.DiffMetadata, runId);
            List <DiffMetadataEntity> diffMetadata        = diffMetadataStorage.DiffMetadataStore.Get(runId).ToList();

            // clean up
            await diffManager.DeleteDiff();

            await downloadStorage.DeleteDataTables();

            await publishStorage.DeleteTables();

            // check route
            Assert.IsNotNull(diffRoutes);
            Assert.AreEqual(diffRoutes.Count(), 1);
            Assert.AreEqual(diffRoutes.First().Id, existingRoute.Id);
            Assert.AreEqual(diffRoutes.First().ShortName, existingRoute.ShortName);
            Assert.AreEqual(diffRoutes.First().LongName, existingRoute.LongName);
            Assert.AreEqual(diffRoutes.First().Description, existingRoute.Description);
            Assert.AreEqual(diffRoutes.First().Url, existingRoute.Url);
            Assert.AreEqual(diffRoutes.First().AgencyId, existingRoute.AgencyId);
            Assert.AreEqual(diffRoutes.First().RegionId, existingRoute.RegionId);
            Assert.AreEqual(diffRoutes.First().RecordType, existingRoute.RecordType);
            Assert.AreEqual(diffRoutes.First().RowState, DataRowState.Resurrect.ToString());
            Assert.AreEqual(diffRoutes.First().RawContent, existingRoute.RawContent);

            // check stop
            Assert.IsNotNull(diffStops);
            Assert.AreEqual(diffStops.Count(), 1);
            Assert.AreEqual(diffStops.First().Id, existingStop.Id);
            Assert.AreEqual(diffStops.First().Lat, existingStop.Lat);
            Assert.AreEqual(diffStops.First().Lon, existingStop.Lon);
            Assert.AreEqual(diffStops.First().Direction, existingStop.Direction);
            Assert.AreEqual(diffStops.First().Name, existingStop.Name);
            Assert.AreEqual(diffStops.First().Code, existingStop.Code);
            Assert.AreEqual(diffStops.First().RegionId, existingStop.RegionId);
            Assert.AreEqual(diffStops.First().RecordType, existingStop.RecordType);
            Assert.AreEqual(diffStops.First().RowState, DataRowState.Resurrect.ToString());
            Assert.AreEqual(diffStops.First().RawContent, existingStop.RawContent);

            // check metadata
            Assert.IsNotNull(diffMetadata);
            Assert.AreEqual(diffMetadata.Count, 2);
            int routeIndex = -1;
            int stopIndex  = -1;

            if (diffMetadata[0].RecordType == RecordType.Route.ToString())
            {
                routeIndex = 0;
                stopIndex  = 1;
            }
            else
            {
                routeIndex = 1;
                stopIndex  = 0;
            }

            Assert.AreEqual(diffMetadata[routeIndex].AddedCount, 0);
            Assert.AreEqual(diffMetadata[routeIndex].AgencyId, existingRoute.AgencyId);
            Assert.AreEqual(diffMetadata[routeIndex].DeletedCount, 0);
            Assert.AreEqual(diffMetadata[routeIndex].RecordType, RecordType.Route.ToString());
            Assert.AreEqual(diffMetadata[routeIndex].RegionId, existingRoute.RegionId);
            Assert.AreEqual(diffMetadata[routeIndex].ResurrectedCount, 1);
            Assert.AreEqual(diffMetadata[routeIndex].RunId, runId);
            Assert.AreEqual(diffMetadata[routeIndex].UpdatedCount, 0);

            Assert.AreEqual(diffMetadata[stopIndex].AddedCount, 0);
            Assert.AreEqual(diffMetadata[stopIndex].AgencyId, string.Empty);
            Assert.AreEqual(diffMetadata[stopIndex].DeletedCount, 0);
            Assert.AreEqual(diffMetadata[stopIndex].RecordType, RecordType.Stop.ToString());
            Assert.AreEqual(diffMetadata[stopIndex].RegionId, existingStop.RegionId);
            Assert.AreEqual(diffMetadata[stopIndex].ResurrectedCount, 1);
            Assert.AreEqual(diffMetadata[stopIndex].RunId, runId);
            Assert.AreEqual(diffMetadata[stopIndex].UpdatedCount, 0);
        }