diff --git a/CHANGELOG.md b/CHANGELOG.md
index fbd4183..dd92944 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [0.5.0] - 2020-06-15
+### Added
+- new component _Block Storage_ (kind: `bst`)
+- new component _Object Storage_ (kind: `ost`)
+- new component _File Storage_ (kind: `fst`)
+- new component _RDBMS_ (kind: `rdb`)
+- new component _No SQL_ (kind: `doc`)
+- new component _Caching_ (kind: `mem`)
+- new commandline flag `--impl=[aws,gcp,azure]` to auto fill components implementations according to the specified provider
+
+### Changed
+- autogenerated id prefix now is equal to the _kind_ value (see [./README.md](README.md)) **breaking change**
+ - modified YAML schema
+- connection info (see [./README.md](README.md)) **breaking change**
+ - modified YAML schema
+### Removed
+- generic html component
## [0.4.0] - 2020-06-11
### Added
diff --git a/README.md b/README.md
index 0203130..79504e2 100644
--- a/README.md
+++ b/README.md
@@ -44,7 +44,7 @@ type Component struct {
ID string `yaml:"id,omitempty"` // optional - autogenerated if omitted (read more for details...)
Kind string `yaml:"kind"` // required - see the table below
Label string `yaml:"label,omitempty"` // optional - works only for: 'queue', 'service', 'storage', 'function', 'database', 'client'
- Provider string `yaml:"provider,omitempty"` // optional - you can use this to specify the cloud provider
+ Outline string `yaml:"outline,omitempty"` // optional - you can use this to groups some components
Impl string `yaml:"impl,omitempty"` // optional - you can use this to specify the implementation
FillColor string `yaml:"fillColor,omitempty"` // optional - the hex code for the background color
FontColor string `yaml:"fontColor,omitempty"` // optional - the hex code for the foreground color
@@ -62,27 +62,38 @@ Eventually you can describe...
Below is a list of all the components currently implemented.
-| Component | Kind | YAML | Output |
-|:----------------------|:------------|:--------------------------------------------------------------|:---------------------------------:|
-| **Client** | `client` | π [examples/client.yml](./examples/client.yml) | ![](./examples/client.png) |
-| **Microservice** | `service` | π [examples/service.yml](./examples/service.yml) | ![](./examples/service.png) |
-| **Gateway** | `gateway` | π [examples/gateway.yml](./examples/gateway.yml) | ![](./examples/gateway.png) |
-| **Firewall** | `waf` | π [examples/waf.yml](./examples/waf.yml) | ![](./examples/waf.png) |
-| **Container Service** | `cos` | π [examples/waf.yml](./examples/cos.yml) | ![](./examples/cos.png) |
-| **Message Broker** | `broker` | π [examples/broker.yml](./examples/broker.yml) | ![](./examples/broker.png) |
-| **Queue Service** | `queue` | π [examples/queue.yml](./examples/queue.yml) | ![](./examples/queue.png) |
-| **Object Storage** | `storage` | π [examples/storage.yml](./examples/storage.yml) | ![](./examples/storage.png) |
-| **Function** | `function` | π [examples/function.yml](./examples/function.yml) | ![](./examples/function.png) |
-| **Database** | `database` | π [examples/database.yml](./examples/database.yml) | ![](./examples/database.png) |
-| **Load Balancer** | `balancer` | π [examples/balancer.yml](./examples/balancer.yml) | ![](./examples/balancer.png) |
-| **CDN** | `cdn` | π [examples/cdn.yml](./examples/cdn.yml) | ![](./examples/cdn.png) |
-| **DNS** | `dns` | π [examples/dns.yml](./examples/dns.yml) | ![](./examples/dns.png) |
-| **Custom Html** | `html` | π [examples/custom_image.yml](./examples/custom_image.yml) | ![](./examples/custom_image.png) |
-
-For custom HTML components (_kind: html_) only these tags are supported:
-
-- ``, `
`, ``, `
`, ``, ` (in
β¦ | only)`
-- ``, ``, ``, ``, ``, ``, ``
+| Component | Kind | YAML | Output |
+|:---------------------|:------|:--------------------------------------------|:------------------------:|
+| **Client** | `cli` | π [examples/cli.yml](./examples/cli.yml) | ![](./examples/cli.png) |
+| **Microservice** | `ser` | π [examples/ser.yml](./examples/ser.yml) | ![](./examples/ser.png) |
+| **API Gateway** | `gtw` | π [examples/gtw.yml](./examples/gtw.yml) | ![](./examples/gtw.png) |
+| **Firewall** | `waf` | π [examples/waf.yml](./examples/waf.yml) | ![](./examples/waf.png) |
+| **K8s Engine** | `kub` | π [examples/kub.yml](./examples/kub.yml) | ![](./examples/kub.png) |
+| **Pub / Sub** | `msg` | π [examples/msg.yml](./examples/msg.yml) | ![](./examples/msg.png) |
+| **Queue** | `que` | π [examples/que.yml](./examples/que.yml) | ![](./examples/que.png) |
+| **Function** | `fun` | π [examples/fun.yml](./examples/fun.yml) | ![](./examples/fun.png) |
+| **Relational DB** | `rdb` | π [examples/rdb.yml](./examples/rdb.yml) | ![](./examples/rdb.png) |
+| **Document DB** | `doc` | π [examples/doc.yml](./examples/doc.yml) | ![](./examples/doc.png) |
+| **Caching** | `mem` | π [examples/mem.yml](./examples/mem.yml) | ![](./examples/mem.png) |
+| **Load Balancer** | `lba` | π [examples/lba.yml](./examples/lba.yml) | ![](./examples/lba.png) |
+| **CDN** | `cdn` | π [examples/cdn.yml](./examples/cdn.yml) | ![](./examples/cdn.png) |
+| **DNS** | `dns` | π [examples/dns.yml](./examples/dns.yml) | ![](./examples/dns.png) |
+| **Block Store** | `bst` | π [examples/bst.yml](./examples/bst.yml) | ![](./examples/bst.png) |
+| **Object Store** | `ost` | π [examples/ost.yml](./examples/ost.yml) | ![](./examples/ost.png) |
+| **File Store** | `fst` | π [examples/fst.yml](./examples/fst.yml) | ![](./examples/fst.png) |
+
+## Auto filling the component implementation
+
+Leave the `impl` fields empty and run [draft](https://github.com/lucasepe/draft/releases/latest) with the `-impl` flag to let [draft](https://github.com/lucasepe/draft/releases/latest) found the implementation by provider.
+
+| example command | output |
+|:------------------------------------------------------------------------------|:------------------------------:|
+| draft -impl aws ./examples/dns.yml | dot -Tpng > test.png
| ![](./examples/dns_aws.png) |
+| draft -impl azure ./examples/dns.yml | dot -Tpng > test.png | ![](./examples/dns_azure.png) |
+| draft -impl gcp ./examples/kub.yml | dot -Tpng > test.png | ![](./examples/kub_gcp.png) |
+| draft -impl aws ./examples/kub.yml | dot -Tpng > test.png | ![](./examples/kub_aws.png) |
+
+... and so on for each kind of component!
### Notes about a component `id`
@@ -94,23 +105,7 @@ For custom HTML components (_kind: html_) only these tags are supported:
An auto-generated component `id` has a prefix and a sequential number
- the prefix is related to the component `kind`
-
-| a kind of... | will generate an `id` prefix with... | example |
-|:-------------|:-------------------------------------|:-----------------|
-| `client` | cl | _cl1, cl2,..._ |
-| `service` | ms | _ms1, ms2,..._ |
-| `gateway` | gt | _gt1, gt2,..._ |
-| `gateway` | waf | _waf1, waf2,..._ |
-| `broker` | br | _br1, br2,..._ |
-| `queue` | qs | _qs1, qs2,..._ |
-| `storage` | st | _st1, st2,..._ |
-| `function` | fn | _fn1, fn2,..._ |
-| `database` | db | _db1, db2,..._ |
-| `balancer` | lb | _lb1, lb2,..._ |
-| `cdn` | cn | _cn1, cn2,..._ |
-| `dns` | dn | _dn1, dn2,..._ |
-| `html` | htm | _htm1, htm2,..._ |
-| `cos` | cos | _cos1, cos2,..._ |
+ - examples _waf1, ..., wafN_ or _ser1, ..., serN_ etc.
## Connections
@@ -122,11 +117,9 @@ A `connection` has the following properties:
```go
type Connection struct {
- Origin struct {
- ComponentID string `yaml:"componentId"`
- } `yaml:"origin"`
+ Origin string `yaml:"origin"`
Targets []struct {
- ComponentID string `yaml:"componentId"`
+ ID string `yaml:"id"`
Label string `yaml:"label,omitempty"`
Color string `yaml:"color,omitempty"`
Dashed bool `yaml:"dashed,omitempty"`
diff --git a/broker.go b/broker.go
deleted file mode 100644
index 1141d3c..0000000
--- a/broker.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package draft
-
-import (
- "fmt"
- "strings"
-
- "github.com/emicklei/dot"
- "github.com/lucasepe/draft/pkg/cluster"
- "github.com/lucasepe/draft/pkg/node"
-)
-
-type broker struct {
- seq int16
-}
-
-func (rcv *broker) nextID() string {
- rcv.seq++
- return fmt.Sprintf("br%d", rcv.seq)
-}
-
-func (rcv *broker) sketch(graph *dot.Graph, comp Component) {
- id := comp.ID
- if strings.TrimSpace(comp.ID) == "" {
- id = rcv.nextID()
- }
-
- cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
-
- el := node.New(cl, id,
- node.Label("Message Broker", false),
- node.Rounded(comp.Rounded),
- node.FontSize(7),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#e0eeeeff"),
- node.Shape("cds"),
- )
- el.Attr("width", "1.4")
-}
-
-/** Alternative
-
-label=
- topic 1 |
- topic 2 |
- ... |
- topic N |
-
>
-shape="plain"
-
-**/
diff --git a/broker_test.go b/broker_test.go
deleted file mode 100644
index 5588ad4..0000000
--- a/broker_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package draft
-
-import (
- "testing"
-
- "github.com/emicklei/dot"
-)
-
-func TestBrokerComponentNextID(t *testing.T) {
- tests := []struct {
- want string
- }{
- {"br1"},
- {"br2"},
- {"br3"},
- {"br4"},
- }
-
- s := broker{}
-
- for _, tt := range tests {
- t.Run(tt.want, func(t *testing.T) {
- if got := s.nextID(); got != tt.want {
- t.Errorf("got [%v] want [%v]", got, tt.want)
- }
- })
- }
-}
-
-func TestBrokerComponent(t *testing.T) {
- want := `label="Message Broker",shape="cds",style="filled"`
- g := dot.NewGraph(dot.Directed)
-
- sketcher := broker{}
- sketcher.sketch(g, Component{})
-
- if got := flatten(g.String()); !verify(got, want) {
- t.Errorf("got [%v] want [%v]", got, want)
- }
-}
diff --git a/bst.go b/bst.go
new file mode 100644
index 0000000..64fd4ac
--- /dev/null
+++ b/bst.go
@@ -0,0 +1,55 @@
+package draft
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/emicklei/dot"
+ "github.com/lucasepe/draft/pkg/cluster"
+ "github.com/lucasepe/draft/pkg/node"
+)
+
+type bst struct {
+ seq int16
+}
+
+func (rcv *bst) nextID() string {
+ rcv.seq++
+ return fmt.Sprintf("bst%d", rcv.seq)
+}
+
+func (rcv *bst) sketch(graph *dot.Graph, comp Component) {
+ id := comp.ID
+ if strings.TrimSpace(comp.ID) == "" {
+ id = rcv.nextID()
+ }
+
+ fillColor := comp.FillColor
+ if strings.TrimSpace(comp.FillColor) == "" {
+ fillColor = "#606f5cff"
+ }
+
+ label := strings.Replace(``, "{{BGCOLOR}}", fillColor, -1)
+
+ cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
+
+ node.New(cl, id,
+ node.Label(label, true),
+ node.FontColor("#000000ff"),
+ node.FontSize(7),
+ node.FillColor("transparent"),
+ // ^^^ hack to set a transparent background
+ // color since we will use the HTML table.
+ node.Shape("plain"),
+ )
+}
diff --git a/balancer_test.go b/bst_test.go
similarity index 50%
rename from balancer_test.go
rename to bst_test.go
index b2e01f2..d1d33df 100644
--- a/balancer_test.go
+++ b/bst_test.go
@@ -6,17 +6,17 @@ import (
"github.com/emicklei/dot"
)
-func TestLoadBalancerComponentNextID(t *testing.T) {
+func TestBlockStorageNextID(t *testing.T) {
tests := []struct {
want string
}{
- {"lb1"},
- {"lb2"},
- {"lb3"},
- {"lb4"},
+ {"bst1"},
+ {"bst2"},
+ {"bst3"},
+ {"bst4"},
}
- s := balancer{}
+ s := bst{}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
@@ -27,11 +27,11 @@ func TestLoadBalancerComponentNextID(t *testing.T) {
}
}
-func TestLoadBalancerComponent(t *testing.T) {
- want := `label="LB",shape="Mdiamond",style="filled"`
+func TestBlockStorageShape(t *testing.T) {
+ want := `label=<>`
g := dot.NewGraph(dot.Directed)
- sketcher := balancer{}
+ sketcher := bst{}
sketcher.sketch(g, Component{})
if got := flatten(g.String()); !verify(got, want) {
diff --git a/cdn.go b/cdn.go
index cc2ef49..b3536cc 100644
--- a/cdn.go
+++ b/cdn.go
@@ -15,7 +15,7 @@ type cdn struct {
func (rcv *cdn) nextID() string {
rcv.seq++
- return fmt.Sprintf("cn%d", rcv.seq)
+ return fmt.Sprintf("cdn%d", rcv.seq)
}
func (rcv *cdn) sketch(graph *dot.Graph, comp Component) {
@@ -25,12 +25,14 @@ func (rcv *cdn) sketch(graph *dot.Graph, comp Component) {
}
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
- node.Label("CDN", false),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#47df9aff"),
+ node.Label("CDN", true),
+ node.FontColor("#000000ff"),
+ node.FillColor("#47df9aff"),
node.Shape("Mcircle"),
)
el.Attr("height", "0.5")
+ el.Attr("color", "#f5f5f5ff")
}
diff --git a/cdn_test.go b/cdn_test.go
index 7ee67bd..e9b3be6 100644
--- a/cdn_test.go
+++ b/cdn_test.go
@@ -6,14 +6,14 @@ import (
"github.com/emicklei/dot"
)
-func TestCDNComponentNextID(t *testing.T) {
+func TestCDNCNextID(t *testing.T) {
tests := []struct {
want string
}{
- {"cn1"},
- {"cn2"},
- {"cn3"},
- {"cn4"},
+ {"cdn1"},
+ {"cdn2"},
+ {"cdn3"},
+ {"cdn4"},
}
s := cdn{}
@@ -27,8 +27,8 @@ func TestCDNComponentNextID(t *testing.T) {
}
}
-func TestCDNComponent(t *testing.T) {
- want := `label="CDN",shape="Mcircle",style="filled"`
+func TestCDNShape(t *testing.T) {
+ want := `shape="Mcircle",style="filled"`
g := dot.NewGraph(dot.Directed)
sketcher := cdn{}
diff --git a/client.go b/cli.go
similarity index 59%
rename from client.go
rename to cli.go
index 680c1f8..a601963 100644
--- a/client.go
+++ b/cli.go
@@ -9,30 +9,35 @@ import (
"github.com/lucasepe/draft/pkg/node"
)
-type client struct {
+type cli struct {
seq int16
}
-func (rcv *client) nextID() string {
+func (rcv *cli) nextID() string {
rcv.seq++
- return fmt.Sprintf("cl%d", rcv.seq)
+ return fmt.Sprintf("cli%d", rcv.seq)
}
-func (rcv *client) sketch(graph *dot.Graph, comp Component) {
+func (rcv *cli) sketch(graph *dot.Graph, comp Component) {
id := comp.ID
if strings.TrimSpace(comp.ID) == "" {
id = rcv.nextID()
}
+ fontColor := "#000000ff"
+ if fc := strings.TrimSpace(comp.FontColor); len(fc) > 0 {
+ fontColor = fc
+ }
+
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
el := node.New(cl, id,
node.Label(comp.Label, false),
node.Rounded(comp.Rounded),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#90ee90ff"),
+ node.FontColor(fontColor),
+ node.FillColor("transparent"),
node.Shape("underline"),
)
el.Attr("fontsize", "8")
- el.Attr("height", "0.3")
+ el.Attr("height", "0.4")
}
diff --git a/client_test.go b/cli_test.go
similarity index 87%
rename from client_test.go
rename to cli_test.go
index 4bd8c8c..adf70ac 100644
--- a/client_test.go
+++ b/cli_test.go
@@ -10,13 +10,13 @@ func TestClientComponentNextID(t *testing.T) {
tests := []struct {
want string
}{
- {"cl1"},
- {"cl2"},
- {"cl3"},
- {"cl4"},
+ {"cli1"},
+ {"cli2"},
+ {"cli3"},
+ {"cli4"},
}
- s := client{}
+ s := cli{}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
@@ -31,7 +31,7 @@ func TestClientComponent(t *testing.T) {
want := `shape="underline",style="filled"`
g := dot.NewGraph(dot.Directed)
- sketcher := client{}
+ sketcher := cli{}
sketcher.sketch(g, Component{})
if got := flatten(g.String()); !verify(got, want) {
diff --git a/cmd/draft-all.sh b/cmd/draft-all.sh
index 0a88d59..149e683 100755
--- a/cmd/draft-all.sh
+++ b/cmd/draft-all.sh
@@ -5,20 +5,23 @@ DPI=120
EXE=./dist/draft_linux_amd64/draft
## declare an array of files
-declare -a arr=("$SRC_DIR/client.yml"
- "$SRC_DIR/service.yml"
- "$SRC_DIR/broker.yml"
- "$SRC_DIR/gateway.yml"
- "$SRC_DIR/queue.yml"
- "$SRC_DIR/function.yml"
- "$SRC_DIR/database.yml"
- "$SRC_DIR/storage.yml"
- "$SRC_DIR/balancer.yml"
+declare -a arr=("$SRC_DIR/cli.yml"
+ "$SRC_DIR/ser.yml"
+ "$SRC_DIR/msg.yml"
+ "$SRC_DIR/gtw.yml"
+ "$SRC_DIR/que.yml"
+ "$SRC_DIR/fun.yml"
+ "$SRC_DIR/rdb.yml"
+ "$SRC_DIR/doc.yml"
+ "$SRC_DIR/bst.yml"
+ "$SRC_DIR/ost.yml"
+ "$SRC_DIR/fst.yml"
+ "$SRC_DIR/lba.yml"
"$SRC_DIR/cdn.yml"
"$SRC_DIR/dns.yml"
"$SRC_DIR/waf.yml"
- "$SRC_DIR/cos.yml"
- "$SRC_DIR/custom_image.yml"
+ "$SRC_DIR/kub.yml"
+ "$SRC_DIR/mem.yml"
"$SRC_DIR/system-view.yml"
"$SRC_DIR/message-bus-pattern.yml"
"$SRC_DIR/aws-cognito-custom-auth-flow.yml"
@@ -32,4 +35,9 @@ do
filename=$(basename -- "$i")
# run draft...run!
"$EXE" "$i" | dot -Tpng -Gdpi=$DPI > "$SRC_DIR/${filename%.*}.png"
+
+ "$EXE" -impl aws "$i" | dot -Tpng -Gdpi=$DPI > "$SRC_DIR/${filename%.*}_aws.png"
+ "$EXE" -impl gcp "$i" | dot -Tpng -Gdpi=$DPI > "$SRC_DIR/${filename%.*}_gcp.png"
+ "$EXE" -impl azure "$i" | dot -Tpng -Gdpi=$DPI > "$SRC_DIR/${filename%.*}_azure.png"
+
done
\ No newline at end of file
diff --git a/cmd/main.go b/cmd/main.go
index a509a5a..05d3ee7 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -21,7 +21,7 @@ ______ __ _
| | | | _ __ __ _ | |_ | |_
| | | || '__| / _' || _|| __| https://github.com/lucasepe/draft
| |/ / | | | (_| || | | |_
-|___/ |_| \__,_||_| \__| {{VERSION}}`
+|___/ |_| \__,_||_| \__| v{{VERSION}}`
)
var (
@@ -31,6 +31,7 @@ var (
flagBottomTop bool
flagOrtho bool
+ flagImpl string
)
func main() {
@@ -42,29 +43,30 @@ func main() {
}
fn, err := filepath.Abs(flag.Args()[0])
- handleErr(err)
+ handleErr(err, fn)
file, err := os.Open(fn)
- handleErr(err)
+ handleErr(err, fn)
defer file.Close()
ark, err := draft.NewDraft(file)
- handleErr(err)
+ handleErr(err, fn)
ark.BottomTop(flagBottomTop)
ark.Ortho(flagOrtho)
+ ark.Provider(flagImpl)
str, err := ark.Sketch()
- handleErr(err)
+ handleErr(err, fn)
fmt.Println(str)
}
// handleErr check for an error and eventually exit
-func handleErr(err error) {
+func handleErr(err error, src string) {
if err != nil {
- fmt.Fprintf(os.Stderr, "error: %s\n", err.Error())
+ fmt.Fprintf(os.Stderr, "error: %s @ %s\n", err.Error(), src)
os.Exit(1)
}
}
@@ -95,6 +97,7 @@ func configureFlags() {
flag.CommandLine.BoolVar(&flagBottomTop, "bottom-top", false, "if true sets layout dir as bottom top")
flag.CommandLine.BoolVar(&flagOrtho, "ortho", false, "if true edges are drawn as line segments")
+ flag.CommandLine.StringVar(&flagImpl, "impl", "", "auto fill the specific provider services (aws, gcp or azure)")
flag.CommandLine.Parse(os.Args[1:])
}
diff --git a/dns.go b/dns.go
index 5806768..1156d67 100644
--- a/dns.go
+++ b/dns.go
@@ -26,12 +26,14 @@ func (rcv *dns) sketch(graph *dot.Graph, comp Component) {
}
cl := cluster.New(graph, id, cluster.BottomTop(rcv.bottomTop), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
- node.Label("DNS", false),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#854eadff"),
+ node.Label("DNS", true),
+ node.FontColor("#f5f5f5ff"),
+ node.FillColor("#854eadff"),
node.Shape("Msquare"),
)
el.Attr("height", "0.3")
+ el.Attr("color", "#f5f5f5ff")
}
diff --git a/dns_test.go b/dns_test.go
index cd9a66e..402dbb3 100644
--- a/dns_test.go
+++ b/dns_test.go
@@ -28,7 +28,7 @@ func TestDNSComponentNextID(t *testing.T) {
}
func TestDNSComponent(t *testing.T) {
- want := `label="DNS",shape="Msquare",style="filled"`
+ want := `label=<DNS>,shape="Msquare",style="filled"`
g := dot.NewGraph(dot.Directed)
sketcher := dns{}
diff --git a/database.go b/doc.go
similarity index 60%
rename from database.go
rename to doc.go
index 54bda08..ed7855a 100644
--- a/database.go
+++ b/doc.go
@@ -9,30 +9,30 @@ import (
"github.com/lucasepe/draft/pkg/node"
)
-type database struct {
+type doc struct {
seq int16
}
-func (rcv *database) nextID() string {
+func (rcv *doc) nextID() string {
rcv.seq++
- return fmt.Sprintf("db%d", rcv.seq)
+ return fmt.Sprintf("doc%d", rcv.seq)
}
-func (rcv *database) sketch(graph *dot.Graph, comp Component) {
+func (rcv *doc) sketch(graph *dot.Graph, comp Component) {
id := comp.ID
if strings.TrimSpace(comp.ID) == "" {
id = rcv.nextID()
}
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
node.Label(comp.Label, false),
node.Rounded(comp.Rounded),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#f5f5dcff"),
- node.Shape("cylinder"),
+ node.FontColor("#000000ff"),
+ node.FillColor("#d1c8d4ff"),
+ node.Shape("note"),
)
el.Attr("height", "0.5")
- el.Attr("fontsize", "6")
}
diff --git a/container_service_test.go b/doc_test.go
similarity index 66%
rename from container_service_test.go
rename to doc_test.go
index e95abd0..40b2e01 100644
--- a/container_service_test.go
+++ b/doc_test.go
@@ -6,17 +6,17 @@ import (
"github.com/emicklei/dot"
)
-func TestCSComponentNextID(t *testing.T) {
+func TestNoSQLNextID(t *testing.T) {
tests := []struct {
want string
}{
- {"cos1"},
- {"cos2"},
- {"cos3"},
- {"cos4"},
+ {"doc1"},
+ {"doc2"},
+ {"doc3"},
+ {"doc4"},
}
- s := containerService{}
+ s := doc{}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
@@ -27,11 +27,11 @@ func TestCSComponentNextID(t *testing.T) {
}
}
-func TestCSComponent(t *testing.T) {
- want := `shape="component",style="filled"`
+func TestNoSQLShape(t *testing.T) {
+ want := `shape="note",style="filled"`
g := dot.NewGraph(dot.Directed)
- sketcher := containerService{}
+ sketcher := doc{}
sketcher.sketch(g, Component{})
if got := flatten(g.String()); !verify(got, want) {
diff --git a/draft.go b/draft.go
index f9a6666..857326c 100644
--- a/draft.go
+++ b/draft.go
@@ -13,34 +13,36 @@ import (
)
const (
- kindHTML = "html"
- kindClient = "client"
- kindGateway = "gateway"
- kindService = "service"
- kindQueue = "queue"
- kindBroker = "broker"
- kindStorage = "storage"
- kindDatabase = "database"
- kindFunction = "function"
- kindBalancer = "balancer"
- kindCDN = "cdn"
- kindDNS = "dns"
- kindFirewall = "waf"
- kindContainerService = "cos"
+ kindHTML = "html"
+ kindClient = "cli"
+ kindGateway = "gtw"
+ kindService = "ser"
+ kindQueue = "que"
+ kindPubSub = "msg"
+ kindObjectStore = "ost"
+ kindRDB = "rdb"
+ kindNoSQL = "doc"
+ kindFunction = "fun"
+ kindLBA = "lba"
+ kindCDN = "cdn"
+ kindDNS = "dns"
+ kindFirewall = "waf"
+ kindContainersManager = "kub"
+ kindBlockStore = "bst"
+ kindCache = "mem"
+ kindFileStore = "fst"
)
// Connection is a link between two components.
type Connection struct {
- Origin struct {
- ComponentID string `yaml:"componentId"`
- } `yaml:"origin"`
+ Origin string `yaml:"origin"`
Targets []struct {
- ComponentID string `yaml:"componentId"`
- Label string `yaml:"label,omitempty"`
- Color string `yaml:"color,omitempty"`
- Dashed bool `yaml:"dashed,omitempty"`
- Dir string `yaml:"dir,omitempty"`
- Highlight bool `yaml:"highlight,omitempty"`
+ ID string `yaml:"id"`
+ Label string `yaml:"label,omitempty"`
+ Color string `yaml:"color,omitempty"`
+ Dashed bool `yaml:"dashed,omitempty"`
+ Dir string `yaml:"dir,omitempty"`
+ Highlight bool `yaml:"highlight,omitempty"`
} `yaml:"targets"`
}
@@ -50,12 +52,13 @@ type Component struct {
Kind string `yaml:"kind"`
Label string `yaml:"label,omitempty"`
Impl string `yaml:"impl,omitempty"`
- Provider string `yaml:"provider,omitempty"`
+ Outline string `yaml:"outline,omitempty"`
FillColor string `yaml:"fillColor,omitempty"`
FontColor string `yaml:"fontColor,omitempty"`
Rounded bool `yaml:"rounded,omitempty"`
bottomTop bool
+ provider string
}
// Draft represents a whole diagram.
@@ -75,6 +78,7 @@ type Draft struct {
bottomTop bool
ortho bool
+ provider string
}
// BottomTop return true if this component
@@ -89,20 +93,24 @@ func NewDraft(r io.Reader) (*Draft, error) {
sketchers: map[string]interface {
sketch(*dot.Graph, Component)
}{
- kindHTML: &html{},
- kindClient: &client{},
- kindGateway: &gateway{},
- kindService: &service{},
- kindBroker: &broker{},
- kindQueue: &queue{},
- kindFunction: &function{},
- kindStorage: &storage{},
- kindDatabase: &database{},
- kindBalancer: &balancer{},
- kindCDN: &cdn{},
- kindDNS: &dns{},
- kindFirewall: &waf{},
- kindContainerService: &containerService{},
+ kindHTML: &html{},
+ kindClient: &cli{},
+ kindGateway: >w{},
+ kindService: &ser{},
+ kindPubSub: &msg{},
+ kindQueue: &que{},
+ kindFunction: &fun{},
+ kindRDB: &rdb{},
+ kindLBA: &lba{},
+ kindBlockStore: &bst{},
+ kindCDN: &cdn{},
+ kindDNS: &dns{},
+ kindFirewall: &waf{},
+ kindContainersManager: &kub{},
+ kindCache: &mem{},
+ kindNoSQL: &doc{},
+ kindObjectStore: &ost{},
+ kindFileStore: &fst{},
},
}
@@ -127,6 +135,11 @@ func (ark *Draft) Ortho(val bool) {
ark.ortho = val
}
+// Provider sets the Cloud Provider name (one of: aws, gcp, azure).
+func (ark *Draft) Provider(name string) {
+ ark.provider = name
+}
+
// Sketch generates the GraphViz definition for this architecture diagram.
func (ark *Draft) Sketch() (string, error) {
g := graph.New(graph.BackgroundColor(ark.BackgroundColor),
@@ -150,6 +163,7 @@ func (ark *Draft) Sketch() (string, error) {
func sketchComponents(graph *dot.Graph, draft *Draft) error {
for _, el := range draft.Components {
el.bottomTop = draft.bottomTop
+ el.provider = draft.provider
sketcher, ok := draft.sketchers[el.Kind]
if !ok {
@@ -157,8 +171,8 @@ func sketchComponents(graph *dot.Graph, draft *Draft) error {
}
parent := graph
- if strings.TrimSpace(el.Provider) != "" {
- parent = cluster.New(graph, el.Provider,
+ if strings.TrimSpace(el.Outline) != "" {
+ parent = cluster.New(graph, el.Outline,
cluster.PenColor("#d9cc31"),
cluster.FontName("Fira Mono"),
cluster.FontSize(10),
@@ -173,10 +187,9 @@ func sketchComponents(graph *dot.Graph, draft *Draft) error {
func sketchConnections(graph *dot.Graph, draft *Draft) error {
for _, el := range draft.Connections {
- var from = el.Origin.ComponentID
for _, x := range el.Targets {
- err := edge.New(graph, from, x.ComponentID,
+ err := edge.New(graph, el.Origin, x.ID,
edge.Label(x.Label),
edge.Dir(x.Dir),
edge.Color(x.Color),
diff --git a/examples/amazon-appsync.png b/examples/amazon-appsync.png
deleted file mode 100644
index c3ab7a6..0000000
Binary files a/examples/amazon-appsync.png and /dev/null differ
diff --git a/examples/aws-cognito-custom-auth-flow.png b/examples/aws-cognito-custom-auth-flow.png
index 3e5310b..0036e7e 100644
Binary files a/examples/aws-cognito-custom-auth-flow.png and b/examples/aws-cognito-custom-auth-flow.png differ
diff --git a/examples/aws-cognito-custom-auth-flow.yml b/examples/aws-cognito-custom-auth-flow.yml
index 3420d58..6e3107e 100644
--- a/examples/aws-cognito-custom-auth-flow.yml
+++ b/examples/aws-cognito-custom-auth-flow.yml
@@ -2,68 +2,62 @@ title: Amazon Cognito Custom Authentication Flow with external database
backgroundColor: '#ffffff'
components:
-
- kind: client
+ kind: cli
label: "Web App"
- provider: Internet
impl: SPA
-
- kind: client
+ kind: cli
label: "Mobile App"
- provider: Internet
impl: "Android & iOS"
-
- kind: service
+ kind: ser
label: "OAuth 2.0\nAuth Service"
provider: AWS
impl: "Cognito"
fillColor: '#991919'
fontColor: '#fafafa'
-
- kind: function
+ kind: fun
label: "Define\nAuthChallange"
provider: AWS
impl: Lambda
-
- kind: function
+ kind: fun
label: "Create\nAuthChallange"
provider: AWS
impl: Lambda
-
- kind: function
+ kind: fun
label: "Verify\nAuthChallange"
provider: AWS
impl: Lambda
-
- kind: database
+ kind: rdb
label: "Users\nRepository"
provider: AWS
impl: RDS
connections:
-
- origin:
- componentId: cl1
+ origin: cli1
targets:
-
- componentId: ms1
+ id: ser1
-
- origin:
- componentId: cl2
+ origin: cli2
targets:
-
- componentId: ms1
+ id: ser1
-
- origin:
- componentId: ms1
+ origin: ser1
targets:
-
- componentId: fn1
+ id: fun1
-
- componentId: fn2
+ id: fun2
-
- componentId: fn3
+ id: fun3
-
- origin:
- componentId: fn2
+ origin: fun2
targets:
-
- componentId: db1
\ No newline at end of file
+ id: rdb1
\ No newline at end of file
diff --git a/examples/aws-cognito-custom-auth-flow_aws.png b/examples/aws-cognito-custom-auth-flow_aws.png
new file mode 100644
index 0000000..0036e7e
Binary files /dev/null and b/examples/aws-cognito-custom-auth-flow_aws.png differ
diff --git a/examples/aws-cognito-custom-auth-flow_azure.png b/examples/aws-cognito-custom-auth-flow_azure.png
new file mode 100644
index 0000000..0036e7e
Binary files /dev/null and b/examples/aws-cognito-custom-auth-flow_azure.png differ
diff --git a/examples/aws-cognito-custom-auth-flow_gcp.png b/examples/aws-cognito-custom-auth-flow_gcp.png
new file mode 100644
index 0000000..0036e7e
Binary files /dev/null and b/examples/aws-cognito-custom-auth-flow_gcp.png differ
diff --git a/examples/backend-for-frontend.png b/examples/backend-for-frontend.png
index 31da7d2..31401d2 100644
Binary files a/examples/backend-for-frontend.png and b/examples/backend-for-frontend.png differ
diff --git a/examples/backend-for-frontend.yml b/examples/backend-for-frontend.yml
index c6cb0ab..565efe2 100644
--- a/examples/backend-for-frontend.yml
+++ b/examples/backend-for-frontend.yml
@@ -2,82 +2,76 @@ title: Backend For Frontend (BFF)
backgroundColor: '#ffffff'
components:
-
- kind: client
+ kind: cli
label: Web App
- fillColor: '#ee82ee'
-
- kind: client
+ kind: cli
label: Mobile App
- fillColor: '#708090'
-
- kind: gateway
+ kind: gtw
impl: |
Web BFF
API Gateway
-
- kind: gateway
+ kind: gtw
impl: |
Mobile BFF
API Gateway
-
- kind: service
+ kind: ser
label: ΞΌService A
fillColor: '#b0e0e6'
-
- kind: service
+ kind: ser
label: ΞΌService B
-
- kind: service
+ kind: ser
label: ΞΌService C
fillColor: '#00ff7f'
-
- kind: service
+ kind: ser
label: ΞΌService D
fillColor: '#00007f'
fontColor: '#fafafa'
connections:
-
- origin:
- componentId: cl1
+ origin: cli1
targets:
-
- componentId: gt1
+ id: gtw1
color: '#ee82ee'
-
- origin:
- componentId: cl2
+ origin: cli2
targets:
-
- componentId: gt2
+ id: gtw2
-
- origin:
- componentId: gt1
+ origin: gtw1
targets:
-
- componentId: ms1
+ id: ser1
color: '#ee82ee'
-
- componentId: ms2
+ id: ser2
color: '#ee82ee'
-
- componentId: ms3
+ id: ser3
color: '#ee82ee'
-
- componentId: ms4
+ id: ser4
color: '#ee82ee'
-
- origin:
- componentId: gt2
+ origin: gtw2
targets:
-
- componentId: ms1
+ id: ser1
highlight: true
-
- componentId: ms2
+ id: ser2
highlight: true
-
- componentId: ms3
+ id: ser3
highlight: true
-
- componentId: ms4
+ id: ser4
highlight: true
\ No newline at end of file
diff --git a/examples/backend-for-frontend_aws.png b/examples/backend-for-frontend_aws.png
new file mode 100644
index 0000000..31401d2
Binary files /dev/null and b/examples/backend-for-frontend_aws.png differ
diff --git a/examples/backend-for-frontend_azure.png b/examples/backend-for-frontend_azure.png
new file mode 100644
index 0000000..31401d2
Binary files /dev/null and b/examples/backend-for-frontend_azure.png differ
diff --git a/examples/backend-for-frontend_gcp.png b/examples/backend-for-frontend_gcp.png
new file mode 100644
index 0000000..31401d2
Binary files /dev/null and b/examples/backend-for-frontend_gcp.png differ
diff --git a/examples/balancer.png b/examples/balancer.png
deleted file mode 100644
index f2601eb..0000000
Binary files a/examples/balancer.png and /dev/null differ
diff --git a/examples/broker.png b/examples/broker.png
deleted file mode 100644
index 66efc2e..0000000
Binary files a/examples/broker.png and /dev/null differ
diff --git a/examples/bst.png b/examples/bst.png
new file mode 100644
index 0000000..48c3c77
Binary files /dev/null and b/examples/bst.png differ
diff --git a/examples/cos.yml b/examples/bst.yml
similarity index 63%
rename from examples/cos.yml
rename to examples/bst.yml
index 9177e72..860f13a 100644
--- a/examples/cos.yml
+++ b/examples/bst.yml
@@ -1,4 +1,4 @@
---
components:
-
- kind: cos
\ No newline at end of file
+ kind: bst
\ No newline at end of file
diff --git a/examples/bst_aws.png b/examples/bst_aws.png
new file mode 100644
index 0000000..0cbf790
Binary files /dev/null and b/examples/bst_aws.png differ
diff --git a/examples/bst_azure.png b/examples/bst_azure.png
new file mode 100644
index 0000000..43920b6
Binary files /dev/null and b/examples/bst_azure.png differ
diff --git a/examples/bst_gcp.png b/examples/bst_gcp.png
new file mode 100644
index 0000000..2d0428f
Binary files /dev/null and b/examples/bst_gcp.png differ
diff --git a/examples/cdn.png b/examples/cdn.png
index 0bffc4a..7a05a77 100644
Binary files a/examples/cdn.png and b/examples/cdn.png differ
diff --git a/examples/cdn_aws.png b/examples/cdn_aws.png
new file mode 100644
index 0000000..3131326
Binary files /dev/null and b/examples/cdn_aws.png differ
diff --git a/examples/cdn_azure.png b/examples/cdn_azure.png
new file mode 100644
index 0000000..6074ea2
Binary files /dev/null and b/examples/cdn_azure.png differ
diff --git a/examples/cdn_gcp.png b/examples/cdn_gcp.png
new file mode 100644
index 0000000..2cef52e
Binary files /dev/null and b/examples/cdn_gcp.png differ
diff --git a/examples/cl.jpg b/examples/cl.jpg
deleted file mode 100644
index 9859aeb..0000000
Binary files a/examples/cl.jpg and /dev/null differ
diff --git a/examples/cli.png b/examples/cli.png
new file mode 100644
index 0000000..5b304e1
Binary files /dev/null and b/examples/cli.png differ
diff --git a/examples/cli.yml b/examples/cli.yml
new file mode 100644
index 0000000..df5363f
--- /dev/null
+++ b/examples/cli.yml
@@ -0,0 +1,6 @@
+---
+components:
+ -
+ kind: cli
+ label: Web App
+ fontColor: '#8b33ac'
diff --git a/examples/cli_aws.png b/examples/cli_aws.png
new file mode 100644
index 0000000..5b304e1
Binary files /dev/null and b/examples/cli_aws.png differ
diff --git a/examples/cli_azure.png b/examples/cli_azure.png
new file mode 100644
index 0000000..5b304e1
Binary files /dev/null and b/examples/cli_azure.png differ
diff --git a/examples/cli_gcp.png b/examples/cli_gcp.png
new file mode 100644
index 0000000..5b304e1
Binary files /dev/null and b/examples/cli_gcp.png differ
diff --git a/examples/client.png b/examples/client.png
deleted file mode 100644
index 2dfdcd4..0000000
Binary files a/examples/client.png and /dev/null differ
diff --git a/examples/client.yml b/examples/client.yml
deleted file mode 100644
index a656f77..0000000
--- a/examples/client.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-components:
- -
- kind: client
- label: "Web App"
- fillColor: '#ee82ee'
diff --git a/examples/cos.png b/examples/cos.png
deleted file mode 100644
index b72e09b..0000000
Binary files a/examples/cos.png and /dev/null differ
diff --git a/examples/custom_image.png b/examples/custom_image.png
index 908fc21..e3d40dc 100644
Binary files a/examples/custom_image.png and b/examples/custom_image.png differ
diff --git a/examples/database.png b/examples/database.png
deleted file mode 100644
index dc1ab32..0000000
Binary files a/examples/database.png and /dev/null differ
diff --git a/examples/database.yml b/examples/database.yml
deleted file mode 100644
index 55060fb..0000000
--- a/examples/database.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-components:
- -
- kind: database
- label: "Users\nRepository"
diff --git a/examples/db.jpg b/examples/db.jpg
deleted file mode 100644
index dedfdea..0000000
Binary files a/examples/db.jpg and /dev/null differ
diff --git a/examples/dns.png b/examples/dns.png
index 7d874b7..66256c8 100644
Binary files a/examples/dns.png and b/examples/dns.png differ
diff --git a/examples/dns_aws.png b/examples/dns_aws.png
new file mode 100644
index 0000000..2e667d4
Binary files /dev/null and b/examples/dns_aws.png differ
diff --git a/examples/dns_azure.png b/examples/dns_azure.png
new file mode 100644
index 0000000..1ee974f
Binary files /dev/null and b/examples/dns_azure.png differ
diff --git a/examples/dns_gcp.png b/examples/dns_gcp.png
new file mode 100644
index 0000000..9d48e91
Binary files /dev/null and b/examples/dns_gcp.png differ
diff --git a/examples/doc.png b/examples/doc.png
new file mode 100644
index 0000000..194eda2
Binary files /dev/null and b/examples/doc.png differ
diff --git a/examples/doc.yml b/examples/doc.yml
new file mode 100644
index 0000000..a8ee87f
--- /dev/null
+++ b/examples/doc.yml
@@ -0,0 +1,7 @@
+---
+components:
+ -
+ kind: doc
+ label: |
+ Users
+ Repository
diff --git a/examples/doc_aws.png b/examples/doc_aws.png
new file mode 100644
index 0000000..f7c3c99
Binary files /dev/null and b/examples/doc_aws.png differ
diff --git a/examples/doc_azure.png b/examples/doc_azure.png
new file mode 100644
index 0000000..edff1d6
Binary files /dev/null and b/examples/doc_azure.png differ
diff --git a/examples/doc_gcp.png b/examples/doc_gcp.png
new file mode 100644
index 0000000..0706bcc
Binary files /dev/null and b/examples/doc_gcp.png differ
diff --git a/examples/fn.jpg b/examples/fn.jpg
deleted file mode 100644
index d5b33d4..0000000
Binary files a/examples/fn.jpg and /dev/null differ
diff --git a/examples/fst.png b/examples/fst.png
new file mode 100644
index 0000000..9002c43
Binary files /dev/null and b/examples/fst.png differ
diff --git a/examples/broker.yml b/examples/fst.yml
similarity index 58%
rename from examples/broker.yml
rename to examples/fst.yml
index c86e9cd..5753b83 100644
--- a/examples/broker.yml
+++ b/examples/fst.yml
@@ -1,4 +1,4 @@
---
components:
-
- kind: broker
\ No newline at end of file
+ kind: fst
\ No newline at end of file
diff --git a/examples/fst_aws.png b/examples/fst_aws.png
new file mode 100644
index 0000000..6c76b53
Binary files /dev/null and b/examples/fst_aws.png differ
diff --git a/examples/fst_azure.png b/examples/fst_azure.png
new file mode 100644
index 0000000..26c168b
Binary files /dev/null and b/examples/fst_azure.png differ
diff --git a/examples/fst_gcp.png b/examples/fst_gcp.png
new file mode 100644
index 0000000..4623b66
Binary files /dev/null and b/examples/fst_gcp.png differ
diff --git a/examples/function.png b/examples/fun.png
similarity index 100%
rename from examples/function.png
rename to examples/fun.png
diff --git a/examples/function.yml b/examples/fun.yml
similarity index 75%
rename from examples/function.yml
rename to examples/fun.yml
index 06dbe4c..09f367a 100644
--- a/examples/function.yml
+++ b/examples/fun.yml
@@ -1,5 +1,5 @@
---
components:
-
- kind: function
+ kind: fun
label: "Create\nAuth Challange"
diff --git a/examples/fun_aws.png b/examples/fun_aws.png
new file mode 100644
index 0000000..bef471e
Binary files /dev/null and b/examples/fun_aws.png differ
diff --git a/examples/fun_azure.png b/examples/fun_azure.png
new file mode 100644
index 0000000..df5a21c
Binary files /dev/null and b/examples/fun_azure.png differ
diff --git a/examples/fun_gcp.png b/examples/fun_gcp.png
new file mode 100644
index 0000000..b2d4229
Binary files /dev/null and b/examples/fun_gcp.png differ
diff --git a/examples/gateway.png b/examples/gateway.png
deleted file mode 100644
index dc956a9..0000000
Binary files a/examples/gateway.png and /dev/null differ
diff --git a/examples/gateway.yml b/examples/gateway.yml
deleted file mode 100644
index c669810..0000000
--- a/examples/gateway.yml
+++ /dev/null
@@ -1,6 +0,0 @@
----
-components:
- -
- kind: gateway
- label: "API Gateway"
- fontColor: '#fafafaff'
\ No newline at end of file
diff --git a/examples/gt.jpg b/examples/gt.jpg
deleted file mode 100644
index 27631b5..0000000
Binary files a/examples/gt.jpg and /dev/null differ
diff --git a/examples/gtw.png b/examples/gtw.png
new file mode 100644
index 0000000..28eeb5a
Binary files /dev/null and b/examples/gtw.png differ
diff --git a/examples/balancer.yml b/examples/gtw.yml
similarity index 56%
rename from examples/balancer.yml
rename to examples/gtw.yml
index 0f03975..33e1097 100644
--- a/examples/balancer.yml
+++ b/examples/gtw.yml
@@ -1,4 +1,4 @@
---
components:
-
- kind: balancer
\ No newline at end of file
+ kind: gtw
\ No newline at end of file
diff --git a/examples/gtw_aws.png b/examples/gtw_aws.png
new file mode 100644
index 0000000..877e697
Binary files /dev/null and b/examples/gtw_aws.png differ
diff --git a/examples/gtw_azure.png b/examples/gtw_azure.png
new file mode 100644
index 0000000..811ec64
Binary files /dev/null and b/examples/gtw_azure.png differ
diff --git a/examples/gtw_gcp.png b/examples/gtw_gcp.png
new file mode 100644
index 0000000..6644053
Binary files /dev/null and b/examples/gtw_gcp.png differ
diff --git a/examples/kub.png b/examples/kub.png
new file mode 100644
index 0000000..fc584d5
Binary files /dev/null and b/examples/kub.png differ
diff --git a/examples/kub.yml b/examples/kub.yml
new file mode 100644
index 0000000..2e8afe0
--- /dev/null
+++ b/examples/kub.yml
@@ -0,0 +1,4 @@
+---
+components:
+ -
+ kind: kub
\ No newline at end of file
diff --git a/examples/kub_aws.png b/examples/kub_aws.png
new file mode 100644
index 0000000..936bf53
Binary files /dev/null and b/examples/kub_aws.png differ
diff --git a/examples/kub_azure.png b/examples/kub_azure.png
new file mode 100644
index 0000000..cb6a830
Binary files /dev/null and b/examples/kub_azure.png differ
diff --git a/examples/kub_gcp.png b/examples/kub_gcp.png
new file mode 100644
index 0000000..034bfc2
Binary files /dev/null and b/examples/kub_gcp.png differ
diff --git a/examples/lba.png b/examples/lba.png
new file mode 100644
index 0000000..91cf895
Binary files /dev/null and b/examples/lba.png differ
diff --git a/examples/lba.yml b/examples/lba.yml
new file mode 100644
index 0000000..20013bd
--- /dev/null
+++ b/examples/lba.yml
@@ -0,0 +1,4 @@
+---
+components:
+ -
+ kind: lba
\ No newline at end of file
diff --git a/examples/lba_aws.png b/examples/lba_aws.png
new file mode 100644
index 0000000..323acad
Binary files /dev/null and b/examples/lba_aws.png differ
diff --git a/examples/lba_azure.png b/examples/lba_azure.png
new file mode 100644
index 0000000..6ef7e30
Binary files /dev/null and b/examples/lba_azure.png differ
diff --git a/examples/lba_gcp.png b/examples/lba_gcp.png
new file mode 100644
index 0000000..5583a50
Binary files /dev/null and b/examples/lba_gcp.png differ
diff --git a/examples/mem.png b/examples/mem.png
new file mode 100644
index 0000000..9e302b8
Binary files /dev/null and b/examples/mem.png differ
diff --git a/examples/mem.yml b/examples/mem.yml
new file mode 100644
index 0000000..40befd7
--- /dev/null
+++ b/examples/mem.yml
@@ -0,0 +1,4 @@
+---
+components:
+ -
+ kind: mem
\ No newline at end of file
diff --git a/examples/mem_aws.png b/examples/mem_aws.png
new file mode 100644
index 0000000..298768a
Binary files /dev/null and b/examples/mem_aws.png differ
diff --git a/examples/mem_azure.png b/examples/mem_azure.png
new file mode 100644
index 0000000..81eba95
Binary files /dev/null and b/examples/mem_azure.png differ
diff --git a/examples/mem_gcp.png b/examples/mem_gcp.png
new file mode 100644
index 0000000..0fb12ab
Binary files /dev/null and b/examples/mem_gcp.png differ
diff --git a/examples/message-bus-pattern-with-icons.yml b/examples/message-bus-pattern-with-icons.yml
new file mode 100644
index 0000000..4582fab
--- /dev/null
+++ b/examples/message-bus-pattern-with-icons.yml
@@ -0,0 +1,55 @@
+title: message bus pattern
+backgroundColor: '#ffffff'
+components:
+ -
+ kind: service
+ label: Producer
+ -
+ id: br1
+ kind: icon
+ label: aws-sns.png
+ -
+ id: qs1
+ kind: icon
+ label: aws-sns.png
+ -
+ id: qs2
+ kind: icon
+ label: aws-sns.png
+ -
+ kind: service
+ label: "Consumer\n@ topic 1"
+ -
+ kind: service
+ label: "Consumer\n@ topic 2"
+connections:
+ -
+ origin:
+ componentId: ms1
+ targets:
+ -
+ componentId: br1
+ -
+ origin:
+ componentId: br1
+ targets:
+ -
+ componentId: qs1
+ dashed: true
+ -
+ componentId: qs2
+ dashed: true
+ -
+ origin:
+ componentId: qs1
+ targets:
+ -
+ componentId: ms2
+ dir: back
+ -
+ origin:
+ componentId: qs2
+ targets:
+ -
+ componentId: ms3
+ dir: back
diff --git a/examples/message-bus-pattern.png b/examples/message-bus-pattern.png
index f9bd06f..5242324 100644
Binary files a/examples/message-bus-pattern.png and b/examples/message-bus-pattern.png differ
diff --git a/examples/message-bus-pattern.yml b/examples/message-bus-pattern.yml
index 8d555e8..d4c4f3d 100644
--- a/examples/message-bus-pattern.yml
+++ b/examples/message-bus-pattern.yml
@@ -2,51 +2,38 @@ title: message bus pattern
backgroundColor: '#ffffff'
components:
-
- kind: service
+ kind: ser
label: Producer
- -
- kind: broker
- label: "Notification\nService"
- -
- kind: queue
- label: "event queue @ topic 1"
- -
- kind: queue
- label: "event queue @ topic 2"
- -
- kind: service
- label: "Consumer\n@ topic 1"
- -
- kind: service
- label: "Consumer\n@ topic 2"
+ fillColor: '#4e8393'
+ -
+ kind: msg
+ label: |
+ Notification
+ Service
+ -
+ kind: ser
+ label: |
+ Subscriber
+ @ topic 1
+ fillColor: '#b8422d'
+ -
+ kind: ser
+ label: |
+ Subscriber
+ @ topic 2
+ fillColor: '#53934e'
connections:
-
- origin:
- componentId: ms1
+ origin: ser1
targets:
-
- componentId: br1
+ id: msg1
-
- origin:
- componentId: br1
+ origin: msg1
targets:
-
- componentId: qs1
+ id: ser2
dashed: true
-
- componentId: qs2
+ id: ser3
dashed: true
- -
- origin:
- componentId: qs1
- targets:
- -
- componentId: ms2
- dir: back
- -
- origin:
- componentId: qs2
- targets:
- -
- componentId: ms3
- dir: back
diff --git a/examples/message-bus-pattern_aws.png b/examples/message-bus-pattern_aws.png
new file mode 100644
index 0000000..b30422b
Binary files /dev/null and b/examples/message-bus-pattern_aws.png differ
diff --git a/examples/message-bus-pattern_azure.png b/examples/message-bus-pattern_azure.png
new file mode 100644
index 0000000..dce9a88
Binary files /dev/null and b/examples/message-bus-pattern_azure.png differ
diff --git a/examples/message-bus-pattern_gcp.png b/examples/message-bus-pattern_gcp.png
new file mode 100644
index 0000000..26bc7a1
Binary files /dev/null and b/examples/message-bus-pattern_gcp.png differ
diff --git a/examples/ms.jpg b/examples/ms.jpg
deleted file mode 100644
index d48fe24..0000000
Binary files a/examples/ms.jpg and /dev/null differ
diff --git a/examples/msg.png b/examples/msg.png
new file mode 100644
index 0000000..0166eaf
Binary files /dev/null and b/examples/msg.png differ
diff --git a/examples/msg.yml b/examples/msg.yml
new file mode 100644
index 0000000..36586b6
--- /dev/null
+++ b/examples/msg.yml
@@ -0,0 +1,4 @@
+---
+components:
+ -
+ kind: msg
\ No newline at end of file
diff --git a/examples/msg_aws.png b/examples/msg_aws.png
new file mode 100644
index 0000000..830f204
Binary files /dev/null and b/examples/msg_aws.png differ
diff --git a/examples/msg_azure.png b/examples/msg_azure.png
new file mode 100644
index 0000000..061410b
Binary files /dev/null and b/examples/msg_azure.png differ
diff --git a/examples/msg_gcp.png b/examples/msg_gcp.png
new file mode 100644
index 0000000..e910d64
Binary files /dev/null and b/examples/msg_gcp.png differ
diff --git a/examples/ost.png b/examples/ost.png
new file mode 100644
index 0000000..9ef1c02
Binary files /dev/null and b/examples/ost.png differ
diff --git a/examples/ost.yml b/examples/ost.yml
new file mode 100644
index 0000000..c3ac254
--- /dev/null
+++ b/examples/ost.yml
@@ -0,0 +1,4 @@
+---
+components:
+ -
+ kind: ost
\ No newline at end of file
diff --git a/examples/ost_aws.png b/examples/ost_aws.png
new file mode 100644
index 0000000..b911fa1
Binary files /dev/null and b/examples/ost_aws.png differ
diff --git a/examples/ost_azure.png b/examples/ost_azure.png
new file mode 100644
index 0000000..5a9e2e8
Binary files /dev/null and b/examples/ost_azure.png differ
diff --git a/examples/ost_gcp.png b/examples/ost_gcp.png
new file mode 100644
index 0000000..db8f696
Binary files /dev/null and b/examples/ost_gcp.png differ
diff --git a/examples/qs.jpg b/examples/qs.jpg
deleted file mode 100644
index ffaf71b..0000000
Binary files a/examples/qs.jpg and /dev/null differ
diff --git a/examples/que.png b/examples/que.png
new file mode 100644
index 0000000..a22b4f2
Binary files /dev/null and b/examples/que.png differ
diff --git a/examples/queue.yml b/examples/que.yml
similarity index 74%
rename from examples/queue.yml
rename to examples/que.yml
index 1b3baab..7650640 100644
--- a/examples/queue.yml
+++ b/examples/que.yml
@@ -1,5 +1,5 @@
---
components:
-
- kind: queue
+ kind: que
label: "event queue"
\ No newline at end of file
diff --git a/examples/que_aws.png b/examples/que_aws.png
new file mode 100644
index 0000000..a22b4f2
Binary files /dev/null and b/examples/que_aws.png differ
diff --git a/examples/que_azure.png b/examples/que_azure.png
new file mode 100644
index 0000000..a22b4f2
Binary files /dev/null and b/examples/que_azure.png differ
diff --git a/examples/que_gcp.png b/examples/que_gcp.png
new file mode 100644
index 0000000..a22b4f2
Binary files /dev/null and b/examples/que_gcp.png differ
diff --git a/examples/queue.png b/examples/queue.png
deleted file mode 100644
index 76c456d..0000000
Binary files a/examples/queue.png and /dev/null differ
diff --git a/examples/rdb.png b/examples/rdb.png
new file mode 100644
index 0000000..e5897e2
Binary files /dev/null and b/examples/rdb.png differ
diff --git a/examples/rdb.yml b/examples/rdb.yml
new file mode 100644
index 0000000..f8d173d
--- /dev/null
+++ b/examples/rdb.yml
@@ -0,0 +1,5 @@
+---
+components:
+ -
+ kind: rdb
+ label: Orders
diff --git a/examples/rdb_aws.png b/examples/rdb_aws.png
new file mode 100644
index 0000000..caaf95a
Binary files /dev/null and b/examples/rdb_aws.png differ
diff --git a/examples/rdb_azure.png b/examples/rdb_azure.png
new file mode 100644
index 0000000..af6ec73
Binary files /dev/null and b/examples/rdb_azure.png differ
diff --git a/examples/rdb_gcp.png b/examples/rdb_gcp.png
new file mode 100644
index 0000000..1f7c48b
Binary files /dev/null and b/examples/rdb_gcp.png differ
diff --git a/examples/s3-upload-presigned-url.png b/examples/s3-upload-presigned-url.png
index 67bde34..452d791 100644
Binary files a/examples/s3-upload-presigned-url.png and b/examples/s3-upload-presigned-url.png differ
diff --git a/examples/s3-upload-presigned-url.yml b/examples/s3-upload-presigned-url.yml
index ff09ec6..7979700 100644
--- a/examples/s3-upload-presigned-url.yml
+++ b/examples/s3-upload-presigned-url.yml
@@ -2,40 +2,36 @@ title: Upload file to S3 using Lambda for pre-signed URL
backgroundColor: '#ffffff'
components:
-
- kind: client
+ kind: cli
label: "Web App"
- provider: Internet
impl: SPA
-
- kind: gateway
+ kind: gtw
provider: AWS
impl: "API Gateway"
-
- kind: function
+ kind: fun
label: "Get\nPre-Signed URL"
provider: AWS
impl: Lambda
-
- kind: storage
+ kind: ost
label: "*.jpg\n*.png"
provider: AWS
impl: S3
connections:
-
- origin:
- componentId: cl1
+ origin: cli1
targets:
-
- componentId: gt1
+ id: gtw1
-
- origin:
- componentId: gt1
+ origin: gtw1
targets:
-
- componentId: fn1
+ id: fun1
-
- origin:
- componentId: fn1
+ origin: fun1
targets:
-
- componentId: st1
\ No newline at end of file
+ id: ost1
\ No newline at end of file
diff --git a/examples/s3-upload-presigned-url_aws.png b/examples/s3-upload-presigned-url_aws.png
new file mode 100644
index 0000000..452d791
Binary files /dev/null and b/examples/s3-upload-presigned-url_aws.png differ
diff --git a/examples/s3-upload-presigned-url_azure.png b/examples/s3-upload-presigned-url_azure.png
new file mode 100644
index 0000000..452d791
Binary files /dev/null and b/examples/s3-upload-presigned-url_azure.png differ
diff --git a/examples/s3-upload-presigned-url_gcp.png b/examples/s3-upload-presigned-url_gcp.png
new file mode 100644
index 0000000..452d791
Binary files /dev/null and b/examples/s3-upload-presigned-url_gcp.png differ
diff --git a/examples/ser.png b/examples/ser.png
new file mode 100644
index 0000000..f8973fe
Binary files /dev/null and b/examples/ser.png differ
diff --git a/examples/service.yml b/examples/ser.yml
similarity index 71%
rename from examples/service.yml
rename to examples/ser.yml
index 705a759..57d965c 100644
--- a/examples/service.yml
+++ b/examples/ser.yml
@@ -1,5 +1,5 @@
---
components:
-
- kind: service
+ kind: ser
label: "ΞΌService"
diff --git a/examples/ser_aws.png b/examples/ser_aws.png
new file mode 100644
index 0000000..f8973fe
Binary files /dev/null and b/examples/ser_aws.png differ
diff --git a/examples/ser_azure.png b/examples/ser_azure.png
new file mode 100644
index 0000000..f8973fe
Binary files /dev/null and b/examples/ser_azure.png differ
diff --git a/examples/ser_gcp.png b/examples/ser_gcp.png
new file mode 100644
index 0000000..f8973fe
Binary files /dev/null and b/examples/ser_gcp.png differ
diff --git a/examples/service.png b/examples/service.png
deleted file mode 100644
index 17e6df2..0000000
Binary files a/examples/service.png and /dev/null differ
diff --git a/examples/st.jpg b/examples/st.jpg
deleted file mode 100644
index 3e103a1..0000000
Binary files a/examples/st.jpg and /dev/null differ
diff --git a/examples/storage.png b/examples/storage.png
deleted file mode 100644
index 547ae8f..0000000
Binary files a/examples/storage.png and /dev/null differ
diff --git a/examples/storage.yml b/examples/storage.yml
deleted file mode 100644
index 8a0870e..0000000
--- a/examples/storage.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-components:
- -
- kind: storage
- label: "*.jpg\n*.png"
\ No newline at end of file
diff --git a/examples/system-view.png b/examples/system-view.png
index 39d3034..5bb5453 100644
Binary files a/examples/system-view.png and b/examples/system-view.png differ
diff --git a/examples/system-view.yml b/examples/system-view.yml
index 7684abf..4af7090 100644
--- a/examples/system-view.yml
+++ b/examples/system-view.yml
@@ -2,7 +2,7 @@ title: System View - Token Manager
backgroundColor: '#ffffff'
components:
-
- kind: client
+ kind: cli
impl: SPA / iOS / Android
label: Client App
-
@@ -14,50 +14,48 @@ components:
impl: AWS Cloudfront
provider: AWS
-
- kind: gateway
+ kind: gtw
impl: API Gateway
provider: AWS
-
- kind: balancer
+ kind: lba
impl: AWS NLB
provider: AWS
-
- kind: function
+ kind: fun
label: Verify JWT
impl: AWS Lambda
provider: AWS
-
- kind: function
+ kind: fun
label: Verify OTP
impl: AWS Lambda
provider: AWS
-
- kind: cos
+ kind: kub
impl: AWS ECS
provider: AWS
-
- kind: service
+ kind: ser
label: Token Manager
impl: AWS EC2
provider: AWS
-
- kind: database
+ kind: mem
label: Redis
impl: Amazon ElastiCache
provider: AWS
fillColor: '#d82a0b'
fontColor: '#ffffff'
-
- kind: storage
- label: |
- Object
- Store
+ kind: ost
+ label: Bucket
impl: AWS S3
provider: AWS
fillColor: '#571307'
fontColor: '#ffffff'
-
- kind: database
+ kind: rdb
label: MySQL
impl: Amazon RDS
provider: AWS
@@ -65,59 +63,52 @@ components:
fontColor: '#ffffff'
connections:
-
- origin:
- componentId: cl1
+ origin: cli1
targets:
-
- componentId: waf1
+ id: waf1
-
- origin:
- componentId: waf1
+ origin: waf1
targets:
-
- componentId: cn1
+ id: cdn1
-
- origin:
- componentId: cn1
+ origin: cdn1
targets:
-
- componentId: gt1
+ id: gtw1
-
- origin:
- componentId: gt1
+ origin: gtw1
targets:
-
- componentId: lb1
+ id: lba1
-
- componentId: fn1
+ id: fun1
-
- componentId: fn2
+ id: fun2
-
- origin:
- componentId: lb1
+ origin: lba1
targets:
-
- componentId: cos1
+ id: kub1
-
- origin:
- componentId: cos1
+ origin: kub1
targets:
-
- componentId: ms1
+ id: ser1
-
- origin:
- componentId: ms1
+ origin: ser1
targets:
-
- componentId: db1
+ id: mem1
-
- componentId: st1
+ id: ost1
-
- componentId: db2
+ id: rdb1
ranks:
-
name: rank1
components:
- - gt1
- - lb1
- - cos1
\ No newline at end of file
+ - gtw1
+ - lba1
+ - kub1
\ No newline at end of file
diff --git a/examples/system-view_aws.png b/examples/system-view_aws.png
new file mode 100644
index 0000000..5bb5453
Binary files /dev/null and b/examples/system-view_aws.png differ
diff --git a/examples/system-view_azure.png b/examples/system-view_azure.png
new file mode 100644
index 0000000..5bb5453
Binary files /dev/null and b/examples/system-view_azure.png differ
diff --git a/examples/system-view_gcp.png b/examples/system-view_gcp.png
new file mode 100644
index 0000000..5bb5453
Binary files /dev/null and b/examples/system-view_gcp.png differ
diff --git a/examples/waf.png b/examples/waf.png
index abd2a0c..f0d7c6d 100644
Binary files a/examples/waf.png and b/examples/waf.png differ
diff --git a/examples/waf_aws.png b/examples/waf_aws.png
new file mode 100644
index 0000000..b258b19
Binary files /dev/null and b/examples/waf_aws.png differ
diff --git a/examples/waf_azure.png b/examples/waf_azure.png
new file mode 100644
index 0000000..4e6a1a9
Binary files /dev/null and b/examples/waf_azure.png differ
diff --git a/examples/waf_gcp.png b/examples/waf_gcp.png
new file mode 100644
index 0000000..ac1f056
Binary files /dev/null and b/examples/waf_gcp.png differ
diff --git a/storage.go b/fst.go
similarity index 50%
rename from storage.go
rename to fst.go
index db73739..82dae45 100644
--- a/storage.go
+++ b/fst.go
@@ -9,30 +9,40 @@ import (
"github.com/lucasepe/draft/pkg/node"
)
-type storage struct {
+type fst struct {
seq int16
}
-func (rcv *storage) nextID() string {
+func (rcv *fst) nextID() string {
rcv.seq++
- return fmt.Sprintf("st%d", rcv.seq)
+ return fmt.Sprintf("fst%d", rcv.seq)
}
-func (rcv *storage) sketch(graph *dot.Graph, comp Component) {
+func (rcv *fst) sketch(graph *dot.Graph, comp Component) {
id := comp.ID
if strings.TrimSpace(comp.ID) == "" {
id = rcv.nextID()
}
+ fontColor := "#000000ff"
+ if fc := strings.TrimSpace(comp.FontColor); fc != "" {
+ fontColor = fc
+ }
+
+ fillColor := "#dadd29ff"
+ if fc := strings.TrimSpace(comp.FillColor); len(fc) > 0 {
+ fillColor = fc
+ }
+
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
node.Label(comp.Label, false),
node.Rounded(comp.Rounded),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#f0e77fff"),
- node.FontSize(8),
+ node.FontColor(fontColor),
+ node.FillColor(fillColor),
node.Shape("folder"),
)
- el.Attr("height", "0.4")
+ el.Attr("width", "0.7")
}
diff --git a/storage_test.go b/fst_test.go
similarity index 73%
rename from storage_test.go
rename to fst_test.go
index 6370b6f..cc33a1c 100644
--- a/storage_test.go
+++ b/fst_test.go
@@ -6,17 +6,17 @@ import (
"github.com/emicklei/dot"
)
-func TestStorageComponentNextID(t *testing.T) {
+func TestFileStoreNextID(t *testing.T) {
tests := []struct {
want string
}{
- {"st1"},
- {"st2"},
- {"st3"},
- {"st4"},
+ {"fst1"},
+ {"fst2"},
+ {"fst3"},
+ {"fst4"},
}
- s := storage{}
+ s := fst{}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
@@ -27,10 +27,10 @@ func TestStorageComponentNextID(t *testing.T) {
}
}
-func TestStorageComponent(t *testing.T) {
+func TestFileStoreShape(t *testing.T) {
g := dot.NewGraph(dot.Directed)
- sketcher := storage{}
+ sketcher := fst{}
sketcher.sketch(g, Component{})
if got, want := flatten(g.String()), `shape="folder",style="filled"`; !verify(got, want) {
diff --git a/function.go b/fun.go
similarity index 63%
rename from function.go
rename to fun.go
index bcd8bb5..2990bdd 100644
--- a/function.go
+++ b/fun.go
@@ -9,16 +9,16 @@ import (
"github.com/lucasepe/draft/pkg/node"
)
-type function struct {
+type fun struct {
seq int16
}
-func (rcv *function) nextID() string {
+func (rcv *fun) nextID() string {
rcv.seq++
- return fmt.Sprintf("fn%d", rcv.seq)
+ return fmt.Sprintf("fun%d", rcv.seq)
}
-func (rcv *function) sketch(graph *dot.Graph, comp Component) {
+func (rcv *fun) sketch(graph *dot.Graph, comp Component) {
id := comp.ID
if strings.TrimSpace(comp.ID) == "" {
id = rcv.nextID()
@@ -29,13 +29,19 @@ func (rcv *function) sketch(graph *dot.Graph, comp Component) {
label = comp.Label
}
+ fillColor := "#abd9e9ff"
+ if fc := strings.TrimSpace(comp.FillColor); len(fc) > 0 {
+ fillColor = fc
+ }
+
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
node.Label(label, false),
node.Rounded(comp.Rounded),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#abd9e9ff"),
+ node.FontColor("#000000ff"),
+ node.FillColor(fillColor),
node.Shape("signature"),
)
el.Attr("fontsize", "6")
diff --git a/function_test.go b/fun_test.go
similarity index 73%
rename from function_test.go
rename to fun_test.go
index 34f6ab1..a51d3cc 100644
--- a/function_test.go
+++ b/fun_test.go
@@ -6,17 +6,17 @@ import (
"github.com/emicklei/dot"
)
-func TestFunctionComponentNextID(t *testing.T) {
+func TestFunctionNextID(t *testing.T) {
tests := []struct {
want string
}{
- {"fn1"},
- {"fn2"},
- {"fn3"},
- {"fn4"},
+ {"fun1"},
+ {"fun2"},
+ {"fun3"},
+ {"fun4"},
}
- s := function{}
+ s := fun{}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
@@ -27,11 +27,11 @@ func TestFunctionComponentNextID(t *testing.T) {
}
}
-func TestFunctionComponent(t *testing.T) {
+func TestFunctionShape(t *testing.T) {
want := `shape="signature",style="filled"`
g := dot.NewGraph(dot.Directed)
- sketcher := function{}
+ sketcher := fun{}
sketcher.sketch(g, Component{})
if got := flatten(g.String()); !verify(got, want) {
diff --git a/gateway_test.go b/gateway_test.go
deleted file mode 100644
index ab42cdc..0000000
--- a/gateway_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package draft
-
-import (
- "testing"
-
- "github.com/emicklei/dot"
-)
-
-func TestGatewayComponentNextID(t *testing.T) {
- tests := []struct {
- want string
- }{
- {"gt1"},
- {"gt2"},
- {"gt3"},
- {"gt4"},
- }
-
- s := gateway{}
-
- for _, tt := range tests {
- t.Run(tt.want, func(t *testing.T) {
- if got := s.nextID(); got != tt.want {
- t.Errorf("got [%v] want [%v]", got, tt.want)
- }
- })
- }
-}
-
-func TestGatewayComponent(t *testing.T) {
- want := `label="GW",shape="doublecircle",style="filled"`
- g := dot.NewGraph(dot.Directed)
-
- sketcher := gateway{}
- sketcher.sketch(g, Component{})
-
- if got := flatten(g.String()); !verify(got, want) {
- t.Errorf("got [%v] want [%v]", got, want)
- }
-}
diff --git a/gateway.go b/gtw.go
similarity index 57%
rename from gateway.go
rename to gtw.go
index d215919..7ed8881 100644
--- a/gateway.go
+++ b/gtw.go
@@ -9,29 +9,31 @@ import (
"github.com/lucasepe/draft/pkg/node"
)
-type gateway struct {
+type gtw struct {
seq int16
}
-func (rcv *gateway) nextID() string {
+func (rcv *gtw) nextID() string {
rcv.seq++
- return fmt.Sprintf("gt%d", rcv.seq)
+ return fmt.Sprintf("gtw%d", rcv.seq)
}
-func (rcv *gateway) sketch(graph *dot.Graph, comp Component) {
+func (rcv *gtw) sketch(graph *dot.Graph, comp Component) {
id := comp.ID
if strings.TrimSpace(comp.ID) == "" {
id = rcv.nextID()
}
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
- node.Label("GW", false),
+ node.Label("GTW", true),
node.Rounded(comp.Rounded),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#ff7f00ff"),
+ node.FontColor("#f5f5f5ff"),
+ node.FillColor("#ff7f00ff"),
node.Shape("doublecircle"),
)
- el.Attr("width", "0.2")
+ el.Attr("width", "0.1")
+ el.Attr("color", "#ff7f00ff")
}
diff --git a/gtw_test.go b/gtw_test.go
new file mode 100644
index 0000000..f0c1776
--- /dev/null
+++ b/gtw_test.go
@@ -0,0 +1,40 @@
+package draft
+
+import (
+ "testing"
+
+ "github.com/emicklei/dot"
+)
+
+func TestGatewayNextID(t *testing.T) {
+ tests := []struct {
+ want string
+ }{
+ {"gtw1"},
+ {"gtw2"},
+ {"gtw3"},
+ {"gtw4"},
+ }
+
+ s := gtw{}
+
+ for _, tt := range tests {
+ t.Run(tt.want, func(t *testing.T) {
+ if got := s.nextID(); got != tt.want {
+ t.Errorf("got [%v] want [%v]", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestGatewayShape(t *testing.T) {
+ want := `label=<GTW>,shape="doublecircle",style="filled"`
+ g := dot.NewGraph(dot.Directed)
+
+ sketcher := gtw{}
+ sketcher.sketch(g, Component{})
+
+ if got := flatten(g.String()); !verify(got, want) {
+ t.Errorf("got [%v] want [%v]", got, want)
+ }
+}
diff --git a/html.go b/html.go
index 99b78db..f6a9d9b 100644
--- a/html.go
+++ b/html.go
@@ -24,12 +24,17 @@ func (rcv *html) sketch(graph *dot.Graph, comp Component) {
id = rcv.nextID()
}
+ fontColor := "#000000ff"
+ if fc := strings.TrimSpace(comp.FontColor); fc != "" {
+ fontColor = fc
+ }
+
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
node.New(cl, id,
node.Label(comp.Label, true),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor("", "transparent"),
+ node.FontColor(fontColor),
+ node.FillColor("transparent"),
node.FontSize(7),
node.Shape("plain"),
)
diff --git a/icon.go b/icon.go
new file mode 100644
index 0000000..72ff113
--- /dev/null
+++ b/icon.go
@@ -0,0 +1,49 @@
+package draft
+
+import (
+ "fmt"
+ "os"
+ "path"
+ "strings"
+
+ "github.com/emicklei/dot"
+ "github.com/lucasepe/draft/pkg/cluster"
+ "github.com/lucasepe/draft/pkg/node"
+)
+
+type icon struct {
+ seq int16
+}
+
+func (rcv *icon) nextID() string {
+ rcv.seq++
+ return fmt.Sprintf("ico%d", rcv.seq)
+}
+
+func (rcv *icon) sketch(graph *dot.Graph, comp Component) {
+ if strings.TrimSpace(comp.Label) == "" {
+ return
+ }
+
+ id := comp.ID
+ if strings.TrimSpace(comp.ID) == "" {
+ id = rcv.nextID()
+ }
+
+ iconsPath := os.Getenv("DRAFT_ICONS_PATH")
+ img := path.Join(iconsPath, comp.Label)
+
+ label := fmt.Sprintf(`
+
+ |
+
+
`, img)
+
+ cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+
+ node.New(cl, id,
+ node.Label(label, true),
+ node.FillColor("transparent"),
+ node.Shape("plain"),
+ )
+}
diff --git a/impl.go b/impl.go
new file mode 100644
index 0000000..5e48830
--- /dev/null
+++ b/impl.go
@@ -0,0 +1,100 @@
+package draft
+
+import (
+ "strings"
+
+ "github.com/emicklei/dot"
+)
+
+func getCloudImpl(provider, kind string) string {
+ switch strings.TrimSpace(strings.ToLower(provider)) {
+ case "aws":
+ return awsImpl()(kind)
+ case "gcp":
+ return gcpImpl()(kind)
+ case "azure":
+ return azureImpl()(kind)
+ default:
+ return ""
+ }
+}
+
+func awsImpl() func(string) string {
+ dict := map[string]string{
+ "bst": "Elastic Block\nStore (EBS)",
+ "cdn": "Cloudfront",
+ "dns": "Route 53",
+ "doc": "DynamoDB",
+ "fst": "Elastic\nFile System (EFS)",
+ "fun": "Lambda",
+ "gtw": "API Gateway",
+ "lba": "Elastic\nLoad Balancer",
+ "kub": "Elastic Container Service\nfor Kubernetes (EKS)",
+ "mem": "ElastiCache",
+ "msg": "SNS",
+ "ost": "Simple Storage\nService (S3)",
+ "rdb": "Relational Database\nService (RDS)",
+ "waf": "AWS WAF",
+ }
+
+ return func(key string) string {
+ return dict[key]
+ }
+}
+
+func gcpImpl() func(string) string {
+ dict := map[string]string{
+ "bst": "Persistent Disk",
+ "cdn": "Cloud CDN",
+ "dns": "Cloud DNS",
+ "doc": "Cloud Datastore",
+ "fst": "Cloud Filestore",
+ "fun": "Cloud Functions",
+ "gtw": "Cloud Endpoints",
+ "lba": "Cloud Load Balancing",
+ "kub": "Google Kubernetes\nEngine",
+ "mem": "Cloud Memorystore",
+ "msg": "Cloud Pub/Sub",
+ "ost": "Cloud Storage",
+ "rdb": "Cloud SQL",
+ "waf": "Google Armor",
+ }
+
+ return func(key string) string {
+ return dict[key]
+ }
+}
+
+func azureImpl() func(string) string {
+ dict := map[string]string{
+ "bst": "Disk Storage",
+ "cdn": "Azure CDN",
+ "dns": "Azure DNS",
+ "doc": "Cosmos DB",
+ "fst": "Azure File Storage",
+ "fun": "Azure Functions",
+ "gtw": "Azure API Management",
+ "lba": "Load Balancer",
+ "kub": "Azure Kubernetes\nService (AKS)",
+ "mem": "Redis Caches",
+ "msg": "Notification Hubs",
+ "ost": "Blob Storage",
+ "rdb": "SQL Database",
+ "waf": "Azure Firewall",
+ }
+
+ return func(key string) string {
+ return dict[key]
+ }
+}
+
+func guessImpl(cmp *Component, cluster *dot.Graph) {
+ if s := strings.TrimSpace(cmp.Impl); len(s) > 0 {
+ return
+ }
+
+ impl := getCloudImpl(cmp.provider, cmp.Kind)
+ if len(impl) > 0 {
+ cluster.Attr("label", impl)
+ }
+}
diff --git a/impl_test.go b/impl_test.go
new file mode 100644
index 0000000..d8ec41d
--- /dev/null
+++ b/impl_test.go
@@ -0,0 +1,94 @@
+package draft
+
+import (
+ "testing"
+
+ "github.com/lucasepe/draft/pkg/cluster"
+ "github.com/lucasepe/draft/pkg/graph"
+)
+
+func TestCloudImpl(t *testing.T) {
+ tests := []struct {
+ provider string
+ key string
+ want string
+ }{
+ {"aws", "bst", "Elastic Block\nStore (EBS)"},
+ {"aws", "lba", "Elastic\nLoad Balancer"},
+ {"aws", "ost", "Simple Storage\nService (S3)"},
+
+ {"gcp", "kub", "Google Kubernetes\nEngine"},
+ {"gcp", "mem", "Cloud Memorystore"},
+ {"gcp", "ost", "Cloud Storage"},
+
+ {"azure", "dns", "Azure DNS"},
+ {"azure", "mem", "Redis Caches"},
+ {"azure", "waf", "Azure Firewall"},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.want, func(t *testing.T) {
+ if got := getCloudImpl(tt.provider, tt.key); got != tt.want {
+ t.Errorf("got [%v] want [%v]", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestGuessImpl(t *testing.T) {
+ tests := []struct {
+ comp Component
+ want string
+ }{
+ {
+ Component{provider: "aws", Kind: "bst"},
+ "Elastic Block\nStore (EBS)",
+ },
+ {
+ Component{provider: "aws", Kind: "lba"},
+ "Elastic\nLoad Balancer",
+ },
+ {
+ Component{provider: "aws", Kind: "ost"},
+ "Simple Storage\nService (S3)",
+ },
+
+ {
+ Component{provider: "gcp", Kind: "kub"},
+ "Google Kubernetes\nEngine",
+ },
+ {
+ Component{provider: "gcp", Kind: "mem"},
+ "Cloud Memorystore",
+ },
+ {
+ Component{provider: "gcp", Kind: "ost"},
+ "Cloud Storage",
+ },
+
+ {
+ Component{provider: "azure", Kind: "dns"},
+ "Azure DNS",
+ },
+ {
+ Component{provider: "azure", Kind: "mem"},
+ "Redis Caches",
+ },
+ {
+ Component{provider: "azure", Kind: "waf"},
+ "Azure Firewall",
+ },
+ }
+
+ gr := graph.New()
+ cl := cluster.New(gr, "DUMMY")
+
+ for _, tt := range tests {
+ t.Run(tt.want, func(t *testing.T) {
+ guessImpl(&tt.comp, cl)
+ if got := cl.AttributesMap.Value("label"); got != tt.want {
+ t.Errorf("got [%v] want [%v]", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/kub.go b/kub.go
new file mode 100644
index 0000000..13b99fe
--- /dev/null
+++ b/kub.go
@@ -0,0 +1,36 @@
+package draft
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/emicklei/dot"
+ "github.com/lucasepe/draft/pkg/cluster"
+ "github.com/lucasepe/draft/pkg/node"
+)
+
+type kub struct {
+ seq int16
+}
+
+func (rcv *kub) nextID() string {
+ rcv.seq++
+ return fmt.Sprintf("kub%d", rcv.seq)
+}
+
+func (rcv *kub) sketch(graph *dot.Graph, comp Component) {
+ id := comp.ID
+ if strings.TrimSpace(comp.ID) == "" {
+ id = rcv.nextID()
+ }
+
+ cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
+
+ node.New(cl, id,
+ node.Label("K8s
Engine", true),
+ node.FontColor("#fafafaff"),
+ node.FillColor("#64a365"),
+ node.Shape("square"),
+ )
+}
diff --git a/kub_test.go b/kub_test.go
new file mode 100644
index 0000000..28272fc
--- /dev/null
+++ b/kub_test.go
@@ -0,0 +1,40 @@
+package draft
+
+import (
+ "testing"
+
+ "github.com/emicklei/dot"
+)
+
+func TestContainerManagerNextID(t *testing.T) {
+ tests := []struct {
+ want string
+ }{
+ {"kub1"},
+ {"kub2"},
+ {"kub3"},
+ {"kub4"},
+ }
+
+ s := kub{}
+
+ for _, tt := range tests {
+ t.Run(tt.want, func(t *testing.T) {
+ if got := s.nextID(); got != tt.want {
+ t.Errorf("got [%v] want [%v]", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestContainerManagerShape(t *testing.T) {
+ want := `shape="square",style="filled"`
+ g := dot.NewGraph(dot.Directed)
+
+ sketcher := kub{}
+ sketcher.sketch(g, Component{})
+
+ if got := flatten(g.String()); !verify(got, want) {
+ t.Errorf("got [%v] want [%v]", got, want)
+ }
+}
diff --git a/balancer.go b/lba.go
similarity index 62%
rename from balancer.go
rename to lba.go
index c475be0..eb0a41d 100644
--- a/balancer.go
+++ b/lba.go
@@ -9,30 +9,32 @@ import (
"github.com/lucasepe/draft/pkg/node"
)
-type balancer struct {
+type lba struct {
seq int16
}
-func (rcv *balancer) nextID() string {
+func (rcv *lba) nextID() string {
rcv.seq++
- return fmt.Sprintf("lb%d", rcv.seq)
+ return fmt.Sprintf("lba%d", rcv.seq)
}
-func (rcv *balancer) sketch(graph *dot.Graph, comp Component) {
+func (rcv *lba) sketch(graph *dot.Graph, comp Component) {
id := comp.ID
if strings.TrimSpace(comp.ID) == "" {
id = rcv.nextID()
}
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
- node.Label("LB", false),
+ node.Label("LB", true),
node.Rounded(comp.Rounded),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#1a5276ff"),
+ node.FontColor("#f5f5f5ff"),
+ node.FillColor("#1a5276ff"),
node.Shape("Mdiamond"),
)
el.Attr("width", "0.3")
el.Attr("height", "0.3")
+ el.Attr("color", "#f5f5f5ff")
}
diff --git a/lba_test.go b/lba_test.go
new file mode 100644
index 0000000..7085397
--- /dev/null
+++ b/lba_test.go
@@ -0,0 +1,40 @@
+package draft
+
+import (
+ "testing"
+
+ "github.com/emicklei/dot"
+)
+
+func TestLoadBalancerNextID(t *testing.T) {
+ tests := []struct {
+ want string
+ }{
+ {"lba1"},
+ {"lba2"},
+ {"lba3"},
+ {"lba4"},
+ }
+
+ s := lba{}
+
+ for _, tt := range tests {
+ t.Run(tt.want, func(t *testing.T) {
+ if got := s.nextID(); got != tt.want {
+ t.Errorf("got [%v] want [%v]", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestLoadBalancerShape(t *testing.T) {
+ want := `label=<LB>,shape="Mdiamond",style="filled"`
+ g := dot.NewGraph(dot.Directed)
+
+ sketcher := lba{}
+ sketcher.sketch(g, Component{})
+
+ if got := flatten(g.String()); !verify(got, want) {
+ t.Errorf("got [%v] want [%v]", got, want)
+ }
+}
diff --git a/mem.go b/mem.go
new file mode 100644
index 0000000..c7339a0
--- /dev/null
+++ b/mem.go
@@ -0,0 +1,70 @@
+package draft
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/emicklei/dot"
+ "github.com/lucasepe/draft/pkg/cluster"
+ "github.com/lucasepe/draft/pkg/node"
+)
+
+type mem struct {
+ seq int16
+}
+
+func (rcv *mem) nextID() string {
+ rcv.seq++
+ return fmt.Sprintf("mem%d", rcv.seq)
+}
+
+func (rcv *mem) sketch(graph *dot.Graph, comp Component) {
+ id := comp.ID
+ if strings.TrimSpace(comp.ID) == "" {
+ id = rcv.nextID()
+ }
+
+ caption := strings.TrimSpace(comp.Label)
+ if len(caption) == 0 {
+ caption = " "
+ }
+
+ fillColor := comp.FillColor
+ if strings.TrimSpace(comp.FillColor) == "" {
+ fillColor = "#f04d30ff"
+ }
+
+ label := strings.Replace(`
+ |
+
+ key |
+ val |
+
+
+ |
+ |
+
+
+ |
+ |
+
+
+ %s |
+
+
`, "{{BGCOLOR}}", fillColor, -1)
+
+ label = fmt.Sprintf(label, caption)
+
+ cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
+
+ el := node.New(cl, id,
+ node.Label(label, true),
+ node.FontColor("#000000ff"),
+ node.FillColor("transparent"),
+ // ^^^ hack to set a transparent background
+ // color since we will use the HTML table.
+ node.Shape("plain"),
+ )
+ el.Attr("color", "#f5f5f5ff")
+}
diff --git a/mem_test.go b/mem_test.go
new file mode 100644
index 0000000..de76774
--- /dev/null
+++ b/mem_test.go
@@ -0,0 +1,40 @@
+package draft
+
+import (
+ "testing"
+
+ "github.com/emicklei/dot"
+)
+
+func TestCacheNextID(t *testing.T) {
+ tests := []struct {
+ want string
+ }{
+ {"mem1"},
+ {"mem2"},
+ {"mem3"},
+ {"mem4"},
+ }
+
+ s := mem{}
+
+ for _, tt := range tests {
+ t.Run(tt.want, func(t *testing.T) {
+ if got := s.nextID(); got != tt.want {
+ t.Errorf("got [%v] want [%v]", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestCacheShape(t *testing.T) {
+ want := `label=<>`
+ g := dot.NewGraph(dot.Directed)
+
+ sketcher := mem{}
+ sketcher.sketch(g, Component{})
+
+ if got := flatten(g.String()); !verify(got, want) {
+ t.Errorf("got [%v] want [%v]", got, want)
+ }
+}
diff --git a/container_service.go b/msg.go
similarity index 50%
rename from container_service.go
rename to msg.go
index 862b041..9f7ffac 100644
--- a/container_service.go
+++ b/msg.go
@@ -9,28 +9,30 @@ import (
"github.com/lucasepe/draft/pkg/node"
)
-type containerService struct {
+type msg struct {
seq int16
}
-func (rcv *containerService) nextID() string {
+func (rcv *msg) nextID() string {
rcv.seq++
- return fmt.Sprintf("cos%d", rcv.seq)
+ return fmt.Sprintf("msg%d", rcv.seq)
}
-func (rcv *containerService) sketch(graph *dot.Graph, comp Component) {
+func (rcv *msg) sketch(graph *dot.Graph, comp Component) {
id := comp.ID
if strings.TrimSpace(comp.ID) == "" {
id = rcv.nextID()
}
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
- node.Label("Container\nService", false),
- node.FontColor(comp.FontColor, "#fafafaff"),
- node.FillColor(comp.FillColor, "#64a365"),
- node.Shape("component"),
+ node.Label("Pub / Sub", true),
+ node.FontColor("#000000ff"),
+ node.FillColor("#e0eeeeff"),
+ node.Shape("cds"),
)
- el.Attr("height", "0.3")
+ el.Attr("height", "0.6")
+ el.Attr("width", "1.3")
}
diff --git a/msg_test.go b/msg_test.go
new file mode 100644
index 0000000..086dc2b
--- /dev/null
+++ b/msg_test.go
@@ -0,0 +1,40 @@
+package draft
+
+import (
+ "testing"
+
+ "github.com/emicklei/dot"
+)
+
+func TestPubSubNextID(t *testing.T) {
+ tests := []struct {
+ want string
+ }{
+ {"msg1"},
+ {"msg2"},
+ {"msg3"},
+ {"msg4"},
+ }
+
+ s := msg{}
+
+ for _, tt := range tests {
+ t.Run(tt.want, func(t *testing.T) {
+ if got := s.nextID(); got != tt.want {
+ t.Errorf("got [%v] want [%v]", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestPubSubShape(t *testing.T) {
+ want := `label=<Pub / Sub>,shape="cds",style="filled"`
+ g := dot.NewGraph(dot.Directed)
+
+ sketcher := msg{}
+ sketcher.sketch(g, Component{})
+
+ if got := flatten(g.String()); !verify(got, want) {
+ t.Errorf("got [%v] want [%v]", got, want)
+ }
+}
diff --git a/ost.go b/ost.go
new file mode 100644
index 0000000..a021856
--- /dev/null
+++ b/ost.go
@@ -0,0 +1,48 @@
+package draft
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/emicklei/dot"
+ "github.com/lucasepe/draft/pkg/cluster"
+ "github.com/lucasepe/draft/pkg/node"
+)
+
+type ost struct {
+ seq int16
+}
+
+func (rcv *ost) nextID() string {
+ rcv.seq++
+ return fmt.Sprintf("ost%d", rcv.seq)
+}
+
+func (rcv *ost) sketch(graph *dot.Graph, comp Component) {
+ id := comp.ID
+ if strings.TrimSpace(comp.ID) == "" {
+ id = rcv.nextID()
+ }
+
+ fontColor := "#000000ff"
+ if fc := strings.TrimSpace(comp.FontColor); fc != "" {
+ fontColor = fc
+ }
+
+ fillColor := "#f5f5dcff"
+ if fc := strings.TrimSpace(comp.FillColor); len(fc) > 0 {
+ fillColor = fc
+ }
+
+ cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
+
+ el := node.New(cl, id,
+ node.Label(comp.Label, false),
+ node.Rounded(comp.Rounded),
+ node.FontColor(fontColor),
+ node.FillColor(fillColor),
+ node.Shape("invtrapezium"),
+ )
+ el.Attr("width", "0.6")
+}
diff --git a/ost_test.go b/ost_test.go
new file mode 100644
index 0000000..b7c796e
--- /dev/null
+++ b/ost_test.go
@@ -0,0 +1,39 @@
+package draft
+
+import (
+ "testing"
+
+ "github.com/emicklei/dot"
+)
+
+func TestObjectStoreNextID(t *testing.T) {
+ tests := []struct {
+ want string
+ }{
+ {"ost1"},
+ {"ost2"},
+ {"ost3"},
+ {"ost4"},
+ }
+
+ s := ost{}
+
+ for _, tt := range tests {
+ t.Run(tt.want, func(t *testing.T) {
+ if got := s.nextID(); got != tt.want {
+ t.Errorf("got [%v] want [%v]", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestObjectStoreShape(t *testing.T) {
+ g := dot.NewGraph(dot.Directed)
+
+ sketcher := ost{}
+ sketcher.sketch(g, Component{})
+
+ if got, want := flatten(g.String()), `shape="invtrapezium",style="filled"`; !verify(got, want) {
+ t.Errorf("got [%v] want [%v]", got, want)
+ }
+}
diff --git a/pkg/node/node.go b/pkg/node/node.go
index 0481309..0d1d760 100644
--- a/pkg/node/node.go
+++ b/pkg/node/node.go
@@ -41,23 +41,19 @@ func Rounded(rounded bool) Attribute {
}
// FillColor sets the node fill color.
-func FillColor(color, fallback string) Attribute {
+func FillColor(color string) Attribute {
return func(el *dot.Node) {
if strings.TrimSpace(color) != "" {
el.Attr("fillcolor", color)
- } else {
- el.Attr("fillcolor", fallback)
}
}
}
// FontColor specify the text color.
-func FontColor(color, fallback string) Attribute {
+func FontColor(color string) Attribute {
return func(el *dot.Node) {
if strings.TrimSpace(color) != "" {
el.Attr("fontcolor", color)
- } else {
- el.Attr("fontcolor", fallback)
}
}
}
diff --git a/pkg/node/node_test.go b/pkg/node/node_test.go
index faad68e..1b9a19f 100644
--- a/pkg/node/node_test.go
+++ b/pkg/node/node_test.go
@@ -17,19 +17,9 @@ func TestDefaultAttributes(t *testing.T) {
}
}
-func TestFontColorFallback(t *testing.T) {
- di := dot.NewGraph(dot.Directed)
- New(di, "NODE_1", FontColor("", "#000000ff"))
-
- want := `digraph {n1[fontcolor="#000000ff",fontname="Fira Mono",fontsize="9.00",label="NODE_1",style="filled"];}`
- if got := flatten(di.String()); got != want {
- t.Errorf("got [%v] want [%v]", got, want)
- }
-}
-
func TestFontColor(t *testing.T) {
di := dot.NewGraph(dot.Directed)
- New(di, "NODE_1", FontColor("#fafafaff", "#000000"))
+ New(di, "NODE_1", FontColor("#fafafaff"))
want := `digraph {n1[fontcolor="#fafafaff",fontname="Fira Mono",fontsize="9.00",label="NODE_1",style="filled"];}`
if got := flatten(di.String()); got != want {
@@ -37,9 +27,9 @@ func TestFontColor(t *testing.T) {
}
}
-func TestFillColorFallback(t *testing.T) {
+func TestFillColor(t *testing.T) {
di := dot.NewGraph(dot.Directed)
- New(di, "NODE_1", FillColor("", "#ff0000ff"))
+ New(di, "NODE_1", FillColor("#ff0000ff"))
want := `digraph {n1[fillcolor="#ff0000ff",fontname="Fira Mono",fontsize="9.00",label="NODE_1",style="filled"];}`
if got := flatten(di.String()); got != want {
diff --git a/queue.go b/que.go
similarity index 53%
rename from queue.go
rename to que.go
index 5f7020b..6a51a07 100644
--- a/queue.go
+++ b/que.go
@@ -9,50 +9,51 @@ import (
"github.com/lucasepe/draft/pkg/node"
)
-type queue struct {
+type que struct {
seq int16
}
-func (rcv *queue) nextID() string {
+func (rcv *que) nextID() string {
rcv.seq++
- return fmt.Sprintf("qs%d", rcv.seq)
+ return fmt.Sprintf("que%d", rcv.seq)
}
-func (rcv *queue) sketch(graph *dot.Graph, comp Component) {
+func (rcv *que) sketch(graph *dot.Graph, comp Component) {
id := comp.ID
if strings.TrimSpace(comp.ID) == "" {
id = rcv.nextID()
}
- cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
-
- el := node.New(cl, id,
- node.Rounded(comp.Rounded),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FontSize(7),
- node.FillColor("", "transparent"),
- // ^^^ hack to set a transparent background
- // color since we will use the HTML table.
- node.Shape("plain"),
- )
+ fillColor := comp.FillColor
+ if strings.TrimSpace(comp.FillColor) == "" {
+ fillColor = "#bdb76bff"
+ }
caption := strings.TrimSpace(comp.Label)
if len(caption) == 0 {
caption = " "
}
- fillColor := comp.FillColor
- if strings.TrimSpace(comp.FillColor) == "" {
- fillColor = "#bdb76bff"
- }
-
- label := fmt.Sprintf(`
+ label := strings.Replace(`
|
- msg N |
- ... |
- msg 1 |
+ msg N |
+ ... |
+ msg 1 |
%s |
-
`, fillColor, fillColor, fillColor, caption)
+
`, "{{BGCOLOR}}", fillColor, -1)
+
+ label = fmt.Sprintf(label, caption)
- el.Attr("label", dot.HTML(label))
+ cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
+
+ node.New(cl, id,
+ node.Label(label, true),
+ node.FontColor("#000000ff"),
+ node.FontSize(8),
+ node.FillColor("transparent"),
+ // ^^^ hack to set a transparent background
+ // color since we will use the HTML table.
+ node.Shape("plain"),
+ )
}
diff --git a/queue_test.go b/que_test.go
similarity index 63%
rename from queue_test.go
rename to que_test.go
index 28e3c38..52d9618 100644
--- a/queue_test.go
+++ b/que_test.go
@@ -10,13 +10,13 @@ func TestQueueComponentNextID(t *testing.T) {
tests := []struct {
want string
}{
- {"qs1"},
- {"qs2"},
- {"qs3"},
- {"qs4"},
+ {"que1"},
+ {"que2"},
+ {"que3"},
+ {"que4"},
}
- s := queue{}
+ s := que{}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
@@ -28,10 +28,10 @@ func TestQueueComponentNextID(t *testing.T) {
}
func TestQueueComponent(t *testing.T) {
- want := `label=<>,shape="plain"`
+ want := `label=<>`
g := dot.NewGraph(dot.Directed)
- sketcher := queue{}
+ sketcher := que{}
sketcher.sketch(g, Component{})
if got := flatten(g.String()); !verify(got, want) {
diff --git a/service.go b/rdb.go
similarity index 58%
rename from service.go
rename to rdb.go
index 146b0d9..45ed131 100644
--- a/service.go
+++ b/rdb.go
@@ -9,29 +9,30 @@ import (
"github.com/lucasepe/draft/pkg/node"
)
-type service struct {
+type rdb struct {
seq int16
}
-func (rcv *service) nextID() string {
+func (rcv *rdb) nextID() string {
rcv.seq++
- return fmt.Sprintf("ms%d", rcv.seq)
+ return fmt.Sprintf("rdb%d", rcv.seq)
}
-func (rcv *service) sketch(graph *dot.Graph, comp Component) {
+func (rcv *rdb) sketch(graph *dot.Graph, comp Component) {
id := comp.ID
if strings.TrimSpace(comp.ID) == "" {
id = rcv.nextID()
}
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
node.Label(comp.Label, false),
node.Rounded(comp.Rounded),
- node.FontColor(comp.FontColor, "#000000ff"),
- node.FillColor(comp.FillColor, "#f5f5dcff"),
- node.Shape("doubleoctagon"),
+ node.FontColor("#000000ff"),
+ node.FillColor("#f5f5dcff"),
+ node.Shape("tab"),
)
- el.Attr("width", "0.8")
+ el.Attr("height", "0.5")
}
diff --git a/database_test.go b/rdb_test.go
similarity index 80%
rename from database_test.go
rename to rdb_test.go
index 80f2d6e..80614ab 100644
--- a/database_test.go
+++ b/rdb_test.go
@@ -10,13 +10,13 @@ func TestDatabaseComponentNextID(t *testing.T) {
tests := []struct {
want string
}{
- {"db1"},
- {"db2"},
- {"db3"},
- {"db4"},
+ {"rdb1"},
+ {"rdb2"},
+ {"rdb3"},
+ {"rdb4"},
}
- s := database{}
+ s := rdb{}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
@@ -28,10 +28,10 @@ func TestDatabaseComponentNextID(t *testing.T) {
}
func TestDatabaseComponent(t *testing.T) {
- want := `shape="cylinder",style="filled"`
+ want := `shape="tab",style="filled"`
g := dot.NewGraph(dot.Directed)
- sketcher := database{}
+ sketcher := rdb{}
sketcher.sketch(g, Component{})
if got := flatten(g.String()); !verify(got, want) {
diff --git a/ser.go b/ser.go
new file mode 100644
index 0000000..6a6cbbe
--- /dev/null
+++ b/ser.go
@@ -0,0 +1,48 @@
+package draft
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/emicklei/dot"
+ "github.com/lucasepe/draft/pkg/cluster"
+ "github.com/lucasepe/draft/pkg/node"
+)
+
+type ser struct {
+ seq int16
+}
+
+func (rcv *ser) nextID() string {
+ rcv.seq++
+ return fmt.Sprintf("ser%d", rcv.seq)
+}
+
+func (rcv *ser) sketch(graph *dot.Graph, comp Component) {
+ id := comp.ID
+ if strings.TrimSpace(comp.ID) == "" {
+ id = rcv.nextID()
+ }
+
+ fontColor := "#000000ff"
+ if fc := strings.TrimSpace(comp.FontColor); fc != "" {
+ fontColor = fc
+ }
+
+ fillColor := "#f5f5dcff"
+ if fc := strings.TrimSpace(comp.FillColor); len(fc) > 0 {
+ fillColor = fc
+ }
+
+ cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+
+ el := node.New(cl, id,
+ node.Label(comp.Label, false),
+ node.Rounded(comp.Rounded),
+ node.FontColor(fontColor),
+ node.FillColor(fillColor),
+ node.Shape("doubleoctagon"),
+ )
+ el.Attr("width", "0.7")
+ el.Attr("color", fillColor)
+}
diff --git a/service_test.go b/ser_test.go
similarity index 87%
rename from service_test.go
rename to ser_test.go
index 4e27105..a642ca3 100644
--- a/service_test.go
+++ b/ser_test.go
@@ -10,13 +10,13 @@ func TestServiceComponentNextID(t *testing.T) {
tests := []struct {
want string
}{
- {"ms1"},
- {"ms2"},
- {"ms3"},
- {"ms4"},
+ {"ser1"},
+ {"ser2"},
+ {"ser3"},
+ {"ser4"},
}
- s := service{}
+ s := ser{}
for _, tt := range tests {
t.Run(tt.want, func(t *testing.T) {
@@ -30,7 +30,7 @@ func TestServiceComponentNextID(t *testing.T) {
func TestServiceComponent(t *testing.T) {
g := dot.NewGraph(dot.Directed)
- sketcher := service{}
+ sketcher := ser{}
sketcher.sketch(g, Component{})
if got, want := flatten(g.String()), `shape="doubleoctagon",style="filled"`; !verify(got, want) {
diff --git a/waf.go b/waf.go
index 1bd93d7..f4a3020 100644
--- a/waf.go
+++ b/waf.go
@@ -25,11 +25,12 @@ func (rcv *waf) sketch(graph *dot.Graph, comp Component) {
}
cl := cluster.New(graph, id, cluster.BottomTop(comp.BottomTop()), cluster.Label(comp.Impl))
+ guessImpl(&comp, cl)
el := node.New(cl, id,
- node.Label("FW", false),
- node.FontColor(comp.FontColor, "#fafafaff"),
- node.FillColor(comp.FillColor, "#f3190b"),
+ node.Label("WAF", true),
+ node.FontColor("#fafafaff"),
+ node.FillColor("#f3190b"),
node.Shape("invhouse"),
)
el.Attr("width", "0.3")
diff --git a/waf_test.go b/waf_test.go
index 59b423f..ba41acf 100644
--- a/waf_test.go
+++ b/waf_test.go
@@ -8,7 +8,7 @@ import (
"github.com/emicklei/dot"
)
-func TestWAFComponentNextID(t *testing.T) {
+func TestWAFNextID(t *testing.T) {
tests := []struct {
want string
}{
@@ -29,7 +29,7 @@ func TestWAFComponentNextID(t *testing.T) {
}
}
-func TestWAFComponent(t *testing.T) {
+func TestWAFShape(t *testing.T) {
g := dot.NewGraph(dot.Directed)
sketcher := waf{}