From 82dfa5974c5f39e17a3f5bee43989f882ac4907f Mon Sep 17 00:00:00 2001 From: Guilherme Caminha Date: Sun, 27 May 2018 11:58:15 -0300 Subject: [PATCH] Adding microservices. --- README.md | 8 ++++++ airports/Dockerfile | 16 +++++++++++ airports/airports.py | 21 +++++++++++++++ airports/config.yml | 3 +++ airports/requirements.txt | 2 ++ airports/run.sh | 13 +++++++++ docker-compose.yml | 56 +++++++++++++++++++++++++++++++++++++++ gateway/Dockerfile | 16 +++++++++++ gateway/config.yml | 1 + gateway/gateway.py | 35 ++++++++++++++++++++++++ gateway/requirements.txt | 1 + gateway/run.sh | 8 ++++++ trips/Dockerfile | 16 +++++++++++ trips/config.yml | 3 +++ trips/requirements.txt | 2 ++ trips/run.sh | 13 +++++++++ trips/trips.py | 24 +++++++++++++++++ 17 files changed, 238 insertions(+) create mode 100644 README.md create mode 100644 airports/Dockerfile create mode 100644 airports/airports.py create mode 100644 airports/config.yml create mode 100644 airports/requirements.txt create mode 100644 airports/run.sh create mode 100644 docker-compose.yml create mode 100644 gateway/Dockerfile create mode 100644 gateway/config.yml create mode 100644 gateway/gateway.py create mode 100644 gateway/requirements.txt create mode 100644 gateway/run.sh create mode 100644 trips/Dockerfile create mode 100644 trips/config.yml create mode 100644 trips/requirements.txt create mode 100644 trips/run.sh create mode 100644 trips/trips.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..0b7532b --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +## Nameko microservices + +Simple microservices example using Nameko. + + +## Running + +`$ docker-compose up` diff --git a/airports/Dockerfile b/airports/Dockerfile new file mode 100644 index 0000000..8d63535 --- /dev/null +++ b/airports/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3 + +RUN apt-get update && apt-get -y install netcat && apt-get clean + +WORKDIR /app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY config.yml ./ +COPY run.sh ./ +COPY airports.py ./ + +RUN chmod +x ./run.sh + +CMD ["./run.sh"] diff --git a/airports/airports.py b/airports/airports.py new file mode 100644 index 0000000..1acadd4 --- /dev/null +++ b/airports/airports.py @@ -0,0 +1,21 @@ +import uuid + +from nameko.rpc import rpc +from nameko_redis import Redis + + +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 diff --git a/airports/config.yml b/airports/config.yml new file mode 100644 index 0000000..fbb98cb --- /dev/null +++ b/airports/config.yml @@ -0,0 +1,3 @@ +AMQP_URI: amqp://${RABBIT_USER}:${RABBIT_PASSWORD}@${RABBIT_HOST}:${RABBIT_PORT}/ +REDIS_URIS: + development: redis://${REDIS_HOST}:${REDIS_PORT}/0 \ No newline at end of file diff --git a/airports/requirements.txt b/airports/requirements.txt new file mode 100644 index 0000000..3fb7e30 --- /dev/null +++ b/airports/requirements.txt @@ -0,0 +1,2 @@ +nameko +nameko-redis \ No newline at end of file diff --git a/airports/run.sh b/airports/run.sh new file mode 100644 index 0000000..e0e9dcd --- /dev/null +++ b/airports/run.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +until nc -z ${RABBIT_HOST} ${RABBIT_PORT}; do + echo "$(date) - waiting for rabbitmq..." + sleep 1 +done + +until nc -z ${REDIS_HOST} ${REDIS_PORT}; do + echo "$(date) - waiting for redis..." + sleep 1 +done + +nameko run --config config.yml airports diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..cb45b1a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,56 @@ +version: "2" +services: + + redis: + image: redis:4-alpine + command: ["redis-server", "--appendonly", "yes"] + hostname: redis + volumes: + - redis-data:/data + + rabbit: + image: rabbitmq:3.6-management + ports: + - "15672:15672" + + airports: + build: + context: airports + depends_on: + - rabbit + environment: + REDIS_HOST: "redis" + REDIS_PORT: "6379" + RABBIT_PASSWORD: "guest" + RABBIT_USER: "guest" + RABBIT_HOST: "rabbit" + RABBIT_PORT: "5672" + + trips: + build: + context: trips + depends_on: + - rabbit + environment: + REDIS_HOST: "redis" + REDIS_PORT: "6379" + RABBIT_PASSWORD: "guest" + RABBIT_USER: "guest" + RABBIT_HOST: "rabbit" + RABBIT_PORT: "5672" + + gateway: + build: + context: gateway + depends_on: + - rabbit + ports: + - "8000:8000" + environment: + RABBIT_PASSWORD: "guest" + RABBIT_USER: "guest" + RABBIT_HOST: "rabbit" + RABBIT_PORT: "5672" + +volumes: + redis-data: \ No newline at end of file diff --git a/gateway/Dockerfile b/gateway/Dockerfile new file mode 100644 index 0000000..bf191e2 --- /dev/null +++ b/gateway/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3 + +RUN apt-get update && apt-get -y install netcat && apt-get clean + +WORKDIR /app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY config.yml ./ +COPY run.sh ./ +COPY gateway.py ./ + +RUN chmod +x ./run.sh + +CMD ["./run.sh"] diff --git a/gateway/config.yml b/gateway/config.yml new file mode 100644 index 0000000..c380693 --- /dev/null +++ b/gateway/config.yml @@ -0,0 +1 @@ +AMQP_URI: amqp://${RABBIT_USER}:${RABBIT_PASSWORD}@${RABBIT_HOST}:${RABBIT_PORT}/ diff --git a/gateway/gateway.py b/gateway/gateway.py new file mode 100644 index 0000000..9afc8d9 --- /dev/null +++ b/gateway/gateway.py @@ -0,0 +1,35 @@ +import json + +from nameko.rpc import RpcProxy +from nameko.web.handlers import http + + +class GatewayService: + name = 'gateway' + + airports_rpc = RpcProxy('airports_service') + trips_rpc = RpcProxy('trips_service') + + @http('GET', '/airport/') + def get_airport(self, request, airport_id): + airport = self.airports_rpc.get(airport_id) + return json.dumps({'airport': airport}) + + @http('POST', '/airport') + def post_airport(self, request): + data = json.loads(request.get_data(as_text=True)) + airport_id = self.airports_rpc.create(data['airport']) + + return airport_id + + @http('GET', '/trip/') + def get_trip(self, request, trip_id): + trip = self.trips_rpc.get(trip_id) + return json.dumps({'trip': trip}) + + @http('POST', '/trip') + def post_trip(self, request): + data = json.loads(request.get_data(as_text=True)) + trip_id = self.trips_rpc.create(data['airport_from'], data['airport_to']) + + return trip_id diff --git a/gateway/requirements.txt b/gateway/requirements.txt new file mode 100644 index 0000000..f09d9bd --- /dev/null +++ b/gateway/requirements.txt @@ -0,0 +1 @@ +nameko diff --git a/gateway/run.sh b/gateway/run.sh new file mode 100644 index 0000000..044e7dc --- /dev/null +++ b/gateway/run.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +until nc -z ${RABBIT_HOST} ${RABBIT_PORT}; do + echo "$(date) - waiting for rabbitmq..." + sleep 1 +done + +nameko run --config config.yml gateway diff --git a/trips/Dockerfile b/trips/Dockerfile new file mode 100644 index 0000000..0f7a49a --- /dev/null +++ b/trips/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3 + +RUN apt-get update && apt-get -y install netcat && apt-get clean + +WORKDIR /app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY config.yml ./ +COPY run.sh ./ +COPY trips.py ./ + +RUN chmod +x ./run.sh + +CMD ["./run.sh"] diff --git a/trips/config.yml b/trips/config.yml new file mode 100644 index 0000000..fb5d517 --- /dev/null +++ b/trips/config.yml @@ -0,0 +1,3 @@ +AMQP_URI: amqp://${RABBIT_USER}:${RABBIT_PASSWORD}@${RABBIT_HOST}:${RABBIT_PORT}/ +REDIS_URIS: + development: redis://${REDIS_HOST}:${REDIS_PORT}/1 \ No newline at end of file diff --git a/trips/requirements.txt b/trips/requirements.txt new file mode 100644 index 0000000..3fb7e30 --- /dev/null +++ b/trips/requirements.txt @@ -0,0 +1,2 @@ +nameko +nameko-redis \ No newline at end of file diff --git a/trips/run.sh b/trips/run.sh new file mode 100644 index 0000000..0122a30 --- /dev/null +++ b/trips/run.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +until nc -z ${RABBIT_HOST} ${RABBIT_PORT}; do + echo "$(date) - waiting for rabbitmq..." + sleep 1 +done + +until nc -z ${REDIS_HOST} ${REDIS_PORT}; do + echo "$(date) - waiting for redis..." + sleep 1 +done + +nameko run --config config.yml trips diff --git a/trips/trips.py b/trips/trips.py new file mode 100644 index 0000000..7e0595a --- /dev/null +++ b/trips/trips.py @@ -0,0 +1,24 @@ +import uuid + +from nameko.rpc import rpc +from nameko_redis import Redis + + +class AirportsService: + 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