Skip to content

Commit

Permalink
Add support for running as windows service
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefano Da Ros committed Nov 19, 2018
1 parent 8b6684d commit dc222a1
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 33 deletions.
11 changes: 6 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ OS ?= linux
STAGE ?= production

# This version-strategy uses git tags to set the version string
#VERSION := $(shell git describe --tags --always --dirty)
VERSION := $(shell git describe --tags --always --dirty)
#
# This version-strategy uses a manual value to set the version string
VERSION := 0.1.0
#VERSION := 0.1.0

###
### These variables should not need tweaking.
Expand All @@ -60,7 +60,7 @@ endif

IMAGE := $(REGISTRY)/$(BIN)-$(ARCH)-$(OS)

BUILD_IMAGE ?= golang:1.9.2-alpine3.6
BUILD_IMAGE ?= golang:1.11-stretch
# If you want to build all binaries, see the 'all-build' rule.
# If you want to build all containers, see the 'all-container' rule.
# If you want to build AND push all containers, see the 'all-push' rule.
Expand All @@ -74,10 +74,11 @@ bin/$(ARCH)/$(OS)/$(BIN): build-dirs container-testing
-ti \
--rm \
-u $$(id -u):$$(id -g) \
-e GO111MODULE=on \
-v "$$(pwd)/.go:/go" \
-v "$$(pwd):/go/src/$(PKG)" \
-v "$$(pwd)/bin/$(ARCH)/$(OS):/go/bin" \
-v "$$(pwd)/bin/$(ARCH)/$(OS):/go/bin/$(OS)_$(ARCH)" \
-v "$$(pwd)/bin/$(ARCH)/$(OS):/go/bin" \
-v "$$(pwd)/bin/$(ARCH)/$(OS):/go/bin/$(OS)_$(ARCH)" \
-v "$$(pwd)/.go/std/$(ARCH):/usr/local/go/pkg/$(OS)_$(ARCH)_static" \
-w /go/src/$(PKG) \
$(IMAGE):$(VERSION)-testing \
Expand Down
2 changes: 1 addition & 1 deletion build/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ export GOARCH="${ARCH}"
export GOOS="${OS}"

go install \
-ldflags "-X ${PKG}/pkg/version.VERSION=${VERSION} main.version=${VERSION}"\
-ldflags "-X ${PKG}/pkg/version.VERSION=${VERSION} -X main.version=${VERSION}"\
./...
7 changes: 6 additions & 1 deletion config/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: workflow-connector
displayName: Signavio Workflow Connector
description: >
A web service which provides a Workflow Accelerator conform
RESTful API on top of standard SQL Databases
port: 443
database:
driver: sqlite
driver: sqlite3
url: test.db
tls:
enabled: false
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f
github.com/go-sql-driver/mysql v1.4.0
github.com/gorilla/mux v1.6.2
github.com/kardianos/service v0.0.0-20181115005516-4c239ee84e7b
github.com/lib/pq v1.0.0
github.com/mattn/go-sqlite3 v1.10.0
github.com/satori/go.uuid v1.2.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGE
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/kardianos/service v0.0.0-20181115005516-4c239ee84e7b h1:vfiqKno48aUndBMjTeWFpCExNnTf2Xnd6d228L4EfTQ=
github.com/kardianos/service v0.0.0-20181115005516-4c239ee84e7b/go.mod h1:10UU/bEkzh2iEN6aYzbevY7J6p03KO5siTxQWXMEerg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/lib/pq v0.0.0-20180523175426-90697d60dd84 h1:it29sI2IM490luSc3RAhp5WuCYnc6RtbfLVAB7nmC5M=
github.com/lib/pq v0.0.0-20180523175426-90697d60dd84/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
Expand Down
4 changes: 2 additions & 2 deletions internal/app/endpoint/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ func NewEndpoint(cfg config.Config) (Endpoint, error) {
switch cfg.Database.Driver {
case "sqlserver":
return sql.NewBackend("sqlserver"), nil
case "sqlite":
return sql.NewBackend("sqlite"), nil
case "sqlite3":
return sql.NewBackend("sqlite3"), nil
case "mysql":
return sql.NewBackend("mysql"), nil
case "postgres":
Expand Down
29 changes: 23 additions & 6 deletions internal/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ import (
)

// Options is populated by this package's init() function
// TODO It should be a singleton
var Options Config

// Config defines the data structures which can be used and configured
// in the config.yaml file and other relevant data structures
type Config struct {
Port string
Database struct {
Name string
DisplayName string
Description string
Port string
Database struct {
Driver string
URL string
Tables []*Table
Expand Down Expand Up @@ -61,6 +63,13 @@ type configDir struct {
val string
}

// service is a command line flag that specifies which control
// should be sent to a service
type service struct {
name string
val string
}

// Initialize configuration file from typical directory locations and parse it
func init() {
db := &db{name: "db", val: ""}
Expand All @@ -69,10 +78,14 @@ func init() {
configDir := &configDir{name: "config-dir", val: "config"}
flag.StringVar(&configDir.val, "config-dir", "", "specify location to config directory")
viper.BindFlagValue("configDir", configDir)
serviceControl := &service{name: "service", val: ""}
flag.StringVar(&serviceControl.val, "service", "", "specify control to send to service")
viper.BindFlagValue("service", serviceControl)
flag.Parse()
viper.SetConfigName("config")
if configDir.ValueString() == "" {
viper.AddConfigPath("config")
viper.AddConfigPath(filepath.Join("C:\\Program Files\\Workflow Connector\\", "config"))
viper.AddConfigPath(filepath.Join("../../../", "config"))
viper.AddConfigPath(filepath.Join("../../../../", "config"))
} else {
Expand All @@ -84,14 +97,14 @@ func init() {
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Can not parse config file: %v\n", err)
log.When(true).Fatalf("Can not parse config file: %v\n", err)
}
if err := viper.Unmarshal(&Options); err != nil {
log.Fatalf("Unable to decode config file into struct: %s", err)
log.When(true).Fatalf("Unable to decode config file into struct: %s", err)
}
descriptorFile, err := os.Open(descriptorFilePath())
if err != nil {
log.Fatalf("Unable to open descriptor.json file: %v\n", err)
log.When(true).Fatalf("Unable to open descriptor.json file: %v\n", err)
}
Options.Descriptor = ParseDescriptorFile(descriptorFile)
for _, td := range Options.Descriptor.TypeDescriptors {
Expand All @@ -113,3 +126,7 @@ func (f configDir) HasChanged() bool { return false }
func (f configDir) Name() string { return f.name }
func (f configDir) ValueString() string { return f.val }
func (f configDir) ValueType() string { return "string" }
func (f service) HasChanged() bool { return false }
func (f service) Name() string { return f.name }
func (f service) ValueString() string { return f.val }
func (f service) ValueType() string { return "string" }
16 changes: 10 additions & 6 deletions internal/pkg/log/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ func (l Logger) Infoln(v ...interface{}) {
fmt.Println(v...)
}
}
func Fatalln(v ...interface{}) {
fmt.Println(v...)
os.Exit(1)
func (l Logger) Fatalln(v ...interface{}) {
if l {
fmt.Println(v...)
os.Exit(1)
}
}
func Fatalf(format string, v ...interface{}) {
fmt.Printf(format, v...)
os.Exit(1)
func (l Logger) Fatalf(format string, v ...interface{}) {
if l {
fmt.Printf(format, v...)
os.Exit(1)
}
}
99 changes: 87 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,109 @@
package main

import (
"context"
"net/http"
"os"

"github.com/kardianos/service"
"github.com/signavio/workflow-connector/internal/app/endpoint"
"github.com/signavio/workflow-connector/internal/app/server"
"github.com/signavio/workflow-connector/internal/pkg/config"
"github.com/signavio/workflow-connector/internal/pkg/log"
"github.com/spf13/viper"
)

var version string
var (
version string
logger service.Logger
)

func main() {
log.When(true).Infof("starting workflow connector v%s\n", version)
type app struct {
server *http.Server
}

func (a *app) Start(s service.Service) error {
logger.Infof("starting workflow connector %s\n", version)
go a.run()
return nil
}
func (a *app) Stop(s service.Service) error {
logger.Infof("\nstopping workflow connector %s\n", version)
if err := a.server.Shutdown(context.Background()); err != nil {
logger.Infof("unable to shutdown server cleanly: %s\n", err)
}
if service.Interactive() {
os.Exit(0)
}
return nil
}
func (a *app) run() {
endpoint, err := endpoint.NewEndpoint(config.Options)
if err != nil {
log.Fatalln(err)
logger.Errorf("unable to create new endpoint: %s\n", err)
os.Exit(1)
}
log.When(true).Infoln("[endpoint] initialize backend")
err = endpoint.Open(
config.Options.Database.Driver,
config.Options.Database.URL,
)
if err != nil {
log.Fatalln(err)
logger.Errorf("unable to initialize backend: %s\n", err)
os.Exit(1)
}
server := server.NewServer(config.Options, endpoint)
println("[server] ready and listening on :" + config.Options.Port)
a.server = server.NewServer(config.Options, endpoint)
logger.Infof(
"server is ready and listening on port %s\n",
config.Options.Port,
)
if config.Options.TLS.Enabled {
log.Fatalln(server.ListenAndServeTLS(config.Options.TLS.PublicKey,
config.Options.TLS.PrivateKey))
err := a.server.ListenAndServeTLS(
config.Options.TLS.PublicKey,
config.Options.TLS.PrivateKey,
)
if err != http.ErrServerClosed {
logger.Errorf("unable to start http server: %s\n", err)
os.Exit(1)
}
} else {
log.Fatalln(server.ListenAndServe())
err := a.server.ListenAndServe()
if err != http.ErrServerClosed {
logger.Errorf("unable to start http server: %s\n", err)
os.Exit(1)
}
}
}

func main() {
a := &app{}
svc, err := service.New(
a,
&service.Config{
Name: config.Options.Name,
DisplayName: config.Options.DisplayName,
Description: config.Options.Description,
},
)
if err != nil {
logger.Errorf("unable to create service: %s\n", err)
os.Exit(1)
}
logger, err = svc.Logger(nil)
if err != nil {
logger.Errorf("unable to initialize logger: %s\n", err)
os.Exit(1)
}
serviceControl, ok := viper.Get("service").(string)
if ok && serviceControl != "" {
// Execute user specified control on service
if err := service.Control(svc, serviceControl); err != nil {
logger.Error(err)
os.Exit(1)
}
return
}
err = svc.Run()
if err != nil {
logger.Errorf("unable to run the service: %s\n", err)
os.Exit(1)
}
}

0 comments on commit dc222a1

Please sign in to comment.