Skip to content

Commit 06c1a10

Browse files
committed
Initial commit
0 parents  commit 06c1a10

29 files changed

+1552
-0
lines changed

.github/workflows/build.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Build
2+
3+
on:
4+
pull_request:
5+
branches: ['main']
6+
7+
jobs:
8+
9+
build:
10+
name: Build
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
- uses: actions/setup-go@v2
16+
with:
17+
go-version: 1.16.x
18+
19+
- run: |
20+
go generate -v .
21+
CGO_ENABLED=0 GOOS=linux go build ./...

.github/workflows/release.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
env:
9+
REGISTRY: ghcr.io
10+
IMAGE_NAME: ${{ github.repository }}
11+
12+
jobs:
13+
goreleaser:
14+
name: Release
15+
runs-on: ubuntu-latest
16+
permissions:
17+
contents: read
18+
packages: write
19+
20+
steps:
21+
- uses: actions/checkout@v2
22+
- uses: actions/setup-go@v2
23+
with:
24+
go-version: 1.16.x
25+
26+
- run: |
27+
go generate -v .
28+
CGO_ENABLED=0 GOOS=linux go build -o build
29+
go test -run=^$ ./...
30+
31+
- name: Log in to the Container registry
32+
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
33+
with:
34+
registry: ${{ env.REGISTRY }}
35+
username: ${{ github.actor }}
36+
password: ${{ secrets.GITHUB_TOKEN }}
37+
38+
- name: Extract metadata (tags, labels) for Docker
39+
id: meta
40+
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
41+
with:
42+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
43+
44+
- name: Build and push Docker image
45+
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
46+
with:
47+
context: .
48+
push: true
49+
tags: ${{ steps.meta.outputs.tags }}
50+
labels: ${{ steps.meta.outputs.labels }}

.github/workflows/test.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: ['main']
6+
pull_request:
7+
branches: ['main']
8+
9+
jobs:
10+
11+
test:
12+
name: Unit Tests
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- uses: actions/checkout@v2
17+
- uses: actions/setup-go@v2
18+
with:
19+
go-version: 1.16.x
20+
21+
- run: |
22+
go generate -v .
23+
go test -coverprofile=coverage.txt -covermode=atomic -race ./...
24+
25+
- uses: codecov/codecov-action@v1

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
cmd/base.meta.go
3+
service/base.meta.go
4+
build

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM scratch
2+
ADD build /
3+
ENTRYPOINT ["/build"]
4+
CMD ["run"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Uniform
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# base-service
2+
A templated starting point for uniform microservices
3+
4+
### Getting Started
5+
First step is to compile resources and metadata into the project's source-code:
6+
```
7+
go generate
8+
```
9+
This will create a file `service/meta.go` which is ignored by the `.gitignore` and contains the project's resources and metadata.
10+
Create `.description` file to override the description as pulled from Github.
11+
12+
### CLI Commands
13+
14+
cmd command example `cmd/command.example-one.go`:
15+
```
16+
package cmd
17+
18+
import (
19+
"github.com/spf13/cobra"
20+
"service/service"
21+
)
22+
23+
var exampleOneCmd = &cobra.Command{
24+
Use: "command:example-one",
25+
Short: "Request the running " + service.AppName + " to execute the example-one command",
26+
Long: "Request the running " + service.AppName + " to execute the example-one command",
27+
Run: func(cmd *cobra.Command, args []string) {
28+
service.Command("example-one", natsUri, compileNatsOptions())
29+
},
30+
}
31+
32+
func init() {
33+
rootCmd.AddCommand(exampleOneCmd)
34+
}
35+
```
36+
37+
service command example `service/command.example-one.go`:
38+
```
39+
package service
40+
41+
import (
42+
"github.com/go-diary/diary"
43+
"github.com/go-uniform/uniform"
44+
)
45+
46+
func init() {
47+
subscribe(local(command("example-one")), exampleOne)
48+
}
49+
50+
func exampleOne(r uniform.IRequest, p diary.IPage) {
51+
// todo: write logic here
52+
}
53+
```
54+
55+
### Background Worker Process
56+
57+
Use a CLI Command and add it to a scheduled cronjob to avoid the background process from being executed multiple times when scaling service instances.
58+
In other words this will work like a sync.Mutex but across all running instances of the given service, allowing us to add as many service instances as we need.
59+
60+
### Routines
61+
62+
service action example `service/routine.example-two.go`:
63+
```
64+
package service
65+
66+
import (
67+
"github.com/go-diary/diary"
68+
"github.com/go-uniform/uniform"
69+
)
70+
71+
func init() {
72+
subscribe(local("example-two"), exampleTwo)
73+
}
74+
75+
func exampleTwo(r uniform.IRequest, p diary.IPage) {
76+
// todo: write logic here
77+
}
78+
```
79+
80+
### Events
81+
82+
service event example `service/event.example-three.go`:
83+
```
84+
package service
85+
86+
import (
87+
"github.com/go-diary/diary"
88+
"github.com/go-uniform/uniform"
89+
)
90+
91+
func init() {
92+
subscribe(local("example-three"), exampleThree)
93+
}
94+
95+
func exampleThree(r uniform.IRequest, p diary.IPage) {
96+
// todo: write logic here
97+
}
98+
```

cmd/base.command.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"github.com/spf13/cobra"
6+
"service/service"
7+
)
8+
9+
func Command(name string, handler func(cmd *cobra.Command, args []string)) *cobra.Command {
10+
return &cobra.Command{
11+
Use: fmt.Sprintf("command:%s", name),
12+
Short: fmt.Sprintf("Request the running %s to execute the %s command", service.AppName, name),
13+
Long: fmt.Sprintf("Request the running %s to execute the %s command", service.AppName, name),
14+
Run: handler,
15+
}
16+
}

cmd/base.execute.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package cmd
2+
3+
import (
4+
"crypto/tls"
5+
"fmt"
6+
"github.com/nats-io/go-nats"
7+
"github.com/spf13/cobra"
8+
"os"
9+
"service/service"
10+
)
11+
12+
var natsUri string
13+
var natsCert string
14+
var natsKey string
15+
var level string
16+
var rate int
17+
var limit int
18+
var test bool
19+
var disableTls bool
20+
21+
var rootCmd = &cobra.Command{
22+
Use: service.AppName,
23+
Short: service.AppDescription,
24+
Long: service.AppDescription,
25+
Run: func(cmd *cobra.Command, args []string) {
26+
if err := cmd.Help(); err != nil {
27+
panic(err)
28+
}
29+
},
30+
}
31+
32+
func init() {
33+
rootCmd.PersistentFlags().StringVarP(&natsUri, "nats", "n", nats.DefaultURL, "The nats cluster URI")
34+
rootCmd.PersistentFlags().StringVarP(&natsCert, "nats-cert", "", "/etc/ssl/certs/ssl-bundle.crt", "The nats cluster TLS certificate file path")
35+
rootCmd.PersistentFlags().StringVarP(&natsKey, "nats-key", "", "/etc/ssl/private/ssl.key", "The nats cluster TLS key file path")
36+
rootCmd.PersistentFlags().BoolVar(&disableTls, "disable-tls", false, "A flag indicating if service should disable tls encryption")
37+
}
38+
39+
func compileNatsOptions() []nats.Option {
40+
var natsOptions = make([]nats.Option, 0)
41+
if !disableTls {
42+
cert, err := tls.LoadX509KeyPair(natsCert, natsKey)
43+
if err != nil {
44+
panic(err)
45+
}
46+
config := &tls.Config{
47+
// since NATS backbone for Fluid will always be on a private line we must skip host verification step
48+
InsecureSkipVerify: true,
49+
50+
Certificates: []tls.Certificate{cert},
51+
MinVersion: tls.VersionTLS12,
52+
}
53+
natsOptions = append(natsOptions, nats.Secure(config))
54+
}
55+
return natsOptions
56+
}
57+
58+
func Execute() {
59+
if err := rootCmd.Execute(); err != nil {
60+
fmt.Println(err)
61+
os.Exit(1)
62+
}
63+
}

cmd/base.version.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"github.com/spf13/cobra"
6+
"service/service"
7+
)
8+
9+
var versionCmd = &cobra.Command{
10+
Use: "version",
11+
Short: "Show " + service.AppName + " version information",
12+
Long: "Show " + service.AppName + " version information",
13+
Run: func(cmd *cobra.Command, args []string) {
14+
fmt.Printf("%s version %s, build %s\n", service.AppName, service.AppVersion, service.AppCommit)
15+
},
16+
}
17+
18+
func init() {
19+
rootCmd.AddCommand(versionCmd)
20+
}

cmd/command.ping.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"service/service"
6+
)
7+
8+
func init() {
9+
rootCmd.AddCommand(Command("ping", func(cmd *cobra.Command, args []string) {
10+
service.InitializeDiary(test, level, rate)
11+
service.Command("ping", natsUri, compileNatsOptions(), map[string]string{})
12+
}))
13+
}

cmd/run.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
"service/service"
6+
)
7+
8+
var runCmd = &cobra.Command{
9+
Use: "run",
10+
Short: "Run " + service.AppName + " service",
11+
Long: "Run " + service.AppName + " service",
12+
Run: func(cmd *cobra.Command, args []string) {
13+
service.InitializeDiary(test, level, rate)
14+
service.Execute(limit, test, natsUri, compileNatsOptions(), service.M{
15+
// todo: add custom args here
16+
})
17+
},
18+
}
19+
20+
func init() {
21+
runCmd.Flags().StringVarP(&level, "lvl", "l", "trace", "The logging level ['trace', 'debug', 'info', 'notice', 'warning', 'error', 'fatal'] that service is running in")
22+
runCmd.Flags().IntVarP(&rate, "rate", "r", 1000, "The sample rate of the trace logs used for performance auditing [set to -1 to log every trace]")
23+
runCmd.Flags().IntVarP(&limit, "limit", "x", 1000, "The messages per second that each topic worker will be limited to [set to 0 or less for maximum throughput]")
24+
runCmd.Flags().BoolVar(&test, "test", false, "A flag indicating if service should enter into test mode")
25+
runCmd.Flags().BoolVar(&disableTls, "disable-tls", false, "A flag indicating if service should disable tls encryption")
26+
27+
rootCmd.AddCommand(runCmd)
28+
}

0 commit comments

Comments
 (0)