def subscribe(self, topic: str): """ Actually sends the subscription request, by picking a broker at random """ logging.info("Trying to discover brokers in the swarm") brokers = discover(get_current_host_ip(), service_type=SERVICE_TYPE.TOPIC_BROKER) # Choose a random broker subscribe_to = random.choice(brokers) poll_ctr = 0 while not poll(subscribe_to) and poll_ctr < 5: subscribe_to = random.choice(Config.DOCKER_BROKER_ADDRESSES) poll_ctr += 1 logging.info("Subscribing to Host: {0}".format(subscribe_to)) if not poll(subscribe_to): logging.error("Broker {0} is down".format(subscribe_to)) return False # The topic to subscribe to subscribe_topic = topic if topic else self.topic # Format the url by adding the schema, eg. 'http://' to it url = add_schema_to_url("{0}/{1}/{2}".format(subscribe_to, ENDPOINTS.SUBSCRIBE, subscribe_topic)) logging.info("Calling URL {}".format(url)) response = requests.get(url) response_json = response.json() if response_json['brokers']: self.brokers = response_json['brokers'] logging.info("Active brokers: {0}".format(self.brokers)) if response.status_code == 200: self.subscriptions[subscribe_topic] = True else: self.subscriptions[subscribe_topic] = False return self.subscriptions[subscribe_topic]
def update_broker_host_ip(self): """ Get the docker assigned IP for this container """ current_broker_addr = add_schema_to_url(get_current_host_ip()) if not broker.current_broker_address: self.current_broker_address = current_broker_addr logging.debug("Current host address: {}".format(current_broker_addr)) return
def notify(self, subscriber, topic, message): """ Sends the message to a subscriber """ if not poll(subscriber): logging.error("Subscriber {0} is down".format(subscriber)) return False url = "{0}/{1}".format(subscriber, ENDPOINTS.NOTIFY) cleaned_url = add_schema_to_url(url) logging.info("Notifying URL: {}".format(cleaned_url)) post_data = {'topic': topic, 'data': message} logging.info("Message being sent is: {}".format(message)) response = requests.post(cleaned_url, data=post_data) return response.status_code == 200
def publish(self, message): """ Publish the message to a subscriber, and hope that it reaches all those who care """ logging.info("Trying to discover brokers in the swarm") brokers = discover(get_current_host_ip(), service_type=SERVICE_TYPE.TOPIC_BROKER) # Choose a random broker publish_to = random.choice(brokers) if not poll(publish_to): logging.error("Broker {0} is down".format(publish_to)) return False url = add_schema_to_url("{0}/{1}/{2}".format(publish_to, ENDPOINTS.PUBLISH, self.topic)) logging.info("Publishing to URL {0} : {1}".format(url, message)) resp = requests.post(url, json=message) return resp
def publish(self, message): """ Publish message to the central broker """ publish_to = Config.BROKER_ADDRESS # Check if broker is up if not poll(publish_to): logging.error("Broker {0} is down".format(publish_to)) return False url = add_schema_to_url("{0}/{1}/{2}".format(publish_to, ENDPOINTS.PUBLISH, self.topic)) logging.info("Publishing to URL {0} : {1}".format(url, message)) resp = requests.post(url, data=message) return resp
def pass_forward(self, topic, message, origin_chain): """ Pass the message along to the remaining hosts in the broker swarm """ logging.debug("Message: {}, Origin chain: {}".format(message, origin_chain)) new_orig_chain = list(set(origin_chain + [self.current_broker_address])) logging.debug("New Origin chain: {}".format(new_orig_chain)) ret_array = [] for ally in self.allies: if ally not in new_orig_chain: data = {'origin_chain': new_orig_chain, 'value': message} formatted_ally_address = "{0}/{1}/{2}".format(add_schema_to_url(ally), ENDPOINTS.PUBLISH, topic) logging.info("Passing message {0} to ally {1}".format(data, formatted_ally_address)) pass_forward_ret = requests.post(formatted_ally_address, json=data) ret_array.append(pass_forward_ret) return ret_array
def subscribe(self, topic: str): """ Subscribe to a topic at the central broker """ if not poll(SUBSCRIBE_TO): logging.error("Broker {0} is down".format(SUBSCRIBE_TO)) return False subscribe_topic = topic if topic else self.topic url = add_schema_to_url("{0}/{1}/{2}".format(SUBSCRIBE_TO, ENDPOINTS.SUBSCRIBE, subscribe_topic)) logging.info("Calling URL {}".format(url)) response = requests.get(url) if response.status_code == 200: self.subscriptions[subscribe_topic] = True else: self.subscriptions[subscribe_topic] = False return self.subscriptions[subscribe_topic]
def enable_subscription(topic): """ Store that a subscriber has asked to be subscribed to a topic """ remote_addr = add_schema_to_url(request.remote_addr) subscriber_address = remote_addr logging.debug( "Adding subscription for address: {}".format(subscriber_address)) if topic in broker.subscriptions: subscriber_list = broker.subscriptions[topic] subscriber_list.append(subscriber_address) broker.subscriptions[topic] = list(set(subscriber_list)) else: broker.subscriptions[topic] = [subscriber_address] logging.debug("All subscriptions: {}".format(broker.subscriptions)) return "Success"
def enable_subscription(topic): """ Store that a subscriber has asked to be subscribed to a topic """ broker.update_broker_host_ip() remote_addr = add_schema_to_url(request.remote_addr) subscriber_address = remote_addr logging.debug("Adding subscription for address: {}".format(subscriber_address)) if topic in broker.subscriptions: subscriber_list = broker.subscriptions[topic] subscriber_list.append(subscriber_address) broker.subscriptions[topic] = list(set(subscriber_list)) else: broker.subscriptions[topic] = [subscriber_address] logging.debug("All subscriptions: {}".format(broker.subscriptions)) broker.ping_allies() # Give the subscriber all the valid brokers response_d = {"brokers": broker.allies + [broker.current_broker_address]} logging.debug("Sending subscribe response: {}".format(response_d)) return Response(json.dumps(response_d), mimetype=MIMETYPES.APP_JSON)
def notify(self, subscriber, topic, message): """ Sends the message to a subscriber """ # Check if subscruber is alive if not poll(subscriber): logging.error("Subscriber {0} is down".format(subscriber)) return False # Check if subscriber has already received the same message from this broker if broker.has_subscriber_seen_this_message(message, subscriber): logging.info( "Subscriber {0} has already seen the message {1} so not sending it again to them".format(subscriber, message)) return True url = "{0}/{1}".format(subscriber, ENDPOINTS.NOTIFY) cleaned_url = add_schema_to_url(url) logging.info("Notifying URL: {}".format(cleaned_url)) post_data = {'topic': topic, 'data': message} logging.info("Message being sent is: {}".format(message)) response = requests.post(cleaned_url, json=post_data) notified = response.status_code == 200 if notified: # Update that the subscriber has been sent this message from this broker self.update_message_receiver(message, subscriber) return notified