def test_default_options(self, strict_redis_cls): client = Redis('redis-uri') client.redis_uri = 'redis-uri' client.start() assert [call('redis-uri', decode_responses=True) ] == strict_redis_cls.from_url.call_args_list
class ConsumerService: """ Microservice responsible for consume data notifications from Service4 and dispatching those data to the Client by saving those data to Redis database. Attributes: name (str): The microservice name. _publication (Exchange): Messagin exchange object. _queue (Queue): Messaging publications queue to be consumed. _redis (Redis): Nameko Redis connector object. """ name = 'consumer' _publication = Exchange('new_publication', type='direct') _queue = Queue('publication_queue', exchange=_publication) _redis = Redis('my_redis') @consume(_queue) def receive_new_publication(self, payload: str): """ Responsible for consuming incoming data received from service4 by saving data to Redis Queue. Args: payload (str): Data to be consumed. """ try: self._redis.rpush('publication_queue', payload) except Exception as e: print('Ooops!', e)
class RoomService: """ Room service class """ name = "bookings_service" redis = Redis('development') @rpc def get(self, booking_id): """ get a room by id :param booking_id: :return: """ booking = self.redis.get(booking_id) return booking @rpc def create(self, booking): """ Create a room :param booking: :return: """ booking_id = uuid.uuid4().hex self.redis.set(booking_id, booking) return booking_id
class SalesforceService: name = 'salesforce' contacts_rpc = RpcProxy('contacts') salesforce = SalesforceAPI() source_tracker = SourceTracker() redis = Redis('lock') @event_handler('contacts', 'contact_created') def handle_platform_contact_created(self, payload): if self.source_tracker.is_sourced_from_salesforce(): print("Ignoring event that was sourced from salesforce") return result = self.salesforce.Contact.create( {'LastName': payload['contact']['name']}) print('Created {} on salesforce'.format(result)) @handle_sobject_notification('Contact', exclude_current_user=True, notify_for_operation_update=False) @skip_duplicates(operator.attrgetter('redis'), key=skip_duplicate_key) def handle_sf_contact_created(self, sobject_type, record_type, notification): with self.source_tracker.sourced_from_salesforce(): contact = self.contacts_rpc.create_contact( {'name': notification['sobject']['Name']}) print('Created {} on platform'.format(contact))
class ArithmeticService: name = 'arithmetic' redis = Redis('newton') @rpc def calculate(self, procedure_uuid: str): arithmetic_procedure = json.loads(self.redis.get(procedure_uuid)) status = None if not arithmetic_procedure: logging.error('Couldnt find procedure with uuid %s to calculate', procedure_uuid) try: operation_function = _OPERATION_FUNCTION[ arithmetic_procedure['operation']] arithmetic_procedure['result'] = operation_function( *arithmetic_procedure['arguments']) status = PROCEDURE_STATUS_DONE except ArithmeticError as error: logging.error(error) status = str(error) except Exception as exception: logging.error(exception) status = PROCEDURE_STATUS_ERROR finally: logging.info('Procedure with uuid %s calculation finished', procedure_uuid) arithmetic_procedure['status'] = status self.redis.set(procedure_uuid, json.dumps(arithmetic_procedure))
class TripsService: name = "trips_service" redis = Redis('development') @rpc def get(self, trip_id): trip = self.redis.hgetall(trip_id) return trip @rpc def create(self, airport_from_id, airport_to_id): trip_id = uuid.uuid4().hex self.redis.hmset(trip_id, { "from": airport_from_id, "to": airport_to_id }) return trip_id # @rpc # def get_trip_with_aid(self, airport_id): # trip_id = uuid.uuid4().hex # self.redis.hmset(trip_id, { # "from": airport_from_id, # "to": airport_to_id # }) # return trip_id
class AddressService: logger = logging.getLogger(__name__) name = 'addresses' redis = Redis('development') def _schema(self, **kwargs): _data = { 'id': kwargs.get('id', uuid.uuid4().hex), 'street_1': kwargs.get('street_1', None), 'street_2': kwargs.get('street_2', None), 'city': kwargs.get('city', None), 'province': kwargs.get('province', None), 'postal_code': kwargs.get('postal_code', None), 'country': kwargs.get('country', None), } return dict((k, v) for k, v in _data.items() if v is not None) @rpc def create(self, **kwargs): data = self._schema(**kwargs) self.redis.hmset(data.get('id'), data) return data.get('id') @rpc def get(self, address_id): self.logger.info(address_id) address = self.redis.hgetall(address_id) return address
class TripsService(object): name = "trips_service" redis = Redis("development") @rpc def get(self, trip_id): """ Gets the trip object from Redis database using the trip_id :param: trip_id :return: Trip object :rtype: object """ trip = self.redis.get(trip_id) return trip @rpc def create(self, airport_from_id, airport_to_id): """ Creates a Trip object with the airiport_from_id and airport_do_id :param: airport_from_id Where the trip beings :param: airport_to_id Id of the airport for the given destination :return: Trip id :rtype: str """ trip_id = uuid.uuid4().hex self.redis.set(trip_id, {"from": airport_from_id, "to": airport_to_id}) return trip_id
class EventsComponet: name = 'events_component' redis = Redis('cache', encoding='utf-8') @event_handler('command_stack', 'news_created') def news_created_normalize_db(self, data): try: del data['version'] del data['status'] NewsQueryModel(**data).save() self.set_cache(data) except Exception as e: logging.error(e) @event_handler('command_stack', 'news_edited') def news_edited_normalize_db(self, data): try: del data['version'] del data['status'] news = NewsQueryModel.objects.get(id=data.get('id')) news.update(**data) news.reload() self.set_cache(data) except Exception as e: logging.error(e) def set_cache(self, data): redis_data = json.dumps(data) self.redis.set(data.get('id'), redis_data) if not self.redis.get(data.get('id')): self.redis.rpush(CACHE_ALL, data.get('id'))
class AirportService(object): name = "airports_service" redis = Redis("development") @rpc def get(self, airport_id): """ Gets the airport object from Redis database using the airport_id :param: airport_id :return: Airport object :rtype: object """ airport = self.redis.get(airport_id) return airport @rpc def create(self, airport): """ Creates an airport object and returns the airport id :param: airport Airport Object :return: Airport id :rtype: str """ airport_id = uuid.uuid4().hex self.redis.set(airport_id, airport) return airport_id
class CrewService: name = 'crew_service' log = StructlogDependency() redis = Redis('development') @rpc def get(self, crew_id): self.log.info('start-get-crew') crew = self.redis.hgetall(crew_id) self.log.info('get-crew', crew_id=crew_id, crew=crew) self.log.info('end-get-crew') return crew @rpc def add(self, ship_id, name, designation, crew_race): self.log.info('start-add-crew') crew_id = uuid.uuid4().hex crew = { "ship_id": ship_id, "name": name, "designation": designation, "race": crew_race } self.log.info("add-crew", crew=crew, crew_id=crew_id) self.redis.hmset(crew_id, crew) self.log.info('end-add-crew') return crew_id
class RoomService: """ Room service class """ name = "rooms_service" redis = Redis('development') @rpc def get(self, room_id): """ get a room by id :param room_id: :return: """ room = self.redis.hget(room_id) return room @rpc def create(self, room_user, room_number): """ Create a room :param room_user: :param room_number: :return: """ room_id = uuid.uuid4().hex self.redis.hmset(room_id, { "room_user": room_user, "room_number": room_number }) return room_id
class SalesforceService: name = 'salesforce' contacts_rpc = RpcProxy('contacts') salesforce = SalesforceAPI() source_tracker = SourceTracker() redis = Redis('lock') schedule_task = ScheduleTask() @event_handler('contacts', 'contact_created') def handle_platform_contact_created(self, payload): if self.source_tracker.is_sourced_from_salesforce(): print("Ignoring event that was sourced from salesforce") return self.schedule_task(self.create_on_salesforce, payload) @handle_sobject_notification('Contact', exclude_current_user=True, notify_for_operation_update=False) @skip_duplicates(operator.attrgetter('redis'), key=skip_duplicate_key) def handle_sf_contact_created(self, sobject_type, record_type, notification): self.schedule_task(self.create_on_platform, notification) @task @debounce(operator.attrgetter('redis'), key=debounce_key_sf, repeat=True) @entrypoint_retry( retry_for=ValueError, limit=4, schedule=(1000, 1000, 2000), ) def create_on_salesforce(self, payload): print('Trying to create on salesforce...') raise ValueError() result = self.salesforce.Contact.create( {'LastName': payload['contact']['name']}) print('Created {} on salesforce'.format(result)) @task @debounce(operator.attrgetter('redis'), key=debounce_key_plat, repeat=True) @entrypoint_retry( retry_for=ValueError, limit=4, schedule=(1000, 1000, 2000), ) def create_on_platform(self, payload): with self.source_tracker.sourced_from_salesforce(): contact = self.contacts_rpc.create_contact( {'name': payload['sobject']['Name']}) print('Created {} on platform'.format(contact))
class TemperatureService: name = ServicesNames.TEMPERATURE_SERVICE dispatch = EventDispatcher() redis = Redis(REDIS_NAME) @rpc def update_temperature(self): humidity, temperature = dht.read_retry(dht.DHT22, TEMPERATURE_SENSOR_PIN) self.redis.set('temperature', temperature)
def test_options(self, strict_redis_cls): client = Redis('redis-uri', decode_responses=False, retry_on_timeout=True, socket_timeout=2, encoding='utf-8') client.redis_uri = 'redis-uri' client.start() expected_options = { 'decode_responses': False, 'retry_on_timeout': True, 'socket_timeout': 2, 'encoding': 'utf-8', } assert [call('redis-uri', **expected_options) ] == strict_redis_cls.from_url.call_args_list
class ExampleService(object): name = "exampleservice" redis = Redis('server') @dummy def write(self, value): self.redis.set(TEST_KEY, value) @dummy def read(self): return self.redis.get(TEST_KEY)
class TripsService: name = 'trips_service' redis = Redis('development') @rpc def get(self, trip_id): trip = self.redis.get(trip_id) return trip @rpc def create(self, airport_from_id, airport_to_id): trip_id = uuid.uuid4().hex self.redis.set(trip_id, {"from": airport_from_id, "to": airport_to_id}) return trip_id
class AirportsService: name = 'airports_service' redis = Redis('development') @rpc def get(self, airport_id): airport = self.redis.get(airport_id) return airport @rpc def create(self, airport): airport_id = uuid.uuid4().hex self.redis.set(airport_id, airport) return airport_id
class Service4: """ Microservice responsible for receiving data notifications from Service3 and dispatching those data to the Client. Attributes: name (str): The microservice name. _redis (Redis): Nameko Redis connector object. _publication (Exchange): Messagin exchange object. _publish (Publisher): Messaging publisher object. """ name = 'service4' _redis = Redis('my_redis') _publication = Exchange('new_publication', type='direct') _publish = Publisher(exchange=_publication) @event_handler('service3', 'number_published') def receive_publication(self, payload: str): """ Event handler function receiver published number from service3 Args: payload (str): A new number published according service3 rules """ self.dispatch_publication(payload) @rpc def dispatch_publication(self, payload: str): """ Notify an event with the passed payload :param payload: A published number to be notify to the client """ self._publish(payload) @rpc def get_history(self) -> List[str]: """ Get the last 100 publications from Redis Database Returns: List[str]: Last publications """ if self._redis.llen('published_numbers') > 100: history = self._redis.lrange('published_numbers', -100, -1) else: history = self._redis.lrange('published_numbers', 0, -1) return history
class DriverService: name = "driver_service" redis = Redis("development") @rpc def get(self, driver_id): driver = self.redis.get(driver_id) return driver @rpc def create(self, driver_name): driver_id = str(uuid.uuid4()) self.redis.set(driver_id, driver_name) return driver_id
class PassengerService: name = "passenger_service" redis = Redis("development") @rpc def get(self, passenger_id): passenger = self.redis.get(passenger_id) return passenger @rpc def create(self, passenger_name): passenger_id = int(uuid.uuid4()) self.redis.set(passenger_id, passenger_name) return passenger_id
class UltrasoundService: name = ServicesNames.ULTRASOUND_SERVICE dispatch = EventDispatcher() redis = Redis(REDIS_NAME) @staticmethod def distance(ultrasound_sensor, temperature): GPIO.output(ultrasound_sensor.trigger_pin, True) time.sleep(0.00001) GPIO.output(ultrasound_sensor.trigger_pin, False) StartTime = time.time() StopTime = time.time() # save StartTime while GPIO.input(ultrasound_sensor.echo_pin) == 0: StartTime = time.time() # save time of arrival while GPIO.input(ultrasound_sensor.echo_pin) == 1: StopTime = time.time() # time difference between start and arrival TimeElapsed = StopTime - StartTime # distance = (TimeElapsed * 34300*(1+float(temperature)/273)) / 2 distance = (TimeElapsed * 34300) / 2 return distance @rpc def run(self): temperature = self.redis.get('temperature') if not temperature: temperature = 25 right_front_distance = self.distance(ULTRA_SOUND_SENSOR_RIGHT, temperature) left_front_distance = self.distance(ULTRA_SOUND_SENSOR_LEFT, temperature) middle_front_distance = self.distance(ULTRA_SOUND_SENSOR_MIDDLE, temperature) if right_front_distance < 15 or middle_front_distance < 15 or left_front_distance < 15: self.dispatch(EventNames.TRIGGER_LIGHTS, True) self.dispatch(EventNames.TRIGGER_ENGINES, {'drive': False}) else: self.dispatch(EventNames.TRIGGER_LIGHTS, False) self.dispatch(EventNames.TRIGGER_ENGINES, { 'drive': True, 'direction': 'forward' })
class CameraService: name = ServicesNames.CAMERA_SERVICE dispatch = EventDispatcher() redis = Redis(REDIS_NAME) @classmethod def string_base64_to_image(cls, base64_string): imgdata = base64.b64decode(base64_string) return cv2.cvtColor(np.array(Image.open(io.BytesIO(imgdata))), cv2.COLOR_RGB2BGR) @rpc def run(self, image): steering_angle = LaneRecognition.process_image( self.string_base64_to_image(image)) print(steering_angle) self.dispatch(EventNames.TRIGGER_ENGINES, {'steering_angle': steering_angle})
class ShoppingCartService: logger = logging.getLogger(__name__) name = 'shopping_carts' redis = Redis('development') def _schema(self, **kwargs): _data = { 'id': kwargs.get('id', uuid.uuid4().hex), 'account_id': kwargs.get('account_id', None), 'listings': kwargs.get('listings', {}), } return dict((k, v) for k, v in _data.items() if v) @rpc def create(self, account_id, listings=None): cart = ShoppingCart.create(account_id) data = self._schema(**cart.to_dict()) cart_id = data.get('id') self._write_data(cart_id, data) return cart_id @rpc def get(self, cart_id): cart = self.redis.hgetall(cart_id) self.logger.info(cart) return cart @rpc def add_listing(self, cart_id: str, listing_id: str, quantity: int) -> None: data = self.redis.hgetall(cart_id) cart = ShoppingCart.from_dict(data) cart.add_listing(listing_id, quantity) self.logger.info(cart) return cart def _write_data(self, _id, data): self.redis.hmset(_id, data) return _id
class QueryNewsService: name = 'query_stack' redis = Redis('cache', encoding='utf-8') @rpc def list_news(self, page, limit): try: if not page: page = 1 offset = (page - 1) * limit # gettting list from cache news_list = self.redis.lrange(CACHE_ALL, (page - 1), limit) if news_list: logging.info('list from cache') return json.dumps( [self.redis.get(news_id) for news_id in news_list]) news_list = NewsQueryModel.objects.skip(offset).limit(limit) logging.info('list from DB') return news_list.to_json() except Exception as e: logging.error(e) return json.dumps({'error': str(e)}) @rpc def get_news(self, news_id): try: # getting from cache news = self.redis.get(news_id) if news: logging.info('from cache') return news news = NewsQueryModel.objects.get(id=news_id) logging.info('from DB') return news.to_json() except mongoengine.DoesNotExist as e: logging.error(e) return json.dumps({'error': str(e)}) except Exception as e: logging.error(e) return json.dumps({'error': str(e)})
class TripService: name = "trip_service" redis = Redis("development") @rpc def get(self, trip_id): trip_data = self.redis.hgetall(trip_id) return trip_data @rpc def create(self, passenger_name, driver_name, from_loc, to_loc): trip_id = str(uuid.uuid4()) self.redis.hmset(trip_id, { "passenger_name": passenger_name, "driver_name": driver_name, "from_loc": from_loc, "to_loc": to_loc }) return trip_id
class ShipService: name = 'ship_service' log = StructlogDependency() redis = Redis('development') @rpc def get(self, ship_id): self.log.info('start-get-ship') ship = self.redis.get(ship_id) self.log.info('get-ship', ship_id=ship_id, ship=ship) self.log.info('end-get-ship') return ship @rpc def add(self, ship): self.log.info('start-add-ship') ship_id = uuid.uuid4().hex self.log.info('add-ship', ship_id=ship_id, ship=ship) self.redis.set(ship_id, ship) self.log.info('end-add-ship') return ship_id
class PricingService: def __init__(self, json_string): instance = parse_as_obj(json_string) self.content = json_string self.customerId = instance.customerId self.createdDate = instance.createdDate self.deliveryType = instance.deliveryType self.address = instance.address if hasattr(instance, 'items'): self.items = [] for item in instance.items: self.items.append(Product(item)) _DEFAULT_DATE_FORMAT = "%Y-%m-%d" _FACTOR = 320 redis = Redis('development') @property def is_valid(self): return len(self.items) and all( [item.is_valid() for item in self.items])
class AirportsService: name = "airports_service" redis = Redis('development') # Now the struture is following # airport_id: { # airport: string, # trips: array # } @rpc def get(self, airport_id): airport = self.redis.get(airport_id) print(airport) return airport @rpc def create(self, airport): airport_id = uuid.uuid4().hex print("aaaaaaaaaaaaaaaaaaaaaaaaa") self.redis.hmset(airport_id, {'airport': airport, 'trips': None}) return airport_id
class TimeService: name = "time_service" day_coef = [1, 1, 1, 1, 1, .75, .5] parameter_service = RpcProxy('parameter_service') redis = Redis('development') # TODO implement timezones (Now let's leave only UTC for simplicity) @staticmethod def get_now(): return datetime.datetime.utcnow() def get_today(self): now = self.get_now() return datetime.datetime(now.year, now.month, now.day) def get_end_of_year(self): now = self.get_now() return datetime.datetime(now.year + 1, 1, 1) - datetime.timedelta(1) @staticmethod def get_num_days_between(start: datetime, end: datetime, week_day: int) -> int: num_weeks, remainder = divmod((end - start).days, 7) if (week_day - start.weekday()) % 7 <= remainder: return num_weeks + 1 else: return num_weeks def get_seconds_until_midnight(self, dt: datetime = None) -> int: dt = dt or self.get_now() this_day = datetime.datetime(dt.year, dt.month, dt.day) next_day = this_day + datetime.timedelta(1) return abs(next_day - dt).seconds def get_days_until_midnight(self, dt: datetime = None) -> float: dt = dt or self.get_now() this_day = datetime.datetime(dt.year, dt.month, dt.day) time_in_days = self.get_seconds_until_midnight(dt) / (24 * 60 * 60) return self.day_coef[this_day.weekday()] * time_in_days @rpc def get_time_left(self, dt: datetime = None, until_day: datetime = None) -> float: dt = dt or self.get_now() until_day = until_day or self.get_end_of_year() time_in_days = self.get_days_until_midnight(dt) # TODO Cache this_day and time_in_days. Makes sense to recalculate only when this_day != cache this_day = datetime.datetime(dt.year, dt.month, dt.day) next_day = this_day + datetime.timedelta(1) for i, coef in enumerate(self.day_coef): time_in_days += coef * self.get_num_days_between( next_day, until_day, i) return time_in_days def set_timer(self, days: float, callback, *args, **kwargs): period = days * (24 * 60 * 60) / self.day_coef[self.get_today().weekday()] timer = threading.Timer(period, callback, args, kwargs) timer.start() # TODO Investigate how to pass callback without wrapping them in time_service @rpc def update_param_after(self, days): self.set_timer(days, self.parameter_service.update_param)