Commit d9be4ff4 by 彭芳

Initial commit

parents
# Reference https://github.com/github/gitignore/blob/master/Go.gitignore
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
vendor/
# Go workspace file
go.work
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# OS General
Thumbs.db
.DS_Store
# project
*.cert
*.key
*.log
bin/
# Develop tools
.vscode/
.idea/
*.swp
FROM golang:1.16 AS builder
COPY . /src
WORKDIR /src
RUN GOPROXY=https://goproxy.cn make build
FROM debian:stable-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
netbase \
&& rm -rf /var/lib/apt/lists/ \
&& apt-get autoremove -y && apt-get autoclean -y
COPY --from=builder /src/bin /app
WORKDIR /app
EXPOSE 8000
VOLUME /data/conf
CMD ["./server", "-conf", "/data/conf"]
GOHOSTOS:=$(shell go env GOHOSTOS)
GOPATH:=$(shell go env GOPATH)
VERSION=$(shell git describe --tags --always)
ifeq ($(GOHOSTOS), windows)
#the `find.exe` is different from `find` in bash/shell.
#to see https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/find.
#changed to use git-bash.exe to run find cli or other cli friendly, caused of every developer has a Git.
#Git_Bash= $(subst cmd\,bin\bash.exe,$(dir $(shell where git)))
Git_Bash=$(subst \,/,$(subst cmd\,bin\bash.exe,$(dir $(shell where git | grep cmd))))
INTERNAL_PROTO_FILES=$(shell $(Git_Bash) -c "find internal -name *.proto")
else
INTERNAL_PROTO_FILES=$(shell find internal -name *.proto)
endif
.PHONY: init
# init env
init:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install github.com/google/wire/cmd/wire@latest
.PHONY: config
# generate internal proto
config:
protoc --proto_path=./internal \
--go_out=paths=source_relative:./internal \
$(INTERNAL_PROTO_FILES)
.PHONY: build
# build
build:
mkdir -p bin/ && go build -ldflags "-X main.Version=$(VERSION)" -o ./bin/ ./...
.PHONY: generate
# generate
generate:
go mod tidy
go get github.com/google/wire/cmd/wire@latest
go generate ./...
.PHONY: all
# generate all
all:
make config;
make generate;
# show help
help:
@echo ''
@echo 'Usage:'
@echo ' make [target]'
@echo ''
@echo 'Targets:'
@awk '/^[a-zA-Z\-\_0-9]+:/ { \
helpMessage = match(lastLine, /^# (.*)/); \
if (helpMessage) { \
helpCommand = substr($$1, 0, index($$1, ":")-1); \
helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
} \
} \
{ lastLine = $$0 }' $(MAKEFILE_LIST)
.DEFAULT_GOAL := help
# Project Template
## Generate other auxiliary files by Makefile
```
# Download and update dependencies
make init
# Generate all files
make all
```
## Automated Initialization (wire)
```
# install wire
go get github.com/google/wire/cmd/wire
# generate wire
cd cmd/server
wire
```
## Docker
```bash
# build
docker build -t <your-docker-image-name> .
# run
docker run --rm -p 8000:8000 -v </path/to/your/configs>:/data/conf <your-docker-image-name>
```
package main
import (
"flag"
"os"
"demo/internal/conf"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/config/file"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/tracing"
"github.com/go-kratos/kratos/v2/transport/http"
_ "go.uber.org/automaxprocs"
)
// go build -ldflags "-X main.Version=x.y.z"
var (
// Name is the name of the compiled software.
Name string
// Version is the version of the compiled software.
Version string
// flagconf is the config flag.
flagconf string
id, _ = os.Hostname()
)
func init() {
flag.StringVar(&flagconf, "conf", "./configs", "config path, eg: -conf config.yaml")
}
func newApp(logger log.Logger, hs *http.Server) *kratos.App {
return kratos.New(
kratos.ID(id),
kratos.Name(Name),
kratos.Version(Version),
kratos.Metadata(map[string]string{}),
kratos.Logger(logger),
kratos.Server(
hs,
),
)
}
func main() {
flag.Parse()
logger := log.With(log.NewStdLogger(os.Stdout),
"ts", log.DefaultTimestamp,
"caller", log.DefaultCaller,
"service.id", id,
"service.name", Name,
"service.version", Version,
"trace.id", tracing.TraceID(),
"span.id", tracing.SpanID(),
)
c := config.New(
config.WithSource(
file.NewSource(flagconf),
),
)
defer c.Close()
if err := c.Load(); err != nil {
panic(err)
}
var bc conf.Bootstrap
if err := c.Scan(&bc); err != nil {
panic(err)
}
app, cleanup, err := wireApp(bc.Server, bc.Data, logger)
if err != nil {
panic(err)
}
defer cleanup()
// start and wait for stop signal
if err := app.Run(); err != nil {
panic(err)
}
}
//go:build wireinject
// +build wireinject
// The build tag makes sure the stub is not built in the final build.
package main
import (
"demo/internal/biz"
"demo/internal/conf"
"demo/internal/data"
"demo/internal/server"
"demo/internal/service"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
)
// wireApp init kratos application.
func wireApp(*conf.Server, *conf.Data, log.Logger) (*kratos.App, func(), error) {
panic(wire.Build(
server.ProviderSet,
data.ProviderSet,
biz.ProviderSet,
service.ProviderSet,
newApp))
}
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package main
import (
"demo/internal/biz"
"demo/internal/conf"
"demo/internal/data"
"demo/internal/server"
"demo/internal/service"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
)
import (
_ "go.uber.org/automaxprocs"
)
// Injectors from wire.go:
// wireApp init kratos application.
func wireApp(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*kratos.App, func(), error) {
dataData, cleanup, err := data.NewData(confData, logger)
if err != nil {
return nil, nil, err
}
greeterRepo := data.NewGreeterRepo(dataData, logger)
greeterUsecase := biz.NewGreeterUsecase(greeterRepo, logger)
greeterService := service.NewGreeterService(greeterUsecase)
httpServer := server.NewHTTPServer(confServer, greeterService, logger)
app := newApp(logger, httpServer)
return app, func() {
cleanup()
}, nil
}
server:
http:
addr: 0.0.0.0:8000
timeout: 1s
data:
database:
driver: mysql
source: adstest:Ey5M6GowXu!7@tcp(ads-mysql-test.adsdesk.cn:13316)/adsdesk_test1?charset=utf8&parseTime=True&loc=Local
module demo
go 1.17
require (
github.com/go-kratos/kratos/v2 v2.4.1
github.com/google/wire v0.5.0
github.com/sirupsen/logrus v1.9.0
go.uber.org/automaxprocs v1.5.1
google.golang.org/genproto v0.0.0-20220524023933-508584e28198 // indirect
google.golang.org/grpc v1.46.2 // indirect
google.golang.org/protobuf v1.28.1
gorm.io/driver/mysql v1.4.6
gorm.io/gorm v1.24.5
)
require github.com/gin-gonic/gin v1.8.2
require (
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/form/v4 v4.2.0 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.11.1 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/goccy/go-json v0.9.11 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/subcommands v1.0.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
go.opentelemetry.io/otel v1.7.0 // indirect
go.opentelemetry.io/otel/trace v1.7.0 // indirect
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.4.0 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/tools v0.1.12 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
This diff is collapsed. Click to expand it.
package biz
import "github.com/google/wire"
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewGreeterUsecase)
package biz
import (
"context"
"github.com/go-kratos/kratos/v2/log"
)
// Greeter is a Greeter model.
type Greeter struct {
Hello string
}
// GreeterRepo is a Greater repo.
type GreeterRepo interface {
Save(context.Context, *Greeter) (*Greeter, error)
Update(context.Context, *Greeter) (*Greeter, error)
FindByID(context.Context, int64) (*Greeter, error)
ListByHello(context.Context, string) ([]*Greeter, error)
ListAll(context.Context) ([]*Greeter, error)
}
// GreeterUsecase is a Greeter usecase.
type GreeterUsecase struct {
repo GreeterRepo
log *log.Helper
}
// NewGreeterUsecase new a Greeter usecase.
func NewGreeterUsecase(repo GreeterRepo, logger log.Logger) *GreeterUsecase {
return &GreeterUsecase{repo: repo, log: log.NewHelper(logger)}
}
// CreateGreeter creates a Greeter, and returns the new Greeter.
func (uc *GreeterUsecase) CreateGreeter(ctx context.Context, g *Greeter) (*Greeter, error) {
uc.log.WithContext(ctx).Infof("CreateGreeter: %v", g.Hello)
return uc.repo.Save(ctx, g)
}
syntax = "proto3";
package kratos.api;
option go_package = "demo/internal/conf;conf";
import "google/protobuf/duration.proto";
message Bootstrap {
Server server = 1;
Data data = 2;
}
message Server {
message HTTP {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
message GRPC {
string network = 1;
string addr = 2;
google.protobuf.Duration timeout = 3;
}
HTTP http = 1;
GRPC grpc = 2;
}
message Data {
message Database {
string driver = 1;
string source = 2;
}
message Redis {
string network = 1;
string addr = 2;
google.protobuf.Duration read_timeout = 3;
google.protobuf.Duration write_timeout = 4;
}
Database database = 1;
Redis redis = 2;
}
package data
import (
"time"
"gorm.io/driver/mysql"
"demo/internal/conf"
"github.com/go-kratos/kratos/v2/log"
"github.com/google/wire"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewGreeterRepo)
// Data .
type Data struct {
db *gorm.DB
}
// NewData .
func NewData(c *conf.Data, logger log.Logger) (*Data, func(), error) {
cleanup := func() {
log.NewHelper(logger).Info("closing the data resources")
}
db, err := gorm.Open(mysql.New(mysql.Config{
DriverName: c.Database.Driver,
DSN: c.Database.Source,
}), &gorm.Config{
Logger: NewGormLogger(),
})
if err != nil {
return nil, cleanup, err
}
return &Data{db: db}, cleanup, nil
}
func NewGormLogger() logger.Interface {
return logger.New(logrus.StandardLogger(), logger.Config{
SlowThreshold: time.Second,
IgnoreRecordNotFoundError: true,
LogLevel: logger.Warn,
})
}
package data
import (
"context"
"fmt"
"demo/internal/biz"
"github.com/go-kratos/kratos/v2/log"
)
type greeterRepo struct {
data *Data
log *log.Helper
}
// NewGreeterRepo .
func NewGreeterRepo(data *Data, logger log.Logger) biz.GreeterRepo {
return &greeterRepo{
data: data,
log: log.NewHelper(logger),
}
}
func (r *greeterRepo) Save(ctx context.Context, g *biz.Greeter) (*biz.Greeter, error) {
var s []int64
if err := r.data.db.Table("ads_media_account").
Where("media_code =? ", "qianchuan").
Pluck("advertiser_id", &s).Error; err != nil {
r.log.Info("select err:", err)
}
g.Hello = fmt.Sprint(g.Hello, " advertiser_id list: ", s)
return g, nil
}
func (r *greeterRepo) Update(ctx context.Context, g *biz.Greeter) (*biz.Greeter, error) {
return g, nil
}
func (r *greeterRepo) FindByID(context.Context, int64) (*biz.Greeter, error) {
return nil, nil
}
func (r *greeterRepo) ListByHello(context.Context, string) ([]*biz.Greeter, error) {
return nil, nil
}
func (r *greeterRepo) ListAll(context.Context) ([]*biz.Greeter, error) {
return nil, nil
}
package server
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware/recovery"
kratos_http "github.com/go-kratos/kratos/v2/transport/http"
"demo/internal/conf"
"demo/internal/service"
)
// NewHTTPServer new an HTTP server.
func NewHTTPServer(c *conf.Server, greeter *service.GreeterService, logger log.Logger) *kratos_http.Server {
var opts = []kratos_http.ServerOption{
kratos_http.Middleware(
recovery.Recovery(),
),
}
if c.Http.Network != "" {
opts = append(opts, kratos_http.Network(c.Http.Network))
}
if c.Http.Addr != "" {
opts = append(opts, kratos_http.Address(c.Http.Addr))
}
if c.Http.Timeout != nil {
opts = append(opts, kratos_http.Timeout(c.Http.Timeout.AsDuration()))
}
srv := kratos_http.NewServer(opts...)
router := gin.Default()
router.NoRoute(func(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{"code": "404", "msg": "PageNo not found"})
})
router.GET("/helloworld/:name", greeter.SayHello)
srv.HandlePrefix("/", router)
return srv
}
package server
import (
"github.com/google/wire"
)
// ProviderSet is server providers.
var ProviderSet = wire.NewSet(NewHTTPServer)
package service
import (
"net/http"
"github.com/gin-gonic/gin"
"demo/internal/biz"
)
// GreeterService is a greeter service.
type GreeterService struct {
uc *biz.GreeterUsecase
}
// NewGreeterService new a greeter service.
func NewGreeterService(uc *biz.GreeterUsecase) *GreeterService {
return &GreeterService{uc: uc}
}
// SayHello implements helloworld.GreeterServer.
func (s *GreeterService) SayHello(ctx *gin.Context) {
name := ctx.Param("name")
g, err := s.uc.CreateGreeter(ctx, &biz.Greeter{Hello: name})
if err != nil {
return
}
ctx.AbortWithStatusJSON(http.StatusOK, gin.H{
"message": g.Hello,
})
return
}
package service
import "github.com/google/wire"
// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewGreeterService)
# Generated with protoc-gen-openapi
# https://github.com/google/gnostic/tree/master/cmd/protoc-gen-openapi
openapi: 3.0.3
info:
title: Greeter API
description: The greeting service definition.
version: 0.0.1
paths:
/helloworld/{name}:
get:
tags:
- Greeter
description: Sends a greeting
operationId: Greeter_SayHello
parameters:
- name: name
in: path
required: true
schema:
type: string
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/helloworld.v1.HelloReply'
components:
schemas:
helloworld.v1.HelloReply:
type: object
properties:
message:
type: string
description: The response message containing the greetings
tags:
- name: Greeter
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment