From 5a3a22159e67a48cb1b412011f1b9554eba05f32 Mon Sep 17 00:00:00 2001 From: Hecheng Li Date: Wed, 29 Aug 2018 19:39:56 +0800 Subject: [PATCH 01/12] Renamed project --- .gitignore | 25 ++++++ app/pom.xml | 83 +++++++++++++++++++ .../example/TianMiao/TianMiaoApplication.java | 21 +++++ .../TianMiao/controller/UserController.java | 61 ++++++++++++++ .../exception/ResourceNotFoundException.java | 30 +++++++ .../java/com/example/TianMiao/model/User.java | 72 ++++++++++++++++ .../TianMiao/repository/UserRepository.java | 11 +++ app/src/main/resources/application.properties | 12 +++ .../TianMeow/TianMeowApplicationTests.java | 16 ++++ 9 files changed, 331 insertions(+) create mode 100644 .gitignore create mode 100644 app/pom.xml create mode 100644 app/src/main/java/com/example/TianMiao/TianMiaoApplication.java create mode 100644 app/src/main/java/com/example/TianMiao/controller/UserController.java create mode 100644 app/src/main/java/com/example/TianMiao/exception/ResourceNotFoundException.java create mode 100644 app/src/main/java/com/example/TianMiao/model/User.java create mode 100644 app/src/main/java/com/example/TianMiao/repository/UserRepository.java create mode 100644 app/src/main/resources/application.properties create mode 100644 app/src/test/java/com/example/TianMeow/TianMeowApplicationTests.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82eca33 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ \ No newline at end of file diff --git a/app/pom.xml b/app/pom.xml new file mode 100644 index 0000000..76a0038 --- /dev/null +++ b/app/pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + + com.example + TianMiao + 0.0.1-SNAPSHOT + war + + TianMeow + Demo project for Online Shopping + + + org.springframework.boot + spring-boot-starter-parent + 2.0.4.RELEASE + + + + + UTF-8 + UTF-8 + 10 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + org.springframework.boot + spring-boot-devtools + runtime + + + mysql + mysql-connector-java + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + javax.xml.bind + jaxb-api + + + javax.servlet + javax.servlet-api + + + + + ${artifactId} + + + + + + + diff --git a/app/src/main/java/com/example/TianMiao/TianMiaoApplication.java b/app/src/main/java/com/example/TianMiao/TianMiaoApplication.java new file mode 100644 index 0000000..ba3dcc9 --- /dev/null +++ b/app/src/main/java/com/example/TianMiao/TianMiaoApplication.java @@ -0,0 +1,21 @@ +package com.example.TianMiao; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +@SpringBootApplication +@EnableJpaAuditing +public class TianMiaoApplication extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(TianMiaoApplication.class); + } + + public static void main(String[] args) { + SpringApplication.run(TianMiaoApplication.class, args); + } +} diff --git a/app/src/main/java/com/example/TianMiao/controller/UserController.java b/app/src/main/java/com/example/TianMiao/controller/UserController.java new file mode 100644 index 0000000..527bb4b --- /dev/null +++ b/app/src/main/java/com/example/TianMiao/controller/UserController.java @@ -0,0 +1,61 @@ +package com.example.TianMiao.controller; + +import java.util.List; + +import javax.validation.Valid; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.example.TianMiao.exception.ResourceNotFoundException; +import com.example.TianMiao.model.User; +import com.example.TianMiao.repository.UserRepository; + +@RestController +@RequestMapping("/api") +public class UserController { + @Autowired + UserRepository userRepository; + + @GetMapping("/users") + public List getAllUsers() { + return userRepository.findAll(); + } + + @PostMapping("/users") + public User createUser(@Valid @RequestBody User user) { + return userRepository.save(user); + } + + @GetMapping("/users/{id}") + public User getUserById(@PathVariable(value = "id") Long userId) { + return userRepository.findById(userId) + .orElseThrow(() -> new ResourceNotFoundException("User", "id", userId)); + } + + @PutMapping("/notes/{id}") + public User updateUser(@PathVariable(value = "id") Long userId, @Valid @RequestBody User userDetails) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new ResourceNotFoundException("User", "id", userId)); + + user.setUsername(userDetails.getUsername()); + User updatedUser = userRepository.save(user); + return updatedUser; + } + + @DeleteMapping("/notes/{id}") + public ResponseEntity deleteUser(@PathVariable(value = "id") Long userId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new ResourceNotFoundException("User", "id", userId)); + userRepository.delete(user); + return ResponseEntity.ok().build(); + } +} diff --git a/app/src/main/java/com/example/TianMiao/exception/ResourceNotFoundException.java b/app/src/main/java/com/example/TianMiao/exception/ResourceNotFoundException.java new file mode 100644 index 0000000..0d2837d --- /dev/null +++ b/app/src/main/java/com/example/TianMiao/exception/ResourceNotFoundException.java @@ -0,0 +1,30 @@ +package com.example.TianMiao.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(value = HttpStatus.NOT_FOUND) +public class ResourceNotFoundException extends RuntimeException { + private String resourceName; + private String fieldName; + private Object fieldValue; + + public ResourceNotFoundException( String resourceName, String fieldName, Object fieldValue) { + super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue)); + this.resourceName = resourceName; + this.fieldName = fieldName; + this.fieldValue = fieldValue; + } + + public String getResourceName() { + return resourceName; + } + + public String getFieldName() { + return fieldName; + } + + public Object getFieldValue() { + return fieldValue; + } +} diff --git a/app/src/main/java/com/example/TianMiao/model/User.java b/app/src/main/java/com/example/TianMiao/model/User.java new file mode 100644 index 0000000..24360f1 --- /dev/null +++ b/app/src/main/java/com/example/TianMiao/model/User.java @@ -0,0 +1,72 @@ +package com.example.TianMiao.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import javax.persistence.*; +import javax.validation.constraints.NotBlank; + +import java.io.Serializable; +import java.util.Date; + +@Entity +@Table(name = "user") +@EntityListeners(AuditingEntityListener.class) +@JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true) +public class User implements Serializable { + /** + * + */ + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotBlank + private String username; + + @Column(nullable = false, updatable = false) + @Temporal(TemporalType.TIMESTAMP) + @CreatedDate + private Date createdAt; + + @Column(nullable = false) + @Temporal(TemporalType.TIMESTAMP) + @LastModifiedDate + private Date updatedAt; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + +} diff --git a/app/src/main/java/com/example/TianMiao/repository/UserRepository.java b/app/src/main/java/com/example/TianMiao/repository/UserRepository.java new file mode 100644 index 0000000..cf4385d --- /dev/null +++ b/app/src/main/java/com/example/TianMiao/repository/UserRepository.java @@ -0,0 +1,11 @@ +package com.example.TianMiao.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.example.TianMiao.model.User; + +@Repository +public interface UserRepository extends JpaRepository { + +} diff --git a/app/src/main/resources/application.properties b/app/src/main/resources/application.properties new file mode 100644 index 0000000..52c2f98 --- /dev/null +++ b/app/src/main/resources/application.properties @@ -0,0 +1,12 @@ +## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) +spring.datasource.url = jdbc:mysql://mysql/TianMiao?allowPublicKeyRetrieval=true&useSSL=false +spring.datasource.username = root +spring.datasource.password = password + + +## Hibernate Properties +# The SQL dialect makes Hibernate generate better SQL for the chosen database +spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect + +# Hibernate ddl auto (create, create-drop, validate, update) +spring.jpa.hibernate.ddl-auto = update \ No newline at end of file diff --git a/app/src/test/java/com/example/TianMeow/TianMeowApplicationTests.java b/app/src/test/java/com/example/TianMeow/TianMeowApplicationTests.java new file mode 100644 index 0000000..63faafa --- /dev/null +++ b/app/src/test/java/com/example/TianMeow/TianMeowApplicationTests.java @@ -0,0 +1,16 @@ +package com.example.TianMeow; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class TianMeowApplicationTests { + + @Test + public void contextLoads() { + } + +} From bdc93c8f163c46fd9d1a5f90229718eca55157d1 Mon Sep 17 00:00:00 2001 From: "Hecheng(Chris) Li" Date: Thu, 30 Aug 2018 17:11:26 +0800 Subject: [PATCH 02/12] modified: TianMiao/pom.xml index.html --- app/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pom.xml b/app/pom.xml index 76a0038..6c4677c 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -8,7 +8,7 @@ 0.0.1-SNAPSHOT war - TianMeow + TianMiao Demo project for Online Shopping From 0c719e32656a6fee2ae3f153ca0aab216c65949d Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Wed, 2 Sep 2020 09:13:20 -0400 Subject: [PATCH 03/12] things work Signed-off-by: Joe Elliott --- app/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/pom.xml b/app/pom.xml index 6c4677c..2301056 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -72,10 +72,10 @@ ${artifactId} - + From 36bdf34a58ceaa3a2cc6ed719cc967bc86b2ab64 Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Wed, 2 Sep 2020 09:44:23 -0400 Subject: [PATCH 04/12] tracing works! Signed-off-by: Joe Elliott --- app/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/pom.xml b/app/pom.xml index 2301056..45269cd 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -66,6 +66,12 @@ javax.servlet javax.servlet-api + + + + io.opentracing.contrib + opentracing-spring-jaeger-cloud-starter + 3.1.2 From d9d7c503d208d3f0dcfa0eebf4c373fc62c7a15e Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Wed, 2 Sep 2020 10:04:18 -0400 Subject: [PATCH 05/12] Added sibling and parent/child traces Signed-off-by: Joe Elliott --- .../TianMiao/controller/UserController.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/example/TianMiao/controller/UserController.java b/app/src/main/java/com/example/TianMiao/controller/UserController.java index 527bb4b..640ccff 100644 --- a/app/src/main/java/com/example/TianMiao/controller/UserController.java +++ b/app/src/main/java/com/example/TianMiao/controller/UserController.java @@ -1,6 +1,7 @@ package com.example.TianMiao.controller; import java.util.List; +import java.util.Map; import javax.validation.Valid; @@ -19,6 +20,11 @@ import com.example.TianMiao.model.User; import com.example.TianMiao.repository.UserRepository; +import io.opentracing.Scope; +import io.opentracing.Span; +import io.opentracing.Tracer; +import io.opentracing.util.GlobalTracer; + @RestController @RequestMapping("/api") public class UserController { @@ -27,7 +33,18 @@ public class UserController { @GetMapping("/users") public List getAllUsers() { - return userRepository.findAll(); + List users; + int value = this.SiblingHelperMethod(); + + Tracer tracer = GlobalTracer.get(); + Span span = tracer.buildSpan("parent-child").start(); + try (Scope scope = tracer.scopeManager().activate(span)) { + users = userRepository.findAll(); + } finally { + span.finish(); + } + + return users; } @PostMapping("/users") @@ -58,4 +75,16 @@ public ResponseEntity deleteUser(@PathVariable(value = "id") Long userId) { userRepository.delete(user); return ResponseEntity.ok().build(); } + + private int SiblingHelperMethod() { + Tracer tracer = GlobalTracer.get(); + Span span = tracer.buildSpan("sibling-span").start(); + try (Scope scope = tracer.scopeManager().activate(span)) { + span.setTag("tag", "value"); + } finally { + span.finish(); + } + + return 3; + } } From 5a0a5c886b303b2806bf3ed14c8167bbf6e20166 Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Wed, 20 Jan 2021 10:47:53 -0500 Subject: [PATCH 06/12] got otel working Signed-off-by: Joe Elliott --- app/pom.xml | 32 +++++++++++++++---- .../TianMiao/controller/UserController.java | 30 +---------------- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/app/pom.xml b/app/pom.xml index 45269cd..406d99d 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -67,12 +67,32 @@ javax.servlet javax.servlet-api - - - io.opentracing.contrib - opentracing-spring-jaeger-cloud-starter - 3.1.2 - + + + org.javassist + javassist + 3.25.0-GA + + diff --git a/app/src/main/java/com/example/TianMiao/controller/UserController.java b/app/src/main/java/com/example/TianMiao/controller/UserController.java index 640ccff..12d0f4c 100644 --- a/app/src/main/java/com/example/TianMiao/controller/UserController.java +++ b/app/src/main/java/com/example/TianMiao/controller/UserController.java @@ -20,11 +20,6 @@ import com.example.TianMiao.model.User; import com.example.TianMiao.repository.UserRepository; -import io.opentracing.Scope; -import io.opentracing.Span; -import io.opentracing.Tracer; -import io.opentracing.util.GlobalTracer; - @RestController @RequestMapping("/api") public class UserController { @@ -33,18 +28,7 @@ public class UserController { @GetMapping("/users") public List getAllUsers() { - List users; - int value = this.SiblingHelperMethod(); - - Tracer tracer = GlobalTracer.get(); - Span span = tracer.buildSpan("parent-child").start(); - try (Scope scope = tracer.scopeManager().activate(span)) { - users = userRepository.findAll(); - } finally { - span.finish(); - } - - return users; + return userRepository.findAll(); } @PostMapping("/users") @@ -75,16 +59,4 @@ public ResponseEntity deleteUser(@PathVariable(value = "id") Long userId) { userRepository.delete(user); return ResponseEntity.ok().build(); } - - private int SiblingHelperMethod() { - Tracer tracer = GlobalTracer.get(); - Span span = tracer.buildSpan("sibling-span").start(); - try (Scope scope = tracer.scopeManager().activate(span)) { - span.setTag("tag", "value"); - } finally { - span.finish(); - } - - return 3; - } } From 7b2830bc709584dc722c3022e90e3d5d099677ea Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Wed, 20 Jan 2021 16:03:25 -0500 Subject: [PATCH 07/12] trace id logging Signed-off-by: Joe Elliott --- .../TianMiao/RequestLoggingFilterConfig.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app/src/main/java/com/example/TianMiao/RequestLoggingFilterConfig.java diff --git a/app/src/main/java/com/example/TianMiao/RequestLoggingFilterConfig.java b/app/src/main/java/com/example/TianMiao/RequestLoggingFilterConfig.java new file mode 100644 index 0000000..d07aeb1 --- /dev/null +++ b/app/src/main/java/com/example/TianMiao/RequestLoggingFilterConfig.java @@ -0,0 +1,19 @@ +package com.example.TianMiao; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.filter.CommonsRequestLoggingFilter; + +@Configuration +public class RequestLoggingFilterConfig { + + @Bean + public CommonsRequestLoggingFilter logFilter() { + CommonsRequestLoggingFilter filter + = new CommonsRequestLoggingFilter(); + filter.setIncludeQueryString(true); + filter.setIncludeHeaders(true); + filter.setIncludeClientInfo(true); + return filter; + } +} \ No newline at end of file From bd94f68b3e7a632de213af2d36579c929b65e267 Mon Sep 17 00:00:00 2001 From: Joe Elliott Date: Thu, 21 Jan 2021 17:13:50 -0500 Subject: [PATCH 08/12] cleanup of pom.xml Signed-off-by: Joe Elliott --- app/pom.xml | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/app/pom.xml b/app/pom.xml index 406d99d..0ae7679 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -67,32 +67,11 @@ javax.servlet javax.servlet-api - org.javassist javassist 3.25.0-GA - From aa18d48d9a6ceb311e32689bdeef9ab847c0c437 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Sat, 6 Feb 2021 10:56:54 +0000 Subject: [PATCH 09/12] Remove golang app. Signed-off-by: Tom Wilkie --- app/Dockerfile | 6 - app/index.html.tmpl | 72 ---------- app/main.go | 318 -------------------------------------------- 3 files changed, 396 deletions(-) delete mode 100644 app/Dockerfile delete mode 100644 app/index.html.tmpl delete mode 100644 app/main.go diff --git a/app/Dockerfile b/app/Dockerfile deleted file mode 100644 index 4a43f5f..0000000 --- a/app/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM alpine:3.9 -ADD app / -ADD index.html.tmpl / -EXPOSE 80 -ENTRYPOINT [ "/app" ] -CMD [ "http://db" ] diff --git a/app/index.html.tmpl b/app/index.html.tmpl deleted file mode 100644 index 68eb275..0000000 --- a/app/index.html.tmpl +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - Grafana News - - -
- - - - - - - - - - - -
- - - - - - -
- Grafana News - -
-
- - {{ range .Links }} - - - - - - - - - - - {{ end }} -
{{ .Rank }}.{{ .Title }}
- {{ .Points }} points -
-
- - - - -
-
-
-
- Title:
- URL:
- -
-
-
-
- - diff --git a/app/main.go b/app/main.go deleted file mode 100644 index cbdfc01..0000000 --- a/app/main.go +++ /dev/null @@ -1,318 +0,0 @@ -package main - -import ( - "bytes" - "crypto/md5" - "crypto/sha1" - "encoding/binary" - "encoding/json" - "flag" - "fmt" - "io" - "io/ioutil" - "math/rand" - "net/http" - "net/url" - "os" - "strconv" - "strings" - "text/template" - "time" - - "github.com/go-kit/kit/log" - "github.com/go-kit/kit/log/level" - "github.com/grafana/tns/client" - "github.com/weaveworks/common/logging" - "github.com/weaveworks/common/server" - "github.com/weaveworks/common/tracing" -) - -func main() { - serverConfig := server.Config{ - MetricsNamespace: "tns", - } - serverConfig.RegisterFlags(flag.CommandLine) - flag.Parse() - - // Use a gokit logger, and tell the server to use it. - logger := level.NewFilter(log.NewLogfmtLogger(log.NewSyncWriter(os.Stdout)), serverConfig.LogLevel.Gokit) - serverConfig.Log = logging.GoKit(logger) - - // Setting the environment variable JAEGER_AGENT_HOST enables tracing - trace, err := tracing.NewFromEnv("app") - if err != nil { - level.Error(logger).Log("msg", "error initializing tracing", "err", err) - os.Exit(1) - } - defer trace.Close() - - s, err := server.New(serverConfig) - if err != nil { - level.Error(logger).Log("msg", "error starting server", "err", err) - os.Exit(1) - } - defer s.Shutdown() - - databases, err := getDatabases(flag.Args()) - if err != nil { - level.Error(logger).Log("msg", "error parsing databases", "err", err) - os.Exit(1) - } - level.Info(logger).Log("database(s)", len(databases)) - - app, err := new(logger, databases) - if err != nil { - level.Error(logger).Log("msg", "error initialising app", "err", err) - os.Exit(1) - } - - s.HTTP.HandleFunc("/", app.Index) - s.HTTP.HandleFunc("/post", app.Post) - s.HTTP.HandleFunc("/vote", app.Vote) - - s.Run() -} - -func getDatabases(args []string) ([]*url.URL, error) { - databases := []*url.URL{} - for _, host := range args { - u, err := url.Parse(host) - if err != nil { - return nil, err - } - databases = append(databases, u) - } - - return databases, nil -} - -type app struct { - logger log.Logger - databases []*url.URL - - id string - client *client.Client - tmpl *template.Template -} - -type Link struct { - ID int - Rank int - Points int - URL string - Title string -} - -func new(logger log.Logger, databases []*url.URL) (*app, error) { - c := client.New(logger) - - tmpl, err := template.ParseFiles("/index.html.tmpl") - if err != nil { - return nil, err - } - - rand.Seed(time.Now().UnixNano()) - h := md5.New() - fmt.Fprintf(h, "%d", rand.Int63()) - id := fmt.Sprintf("app-%x", h.Sum(nil)) - - return &app{ - logger: logger, - databases: databases, - - tmpl: tmpl, - id: id, - client: c, - }, nil -} - -func (a *app) Index(w http.ResponseWriter, r *http.Request) { - db := a.databases[rand.Intn(len(a.databases))].String() - req, err := http.NewRequest("GET", db, nil) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "%v\n", err) - return - } - req = req.WithContext(r.Context()) - - resp, err := a.client.Do(req) - if err != nil { - w.WriteHeader(http.StatusServiceUnavailable) - fmt.Fprintf(w, "%v\n", err) - return - } - defer resp.Body.Close() - - if resp.StatusCode/100 != 2 { - body, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 1024)) - level.Error(a.logger).Log("msg", "HTTP request faild", "status", resp.StatusCode, "body", body) - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "%s\n", body) - return - } - - var response struct { - Links []Link - } - - if err := json.NewDecoder(resp.Body).Decode(&response); err != nil { - level.Error(a.logger).Log("msg", "failed to parse db response", "err", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - for i := range response.Links { - response.Links[i].Rank = i + 1 - } - - w.WriteHeader(http.StatusOK) - if err := a.tmpl.Execute(w, struct { - Now time.Time - ID string - Links []Link - }{ - Now: time.Now(), - ID: a.id, - Links: response.Links, - }); err != nil { - level.Error(a.logger).Log("msg", "failed to execute template", "err", err) - } -} - -func (a *app) Post(w http.ResponseWriter, r *http.Request) { - if err := r.ParseForm(); err != nil { - level.Error(a.logger).Log("msg", "error parsing form", "err", err) - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - u := strings.TrimSpace(r.PostForm.Get("url")) - if u == "" { - level.Error(a.logger).Log("msg", "empty url") - http.Error(w, "empty url", http.StatusBadRequest) - return - } - - parsed, err := url.Parse(u) - if err != nil { - level.Error(a.logger).Log("msg", "invalid url", "url", u, "err", err) - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - if parsed.Scheme != "http" && parsed.Scheme != "https" { - parsed.Scheme = "http" - } - - title := strings.TrimSpace(r.PostForm.Get("title")) - if title == "" { - level.Error(a.logger).Log("msg", "empty url") - http.Error(w, "empty title", http.StatusBadRequest) - return - } - - hash := sha1.Sum([]byte(parsed.String())) - id := binary.BigEndian.Uint16(hash[:]) - - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(struct { - ID int - URL string - Title string - }{ - ID: int(id), - URL: parsed.String(), - Title: title, - }); err != nil { - level.Error(a.logger).Log("msg", "error encoding post", "err", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - db := a.databases[rand.Intn(len(a.databases))].String() - req, err := http.NewRequest("POST", db+"/post", &buf) - if err != nil { - level.Error(a.logger).Log("msg", "error building request", "err", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - req = req.WithContext(r.Context()) - resp, err := a.client.Do(req) - if err != nil { - w.WriteHeader(http.StatusServiceUnavailable) - fmt.Fprintf(w, "%v\n", err) - return - } - defer resp.Body.Close() - - if resp.StatusCode/100 != 2 { - body, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 1024)) - level.Error(a.logger).Log("msg", "HTTP request faild", "status", resp.StatusCode, "body", body) - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "%s\n", body) - return - } - - // Implement PRG pattern to prevent double-POST. - newURL := strings.TrimSuffix(req.RequestURI, "/post") - http.Redirect(w, req, newURL, http.StatusFound) - return -} - -func (a *app) Vote(w http.ResponseWriter, r *http.Request) { - if err := r.ParseForm(); err != nil { - level.Error(a.logger).Log("msg", "error parsing form", "err", err) - http.Error(w, err.Error(), http.StatusBadRequest) - return - } - - id, err := strconv.Atoi(r.Form.Get("id")) - if err != nil { - level.Error(a.logger).Log("msg", "invalid id", "err", err) - http.Error(w, "invalid id", http.StatusBadRequest) - return - } - - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(struct { - ID int - }{ - ID: id, - }); err != nil { - level.Error(a.logger).Log("msg", "error encoding post", "err", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - db := a.databases[rand.Intn(len(a.databases))].String() - req, err := http.NewRequest("POST", db+"/vote", &buf) - if err != nil { - level.Error(a.logger).Log("msg", "error building request", "err", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - req = req.WithContext(r.Context()) - resp, err := a.client.Do(req) - if err != nil { - w.WriteHeader(http.StatusServiceUnavailable) - fmt.Fprintf(w, "%v\n", err) - return - } - defer resp.Body.Close() - - if resp.StatusCode/100 != 2 { - body, _ := ioutil.ReadAll(io.LimitReader(resp.Body, 1024)) - level.Error(a.logger).Log("msg", "HTTP request faild", "status", resp.StatusCode, "body", body) - w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "%s\n", body) - return - } - - // Implement PRG pattern to prevent double-POST. - newURL := strings.TrimSuffix(req.RequestURI, "/vote") - http.Redirect(w, req, newURL, http.StatusFound) - return -} From 8168ec3c150498546eeef08841a3e76c9803c108 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Sat, 6 Feb 2021 11:38:00 +0000 Subject: [PATCH 10/12] Update Makefile and add Dockerfile for the java bits. Signed-off-by: Tom Wilkie --- Makefile | 2 +- app/Dockerfile | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 app/Dockerfile diff --git a/Makefile b/Makefile index abcede9..82ea8fa 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ db/.uptodate: db/db db/Dockerfile docker tag $(DOCKER_IMAGE_BASE)/tns-db $(DOCKER_IMAGE_BASE)/tns-db:$(IMAGE_TAG) touch $@ -app/.uptodate: app/app app/Dockerfile app/index.html.tmpl +app/.uptodate: app/Dockerfile docker build -t $(DOCKER_IMAGE_BASE)/tns-app app/ docker tag $(DOCKER_IMAGE_BASE)/tns-app $(DOCKER_IMAGE_BASE)/tns-app:$(IMAGE_TAG) touch $@ diff --git a/app/Dockerfile b/app/Dockerfile new file mode 100644 index 0000000..4422c66 --- /dev/null +++ b/app/Dockerfile @@ -0,0 +1,16 @@ +FROM maven:3.6.3-openjdk-11 as build +WORKDIR /usr/src/app + +# We copy the pom and install the dependencies as a sepearate step so docker will cache them. +COPY pom.xml /usr/src/app +RUN mvn dependency:resolve + +# Now actually build the thing. +COPY src /usr/src/app/src +RUN mvn install -Dmaven.test.skip=true + + +FROM tomcat:9-jre11 +COPY --from=build /usr/src/app/target/TianMiao.war /usr/local/tomcat/webapps/TianMiao.war +RUN curl -o /usr/local/tomcat/opentelemetry-javaagent-all.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v0.15.1/opentelemetry-javaagent-all.jar +ENV JAVA_OPTS="-javaagent:/opentelemetry-javaagent-all.jar -Dlogging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG '-Dlogging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %msg traceID=%X{traceId} %n'" From 6bf86041068af6ad71c93f4df4b9789ccc8d974d Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Sun, 7 Feb 2021 10:49:21 +0000 Subject: [PATCH 11/12] Adapt the example app to the grafana news idea. Signed-off-by: Tom Wilkie --- Makefile | 5 +- app/Dockerfile | 6 +- app/pom.xml | 8 +-- .../TianMiao/controller/UserController.java | 62 ------------------- .../TianMiao/repository/UserRepository.java | 11 ---- .../news/NewsApplication.java} | 10 +-- .../news}/RequestLoggingFilterConfig.java | 4 +- .../news/controller/PostController.java | 47 ++++++++++++++ .../exception/ResourceNotFoundException.java | 10 +-- .../news/model/Post.java} | 57 ++++++++++------- .../news/repository/PostRepository.java | 11 ++++ app/src/main/resources/application.properties | 4 +- .../news/NewsApplicationTests.java} | 4 +- production/docker-compose.yml | 16 +++-- 14 files changed, 124 insertions(+), 131 deletions(-) delete mode 100644 app/src/main/java/com/example/TianMiao/controller/UserController.java delete mode 100644 app/src/main/java/com/example/TianMiao/repository/UserRepository.java rename app/src/main/java/com/{example/TianMiao/TianMiaoApplication.java => grafana/news/NewsApplication.java} (70%) rename app/src/main/java/com/{example/TianMiao => grafana/news}/RequestLoggingFilterConfig.java (94%) create mode 100644 app/src/main/java/com/grafana/news/controller/PostController.java rename app/src/main/java/com/{example/TianMiao => grafana/news}/exception/ResourceNotFoundException.java (94%) rename app/src/main/java/com/{example/TianMiao/model/User.java => grafana/news/model/Post.java} (60%) create mode 100644 app/src/main/java/com/grafana/news/repository/PostRepository.java rename app/src/test/java/com/{example/TianMeow/TianMeowApplicationTests.java => grafana/news/NewsApplicationTests.java} (79%) diff --git a/Makefile b/Makefile index 82ea8fa..ae82c80 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,6 @@ GOENV=GOOS=linux GOARCH=amd64 CGO_ENABLED=0 GO111MODULE=on db/db: db/*.go env $(GOENV) go build -o $@ ./db -app/app: app/*.go - env $(GOENV) go build -o $@ ./app - loadgen/loadgen: loadgen/*.go env $(GOENV) go build -o $@ ./loadgen @@ -26,7 +23,7 @@ db/.uptodate: db/db db/Dockerfile docker tag $(DOCKER_IMAGE_BASE)/tns-db $(DOCKER_IMAGE_BASE)/tns-db:$(IMAGE_TAG) touch $@ -app/.uptodate: app/Dockerfile +app/.uptodate: app/Dockerfile app/pom.xml $(shell find app/src) docker build -t $(DOCKER_IMAGE_BASE)/tns-app app/ docker tag $(DOCKER_IMAGE_BASE)/tns-app $(DOCKER_IMAGE_BASE)/tns-app:$(IMAGE_TAG) touch $@ diff --git a/app/Dockerfile b/app/Dockerfile index 4422c66..017323a 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -11,6 +11,6 @@ RUN mvn install -Dmaven.test.skip=true FROM tomcat:9-jre11 -COPY --from=build /usr/src/app/target/TianMiao.war /usr/local/tomcat/webapps/TianMiao.war -RUN curl -o /usr/local/tomcat/opentelemetry-javaagent-all.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v0.15.1/opentelemetry-javaagent-all.jar -ENV JAVA_OPTS="-javaagent:/opentelemetry-javaagent-all.jar -Dlogging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG '-Dlogging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %msg traceID=%X{traceId} %n'" +RUN curl -L -o /usr/local/tomcat/opentelemetry-javaagent-all.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v0.15.1/opentelemetry-javaagent-all.jar +COPY --from=build /usr/src/app/target/News.war /usr/local/tomcat/webapps/News.war +ENV JAVA_OPTS="-javaagent:/usr/local/tomcat/opentelemetry-javaagent-all.jar -Dlogging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG '-Dlogging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %logger{36} - %msg traceID=%X{traceId} %n'" diff --git a/app/pom.xml b/app/pom.xml index 0ae7679..82b107d 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -3,13 +3,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.example - TianMiao + com.grafana + News 0.0.1-SNAPSHOT war - TianMiao - Demo project for Online Shopping + News + Demo application for Grafana news org.springframework.boot diff --git a/app/src/main/java/com/example/TianMiao/controller/UserController.java b/app/src/main/java/com/example/TianMiao/controller/UserController.java deleted file mode 100644 index 12d0f4c..0000000 --- a/app/src/main/java/com/example/TianMiao/controller/UserController.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.example.TianMiao.controller; - -import java.util.List; -import java.util.Map; - -import javax.validation.Valid; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.example.TianMiao.exception.ResourceNotFoundException; -import com.example.TianMiao.model.User; -import com.example.TianMiao.repository.UserRepository; - -@RestController -@RequestMapping("/api") -public class UserController { - @Autowired - UserRepository userRepository; - - @GetMapping("/users") - public List getAllUsers() { - return userRepository.findAll(); - } - - @PostMapping("/users") - public User createUser(@Valid @RequestBody User user) { - return userRepository.save(user); - } - - @GetMapping("/users/{id}") - public User getUserById(@PathVariable(value = "id") Long userId) { - return userRepository.findById(userId) - .orElseThrow(() -> new ResourceNotFoundException("User", "id", userId)); - } - - @PutMapping("/notes/{id}") - public User updateUser(@PathVariable(value = "id") Long userId, @Valid @RequestBody User userDetails) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new ResourceNotFoundException("User", "id", userId)); - - user.setUsername(userDetails.getUsername()); - User updatedUser = userRepository.save(user); - return updatedUser; - } - - @DeleteMapping("/notes/{id}") - public ResponseEntity deleteUser(@PathVariable(value = "id") Long userId) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new ResourceNotFoundException("User", "id", userId)); - userRepository.delete(user); - return ResponseEntity.ok().build(); - } -} diff --git a/app/src/main/java/com/example/TianMiao/repository/UserRepository.java b/app/src/main/java/com/example/TianMiao/repository/UserRepository.java deleted file mode 100644 index cf4385d..0000000 --- a/app/src/main/java/com/example/TianMiao/repository/UserRepository.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.TianMiao.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import com.example.TianMiao.model.User; - -@Repository -public interface UserRepository extends JpaRepository { - -} diff --git a/app/src/main/java/com/example/TianMiao/TianMiaoApplication.java b/app/src/main/java/com/grafana/news/NewsApplication.java similarity index 70% rename from app/src/main/java/com/example/TianMiao/TianMiaoApplication.java rename to app/src/main/java/com/grafana/news/NewsApplication.java index ba3dcc9..3e7ee87 100644 --- a/app/src/main/java/com/example/TianMiao/TianMiaoApplication.java +++ b/app/src/main/java/com/grafana/news/NewsApplication.java @@ -1,4 +1,4 @@ -package com.example.TianMiao; +package com.grafana.news; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -8,14 +8,14 @@ @SpringBootApplication @EnableJpaAuditing -public class TianMiaoApplication extends SpringBootServletInitializer { +public class NewsApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { - return application.sources(TianMiaoApplication.class); + return application.sources(NewsApplication.class); } - + public static void main(String[] args) { - SpringApplication.run(TianMiaoApplication.class, args); + SpringApplication.run(NewsApplication.class, args); } } diff --git a/app/src/main/java/com/example/TianMiao/RequestLoggingFilterConfig.java b/app/src/main/java/com/grafana/news/RequestLoggingFilterConfig.java similarity index 94% rename from app/src/main/java/com/example/TianMiao/RequestLoggingFilterConfig.java rename to app/src/main/java/com/grafana/news/RequestLoggingFilterConfig.java index d07aeb1..77c264e 100644 --- a/app/src/main/java/com/example/TianMiao/RequestLoggingFilterConfig.java +++ b/app/src/main/java/com/grafana/news/RequestLoggingFilterConfig.java @@ -1,4 +1,4 @@ -package com.example.TianMiao; +package com.grafana.news; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -16,4 +16,4 @@ public CommonsRequestLoggingFilter logFilter() { filter.setIncludeClientInfo(true); return filter; } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/grafana/news/controller/PostController.java b/app/src/main/java/com/grafana/news/controller/PostController.java new file mode 100644 index 0000000..4d40674 --- /dev/null +++ b/app/src/main/java/com/grafana/news/controller/PostController.java @@ -0,0 +1,47 @@ +package com.grafana.news.controller; + +import java.util.List; +import java.util.Map; + +import javax.validation.Valid; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.grafana.news.exception.ResourceNotFoundException; +import com.grafana.news.model.Post; +import com.grafana.news.repository.PostRepository; + +@RestController +@RequestMapping("/") +public class PostController { + @Autowired + PostRepository postRepository; + + @GetMapping("/") + public List getPosts() { + return postRepository.findAll(); + } + + @PutMapping("/post") + public Post createPost(@Valid @RequestBody Post post) { + return postRepository.save(post); + } + + @PostMapping("/vote") + public ResponseEntity upvote(@PathVariable(value = "id") Long postId) { + Post post = postRepository.findById(postId) + .orElseThrow(() -> new ResourceNotFoundException("Post", "id", postId)); + post.upvote(); + postRepository.save(post); + return ResponseEntity.ok().build(); + } +} diff --git a/app/src/main/java/com/example/TianMiao/exception/ResourceNotFoundException.java b/app/src/main/java/com/grafana/news/exception/ResourceNotFoundException.java similarity index 94% rename from app/src/main/java/com/example/TianMiao/exception/ResourceNotFoundException.java rename to app/src/main/java/com/grafana/news/exception/ResourceNotFoundException.java index 0d2837d..7bdf943 100644 --- a/app/src/main/java/com/example/TianMiao/exception/ResourceNotFoundException.java +++ b/app/src/main/java/com/grafana/news/exception/ResourceNotFoundException.java @@ -1,4 +1,4 @@ -package com.example.TianMiao.exception; +package com.grafana.news.exception; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @@ -8,22 +8,22 @@ public class ResourceNotFoundException extends RuntimeException { private String resourceName; private String fieldName; private Object fieldValue; - + public ResourceNotFoundException( String resourceName, String fieldName, Object fieldValue) { super(String.format("%s not found with %s : '%s'", resourceName, fieldName, fieldValue)); this.resourceName = resourceName; this.fieldName = fieldName; this.fieldValue = fieldValue; } - + public String getResourceName() { return resourceName; } - + public String getFieldName() { return fieldName; } - + public Object getFieldValue() { return fieldValue; } diff --git a/app/src/main/java/com/example/TianMiao/model/User.java b/app/src/main/java/com/grafana/news/model/Post.java similarity index 60% rename from app/src/main/java/com/example/TianMiao/model/User.java rename to app/src/main/java/com/grafana/news/model/Post.java index 24360f1..65d65d9 100644 --- a/app/src/main/java/com/example/TianMiao/model/User.java +++ b/app/src/main/java/com/grafana/news/model/Post.java @@ -1,4 +1,4 @@ -package com.example.TianMiao.model; +package com.grafana.news.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.springframework.data.annotation.CreatedDate; @@ -11,31 +11,33 @@ import java.util.Date; @Entity -@Table(name = "user") +@Table(name = "post") @EntityListeners(AuditingEntityListener.class) -@JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true) -public class User implements Serializable { +@JsonIgnoreProperties(value = {"createdAt"}, allowGetters = true) +public class Post implements Serializable { /** - * + * */ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - + @NotBlank - private String username; - + private String title; + @Column(nullable = false, updatable = false) @Temporal(TemporalType.TIMESTAMP) @CreatedDate private Date createdAt; - - @Column(nullable = false) - @Temporal(TemporalType.TIMESTAMP) - @LastModifiedDate - private Date updatedAt; + + @NotBlank + private String url; + + @NotBlank + private Long points; + public Long getId() { return id; @@ -45,12 +47,12 @@ public void setId(Long id) { this.id = id; } - public String getUsername() { - return username; + public String getTitle() { + return title; } - public void setUsername(String username) { - this.username = username; + public void setTitle(String title) { + this.title = title; } public Date getCreatedAt() { @@ -61,12 +63,23 @@ public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } - public Date getUpdatedAt() { - return updatedAt; + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Long getPoints() { + return points; + } + + public void setPoints(Long points) { + this.points = points; } - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; + public void upvote() { + this.points++; } - } diff --git a/app/src/main/java/com/grafana/news/repository/PostRepository.java b/app/src/main/java/com/grafana/news/repository/PostRepository.java new file mode 100644 index 0000000..bf968c2 --- /dev/null +++ b/app/src/main/java/com/grafana/news/repository/PostRepository.java @@ -0,0 +1,11 @@ +package com.grafana.news.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import com.grafana.news.model.Post; + +@Repository +public interface PostRepository extends JpaRepository { + +} diff --git a/app/src/main/resources/application.properties b/app/src/main/resources/application.properties index 52c2f98..3a595fc 100644 --- a/app/src/main/resources/application.properties +++ b/app/src/main/resources/application.properties @@ -1,5 +1,5 @@ ## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties) -spring.datasource.url = jdbc:mysql://mysql/TianMiao?allowPublicKeyRetrieval=true&useSSL=false +spring.datasource.url = jdbc:mysql://mysql/news?allowPublicKeyRetrieval=true&useSSL=false spring.datasource.username = root spring.datasource.password = password @@ -9,4 +9,4 @@ spring.datasource.password = password spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect # Hibernate ddl auto (create, create-drop, validate, update) -spring.jpa.hibernate.ddl-auto = update \ No newline at end of file +spring.jpa.hibernate.ddl-auto = update diff --git a/app/src/test/java/com/example/TianMeow/TianMeowApplicationTests.java b/app/src/test/java/com/grafana/news/NewsApplicationTests.java similarity index 79% rename from app/src/test/java/com/example/TianMeow/TianMeowApplicationTests.java rename to app/src/test/java/com/grafana/news/NewsApplicationTests.java index 63faafa..e7c408f 100644 --- a/app/src/test/java/com/example/TianMeow/TianMeowApplicationTests.java +++ b/app/src/test/java/com/grafana/news/NewsApplicationTests.java @@ -1,4 +1,4 @@ -package com.example.TianMeow; +package com.grafana.news; import org.junit.Test; import org.junit.runner.RunWith; @@ -7,7 +7,7 @@ @RunWith(SpringRunner.class) @SpringBootTest -public class TianMeowApplicationTests { +public class NewsApplicationTests { @Test public void contextLoads() { diff --git a/production/docker-compose.yml b/production/docker-compose.yml index e5f3904..0f89c20 100644 --- a/production/docker-compose.yml +++ b/production/docker-compose.yml @@ -14,19 +14,17 @@ services: JAEGER_SAMPLER_PARAM: 1 app: - image: grafana/tns-app:9c1ab38 - command: - - '-log.level=debug' - - 'http://db' + image: grafana/tns-app:8168ec3 links: - db ports: - - 0.0.0.0:8001:80 + - 8080:8080 + - 9464:9464 environment: - JAEGER_ENDPOINT: 'http://tempo:14268/api/traces' - JAEGER_TAGS: cluster=tns,namespace=tns - JAEGER_SAMPLER_TYPE: const - JAEGER_SAMPLER_PARAM: 1 + - OTEL_EXPORTER=otlp_span,prometheus + - OTEL_EXPORTER_OTLP_ENDPOINT=tempo:55680 + - OTEL_EXPORTER_OTLP_INSECURE=true + - OTEL_RESOURCE_ATTRIBUTES=service.name=demo loadgen: image: grafana/tns-loadgen:9c1ab38 From 2f6549c253d94aa5abf322e94f7fc6541fa33410 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Sun, 7 Feb 2021 11:21:22 +0000 Subject: [PATCH 12/12] Add prometheus metrics to spring app using micrometer. Signed-off-by: Tom Wilkie --- app/pom.xml | 8 ++++++++ app/src/main/resources/application.properties | 5 ++++- production/docker-compose.yml | 16 ++++++++++++---- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/app/pom.xml b/app/pom.xml index 82b107d..c2e8e80 100644 --- a/app/pom.xml +++ b/app/pom.xml @@ -72,6 +72,14 @@ javassist 3.25.0-GA + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-registry-prometheus + diff --git a/app/src/main/resources/application.properties b/app/src/main/resources/application.properties index 3a595fc..d855298 100644 --- a/app/src/main/resources/application.properties +++ b/app/src/main/resources/application.properties @@ -3,10 +3,13 @@ spring.datasource.url = jdbc:mysql://mysql/news?allowPublicKeyRetrieval=true&use spring.datasource.username = root spring.datasource.password = password - ## Hibernate Properties # The SQL dialect makes Hibernate generate better SQL for the chosen database spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect # Hibernate ddl auto (create, create-drop, validate, update) spring.jpa.hibernate.ddl-auto = update + +management.server.port=8080 +management.server.ssl.enabled=false +management.endpoints.web.exposure.include=* diff --git a/production/docker-compose.yml b/production/docker-compose.yml index 0f89c20..2ca581d 100644 --- a/production/docker-compose.yml +++ b/production/docker-compose.yml @@ -1,6 +1,14 @@ version: "2" services: + mysql: + image: mysql:8 + container_name: mysql_service + restart: always + environment: + MYSQL_ROOT_PASSWORD: password + MYSQL_DATABASE: news + db: image: grafana/tns-db:9c1ab38 command: @@ -14,12 +22,12 @@ services: JAEGER_SAMPLER_PARAM: 1 app: - image: grafana/tns-app:8168ec3 - links: - - db + image: grafana/tns-app ports: - 8080:8080 - - 9464:9464 + - 8009:8009 + depends_on: + - mysql environment: - OTEL_EXPORTER=otlp_span,prometheus - OTEL_EXPORTER_OTLP_ENDPOINT=tempo:55680