public static void runCal() { // Define the syncToken var string syncToken; bool ran = false; // Sync all calendars and send a message to RMQ foreach (var item in syncCalendars(out syncToken)) { // Try to send the message to the queue try { SyncConverter.sendMessage(SyncConverter.calMessage(item)); ran = true; } // Could not send the message, do not save the syncToken! catch (Exception e) { // Set the token to null syncToken = null; } } // Update if (ran && !String.IsNullOrEmpty(syncToken)) { uuidMaster.PutUpdateUUID(calendarSyncTokenUUID, syncToken, Calendarss.getversion(calendarSyncTokenUUID) + 1); } }
// Create a calendar XML message public static string calMessage(CalendarListEntry cal) { string version = ""; string uuid = ""; try { // Fetch data from the UUID master UUID uuidMaster = new UUID(); // Check if the calendar exists or not; create or update the UUID try { uuid = uuidMaster.GetUuidBy(7, cal.Id); // uuid exists, so it is an update request -> check time name difference with IdOutput output = JsonConvert.DeserializeObject <IdOutput>(uuidMaster.GetIdBy(uuid, 7)); // Delete detected if (cal.Deleted == true) { // Event was made trough the interface, not us version = (output.version + 1).ToString(); } else { IdOutput name = JsonConvert.DeserializeObject <IdOutput>(uuidMaster.GetIdBy(String.Format("name-property-{0}", cal.Id), 7)); // Name change detected if (!cal.Summary.Trim().Equals(name.id)) { // update the name in the uuid master uuidMaster.PutUpdateUUID(String.Format("name-property-{0}", cal.Id), cal.Summary.Trim(), Calendarss.getversion(String.Format("name-property-{0}", cal.Id)) + 1); // Event was made trough the interface, not us version = (output.version + 1).ToString(); } } if (version.Equals(output.version)) { return(""); } uuidMaster.PutUpdateUUID(uuid, cal.Id, Convert.ToInt32(version)); } // UUID did not exist for the calendar, create it and make an entry for the calendar name catch (Exception e) { // Create listener :) GService.service.Events.Watch(KeySync.newChannel(String.Format("&calId={0}", cal.Id)), cal.Id).Execute(); uuid = uuidMaster.PutCreateUUID(cal.Id); uuidMaster.PutUpdateUUID(String.Format("name-property-{0}", cal.Id), cal.Summary.Trim(), 1); version = "1"; } } catch (Exception e) { // Notify CR when something happens ControlRoom.SendErrorMessage("Google Calendar Sync Error", e.Message); return(""); } // Construct the XML msg return("<message>" + "<header><messageType>CreateEvent</messageType><description>CRUD of an event</description><sender>planning</sender></header>" + "<datastructure>" + "<UUID>" + uuid + "</UUID>" + "<eventName>" + cal.Summary + "</eventName>" + "<timestamp>" + new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds() + "</timestamp>" + "<isActive>" + (cal.Deleted == true ? "0" : "1") + "</isActive>" + "<version>" + version + "</version>" + "<extraField></extraField>" + "</datastructure>" + "</message>"); }
public static void Main(string[] args) { new GService(); // Create RMQ connection var factory = new ConnectionFactory() { HostName = ConfigurationManager.AppSettings["server"].ToString(), UserName = ConfigurationManager.AppSettings["username"].ToString(), Password = ConfigurationManager.AppSettings["password"].ToString(), Port = Convert.ToInt16(ConfigurationManager.AppSettings["port"].ToString()) }; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { // Configurating channel channel.ExchangeDeclare(exchange: ConfigurationManager.AppSettings["exchange"].ToString(), type: ConfigurationManager.AppSettings["type"].ToString()); channel.QueueBind(queue: ConfigurationManager.AppSettings["queue"].ToString(), exchange: ConfigurationManager.AppSettings["exchange"].ToString(), routingKey: ConfigurationManager.AppSettings["routingKey"].ToString()); Console.WriteLine("[*] Waiting for messages."); // Create a RMQ listener var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { try { // Load in the the message var message = Encoding.UTF8.GetString(ea.Body); //check validity of message with controlroom nuget package / library var valid = ControlRoom.CheckMessage(message); Console.WriteLine("Message is valid: " + valid); Console.WriteLine(" [x] {0}", message); if (!valid) { throw new CleanException(); } // Create a new xml doc to catch message XmlDocument doc = new XmlDocument(); doc.LoadXml(message); // Find out who the sender is and if it is set or not // Discard any messages that we send ourselves so we do not create a loop XmlNodeList xmlSender = doc.GetElementsByTagName("sender"); if (xmlSender.Count == 0 || xmlSender[0].InnerText.ToLower().Equals("planning")) { throw new CleanException(); } // Get a the messageType, stop if we cannot find it // Create a local messagetype variable (lower version) XmlNodeList xmlMessageType = doc.GetElementsByTagName("messageType"); if (xmlMessageType.Count == 0) { throw new CleanException(); } string messageType = xmlMessageType[0].InnerText.ToLower(); // Check if the message is supported or not if (!messageTypes.Contains(messageType)) { Console.WriteLine("Unsupported messageType found {0}", messageType); throw new CleanException(); } // Version checks & parsing, get the latest version from the UUID master XmlNodeList xmlVersion = doc.GetElementsByTagName("version"); int version = 0; XmlNodeList xmlUUID = doc.GetElementsByTagName("session_UUID"); if (xmlUUID.Count == 0) { xmlUUID = doc.GetElementsByTagName("UUID"); } int latestVersion = Calendarss.getversion(xmlUUID[0].InnerText); if (xmlVersion.Count > 0) { if (xmlVersion[0].InnerText != string.Empty) { version = Convert.ToInt32(xmlVersion[0].InnerText); } } // Check if we should discard the message or not if (latestVersion >= version) { Console.WriteLine("Receiving old data, discarding; Received: {0} Latest: {1}", version, latestVersion); throw new CleanException(); } // IsActive checks & parsing bool isActive = true; XmlNodeList xmlIsActive = doc.GetElementsByTagName("isActive"); if (xmlIsActive.Count > 0) { if (xmlIsActive[0].InnerText != string.Empty) { isActive = Convert.ToBoolean(Convert.ToInt16(xmlIsActive[0].InnerText)); } } Console.WriteLine("Trying to process a messageType {0}, with version {1} and active state of {2}", messageType, version, isActive); // Picking up messageType (event/session/employee) with CRUD operation based off isActive/version switch (messageType) { case "createevent": if (isActive == false) { new ReceiveMessage().deleteCalendar(doc); break; } else if (version == 1) { new ReceiveMessage().createCalendar(doc); break; } else if (version > 1) { new ReceiveMessage().updateCalendar(doc); break; } break; case "createsession": if (isActive == false) { new ReceiveMessage().deleteEvent(doc); break; } else if (version == 1) { new ReceiveMessage().createEvent(doc); break; } else if (version > 1) { new ReceiveMessage().updateEvent(doc); break; } break; case "createemployee": if (isActive == false) { new ReceiveMessage().deleteEmployee(doc); break; } else if (version == 1) { new ReceiveMessage().createEmployee(doc); break; } else if (version > 1) { new ReceiveMessage().updateEmployee(doc); break; } break; default: break; } // Nothing went wrong?! Good! Send an ack to RMQ channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); } catch (CleanException e) { // Nothing went wrong, we're just invalidating this message channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); } // Attendee overlay exception catch (AttendeeOverlayException e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Attendee overlay error", e.Message); } // Date is invalid catch (DateExpception e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Invalid date error", e.Message); } catch (DeletedException e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Delete error", e.Message); } // Duplication error catch (DuplicationException e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Duplication error", e.Message); } // Format error (could possibly appear with dates) catch (FormatException e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Formatting error", e.Message); } // Location overlaying with another catch (LocationOverlayException e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Location overlay error", e.Message); } // Unexpectedly could not delete catch (NotDeletedException e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Not deleted error", e.Message); } // Not found exception catch (NotFoundException e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Not found error", e.Message); } // Requirements do not match catch (RequirementsNotMetcs e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Requirements not met error", e.Message); } // Server error catch (ServerFault e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Server error", e.Message); } // Wrong version of message (got vers < curr vers) catch (WrongVersionException e) { // Something went wrong, we're just invalidating this message & notifying the CR channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); ControlRoom.SendErrorMessage("Planning Wrong version error", e.Message); } //all exceptions catcher catch (Exception e) { Console.WriteLine(e.StackTrace); // In case something goes wrong... //channel.BasicNack(deliveryTag: ea.DeliveryTag, multiple: false, requeue: false); ControlRoom.SendErrorMessage("Planning Receiver error", e.Message); } }; channel.BasicConsume(queue: ConfigurationManager.AppSettings["queue"].ToString(), autoAck: Convert.ToBoolean(ConfigurationManager.AppSettings["autoAck"].ToString()), consumer: consumer); Console.WriteLine("Press any key to exit planning RabbitMQ receiver"); Console.ReadKey(true); } }