You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2021/11/04 04:34:38 UTC
[skywalking-showcase] 05/12: Add Python service
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 <ke...@apache.org>
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)
;