Skip to content

Commit

Permalink
Resolved conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
massenz committed Mar 16, 2024
2 parents dd3da8f + 8441665 commit 6e9e42d
Show file tree
Hide file tree
Showing 54 changed files with 1,559 additions and 237 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml → .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
run: |
mkdir -p ${HOME}/.aws && cp data/credentials ${HOME}/.aws/
export AWS_REGION=us-west-2
go test ./api ./grpc ./pubsub ./storage
go test ./pkg/api ./pkg/grpc ./pkg/pubsub ./pkg/storage
# TODO: need to disable for now, as this fails and I can't figure out why
# - name: Test CLI
Expand Down
44 changes: 23 additions & 21 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ GOOS ?= $(shell uname -s | tr "[:upper:]" "[:lower:]")
GOARCH ?= amd64
GOMOD := $(shell go list -m)

version := v0.12.0
version := v0.13.0
release := $(version)-g$(shell git rev-parse --short HEAD)
prog := fsm-server
bin := out/bin/$(prog)-$(version)_$(GOOS)-$(GOARCH)
out := build/bin
server := fsm-server-$(version)_$(GOOS)-$(GOARCH)
cli := fsm-cli-$(version)_$(GOOS)-$(GOARCH)

# CLI Configuration
cli := out/bin/fsm-cli-$(version)_$(GOOS)-$(GOARCH)
cli_config := ${HOME}/.fsm

image := massenz/statemachine
Expand All @@ -24,7 +24,7 @@ dockerfile := docker/Dockerfile
# Edit only the packages list, when adding new functionality,
# the rest is deduced automatically.
#
pkgs := ./api ./grpc ./pubsub ./storage
pkgs := pkg/api pkg/grpc pkg/pubsub pkg/storage pkg/internal
all_go := $(shell for d in $(pkgs); do find $$d -name "*.go"; done)
test_srcs := $(shell for d in $(pkgs); do find $$d -name "*_test.go"; done)
srcs := $(filter-out $(test_srcs),$(all_go))
Expand All @@ -49,39 +49,41 @@ help: ## Display this help.
.PHONY: clean
img=$(shell docker images -q --filter=reference=$(image))
clean: ## Cleans up the binary, container image and other data
@rm -f $(bin)
@rm $(out)/$(server) $(out)/$(cli)
@[ ! -z $(img) ] && docker rmi $(img) || true
@rm -rf certs

version: ## Displays the current version tag (release)
@echo $(release)

fmt: ## Formats the Go source code using 'go fmt'
@go fmt $(pkgs) ./cmd ./clients
@go fmt $(pkgs) ./cmd fsm-cli/client fsm-cli/cmd

##@ Development
.PHONY: build test container cov clean fmt
$(bin): server/main.go $(srcs)
@mkdir -p $(shell dirname $(bin))
$(out)/$(server): cmd/main.go $(srcs)
@mkdir -p $(out)
GOOS=$(GOOS) GOARCH=$(GOARCH) go build \
-ldflags "-X $(GOMOD)/api.Release=$(release)" \
-o $(bin) server/main.go
-ldflags "-X $(GOMOD)/pkg/api.Release=$(release)" \
-o $(out)/$(server) cmd/main.go

.PHONY: build
build: $(bin) ## Builds the Statemachine server binary
build: $(out)/$(server) ## Builds the Statemachine server binary

.PHONY: cli
cli: cli/fsm-cli.go ## Builds the CLI client used to connect to the server
@mkdir -p $(shell dirname $(cli))
GOOS=$(GOOS) GOARCH=$(GOARCH) go build \
cli: fsm-cli/cmd/main.go ## Builds the CLI client used to connect to the server
@mkdir -p $(out)
cd fsm-cli && GOOS=$(GOOS) GOARCH=$(GOARCH) go build \
-ldflags "-X main.Release=$(version)" \
-o $(cli) cli/fsm-cli.go
-o ../$(out)/$(cli) cmd/main.go

.PHONY: cli_tests
cli-test: client/handlers_test.go ## Run tests for the CLI Client
.PHONY: cli-test
cli-test: ## Run tests for the CLI Client
@mkdir -p $(cli_config)/certs
@cp certs/ca.pem $(cli_config)/certs
RELEASE=$(release) BASEDIR=$(shell pwd) ginkgo test ./client
@cp certs/ca.pem $(cli_config)/certs || true
cd fsm-cli && RELEASE=$(release) BASEDIR=$(shell pwd) \
CLI_TEST_COMPOSE=$(shell pwd)/docker/cli-test-compose.yaml \
ginkgo test ./client

test: $(srcs) $(test_srcs) ## Runs all tests
ginkgo $(pkgs)
Expand Down Expand Up @@ -123,7 +125,7 @@ ca-config := $(config_dir)/ca-config.json
server-csr := $(config_dir)/localhost-csr.json

.PHONY: gencert
gencert: $(ca-csr) $(config) $(server-csr) ## Generates all certificates in the certs directory (requires cfssl and cfssl, see https://github.com/cloudflare/cfssl#installation)
gencert: $(ca-csr) $(ca-config) $(server-csr) ## Generates all certificates in the certs directory (requires cfssl and cfssl, see https://github.com/cloudflare/cfssl#installation)
cfssl gencert \
-initca $(ca-csr) | cfssljson -bare ca

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ _, err = queue.SendMessage(&sqs.SendMessageInput{
})
```

This will cause a `backorder` event to be sent to our FSM whose `id` matches the UUID in `Dest`; if there are errors (eg, the FSM does not exist, or the event is not allowed for the machine's configuration and current state) errors may be optionally sent to the SQS queue configured via the `-notifications` option (see [Running the Server](#running-the-server)): see the [`pubsub` code](pubsub/sqs_pub.go) code for details as to how we encode the error message as an SQS message.
This will cause a `backorder` event to be sent to our FSM whose `id` matches the UUID in `Dest`; if there are errors (eg, the FSM does not exist, or the event is not allowed for the machine's configuration and current state) errors may be optionally sent to the SQS queue configured via the `-notifications` option (see [Running the Server](#running-the-server)): see the [`pubsub` code](pkg/pubsub/sqs_pub.go) code for details as to how we encode the error message as an SQS message.

See [`EventRequest` in `statemachine-proto`](https://github.com/massenz/statemachine-proto/blob/golang/v1.1.0-beta-g1fc5dd8/api/statemachine.proto#L86) for details on the event being sent.

Expand All @@ -187,7 +187,7 @@ See the example in the [`SQS Client`](client/sqs_client.go).

#### SQS Notifications

Event processing outcomes are returned in [`EventResponse` protocol buffers](https://github.com/massenz/statemachine-proto/blob/golang/v1.1.0-beta-g1fc5dd8/api/statemachine.proto#L112), which are then serialized inside the `body` of the SQS message; to retrieve the actual Go struct, you can use code such as this (see [test code](pubsub/sqs_pub_test.go#L148) for actual working code):
Event processing outcomes are returned in [`EventResponse` protocol buffers](https://github.com/massenz/statemachine-proto/blob/golang/v1.1.0-beta-g1fc5dd8/api/statemachine.proto#L112), which are then serialized inside the `body` of the SQS message; to retrieve the actual Go struct, you can use code such as this (see [test code](pkg/pubsub/sqs_pub_test.go#L148) for actual working code):

```
// `res` is what AWS SQS Client will return to the Messages slice
Expand Down
29 changes: 29 additions & 0 deletions catalog-info.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
annotations:
crashoverride.com/artifact: "fsm-cmd"
crashoverride.com/component: "go-statemachine"

name: statemachine
title: 'Statemachine Server (gRPC)'
description: |
[The Statemachine Server](http://github.com/massenz/go-statemachine)
exposes a gRPC API to manage statemachines and relative configurations,
and a PubSub API to receive events for those.
links:
- url: https://github.com/massenz/go-statemachine
title: GitHub Repo
icon: github
- url: https://github.com/massenz/go-statemachine/releases
title: Releases
icon: settings
spec:
type: service
lifecycle: experimental
owner: user:marco
team: Backend
providesApis:
- statemachines
- configurations
- events
19 changes: 9 additions & 10 deletions server/main.go → cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import (
"errors"
"flag"
"fmt"
"github.com/massenz/go-statemachine/pkg/api"
"github.com/massenz/go-statemachine/pkg/grpc"
"github.com/massenz/go-statemachine/pkg/pubsub"
"github.com/massenz/go-statemachine/pkg/storage"
g "google.golang.org/grpc"
"net"
"os"
Expand All @@ -22,11 +26,6 @@ import (

log "github.com/massenz/slf4go/logging"
protos "github.com/massenz/statemachine-proto/golang/api"

"github.com/massenz/go-statemachine/api"
"github.com/massenz/go-statemachine/grpc"
"github.com/massenz/go-statemachine/pubsub"
"github.com/massenz/go-statemachine/storage"
)

func SetLogLevel(services []log.Loggable, level log.LogLevel) {
Expand All @@ -38,7 +37,7 @@ func SetLogLevel(services []log.Loggable, level log.LogLevel) {
}

var (
logger = log.NewLog("server")
logger = log.NewLog("fsmsrv")

listener *pubsub.EventsListener
pub *pubsub.SqsPublisher
Expand All @@ -57,7 +56,7 @@ var (
notificationsCh chan protos.EventResponse = nil

// eventsCh is the channel over which the Listener receive Events to process.
// Both the gRPC server and the PubSub Subscriber (if configured) will produce
// Both the gRPC Server and the PubSub Subscriber (if configured) will produce
// events for this channel.
//
// Currently, this is a blocking channel (capacity for one item), but once we
Expand All @@ -75,7 +74,7 @@ func main() {
var debug = flag.Bool("debug", false,
"Verbose logs; better to avoid on Production services")
var eventsTopic = flag.String("events", "", "Topic name to receive events from")
var grpcPort = flag.Int("grpc-port", 7398, "The port for the gRPC server")
var grpcPort = flag.Int("grpc-port", 7398, "The port for the gRPC Server")
var noTls = flag.Bool("insecure", false, "If set, TLS will be disabled (NOT recommended)")
var maxRetries = flag.Int("max-retries", storage.DefaultMaxRetries,
"Max number of attempts for a recoverable error to be retried against the Redis cluster")
Expand Down Expand Up @@ -141,7 +140,7 @@ func main() {
listener.ListenForMessages()
}()

logger.Info("gRPC server running at tcp://:%d", *grpcPort)
logger.Info("gRPC Server running at tcp://:%d", *grpcPort)
svr := startGrpcServer(*grpcPort, *noTls, eventsCh)

// This should not be invoked until we have initialized all the services.
Expand Down Expand Up @@ -208,7 +207,7 @@ func startGrpcServer(port int, disableTls bool, events chan<- protos.EventReques
if err != nil {
logger.Fatal(err)
}
logger.Info("gRPC server exited")
logger.Info("gRPC Server exited")
}()
return grpcServer
}
9 changes: 5 additions & 4 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ WORKDIR /server
COPY . .
RUN rm -rf certs data
RUN CGO_ENABLED=0 make build
RUN CGO_ENABLED=0 go build -o out/bin/hc docker/grpc_health.go
RUN CGO_ENABLED=0 go build -o build/bin/hc docker/grpc_health.go

# NOTE: Use the Ubuntu image; other images will encounter errors,
# including the "`GLIBC_2.32' not found" error.
# Alpine (which uses /bin/sh) emits an error which makes no sense (./fsm-server not found)
# Alpine (which uses /bin/sh) emits an error which makes no sense (./fsm-cmd not found)
# only because, in fact, it cannot find the library.
FROM ubuntu:22.04
LABEL org.opencontainers.image.authors="Marco Massenzio <[email protected]>"
Expand All @@ -21,6 +21,7 @@ LABEL org.opencontainers.image.licenses=Apache-2.0

RUN apt-get update && apt-get install ca-certificates -y
RUN groupadd -r sm-bot && useradd -r -g sm-bot sm-bot

# Sensible defaults for the server, for reference
# we list all the environment variables used by the
# entrypoint script.
Expand All @@ -34,8 +35,8 @@ WORKDIR /app
RUN chown sm-bot:sm-bot /app

USER sm-bot
COPY --from=builder /server/out/bin/fsm-server* ./fsm-server
COPY --from=builder /server/out/bin/hc ./
COPY --from=builder /server/build/bin/fsm-server* ./fsm-server
COPY --from=builder /server/build/bin/hc ./
ADD docker/entrypoint.sh ./

EXPOSE ${SERVER_PORT}
Expand Down
2 changes: 1 addition & 1 deletion docker/cli-test-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ services:

server:
depends_on:
# - localstack
- redis
networks:
- test-net
Expand All @@ -27,6 +26,7 @@ services:
EVENTS_Q: ""
NOTIFICATIONS_Q: ""
TIMEOUT: 200ms
INSECURE: -insecure
volumes:
- ${BASEDIR}/docker/aws-credentials:/home/sm-bot/.aws/credentials
- ${BASEDIR}/certs:/etc/statemachine/certs
Expand Down
2 changes: 1 addition & 1 deletion docker/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ services:
container_name: "redis"
image: "redis:6.2-alpine"
hostname: redis
command: "redis-server --save 60 1 --loglevel warning"
command: "redis-cmd --save 60 1 --loglevel warning"
volumes:
- "${TMPDIR:-/tmp}/redis:/data"
ports:
Expand Down
6 changes: 3 additions & 3 deletions docker/grpc_health.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ import (
"time"
)

// Most basic binary to run health checks on the server.
// Most basic binary to run health checks on the cmd.
// Used to assert readiness of the container/pod in Docker/Kubernetes.
func main() {
var address = flag.String("host", "localhost:7398",
"The address (host:port) for the GRPC server")
"The address (host:port) for the GRPC cmd")
var timeout = flag.Duration("timeout", 200*time.Millisecond,
"timeout expressed as a duration string (e.g., 200ms, 1s, etc.)")
var noTLS = flag.Bool("insecure", false, "disables TLS")
Expand Down Expand Up @@ -56,7 +56,7 @@ func main() {

resp, err := client.Health(ctx, &emptypb.Empty{})
if err != nil {
log.Fatal("cannot connect to server:", err)
log.Fatal("cannot connect to cmd:", err)
}
marshaler := &jsonpb.Marshaler{}
jsonString, err := marshaler.MarshalToString(resp)
Expand Down
10 changes: 5 additions & 5 deletions docs/examples/sqs_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Author: Marco Massenzio ([email protected])
*/

package examples
package main

import (
"context"
Expand Down Expand Up @@ -44,9 +44,9 @@ func NewOrderDetails(orderId, customerId string, orderTotal float64) *OrderDetai
}

func (o *OrderDetails) String() string {
res, error := json.Marshal(o)
if error != nil {
panic(error)
res, err := json.Marshal(o)
if err != nil {
panic(err)
}
return string(res)
}
Expand Down Expand Up @@ -86,7 +86,7 @@ func NewSqs(endpoint *string) *sqs.SQS {
}

// main simulates a Client sending an SQS event message for an Order entity
// whose status is being tracked by `fsm-server`.
// whose status is being tracked by `fsm-cmd`.
func main() {
endpoint := flag.String("endpoint", "", "Use http://localhost:4566 to use LocalStack")
q := flag.String("q", "", "The SQS Queue to send an Event to")
Expand Down
9 changes: 5 additions & 4 deletions client/client.go → fsm-cli/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ import (
"crypto/tls"
"fmt"
"github.com/golang/protobuf/ptypes/wrappers"
"github.com/massenz/go-statemachine/api"
"github.com/massenz/go-statemachine/grpc"
protos "github.com/massenz/statemachine-proto/golang/api"
"golang.org/x/text/cases"
"golang.org/x/text/language"
g "google.golang.org/grpc"
Expand All @@ -29,6 +26,10 @@ import (
"path"
"strings"
"time"

"github.com/massenz/go-statemachine/api"
"github.com/massenz/go-statemachine/grpc"
protos "github.com/massenz/statemachine-proto/golang/api"
)

const (
Expand Down Expand Up @@ -145,7 +146,7 @@ func (c *CliClient) Send(path string) error {
return err
}

// Get will retrieve the required entity from the server and generate the
// Get will retrieve the required entity from the FSM Server and generate the
// YAML representation accordingly.
// It takes two arguments, the kind and the id of the entity, and prints the
// contents returned by the server to stdout (or returns an error if not found)
Expand Down
Loading

0 comments on commit 6e9e42d

Please sign in to comment.