This is an automated email from the ASF dual-hosted git repository. kezhenxu94 pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/skywalking-showcase.git
commit 28db6046d8f9675d38419027d83e086821ac80ae Author: kezhenxu94 <[email protected]> AuthorDate: Fri Oct 29 14:41:02 2021 +0800 Add Python service --- .gitignore | 2 +- Makefile | 26 ++++++++++---- Makefile.in | 6 ++++ deploy/platform/docker/.env | 3 -- deploy/platform/docker/Makefile | 6 +--- deploy/platform/docker/docker-compose.yaml | 22 +++++++++--- services/camry-music/package.json | 10 ++++++ .../src/main/resources/application.yaml | 4 +++ services/recommendation-service/.dockerignore | 2 ++ services/recommendation-service/Dockerfile | 11 ++++++ .../recommendation-service/Makefile | 16 +++++++-- services/recommendation-service/requirements.txt | 2 ++ services/recommendation-service/src/app.py | 40 ++++++++++++++++++++++ .../services/song/SongServiceApplication.java | 17 +++++++-- .../services/song/controller/SongController.java | 19 ++++++++++ .../showcase/services/song/entity/Song.java | 3 ++ .../showcase/services/song/repo/SongsRepo.java | 2 ++ .../showcase/services/song/vo/TrendingList.java | 11 ++++++ services/songs-service/src/main/resources/data.sql | 8 +++-- 19 files changed, 181 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index b14baaa..6388ee9 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,7 @@ # Ignore Gradle build output directory build -.venv +venv .DS_Store diff --git a/Makefile b/Makefile index afe2e86..2ccce23 100644 --- a/Makefile +++ b/Makefile @@ -16,18 +16,30 @@ # under the License. # +# Build each project under services/* + +services = $(wildcard services/*) + +.PHONY: $(services) +$(services): + $(MAKE) -C $@ build + .PHONY: build -build: - $(MAKE) -C services/gateway-service build - $(MAKE) -C services/songs-service build +build: $(services) + +# Build Docker images + +services_docker = $(foreach svc,$(services),$(svc).docker.build) .PHONY: docker -docker: docker.build +docker: $(services_docker) + +.PHONY: $(services_docker) +$(services_docker): %.docker.build: % + $(MAKE) -C $< docker.build .PHONY: docker.build -docker.build: - $(MAKE) -C services/gateway-service docker.build - $(MAKE) -C services/songs-service docker.build +docker.build: $(services_docker) .PHONY: deploy.docker deploy.docker: undeploy.docker docker.build diff --git a/Makefile.in b/Makefile.in index 1a32095..800ad9a 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,5 +16,11 @@ # under the License. # +.EXPORT_ALL_VARIABLES: + HUB ?= ghcr.io/apache/skywalking-showcase TAG ?= $(shell git rev-parse --short HEAD) + +ES_VERSION ?= 7.10.0 +OAP_IMAGE ?= ghcr.io/apache/skywalking/oap:c9bd79e8bb974e404766e3490c00c7404b9baf1e +ROCKET_BOT_IMAGE ?= ghcr.io/apache/skywalking/ui:c9bd79e8bb974e404766e3490c00c7404b9baf1e diff --git a/deploy/platform/docker/.env b/deploy/platform/docker/.env deleted file mode 100644 index 977da00..0000000 --- a/deploy/platform/docker/.env +++ /dev/null @@ -1,3 +0,0 @@ -ES_VERSION=7.10.0 -OAP_IMAGE=ghcr.io/apache/skywalking/oap:c9bd79e8bb974e404766e3490c00c7404b9baf1e -ROCKET_BOT_IMAGE=ghcr.io/apache/skywalking/ui:c9bd79e8bb974e404766e3490c00c7404b9baf1e diff --git a/deploy/platform/docker/Makefile b/deploy/platform/docker/Makefile index 06547b7..f0b5f4b 100644 --- a/deploy/platform/docker/Makefile +++ b/deploy/platform/docker/Makefile @@ -2,12 +2,8 @@ include ../../../Makefile.in .PHONY: deploy deploy: - export HUB=$(HUB); \ - export TAG=$(TAG); \ docker-compose up -d .PHONY: undeploy undeploy: - export HUB=$(HUB); \ - export TAG=$(TAG); \ - docker-compose down + docker-compose --log-level ERROR down diff --git a/deploy/platform/docker/docker-compose.yaml b/deploy/platform/docker/docker-compose.yaml index 201a8d6..f23f0d3 100644 --- a/deploy/platform/docker/docker-compose.yaml +++ b/deploy/platform/docker/docker-compose.yaml @@ -55,8 +55,6 @@ services: environment: SW_AGENT_NAME: gateway SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800 - ports: - - "7389:80" healthcheck: test: [ "CMD-SHELL", "wget http://localhost/actuator/health" ] interval: 30s @@ -74,8 +72,6 @@ services: environment: SW_AGENT_NAME: songs SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800 - ports: - - "7390:80" healthcheck: test: [ "CMD-SHELL", "wget http://localhost/actuator/health" ] interval: 30s @@ -85,6 +81,21 @@ services: oap: condition: service_healthy + rcmd: + image: ${HUB}/recommendation-service:${TAG} + networks: [ sw ] + environment: + SW_AGENT_NAME: recommendation + SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800 + healthcheck: + test: [ "CMD-SHELL", "curl http://localhost/health" ] + interval: 30s + timeout: 10s + retries: 3 + depends_on: + oap: + condition: service_healthy + loadgen: image: curlimages/curl networks: [ sw ] @@ -96,7 +107,8 @@ services: - -c - | while true; do - curl http://gateway/songs + curl http://gateway/songs/top + curl http://gateway/songs/favorites sleep 3 done diff --git a/services/camry-music/package.json b/services/camry-music/package.json new file mode 100644 index 0000000..6e45e8b --- /dev/null +++ b/services/camry-music/package.json @@ -0,0 +1,10 @@ +{ + "name": "camry-music", + "version": "1.0.0", + "description": "The entrypoint of the showcase application", + "main": "index.js", + "scripts": { + }, + "author": "kezhenxu94", + "license": "Apache-2.0" +} diff --git a/services/gateway-service/src/main/resources/application.yaml b/services/gateway-service/src/main/resources/application.yaml index 582dff9..4fa9a53 100644 --- a/services/gateway-service/src/main/resources/application.yaml +++ b/services/gateway-service/src/main/resources/application.yaml @@ -10,3 +10,7 @@ spring: uri: http://songs predicates: - Path=/songs/** + - id: recommendation-service + uri: http://rcmd + predicates: + - Path=/rcmd/** diff --git a/services/recommendation-service/.dockerignore b/services/recommendation-service/.dockerignore new file mode 100644 index 0000000..a415184 --- /dev/null +++ b/services/recommendation-service/.dockerignore @@ -0,0 +1,2 @@ +venv +.venv diff --git a/services/recommendation-service/Dockerfile b/services/recommendation-service/Dockerfile new file mode 100644 index 0000000..bff98f7 --- /dev/null +++ b/services/recommendation-service/Dockerfile @@ -0,0 +1,11 @@ +FROM apache/skywalking-python:0.7.0-grpc-py3.9 + +WORKDIR /workspace + +COPY requirements.txt . + +RUN pip install -r requirements.txt + +COPY src . + +CMD python app.py diff --git a/Makefile.in b/services/recommendation-service/Makefile similarity index 74% copy from Makefile.in copy to services/recommendation-service/Makefile index 1a32095..3395621 100644 --- a/Makefile.in +++ b/services/recommendation-service/Makefile @@ -16,5 +16,17 @@ # under the License. # -HUB ?= ghcr.io/apache/skywalking-showcase -TAG ?= $(shell git rev-parse --short HEAD) +include ../../Makefile.in + +.PHONY: build +build: docker.build + +.PHONY: docker docker.build docker.push + +docker: docker.push + +docker.build: + docker build . -t $(HUB)/recommendation-service:$(TAG) + +docker.push: docker.build + docker push $(HUB)/recommendation-service:$(TAG) diff --git a/services/recommendation-service/requirements.txt b/services/recommendation-service/requirements.txt new file mode 100644 index 0000000..50691c2 --- /dev/null +++ b/services/recommendation-service/requirements.txt @@ -0,0 +1,2 @@ +Flask==2.0.2 +requests==2.26.0 diff --git a/services/recommendation-service/src/app.py b/services/recommendation-service/src/app.py new file mode 100644 index 0000000..64aa0b1 --- /dev/null +++ b/services/recommendation-service/src/app.py @@ -0,0 +1,40 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import os + +import requests + +if __name__ == '__main__': + from flask import Flask, jsonify + + app = Flask(__name__) + + + @app.route('/health', methods=['GET']) + def health(): + return 'OK' + + + @app.route('/rcmd', methods=['GET']) + def application(): + r = requests.get('http://gateway/songs') + recommendations = r.json() + return jsonify(recommendations) + + + PORT = os.getenv('PORT', 80) + app.run(host='0.0.0.0', port=PORT) diff --git a/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/SongServiceApplication.java b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/SongServiceApplication.java index 034a90f..3040714 100644 --- a/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/SongServiceApplication.java +++ b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/SongServiceApplication.java @@ -17,16 +17,27 @@ * under the License. * */ + package org.apache.skywalking.showcase.services.song; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.DefaultUriTemplateHandler; @SpringBootApplication public class SongServiceApplication { + @Bean + public RestTemplate restTemplate() { + return new RestTemplateBuilder() + .rootUri("http://gateway") + .build(); + } - public static void main(String[] args) { - SpringApplication.run(SongServiceApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(SongServiceApplication.class, args); + } } diff --git a/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/controller/SongController.java b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/controller/SongController.java index 6dcafb2..4fcbbb2 100644 --- a/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/controller/SongController.java +++ b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/controller/SongController.java @@ -22,18 +22,37 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.apache.skywalking.showcase.services.song.entity.Song; import org.apache.skywalking.showcase.services.song.repo.SongsRepo; +import org.apache.skywalking.showcase.services.song.vo.TrendingList; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; @RestController @RequiredArgsConstructor @RequestMapping("/songs") public class SongController { private final SongsRepo songsRepo; + private final RestTemplate restTemplate; @GetMapping public List<Song> songs() { return songsRepo.findAll(); } + + @GetMapping("/top") + public TrendingList top() { + final List<Song> top = songsRepo.findByLikedGreaterThan(1000); + final ResponseEntity<List<Song>> res = restTemplate.exchange( + "/rcmd", HttpMethod.GET, null, new ParameterizedTypeReference<List<Song>>() { + }); + if (res.getStatusCode() != HttpStatus.OK) { + throw new RuntimeException("Failed to get recommendations"); + } + return new TrendingList(top, res.getBody()); + } } diff --git a/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/entity/Song.java b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/entity/Song.java index 7d5a57a..10c683c 100644 --- a/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/entity/Song.java +++ b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/entity/Song.java @@ -43,4 +43,7 @@ public class Song { @Column private String genre; + + @Column(nullable = false) + private long liked = 0; } diff --git a/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/repo/SongsRepo.java b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/repo/SongsRepo.java index 7e12707..756053b 100644 --- a/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/repo/SongsRepo.java +++ b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/repo/SongsRepo.java @@ -18,10 +18,12 @@ package org.apache.skywalking.showcase.services.song.repo; +import java.util.List; import org.apache.skywalking.showcase.services.song.entity.Song; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface SongsRepo extends JpaRepository<Song, Integer> { + List<Song> findByLikedGreaterThan(long count); } diff --git a/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/vo/TrendingList.java b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/vo/TrendingList.java new file mode 100644 index 0000000..cc4438e --- /dev/null +++ b/services/songs-service/src/main/java/org/apache/skywalking/showcase/services/song/vo/TrendingList.java @@ -0,0 +1,11 @@ +package org.apache.skywalking.showcase.services.song.vo; + +import java.util.List; +import lombok.Data; +import org.apache.skywalking.showcase.services.song.entity.Song; + +@Data +public class TrendingList { + private final List<Song> top; + private final List<Song> recommendations; +} diff --git a/services/songs-service/src/main/resources/data.sql b/services/songs-service/src/main/resources/data.sql index 0bda17a..2942750 100644 --- a/services/songs-service/src/main/resources/data.sql +++ b/services/songs-service/src/main/resources/data.sql @@ -27,7 +27,9 @@ -- insert into song - (id, name, artist, genre) -values (1, '倩女幽魂', '张国荣', 'HK-POP'), - (2, '沉默是金', '张国荣', 'HK-POP') + (id, name, artist, genre, liked) +values (1, '倩女幽魂', '张国荣', 'HK-POP', 999), + (2, '沉默是金', '张国荣', 'HK-POP', 1000), + (3, '风继续吹', '张国荣', 'HK-POP', 1002), + (4, '灰色轨迹', 'Beyond', 'HK-POP', 9000) ;
