/// <summary> /// Processes GetNeighbourNodesByDistanceResponse message received from LOC server. /// <para>This message contains information about proximity server's neighbors, with which it should share its activity database.</para> /// </summary> /// <param name="ResponseMessage">Full response message.</param> /// <param name="IsInitialization">true if the response was received to the request during the LOC initialization, false if it was received to the refresh request after the initialization.</param> /// <returns>true if the connection to the LOC server should remain open, false if it should be closed.</returns> public async Task <bool> ProcessMessageGetNeighbourNodesByDistanceResponseAsync(LocProtocolMessage ResponseMessage, bool IsInitialization) { log.Trace("(IsInitialization:{0})", IsInitialization); bool res = false; bool signalActionProcessor = false; GetNeighbourNodesByDistanceResponse getNeighbourNodesByDistanceResponse = ResponseMessage.Response.LocalService.GetNeighbourNodes; if (getNeighbourNodesByDistanceResponse.Nodes.Count > 0) { using (UnitOfWork unitOfWork = new UnitOfWork()) { DatabaseLock[] lockObjects = new DatabaseLock[] { UnitOfWork.NeighborLock, UnitOfWork.NeighborhoodActionLock }; using (IDbContextTransaction transaction = await unitOfWork.BeginTransactionWithLockAsync(lockObjects)) { bool success = false; bool saveDb = false; try { int neighborhoodSize = await unitOfWork.NeighborRepository.CountAsync(); foreach (NodeInfo nodeInfo in getNeighbourNodesByDistanceResponse.Nodes) { // Check whether a proximity server is running on this node. // If not, it is not interesting for us at all, skip it. int proximityServerPort; byte[] proximityServerId; if (!HasProximityServerService(nodeInfo, out proximityServerPort, out proximityServerId)) { continue; } NodeContact contact = nodeInfo.Contact; byte[] ipBytes = contact.IpAddress.ToByteArray(); IPAddress ipAddress = new IPAddress(ipBytes); int latitude = nodeInfo.Location.Latitude; int longitude = nodeInfo.Location.Longitude; AddOrChangeNeighborResult addChangeRes = await AddOrChangeNeighborAsync(unitOfWork, proximityServerId, ipAddress, proximityServerPort, latitude, longitude, neighborhoodSize); neighborhoodSize = addChangeRes.NeighborhoodSize; if (addChangeRes.SaveDb) { saveDb = true; } if (addChangeRes.SignalActionProcessor) { signalActionProcessor = true; } // We do ignore errors here and just continue processing another item from the list. } if (saveDb) { await unitOfWork.SaveThrowAsync(); transaction.Commit(); } success = true; res = true; } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } if (!success) { log.Warn("Rolling back transaction."); unitOfWork.SafeTransactionRollback(transaction); } unitOfWork.ReleaseLock(lockObjects); } } } else { log.Debug("No neighbors announced by LOC server."); res = true; } if (signalActionProcessor) { NeighborhoodActionProcessor neighborhoodActionProcessor = (NeighborhoodActionProcessor)Base.ComponentDictionary[NeighborhoodActionProcessor.ComponentName]; neighborhoodActionProcessor.Signal(); } if (res && IsInitialization) { log.Debug("LOC component is now considered in sync with LOC server."); serverComponent.SetLocServerInitialized(true); } log.Trace("(-):{0}", res); return(res); }
/// <summary> /// Processes NeighbourhoodChangedNotificationRequest message from LOC server. /// <para>Adds, changes, or deletes neighbor and possibly adds new neighborhood action to the database.</para> /// </summary> /// <param name="Client">TCP client who received the message.</param> /// <param name="RequestMessage">Full request message.</param> /// <returns>Response message to be sent to the client.</returns> public async Task <LocProtocolMessage> ProcessMessageNeighbourhoodChangedNotificationRequestAsync(LocClient Client, LocProtocolMessage RequestMessage) { log.Trace("()"); LocProtocolMessage res = Client.MessageBuilder.CreateErrorInternalResponse(RequestMessage); bool signalActionProcessor = false; NeighbourhoodChangedNotificationRequest neighbourhoodChangedNotificationRequest = RequestMessage.Request.LocalService.NeighbourhoodChanged; using (UnitOfWork unitOfWork = new UnitOfWork()) { DatabaseLock[] lockObjects = new DatabaseLock[] { UnitOfWork.NeighborLock, UnitOfWork.NeighborhoodActionLock }; using (IDbContextTransaction transaction = await unitOfWork.BeginTransactionWithLockAsync(lockObjects)) { bool success = false; bool saveDb = false; try { int neighborhoodSize = await unitOfWork.NeighborRepository.CountAsync(); foreach (NeighbourhoodChange change in neighbourhoodChangedNotificationRequest.Changes) { // We do ignore errors here for each individual change and just continue processing the next item from the list. log.Trace("Neighborhood change type is {0}.", change.ChangeTypeCase); switch (change.ChangeTypeCase) { case NeighbourhoodChange.ChangeTypeOneofCase.AddedNodeInfo: case NeighbourhoodChange.ChangeTypeOneofCase.UpdatedNodeInfo: { bool isAdd = change.ChangeTypeCase == NeighbourhoodChange.ChangeTypeOneofCase.AddedNodeInfo; NodeInfo nodeInfo = isAdd ? change.AddedNodeInfo : change.UpdatedNodeInfo; // Check whether a proximity server is running on this node. // If not, it is not interesting for us at all, skip it. int proximityServerPort; byte[] proximityServerId; if (!HasProximityServerService(nodeInfo, out proximityServerPort, out proximityServerId)) { break; } NodeContact contact = nodeInfo.Contact; IPAddress ipAddress = new IPAddress(contact.IpAddress.ToByteArray()); Iop.Locnet.GpsLocation location = nodeInfo.Location; int latitude = location.Latitude; int longitude = location.Longitude; AddOrChangeNeighborResult addChangeRes = await AddOrChangeNeighborAsync(unitOfWork, proximityServerId, ipAddress, proximityServerPort, latitude, longitude, neighborhoodSize); neighborhoodSize = addChangeRes.NeighborhoodSize; if (addChangeRes.SaveDb) { saveDb = true; } if (addChangeRes.SignalActionProcessor) { signalActionProcessor = true; } break; } case NeighbourhoodChange.ChangeTypeOneofCase.RemovedNodeId: { byte[] serverId = change.RemovedNodeId.ToByteArray(); bool serverIdValid = serverId.Length == ProtocolHelper.NetworkIdentifierLength; if (!serverIdValid) { log.Error("Received invalid neighbor server ID '{0}' from LOC server.", serverId.ToHex()); break; } // Data processing. Neighbor existingNeighbor = (await unitOfWork.NeighborRepository.GetAsync(n => n.NetworkId == serverId)).FirstOrDefault(); if (existingNeighbor != null) { log.Trace("Creating neighborhood action to deleting neighbor ID '{0}' from the database.", serverId.ToHex()); string neighborInfo = JsonConvert.SerializeObject(existingNeighbor); // Delete neighbor completely. // This will cause our proximity server to erase all activities of the neighbor that has been removed. bool deleted = await unitOfWork.NeighborRepository.DeleteNeighborAsync(serverId, -1, true); if (deleted) { // Add action that will contact the neighbor and ask it to stop sending updates. // Note that the neighbor information will be deleted by the time this action // is executed and this is why we have to fill in AdditionalData. NeighborhoodAction stopUpdatesAction = new NeighborhoodAction() { ServerId = serverId, Timestamp = DateTime.UtcNow, Type = NeighborhoodActionType.StopNeighborhoodUpdates, TargetActivityId = 0, TargetActivityOwnerId = null, ExecuteAfter = DateTime.UtcNow, AdditionalData = neighborInfo }; await unitOfWork.NeighborhoodActionRepository.InsertAsync(stopUpdatesAction); signalActionProcessor = true; saveDb = true; } else { log.Error("Failed to remove neighbor ID '{0}' from the database.", serverId.ToHex()); // This is actually bad, we failed to remove a record from the database, which should never happen. // We try to insert action to remove this neighbor later, but adding the action might fail as well. NeighborhoodAction action = new NeighborhoodAction() { ServerId = serverId, Timestamp = DateTime.UtcNow, Type = NeighborhoodActionType.RemoveNeighbor, TargetActivityId = 0, TargetActivityOwnerId = null, AdditionalData = null }; await unitOfWork.NeighborhoodActionRepository.InsertAsync(action); signalActionProcessor = true; saveDb = true; } } else { log.Debug("Neighbor ID '{0}' not found, can not be removed.", serverId.ToHex()); // It can be the case that this node has not an associated proximity server, so in that case we should ignore it. // If the node has an associated proximity server, then nothing bad really happens here if we have activities // of such a neighbor in NeighborActivity table. Those entries will expire and will be deleted. } break; } default: log.Error("Invalid neighborhood change type '{0}'.", change.ChangeTypeCase); break; } } if (saveDb) { await unitOfWork.SaveThrowAsync(); transaction.Commit(); } success = true; res = Client.MessageBuilder.CreateNeighbourhoodChangedNotificationResponse(RequestMessage); } catch (Exception e) { log.Error("Exception occurred: {0}", e.ToString()); } if (!success) { log.Warn("Rolling back transaction."); unitOfWork.SafeTransactionRollback(transaction); } unitOfWork.ReleaseLock(lockObjects); } } if (signalActionProcessor) { NeighborhoodActionProcessor neighborhoodActionProcessor = (NeighborhoodActionProcessor)Base.ComponentDictionary[NeighborhoodActionProcessor.ComponentName]; neighborhoodActionProcessor.Signal(); } log.Trace("(-):*.Response.Status={0}", res.Response.Status); return(res); }
protected void Page_Load(object sender, EventArgs e) { string systemPrefix = WebConfigurationManager.AppSettings["systemPrefix"]; String connectionString = ConfigurationManager.ConnectionStrings[systemPrefix + "ConnectionString"].ConnectionString; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load("C:\\Users\\gtichbon\\Source\\Repos\\WebSites\\VehicleService\\Imports\\CampbellContacts.xml"); XmlNodeList nodeListContact = xmlDoc.SelectNodes("//Contact"); foreach (XmlNode NodeContact in nodeListContact) { //Response.Write(NodeContact.Name + "<br />"); if (NodeContact["IsCustomer"].InnerText == "true") { string XeroXML = NodeContact.OuterXml; string XeroID = NodeContact["ContactID"].InnerText; string Name = NodeContact["Name"].InnerText; string EmailAddress = ""; if (NodeContact["EmailAddress"] != null) { EmailAddress = NodeContact["EmailAddress"].InnerText; } string FirstName = ""; if (NodeContact["FirstName"] != null) { FirstName = NodeContact["FirstName"].InnerText; } string LastName = ""; if (NodeContact["LastName"] != null) { LastName = NodeContact["LastName"].InnerText; } string Phone = ""; String Mobile = ""; string Address = ""; Response.Write(XeroID + "<br />"); //guid Response.Write(Name + "<br />"); Response.Write(NodeContact["UpdatedDateUTC"].InnerText + "<br />"); int DefaultCount = 0; int MobileCount = 0; int DDICount = 0; XmlNodeList nodeListContactPhones = NodeContact.SelectNodes("Phones"); foreach (XmlNode NodeContactPhones in nodeListContactPhones) { XmlNodeList nodeListContactPhone = NodeContactPhones.SelectNodes("Phone"); foreach (XmlNode NodeContactPhone in nodeListContactPhone) { string phonetype = NodeContactPhone.SelectSingleNode("PhoneType").InnerText; string phoneNumber = ""; if (NodeContactPhone.SelectSingleNode("PhoneAreaCode") != null) { phoneNumber = NodeContactPhone["PhoneAreaCode"].InnerText; } if (NodeContactPhone.SelectSingleNode("PhoneNumber") != null) { phoneNumber += NodeContactPhone["PhoneNumber"].InnerText; Response.Write(" - " + phoneNumber + "<br />"); switch (phonetype) { case "DEFAULT": DefaultCount++; Phone = phoneNumber; break; case "DDI": DDICount++; break; case "MOBILE": MobileCount++; Mobile = phoneNumber; break; } } } } if (DefaultCount > 1 || MobileCount > 1 || DDICount > 0) { string x = "x"; } XmlNodeList nodeListContactAddresses = NodeContact.SelectNodes("Addresses"); foreach (XmlNode NodeContactAddresses in nodeListContactAddresses) { XmlNodeList nodeListContactAddress = NodeContactAddresses.SelectNodes("Address"); foreach (XmlNode NodeContactAddress in nodeListContactAddress) { string Addresstype = NodeContactAddress.SelectSingleNode("AddressType").InnerText; if (Addresstype == "STREET") { string delim = ""; if (NodeContactAddress.SelectSingleNode("AddressLine1") != null) { Address = NodeContactAddress["AddressLine1"].InnerText; delim = "\r\n"; } if (NodeContactAddress.SelectSingleNode("AddressLine2") != null) { Address += delim + NodeContactAddress["AddressLine2"].InnerText; delim = "\r\n"; } if (NodeContactAddress.SelectSingleNode("City") != null) { Address += delim + NodeContactAddress["City"].InnerText.Replace("Wanganui", "Whanganui"); } if (NodeContactAddress.SelectSingleNode("PostalCode") != null) { Address += " " + NodeContactAddress["PostalCode"].InnerText; } } } } string id; if (1 == 1) { using (SqlConnection con = new SqlConnection(connectionString)) using (SqlCommand cmd = new SqlCommand("Update_Customer", con)) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add("@Customer_CTR", SqlDbType.VarChar).Value = "new"; cmd.Parameters.Add("@XeroID", SqlDbType.VarChar).Value = XeroID; cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = Name; cmd.Parameters.Add("@FirstName", SqlDbType.VarChar).Value = FirstName; cmd.Parameters.Add("@Surname", SqlDbType.VarChar).Value = LastName; cmd.Parameters.Add("@Address", SqlDbType.VarChar).Value = Address; cmd.Parameters.Add("@EmailAddress", SqlDbType.VarChar).Value = EmailAddress; cmd.Parameters.Add("@MobilePhone", SqlDbType.VarChar).Value = Mobile; cmd.Parameters.Add("@HomePhone", SqlDbType.VarChar).Value = Phone; cmd.Parameters.Add("@XeroXML", SqlDbType.Xml).Value = XeroXML; con.Open(); id = cmd.ExecuteScalar().ToString(); con.Close(); } } } } }