From 334054448d62efe775daa28f21a3b9b1d1f64a10 Mon Sep 17 00:00:00 2001 From: docktermj Date: Tue, 9 Jul 2024 09:50:38 -0400 Subject: [PATCH 1/8] #58 Update dependencies --- cmd/root.go | 4 +- go.mod | 67 +++++++++++++------------- go.sum | 135 ++++++++++++++++++++++++++-------------------------- 3 files changed, 104 insertions(+), 102 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 3672615..123a166 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -12,8 +12,8 @@ import ( "github.com/senzing-garage/demo-quickstart/httpserver" "github.com/senzing-garage/go-cmdhelping/cmdhelper" - "github.com/senzing-garage/go-cmdhelping/engineconfiguration" "github.com/senzing-garage/go-cmdhelping/option" + "github.com/senzing-garage/go-cmdhelping/settings" "github.com/senzing-garage/go-observing/observer" "github.com/senzing-garage/go-rest-api-service/senzingrestservice" "github.com/senzing-garage/serve-grpc/grpcserver" @@ -129,7 +129,7 @@ func RunE(_ *cobra.Command, _ []string) error { // Build configuration for Senzing engine. - senzingSettings, err := engineconfiguration.BuildAndVerifySenzingEngineConfigurationJson(ctx, viper.GetViper()) + senzingSettings, err := settings.BuildAndVerifySenzingEngineConfigurationJson(ctx, viper.GetViper()) if err != nil { return err } diff --git a/go.mod b/go.mod index 4a1bf00..34bc8f0 100644 --- a/go.mod +++ b/go.mod @@ -8,15 +8,15 @@ require ( github.com/docktermj/cloudshell v0.2.0 github.com/flowchartsman/swaggerui v0.0.0-20221017034628-909ed4f3701b github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c - github.com/senzing-garage/demo-entity-search v0.1.1 - github.com/senzing-garage/go-cmdhelping v0.2.1 - github.com/senzing-garage/go-observing v0.3.1 - github.com/senzing-garage/go-rest-api-service v0.9.3 + github.com/senzing-garage/demo-entity-search v0.1.2 + github.com/senzing-garage/go-cmdhelping v0.2.2 + github.com/senzing-garage/go-observing v0.3.2 + github.com/senzing-garage/go-rest-api-service v0.9.4 github.com/senzing-garage/go-rest-api-service-legacy v0.1.1 - github.com/senzing-garage/serve-grpc v0.7.2 - github.com/spf13/cobra v1.8.0 + github.com/senzing-garage/serve-grpc v0.7.4 + github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 - google.golang.org/grpc v1.64.0 + google.golang.org/grpc v1.65.0 ) require ( @@ -24,60 +24,61 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/creack/pty v1.1.21 // indirect - github.com/dlclark/regexp2 v1.11.0 // indirect - github.com/fatih/color v1.16.0 // indirect + github.com/dlclark/regexp2 v1.11.1 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-faster/errors v0.7.1 // indirect github.com/go-faster/jx v1.1.0 // indirect github.com/go-faster/yaml v0.4.6 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.1 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/ogen-go/ogen v1.1.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/ogen-go/ogen v1.2.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.53.0 // indirect - github.com/prometheus/procfs v0.14.0 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/segmentio/asm v1.2.0 // indirect - github.com/senzing-garage/go-helpers v0.5.1 // indirect - github.com/senzing-garage/go-logging v1.4.1 // indirect - github.com/senzing-garage/go-messaging v1.4.1 // indirect - github.com/senzing-garage/go-sdk-abstract-factory v0.8.0 // indirect - github.com/senzing-garage/sz-sdk-go v0.12.3 // indirect - github.com/senzing-garage/sz-sdk-go-core v0.7.1 // indirect - github.com/senzing-garage/sz-sdk-go-grpc v0.7.1 // indirect - github.com/senzing-garage/sz-sdk-json-type-definition v0.2.4 // indirect - github.com/senzing-garage/sz-sdk-proto v0.7.5 // indirect + github.com/senzing-garage/go-helpers v0.5.2 // indirect + github.com/senzing-garage/go-logging v1.5.0 // indirect + github.com/senzing-garage/go-messaging v1.5.1 // indirect + github.com/senzing-garage/go-sdk-abstract-factory v0.8.1 // indirect + github.com/senzing-garage/sz-sdk-go v0.13.5 // indirect + github.com/senzing-garage/sz-sdk-go-core v0.7.4 // indirect + github.com/senzing-garage/sz-sdk-go-grpc v0.7.2 // indirect + github.com/senzing-garage/sz-sdk-json-type-definition v0.2.6 // indirect + github.com/senzing-garage/sz-sdk-proto v0.7.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect - go.opentelemetry.io/otel v1.26.0 // indirect - go.opentelemetry.io/otel/metric v1.26.0 // indirect - go.opentelemetry.io/otel/trace v1.26.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 // indirect - google.golang.org/protobuf v1.34.1 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 2e21849..5eb3687 100644 --- a/go.sum +++ b/go.sum @@ -4,7 +4,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= @@ -13,12 +12,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= -github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dlclark/regexp2 v1.11.1 h1:CJs78ewKXO9PuNf6Xwlw6eibMadBkXTRpOeUdv+IcWM= +github.com/dlclark/regexp2 v1.11.1/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/docktermj/cloudshell v0.2.0 h1:cDt4+A0LOHUy/odwUEs1u4gPxY2yAow+XlPBnS0rhqQ= github.com/docktermj/cloudshell v0.2.0/go.mod h1:EJ4boCOLil6MIghSCwOf+/ue5Ci5Ag3AIDNoigTzM1c= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/flowchartsman/swaggerui v0.0.0-20221017034628-909ed4f3701b h1:oy54yVy300Db264NfQCJubZHpJOl+SoT6udALQdFbSI= github.com/flowchartsman/swaggerui v0.0.0-20221017034628-909ed4f3701b/go.mod h1:/RJwPD5L4xWgCbqQ1L5cB12ndgfKKT54n9cZFf+8pus= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -34,16 +33,16 @@ github.com/go-faster/jx v1.1.0/go.mod h1:vKDNikrKoyUmpzaJ0OkIkRQClNHFX/nF3dnTJZb github.com/go-faster/yaml v0.4.6 h1:lOK/EhI04gCpPgPhgt0bChS6bvw7G3WwI8xxVe0sw9I= github.com/go-faster/yaml v0.4.6/go.mod h1:390dRIvV4zbnO7qC9FGo6YYutc+wyyUSHBgbXL52eXk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -61,8 +60,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/ogen-go/ogen v1.1.0 h1:hM4osoOPGWvx8pcdqE8jb5VvzHA+wi3u+DwCvZoW4dg= -github.com/ogen-go/ogen v1.1.0/go.mod h1:d5Ph7PWpJz453ZdGbVe+DBVPS150idePr5dZ+S0JG00= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/ogen-go/ogen v1.2.2 h1:fFqZzRacbdnOQeqep4efVeqj7/4hI1mlimrY8rn970A= +github.com/ogen-go/ogen v1.2.2/go.mod h1:S8X2dBfTKlpy+pcGLXP+aLLzvUAXAvtONtuovrN3+gw= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -74,50 +75,50 @@ github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQ github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= -github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= -github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s= -github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= +github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= -github.com/senzing-garage/demo-entity-search v0.1.1 h1:W1xVGJnJ1ttRwdQ3FxZqOz8CvFV1NuwLzkp88SIToT4= -github.com/senzing-garage/demo-entity-search v0.1.1/go.mod h1:bryMu/zGq3Fgsr3knqRkUmNLZR2jao/ZdNTT6msWNyg= -github.com/senzing-garage/go-cmdhelping v0.2.1 h1:F40uSBtxP03/5aXAUW9C5kMuCFj8lFvmvDlJDvAq9qE= -github.com/senzing-garage/go-cmdhelping v0.2.1/go.mod h1:76FIsPpEWQrsY7DLR5f/I0bi5UB43KfmDd7b1jBfot8= -github.com/senzing-garage/go-helpers v0.5.1 h1:ezVW5oAHihfG2QVpe/Ooyz8q9UPrCuDdg+W43wk9phY= -github.com/senzing-garage/go-helpers v0.5.1/go.mod h1:Gx66fvdAqt4YVf1KVCjzK2Rmr/C7qe5zaZW4VQ3goyM= -github.com/senzing-garage/go-logging v1.4.1 h1:ubNspaf0r4Q29XeNW58q0oPGLq4c1pdf9FciQLw6hpc= -github.com/senzing-garage/go-logging v1.4.1/go.mod h1:TW1w0UE9fQpy9odkx1jJQeffW+OTdrqEyxhtWKGW1n4= -github.com/senzing-garage/go-messaging v1.4.1 h1:ZdFcemh1iACP+HJWGS5/QLaUSD7PUYVXhzW7Zbju9f0= -github.com/senzing-garage/go-messaging v1.4.1/go.mod h1:7tEicOa0baYz0lh0w1BJEiQ6ry1FIQl/67JAWwFpcRY= -github.com/senzing-garage/go-observing v0.3.1 h1:EGqe+Uix8VNQ9HCwm5xZkAF0hGoHaC1URAaT/5FW37A= -github.com/senzing-garage/go-observing v0.3.1/go.mod h1:x60vlRIR0ZdJrHDuK82nzmQG4sN0G6oqdLE9vQl9pVc= -github.com/senzing-garage/go-rest-api-service v0.9.3 h1:YOYZobOEhhc4S+CasMF9uRnpvSkwlHqJsQNBJVgm2Pw= -github.com/senzing-garage/go-rest-api-service v0.9.3/go.mod h1:c/bkYsIHITjdcBAsdiZ4yAeMJD7E93Rr8ctxbuwxGXg= +github.com/senzing-garage/demo-entity-search v0.1.2 h1:Rswk48ifgdmixfHes2cd2YBZkXBx24mbxBM6IanMRVg= +github.com/senzing-garage/demo-entity-search v0.1.2/go.mod h1:8WfEMi/lLhEndK0NonAqNsbUIVJVEKa38QrMhq6d8wQ= +github.com/senzing-garage/go-cmdhelping v0.2.2 h1:2DE6uapQuoHodlOu6dFEspo8RNwhEkMZrb9azo+6uiw= +github.com/senzing-garage/go-cmdhelping v0.2.2/go.mod h1:cE/9aV+4NizpnduntqbjGBmRS1+VAGn9oTR0yybgeko= +github.com/senzing-garage/go-helpers v0.5.2 h1:MuXQcy0sw/+v5LmDY1Z8wwh6t1DCtKNgJj7nkDu0yxY= +github.com/senzing-garage/go-helpers v0.5.2/go.mod h1:QwQEA1FZVfpU7lLGN47iQDoMug1JCfsRDIbLI9ve+rA= +github.com/senzing-garage/go-logging v1.5.0 h1:Qf7u2l+fP1SYl8dVElflhn4n7Kdl3KemSl8koeRoCy0= +github.com/senzing-garage/go-logging v1.5.0/go.mod h1:oJvDi8BwljDAE1RRlGWk3glgq3czTaIZyL+TnpaTUAE= +github.com/senzing-garage/go-messaging v1.5.1 h1:rvBP06mURgUQV8xNRKZ1V1pkMLbXizdjak16TE6/zQg= +github.com/senzing-garage/go-messaging v1.5.1/go.mod h1:W93FrFoYrJWQ1302jgY8U5ylSA0whAOCLo1x1ESbVX4= +github.com/senzing-garage/go-observing v0.3.2 h1:jXW5u656aZywe/UEUi7ga7nieBSW4CUO8YKvpNNAFMQ= +github.com/senzing-garage/go-observing v0.3.2/go.mod h1:5yHCwaaIrwX81JOghAL/1Q1V8eF7SQhyBBdhTb7+rgY= +github.com/senzing-garage/go-rest-api-service v0.9.4 h1:Brfyc2DLr/faPGZGaiopArUr/H13b/p9UxbRsIi1XoI= +github.com/senzing-garage/go-rest-api-service v0.9.4/go.mod h1:JYI5aC592hrmcF3Rh18w1AyhVxx87B6Td4VZaH7uLHA= github.com/senzing-garage/go-rest-api-service-legacy v0.1.1 h1:Ka0Livm51aUdv5s8z+pZ69VmDtKIGWLEZoZqvKapx9c= github.com/senzing-garage/go-rest-api-service-legacy v0.1.1/go.mod h1:s+lMso2zTmKgNYnayo9lVdUle1EMMax2BcVJnvFoRpI= -github.com/senzing-garage/go-sdk-abstract-factory v0.8.0 h1:RvlYWPws6r7v3vqJQz1+JAOlzrDjqS9gFGktLUGizXE= -github.com/senzing-garage/go-sdk-abstract-factory v0.8.0/go.mod h1:LVggzWmDY3Booa4nphl1WUWMus76yEGW6szad1Aoyvc= -github.com/senzing-garage/serve-grpc v0.7.2 h1:7ktNOySA0cY1vxrX/vIdVb4CnuORMcyawA4orVUacvQ= -github.com/senzing-garage/serve-grpc v0.7.2/go.mod h1:KMbkD9hvhqrdb8Jmgp4Qiy3QqUQ2Agj8RHIDksKL5Mg= -github.com/senzing-garage/sz-sdk-go v0.12.3 h1:KDOByEcJ5oTMogR9BKx7UWfEiy2/lswSQqykRmdyJt8= -github.com/senzing-garage/sz-sdk-go v0.12.3/go.mod h1:K+tiyY6W5FnUrzBZXIg5x7cWbZKpO/6rzpkCoKhcK6o= -github.com/senzing-garage/sz-sdk-go-core v0.7.1 h1:J1qAXrMxhYIStEdc7r4+RnPR9W13x/9h5HRYn7OwQO4= -github.com/senzing-garage/sz-sdk-go-core v0.7.1/go.mod h1:+WbyXc3vgmGaYO5tbHSFAxfTfiart5g/ljR+I0g8b7s= -github.com/senzing-garage/sz-sdk-go-grpc v0.7.1 h1:MzxEUojOBboNvWFUE6wo8cs6g8FpnHDGGLuA44CiSLA= -github.com/senzing-garage/sz-sdk-go-grpc v0.7.1/go.mod h1:nD9wzF3CpUGQAnbGiR1UDVM0t8KQHBG9cd75NArJBtI= -github.com/senzing-garage/sz-sdk-json-type-definition v0.2.4 h1:mM3yu8Ntbupl92I78Z1VzOMguL7/4oI/0LmfB8pLifM= -github.com/senzing-garage/sz-sdk-json-type-definition v0.2.4/go.mod h1:UlKL1vflvcE8rNOpbptlNiw57SixFAUWk5ftu5gHL9Y= -github.com/senzing-garage/sz-sdk-proto v0.7.5 h1:XDEVh9gsB1DRSE/O/bb9fYIoror3K8NNNbTzDHaFvPo= -github.com/senzing-garage/sz-sdk-proto v0.7.5/go.mod h1:Volu1U+jmQZKA3XkcyRgj9VpKVLmsdjhVBGSwWS+bvs= +github.com/senzing-garage/go-sdk-abstract-factory v0.8.1 h1:p0LriaGxa31DxB50L89b+XO357M6/glYFF4TGcDQOrw= +github.com/senzing-garage/go-sdk-abstract-factory v0.8.1/go.mod h1:CP9KfyIyzDxFJJjAH9//lo2ZRiceMlumHMDgnl303No= +github.com/senzing-garage/serve-grpc v0.7.4 h1:wnzUs8aNzoYV8Zev+P0EGTkO+iquxQqupkGoRpIoxPg= +github.com/senzing-garage/serve-grpc v0.7.4/go.mod h1:Bm3vSxQoy93SYF21GmAORd+07Aq9CTtc/JiTkcvhCAM= +github.com/senzing-garage/sz-sdk-go v0.13.5 h1:7JvU13ofse+5bwdr/Ud0CGS33Z9ybVXFd2akpAFc1L4= +github.com/senzing-garage/sz-sdk-go v0.13.5/go.mod h1:pr9d622FPNGFPgAFooCcUWNeh+AEyVDkvR3Fmsp6whg= +github.com/senzing-garage/sz-sdk-go-core v0.7.4 h1:jlD6AzMnWORdBtmR3IRrpahx86MOtFwUuuoBX+oDZ1k= +github.com/senzing-garage/sz-sdk-go-core v0.7.4/go.mod h1:MHRe4w+o57NqbtUJe71aurwQeoVGB45CPwUZhT8QpoY= +github.com/senzing-garage/sz-sdk-go-grpc v0.7.2 h1:3HmIJQxs5mP9wK/1cLb17jMXseyewvDKhkoxSYPBhOI= +github.com/senzing-garage/sz-sdk-go-grpc v0.7.2/go.mod h1:fMpGwBf2hZ0AxK9xIWjt5CM9g7vb2dQyWcsAA2ohN8A= +github.com/senzing-garage/sz-sdk-json-type-definition v0.2.6 h1:306hNQumqaZ5Ge2aKdEMueKJ2KCSHh5WC5cs2EOdMRQ= +github.com/senzing-garage/sz-sdk-json-type-definition v0.2.6/go.mod h1:UlKL1vflvcE8rNOpbptlNiw57SixFAUWk5ftu5gHL9Y= +github.com/senzing-garage/sz-sdk-proto v0.7.6 h1:mHiZr094UTBcRW1OkNam1Pu/pMLZRO/4cIIyjQ/yDlY= +github.com/senzing-garage/sz-sdk-proto v0.7.6/go.mod h1:7CZSZ5yEVmT2T0yiijjdq7dWsdQ/KtRgvKRqCy+j7SI= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= @@ -126,8 +127,8 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= @@ -144,38 +145,38 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= -go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= -go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= -go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= -go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= -go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 h1:umK/Ey0QEzurTNlsV3R+MfxHAb78HCEX/IkuR+zH4WQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434/go.mod h1:I7Y+G38R2bu5j1aLzfFmQfTcU/WnFuqDwLZAbvKTKpM= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From 9efa294ba59eb641da416550e3b1a769c6a9c9f0 Mon Sep 17 00:00:00 2001 From: docktermj Date: Tue, 9 Jul 2024 09:56:57 -0400 Subject: [PATCH 2/8] #58 Working tests --- cmd/root.go | 18 +++++++++--------- httpserver/httpserver.go | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 123a166..0866a66 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -39,15 +39,15 @@ A server supporting the following services: var ContextVariablesForMultiPlatform = []option.ContextVariable{ option.Configuration, - option.DatabaseUrl, - option.EngineConfigurationJson, + option.DatabaseURL, + option.EngineConfigurationJSON, option.EngineLogLevel, option.EngineModuleName, option.GrpcPort, - option.HttpPort, + option.HTTPPort, option.LogLevel, option.ObserverOrigin, - option.ObserverUrl, + option.ObserverURL, option.ServerAddress, option.TtyOnly, option.XtermAllowedHostnames.SetDefault(getDefaultAllowedHostnames()), @@ -129,7 +129,7 @@ func RunE(_ *cobra.Command, _ []string) error { // Build configuration for Senzing engine. - senzingSettings, err := settings.BuildAndVerifySenzingEngineConfigurationJson(ctx, viper.GetViper()) + senzingSettings, err := settings.BuildAndVerifySettings(ctx, viper.GetViper()) if err != nil { return err } @@ -140,11 +140,11 @@ func RunE(_ *cobra.Command, _ []string) error { // Setup gRPC server - grpcserver := &grpcserver.GrpcServerImpl{ + grpcserver := &grpcserver.BasicGrpcServer{ EnableAll: true, LogLevelName: viper.GetString(option.LogLevel.Arg), ObserverOrigin: viper.GetString(option.ObserverOrigin.Arg), - ObserverUrl: viper.GetString(option.ObserverUrl.Arg), + ObserverURL: viper.GetString(option.ObserverURL.Arg), Port: viper.GetInt(option.GrpcPort.Arg), SenzingSettings: senzingSettings, SenzingInstanceName: viper.GetString(option.EngineModuleName.Arg), @@ -160,13 +160,13 @@ func RunE(_ *cobra.Command, _ []string) error { LogLevelName: viper.GetString(option.LogLevel.Arg), ObserverOrigin: viper.GetString(option.ObserverOrigin.Arg), Observers: observers, - OpenApiSpecificationRest: senzingrestservice.OpenApiSpecificationJson, + OpenApiSpecificationRest: senzingrestservice.OpenAPISpecificationJSON, ReadHeaderTimeout: 60 * time.Second, SenzingEngineConfigurationJson: senzingSettings, SenzingModuleName: viper.GetString(option.EngineModuleName.Arg), SenzingVerboseLogging: viper.GetInt64(option.EngineLogLevel.Arg), ServerAddress: viper.GetString(option.ServerAddress.Arg), - ServerPort: viper.GetInt(option.HttpPort.Arg), + ServerPort: viper.GetInt(option.HTTPPort.Arg), SwaggerUrlRoutePrefix: "swagger", TtyOnly: viper.GetBool(option.TtyOnly.Arg), XtermAllowedHostnames: viper.GetStringSlice(option.XtermAllowedHostnames.Arg), diff --git a/httpserver/httpserver.go b/httpserver/httpserver.go index b0ebe0a..8646062 100644 --- a/httpserver/httpserver.go +++ b/httpserver/httpserver.go @@ -198,7 +198,7 @@ func (httpServer *HttpServerImpl) getSenzingRestApiProxyMux(ctx context.Context) } func (httpServer *HttpServerImpl) getEntitySearchMux(ctx context.Context) *http.ServeMux { - service := &entitysearchservice.HttpServiceImpl{} + service := &entitysearchservice.BasicHTTPService{} return service.Handler(ctx) } From 3a431d1c9a97fcf57bec072a482a8f10f153a90c Mon Sep 17 00:00:00 2001 From: docktermj Date: Tue, 9 Jul 2024 10:40:26 -0400 Subject: [PATCH 3/8] #58 Working test and lint --- .github/coverage/testcoverage.yaml | 68 ++++++++ .github/linters/.golangci.yml | 47 ++++++ .github/linters/.jscpd.json | 5 +- .github/workflows/docker-build-container.yaml | 2 +- .github/workflows/go-proxy-pull.yaml | 3 +- .../workflows/go-test-darwin.yaml.disabled | 34 +++- .github/workflows/go-test-linux.yaml | 30 +++- .github/workflows/go-test-windows.yaml | 40 ++++- .github/workflows/gofmt.yaml | 12 -- .github/workflows/golangci-lint.yaml | 59 +++++++ .github/workflows/gosec.yaml | 27 ---- .github/workflows/make-go-github-file.yaml | 2 +- Dockerfile | 44 +++--- Makefile | 33 +++- cmd/cmd_test.go | 3 +- cmd/completion.go | 2 + cmd/context_darwin.go | 2 +- cmd/context_linux.go | 2 +- cmd/context_windows.go | 2 +- cmd/docs.go | 1 + cmd/github.go | 14 +- cmd/root.go | 56 +++---- .../{httpserver.go => httpserver_basic.go} | 147 +++++++++--------- httpserver/httpserver_examples_test.go | 9 ++ httpserver/httpserver_test.go | 41 +---- httpserver/main.go | 4 +- main_test.go | 7 +- makefiles/darwin.mk | 15 +- makefiles/linux.mk | 20 ++- makefiles/windows.mk | 13 +- 30 files changed, 503 insertions(+), 241 deletions(-) create mode 100644 .github/coverage/testcoverage.yaml create mode 100644 .github/linters/.golangci.yml delete mode 100644 .github/workflows/gofmt.yaml create mode 100644 .github/workflows/golangci-lint.yaml delete mode 100644 .github/workflows/gosec.yaml rename httpserver/{httpserver.go => httpserver_basic.go} (69%) create mode 100644 httpserver/httpserver_examples_test.go diff --git a/.github/coverage/testcoverage.yaml b/.github/coverage/testcoverage.yaml new file mode 100644 index 0000000..05d9160 --- /dev/null +++ b/.github/coverage/testcoverage.yaml @@ -0,0 +1,68 @@ +# (mandatory) +# Path to coverprofile file (output of `go test -coverprofile` command). +# +# For cases where there are many coverage profiles, such as when running +# unit tests and integration tests separately, you can combine all those +# profiles into one. In this case, the profile should have a comma-separated list +# of profile files, e.g., 'cover_unit.out,cover_integration.out'. +profile: cover.out + +# (optional; but recommended to set) +# When specified reported file paths will not contain local prefix in the output +local-prefix: "github.com/org/project" + +# Holds coverage thresholds percentages, values should be in range [0-100] +threshold: + # (optional; default 0) + # The minimum coverage that each file should have + file: 80 + + # (optional; default 0) + # The minimum coverage that each package should have + package: 80 + + # (optional; default 0) + # The minimum total coverage project should have + total: 80 +# Holds regexp rules which will override thresholds for matched files or packages +# using their paths. +# +# First rule from this list that matches file or package is going to apply +# new threshold to it. If project has multiple rules that match same path, +# override rules should be listed in order from specific to more general rules. +#override: +# Increase coverage threshold to 100% for `foo` package +# (default is 80, as configured above in this example) +#- threshold: 100 +# path: ^pkg/lib/foo$ + +# Holds regexp rules which will exclude matched files or packages +# from coverage statistics +#exclude: +# Exclude files or packages matching their paths +#paths: +# - \.pb\.go$ # excludes all protobuf generated files +# - ^pkg/bar # exclude package `pkg/bar` + +exclude: + paths: + - senzingchatapi/oas_cfg_gen.go + - senzingchatapi/oas_client_gen.go + - senzingchatapi/oas_handlers_gen.go + - senzingchatapi/oas_interfaces_gen.go + - senzingchatapi/oas_json_gen.go + - senzingchatapi/oas_labeler_gen.go + - senzingchatapi/oas_middleware_gen.go + - senzingchatapi/oas_parameters_gen.go + - senzingchatapi/oas_request_decoders_gen.go + - senzingchatapi/oas_request_encoders_gen.go + - senzingchatapi/oas_response_decoders_gen.go + - senzingchatapi/oas_response_encoders_gen.go + - senzingchatapi/oas_router_gen.go + - senzingchatapi/oas_schemas_gen.go + - senzingchatapi/oas_server_gen.go + - senzingchatapi/oas_unimplemented_gen.go + - senzingchatapi/oas_validators_gen.go +# NOTES: +# - symbol `/` in all path regexps will be replaced by current OS file path separator +# to properly work on Windows diff --git a/.github/linters/.golangci.yml b/.github/linters/.golangci.yml new file mode 100644 index 0000000..389317d --- /dev/null +++ b/.github/linters/.golangci.yml @@ -0,0 +1,47 @@ +run: + modules-download-mode: readonly + show-stats: true + +output: + print-linter-name: false + sort-results: true + +linters: + enable: + # List generated from: https://golangci-lint.run/usage/linters/ + # We are enabling all defaults as well as any bug/security related + - asasalint + - asciicheck + - bidichk + - bodyclose + - contextcheck + - durationcheck + - errcheck + - errchkjson + - errorlint + - exhaustive + - exportloopref + - gocheckcompilerdirectives + - gochecksumtype + - gocritic + - gofmt + - gosec + - gosimple + - gosmopolitan + - govet + - ineffassign + - loggercheck + - makezero + - musttag + - nilerr + - noctx + - protogetter + - reassign + - revive + - rowserrcheck + - spancheck + - sqlclosecheck + - staticcheck + - testifylint + - unused + - zerologlint diff --git a/.github/linters/.jscpd.json b/.github/linters/.jscpd.json index 6eb5f17..4dd8b09 100644 --- a/.github/linters/.jscpd.json +++ b/.github/linters/.jscpd.json @@ -1,3 +1,6 @@ { - "threshold": 3 + "ignore": [ + "**/*.go,**/go-test*.yaml" + ], + "threshold": 20 } \ No newline at end of file diff --git a/.github/workflows/docker-build-container.yaml b/.github/workflows/docker-build-container.yaml index b95c594..a12da5f 100644 --- a/.github/workflows/docker-build-container.yaml +++ b/.github/workflows/docker-build-container.yaml @@ -20,7 +20,7 @@ jobs: echo "repo=$(basename ${{ github.repository }})" >> "$GITHUB_OUTPUT" shell: bash - - name: Build docker image + - name: build docker image uses: senzing-factory/github-action-docker-buildx-build@v1 with: image-repository: senzing/${{ steps.repo-basename.outputs.repo }} diff --git a/.github/workflows/go-proxy-pull.yaml b/.github/workflows/go-proxy-pull.yaml index 6873635..7d2bb6e 100644 --- a/.github/workflows/go-proxy-pull.yaml +++ b/.github/workflows/go-proxy-pull.yaml @@ -11,8 +11,9 @@ permissions: jobs: go-proxy-pull: runs-on: ubuntu-latest + steps: - name: pull new module version - uses: andrewslotin/go-proxy-pull-action@v1.1.0 + uses: andrewslotin/go-proxy-pull-action@v1.2.0 with: import_path: github.com/${{ github.repository }} diff --git a/.github/workflows/go-test-darwin.yaml.disabled b/.github/workflows/go-test-darwin.yaml.disabled index eca6b01..bc803b3 100644 --- a/.github/workflows/go-test-darwin.yaml.disabled +++ b/.github/workflows/go-test-darwin.yaml.disabled @@ -1,6 +1,6 @@ name: go test darwin -on: [push] +on: [pull_request, workflow_dispatch] env: DYLD_LIBRARY_PATH: /opt/senzing/g2/lib:/opt/senzing/g2/lib/macos @@ -18,7 +18,7 @@ jobs: strategy: matrix: go: ["1.21"] - os: [macos-latest] + os: [macos-13] senzingapi-version: [staging-v4] steps: @@ -32,8 +32,13 @@ jobs: with: go-version: ${{ matrix.go }} + - name: Set up gotestfmt + uses: gotesttools/gotestfmt-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: install Senzing API - uses: Senzing/github-action-install-senzing-api@v3 + uses: senzing-factory/github-action-install-senzing-api@v3 with: senzingapi-version: ${{ matrix.senzingapi-version }} @@ -44,4 +49,25 @@ jobs: run: mkdir /tmp/sqlite && cp testdata/sqlite/G2C.db /tmp/sqlite/G2C.db - name: run go test - run: go test -exec /Users/runner/work/demo-quickstart/demo-quickstart/bin/macos_exec_dyld.sh -v -p 1 ./... + run: go test -exec /Users/runner/work/demo-quickstart/demo-quickstart/bin/macos_exec_dyld.sh -json -v -p 1 -coverprofile=./cover.out -covermode=atomic -coverpkg=./... ./... 2>&1 | tee /tmp/gotest.log | gotestfmt + + - name: Store coverage file + uses: actions/upload-artifact@v4 + with: + name: cover.out + path: ./cover.out + + - name: Upload test log + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-log + path: /tmp/gotest.log + if-no-files-found: error + + coverage: + name: coverage + needs: go-test-darwin + uses: senzing-factory/build-resources/.github/workflows/go-coverage.yaml@v2 + with: + coverage-config: ./.github/coverage/testcoverage.yaml diff --git a/.github/workflows/go-test-linux.yaml b/.github/workflows/go-test-linux.yaml index 1e02b7d..f340636 100644 --- a/.github/workflows/go-test-linux.yaml +++ b/.github/workflows/go-test-linux.yaml @@ -30,8 +30,13 @@ jobs: with: go-version: ${{ matrix.go }} + - name: Set up gotestfmt + uses: gotesttools/gotestfmt-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: install Senzing API - uses: Senzing/github-action-install-senzing-api@v3 + uses: senzing-factory/github-action-install-senzing-api@v3 with: senzingapi-runtime-version: ${{ matrix.senzingapi-version }} @@ -42,4 +47,25 @@ jobs: run: mkdir /tmp/sqlite && cp testdata/sqlite/G2C.db /tmp/sqlite/G2C.db - name: run go test - run: go test -v -p 1 ./... + run: go test -json -v -p 1 -coverprofile=./cover.out -covermode=atomic -coverpkg=./... ./... 2>&1 | tee /tmp/gotest.log | gotestfmt + + - name: Store coverage file + uses: actions/upload-artifact@v4 + with: + name: cover.out + path: ./cover.out + + - name: Upload test log + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-log + path: /tmp/gotest.log + if-no-files-found: error + + coverage: + name: coverage + needs: go-test-linux + uses: senzing-factory/build-resources/.github/workflows/go-coverage.yaml@v2 + with: + coverage-config: ./.github/coverage/testcoverage.yaml diff --git a/.github/workflows/go-test-windows.yaml b/.github/workflows/go-test-windows.yaml index d9492ea..33382f6 100644 --- a/.github/workflows/go-test-windows.yaml +++ b/.github/workflows/go-test-windows.yaml @@ -1,13 +1,13 @@ name: go test windows -on: [push] +on: [pull_request, workflow_dispatch] + +env: + SENZING_TOOLS_DATABASE_URL: "sqlite3://na:na@nowhere/C:\\Temp\\sqlite\\G2C.db" permissions: contents: read -env: - SENZING_TOOLS_DATABASE_URL: 'sqlite3://na:na@nowhere/C:\Temp\sqlite\G2C.db' - jobs: go-test-windows: name: "go test with Senzing: ${{ matrix.senzingapi-version }}; OS: ${{ matrix.os }}; Go: ${{ matrix.go }}" @@ -29,8 +29,13 @@ jobs: with: go-version: ${{ matrix.go }} + - name: Set up gotestfmt + uses: gotesttools/gotestfmt-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: install Senzing API - uses: Senzing/github-action-install-senzing-api@v3 + uses: senzing-factory/github-action-install-senzing-api@v3 with: senzingapi-version: ${{ matrix.senzingapi-version }} @@ -44,4 +49,27 @@ jobs: run: mkdir "C:\Temp\sqlite" && copy testdata/sqlite/G2C.db "C:\Temp\sqlite\G2C.db" - name: run go test - run: go test -v -p 1 ./... + run: | + go test -json -v -p 1 -coverprofile=cover -covermode=atomic -coverpkg=./... ./... 2>&1 | tee "C:\Temp\gotest.log" | gotestfmt + cp cover cover.out + + - name: Store coverage file + uses: actions/upload-artifact@v4 + with: + name: cover.out + path: cover.out + + - name: Upload test log + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-log + path: "C:\\Temp\\gotest.log" + if-no-files-found: error + + coverage: + name: coverage + needs: go-test-windows + uses: senzing-factory/build-resources/.github/workflows/go-coverage.yaml@v2 + with: + coverage-config: ./.github/coverage/testcoverage.yaml diff --git a/.github/workflows/gofmt.yaml b/.github/workflows/gofmt.yaml deleted file mode 100644 index 54b4e5a..0000000 --- a/.github/workflows/gofmt.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: gofmt - -on: - pull_request: - branches: [main] - -permissions: - contents: read - -jobs: - gofmt: - uses: senzing-factory/build-resources/.github/workflows/gofmt.yaml@v2 diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml new file mode 100644 index 0000000..2e701ef --- /dev/null +++ b/.github/workflows/golangci-lint.yaml @@ -0,0 +1,59 @@ +name: golangci-lint + +on: + push: + branches-ignore: [main] + pull_request: + branches: [main] + +permissions: + # Required: allow read access to the content for analysis. + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + pull-requests: read + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + + steps: + - name: checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install Senzing API + uses: senzing-factory/github-action-install-senzing-api@v3 + with: + senzingapi-runtime-version: staging-v4 + + - name: Copy Senzing headers + run: | + mkdir --parents ./szconfig/gohelpers + cp /opt/senzing/g2/sdk/c/*.h ./szconfig/ + cp /opt/senzing/g2/sdk/c/gohelpers/*.h ./szconfig/gohelpers + mkdir --parents ./szconfigmanager/gohelpers + cp /opt/senzing/g2/sdk/c/*.h ./szconfigmanager/ + cp /opt/senzing/g2/sdk/c/gohelpers/*.h ./szconfigmanager/gohelpers + mkdir --parents ./szdiagnostic/gohelpers + cp /opt/senzing/g2/sdk/c/*.h ./szdiagnostic/ + cp /opt/senzing/g2/sdk/c/gohelpers/*.h ./szdiagnostic/gohelpers + mkdir --parents ./szengine/gohelpers + cp /opt/senzing/g2/sdk/c/*.h ./szengine/ + cp /opt/senzing/g2/sdk/c/gohelpers/*.h ./szengine/gohelpers + mkdir --parents ./szproduct/gohelpers + cp /opt/senzing/g2/sdk/c/*.h ./szproduct/ + cp /opt/senzing/g2/sdk/c/gohelpers/*.h ./szproduct/gohelpers + + - name: setup go + uses: actions/setup-go@v5 + with: + go-version: 1.21 + + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + args: --config=${{ github.workspace }}/.github/linters/.golangci.yml + only-new-issues: false + version: latest diff --git a/.github/workflows/gosec.yaml b/.github/workflows/gosec.yaml deleted file mode 100644 index a71c492..0000000 --- a/.github/workflows/gosec.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: gosec - -on: - push: - branches: - - main - pull_request: - branches: - - main - -permissions: - contents: read - -jobs: - gosec: - runs-on: ubuntu-latest - env: - GO111MODULE: on - - steps: - - name: checkout repository - uses: actions/checkout@v4 - - - name: run Gosec Security Scanner - uses: securego/gosec@v2.20.0 - with: - args: ./... diff --git a/.github/workflows/make-go-github-file.yaml b/.github/workflows/make-go-github-file.yaml index 704e007..6aadd14 100644 --- a/.github/workflows/make-go-github-file.yaml +++ b/.github/workflows/make-go-github-file.yaml @@ -11,8 +11,8 @@ permissions: jobs: make-go-github-file: - uses: senzing-factory/build-resources/.github/workflows/make-go-github-file.yaml@v2 secrets: SENZING_GITHUB_ACTOR: ${{ secrets.SENZING_GITHUB_ACTOR }} SENZING_GITHUB_GPG_PASSPHRASE: ${{ secrets.SENZING_GITHUB_GPG_PASSPHRASE }} SENZING_GITHUB_GPG_PRIVATE_KEY: ${{ secrets.SENZING_GITHUB_GPG_PRIVATE_KEY }} + uses: senzing-factory/build-resources/.github/workflows/make-go-github-file.yaml@v2 diff --git a/Dockerfile b/Dockerfile index c6a838a..a2977c1 100755 --- a/Dockerfile +++ b/Dockerfile @@ -18,8 +18,8 @@ FROM ${IMAGE_FINAL} as senzingapi_runtime FROM ${IMAGE_GO_BUILDER} as go_builder ENV REFRESHED_AT=2024-02-07 LABEL Name="senzing/demo-quickstart-builder" \ - Maintainer="support@senzing.com" \ - Version="0.0.4" + Maintainer="support@senzing.com" \ + Version="0.0.4" # Copy local files from the Git repository. @@ -43,7 +43,7 @@ RUN make build # Copy binaries to /output. RUN mkdir -p /output \ - && cp -R ${GOPATH}/src/demo-quickstart/target/* /output/ + && cp -R ${GOPATH}/src/demo-quickstart/target/* /output/ # ----------------------------------------------------------------------------- # Stage: final @@ -52,8 +52,8 @@ RUN mkdir -p /output \ FROM ${IMAGE_FINAL} as final ENV REFRESHED_AT=2024-02-07 LABEL Name="senzing/demo-quickstart" \ - Maintainer="support@senzing.com" \ - Version="0.0.1" + Maintainer="support@senzing.com" \ + Version="0.0.1" # Copy local files from the Git repository. @@ -66,31 +66,31 @@ COPY --from=go_builder "/output/linux/demo-quickstart" "/app/demo-quickstart" # Install packages via apt-get. RUN export STAT_TMP=$(stat --format=%a /tmp) \ - && chmod 777 /tmp \ - && apt-get update \ - && apt-get -y install \ - gnupg2 \ - jq \ - libodbc1 \ - postgresql-client \ - supervisor \ - unixodbc \ - && chmod ${STAT_TMP} /tmp \ - && rm -rf /var/lib/apt/lists/* + && chmod 777 /tmp \ + && apt-get update \ + && apt-get -y install \ + gnupg2 \ + jq \ + libodbc1 \ + postgresql-client \ + supervisor \ + unixodbc \ + && chmod ${STAT_TMP} /tmp \ + && rm -rf /var/lib/apt/lists/* # Install Java-11. RUN mkdir -p /etc/apt/keyrings \ - && wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public > /etc/apt/keyrings/adoptium.asc + && wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public > /etc/apt/keyrings/adoptium.asc RUN echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" >> /etc/apt/sources.list RUN export STAT_TMP=$(stat --format=%a /tmp) \ - && chmod 777 /tmp \ - && apt-get update \ - && apt-get -y install temurin-11-jdk \ - && chmod ${STAT_TMP} /tmp \ - && rm -rf /var/lib/apt/lists/* + && chmod 777 /tmp \ + && apt-get update \ + && apt-get -y install temurin-11-jdk \ + && chmod ${STAT_TMP} /tmp \ + && rm -rf /var/lib/apt/lists/* HEALTHCHECK CMD ["/app/healthcheck.sh"] diff --git a/Makefile b/Makefile index b74da1c..a289b02 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,9 @@ GO_ARCH = $(word 2, $(GO_OSARCH)) # Conditional assignment. ('?=') # Can be overridden with "export" -# Example: "export LD_LIBRARY_PATH=/path/to/my/senzing/g2/lib" +# Example: "export LD_LIBRARY_PATH=/path/to/my/senzing-garage/g2/lib" + +GOBIN ?= $(shell go env GOPATH)/bin # Export environment variables. @@ -61,6 +63,13 @@ hello-world: hello-world-osarch-specific # Dependency management # ----------------------------------------------------------------------------- +.PHONY: make-dependencies +make-dependencies: + @go install github.com/gotesttools/gotestfmt/v2/cmd/gotestfmt@latest + @go install github.com/vladopajic/go-test-coverage/v2@latest + @curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.58.1 + + .PHONY: dependencies dependencies: @go get -u ./... @@ -95,6 +104,28 @@ docker-build: .PHONY: test test: test-osarch-specific +# ----------------------------------------------------------------------------- +# Coverage +# ----------------------------------------------------------------------------- + +.PHONY: coverage +coverage: coverage-osarch-specific + + +.PHONY: check-coverage +check-coverage: export SENZING_LOG_LEVEL=TRACE +check-coverage: + go test ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./... + ${GOBIN}/go-test-coverage --config=./.testcoverage.yml + +# ----------------------------------------------------------------------------- +# Lint +# ----------------------------------------------------------------------------- + +.PHONY: run-golangci-lint +run-golangci-lint: + ${GOBIN}/golangci-lint run --config=.github/linters/.golangci.yml + # ----------------------------------------------------------------------------- # Run # ----------------------------------------------------------------------------- diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index a84532e..a96d8c1 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -7,5 +7,6 @@ import ( /* * The unit tests in this file simulate command line invocation. */ -func TestMain(testing *testing.T) { +func TestMain(test *testing.T) { + _ = test } diff --git a/cmd/completion.go b/cmd/completion.go index f3ba690..2884b1f 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -20,6 +20,8 @@ To load completions automaticallon on login, add this line to your .bashrc file: source < (demo-quickstart completion) `, RunE: func(cmd *cobra.Command, args []string) error { + _ = cmd + _ = args return completionAction(os.Stdout) }, } diff --git a/cmd/context_darwin.go b/cmd/context_darwin.go index a2f244b..1b86bff 100644 --- a/cmd/context_darwin.go +++ b/cmd/context_darwin.go @@ -11,4 +11,4 @@ var ContextVariablesForOsArch = []option.ContextVariable{ option.SupportPath, } -const SENZING_TOOLS_DATABASE_URL = "sqlite3://na:na@/tmp/sqlite/G2C.db" +const SenzingToolsDatabaseURL = "sqlite3://na:na@/tmp/sqlite/G2C.db" diff --git a/cmd/context_linux.go b/cmd/context_linux.go index 12b8b6c..c18be82 100644 --- a/cmd/context_linux.go +++ b/cmd/context_linux.go @@ -6,4 +6,4 @@ import "github.com/senzing-garage/go-cmdhelping/option" var ContextVariablesForOsArch = []option.ContextVariable{} -const SENZING_TOOLS_DATABASE_URL = "sqlite3://na:na@/tmp/sqlite/G2C.db" +const SenzingToolsDatabaseURL = "sqlite3://na:na@/tmp/sqlite/G2C.db" diff --git a/cmd/context_windows.go b/cmd/context_windows.go index d50e61b..e73bd26 100644 --- a/cmd/context_windows.go +++ b/cmd/context_windows.go @@ -6,4 +6,4 @@ import "github.com/senzing-garage/go-cmdhelping/option" var ContextVariablesForOsArch = []option.ContextVariable{} -const SENZING_TOOLS_DATABASE_URL = "" +const SenzingToolsDatabaseURL = "" diff --git a/cmd/docs.go b/cmd/docs.go index 51c6184..f203478 100644 --- a/cmd/docs.go +++ b/cmd/docs.go @@ -16,6 +16,7 @@ var docsCmd = &cobra.Command{ Use: "docs", Short: "Generate documentation for the command", RunE: func(cmd *cobra.Command, args []string) error { + _ = args dir, err := cmd.Flags().GetString("dir") if err != nil { return err diff --git a/cmd/github.go b/cmd/github.go index 45a6372..ed8bfbd 100644 --- a/cmd/github.go +++ b/cmd/github.go @@ -5,11 +5,11 @@ package cmd var ( - githubDate string = "2024-05-10" - githubIteration string = "0" - githubRef string = "refs/tags/0.1.1" - githubRefName string = "0.1.1" - githubRepository string = "senzing-garage/demo-quickstart" - githubRepositoryName string = "demo-quickstart" - githubVersion string = "0.1.1" + githubDate = "2024-05-10" + githubIteration = "0" + githubRef = "refs/tags/0.1.1" + githubRefName = "0.1.1" + githubRepository = "senzing-garage/demo-quickstart" + githubRepositoryName = "demo-quickstart" + githubVersion = "0.1.1" ) diff --git a/cmd/root.go b/cmd/root.go index 0866a66..5fbd86f 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -87,9 +87,9 @@ func getOutboundIP() net.IP { func getDefaultAllowedHostnames() []string { result := []string{"localhost"} - outboundIpAddress := getOutboundIP().String() - if len(outboundIpAddress) > 0 { - result = append(result, outboundIpAddress) + outboundIPAddress := getOutboundIP().String() + if len(outboundIPAddress) > 0 { + result = append(result, outboundIPAddress) } return result } @@ -114,14 +114,14 @@ func PreRun(cobraCommand *cobra.Command, args []string) { // Used in construction of cobra.Command func RunE(_ *cobra.Command, _ []string) error { - var err error = nil + var err error ctx := context.Background() // Set default value for SENZING_TOOLS_DATABASE_URL. _, isSet := os.LookupEnv("SENZING_TOOLS_DATABASE_URL") if !isSet { - err = os.Setenv("SENZING_TOOLS_DATABASE_URL", SENZING_TOOLS_DATABASE_URL) + err = os.Setenv("SENZING_TOOLS_DATABASE_URL", SenzingToolsDatabaseURL) if err != nil { return err } @@ -153,29 +153,29 @@ func RunE(_ *cobra.Command, _ []string) error { // Create object and Serve. - httpServer := &httpserver.HttpServerImpl{ - ApiUrlRoutePrefix: "api", - EnableAll: true, - EntitySearchRoutePrefix: "entity-search", - LogLevelName: viper.GetString(option.LogLevel.Arg), - ObserverOrigin: viper.GetString(option.ObserverOrigin.Arg), - Observers: observers, - OpenApiSpecificationRest: senzingrestservice.OpenAPISpecificationJSON, - ReadHeaderTimeout: 60 * time.Second, - SenzingEngineConfigurationJson: senzingSettings, - SenzingModuleName: viper.GetString(option.EngineModuleName.Arg), - SenzingVerboseLogging: viper.GetInt64(option.EngineLogLevel.Arg), - ServerAddress: viper.GetString(option.ServerAddress.Arg), - ServerPort: viper.GetInt(option.HTTPPort.Arg), - SwaggerUrlRoutePrefix: "swagger", - TtyOnly: viper.GetBool(option.TtyOnly.Arg), - XtermAllowedHostnames: viper.GetStringSlice(option.XtermAllowedHostnames.Arg), - XtermArguments: viper.GetStringSlice(option.XtermArguments.Arg), - XtermCommand: viper.GetString(option.XtermCommand.Arg), - XtermConnectionErrorLimit: viper.GetInt(option.XtermConnectionErrorLimit.Arg), - XtermKeepalivePingTimeout: viper.GetInt(option.XtermKeepalivePingTimeout.Arg), - XtermMaxBufferSizeBytes: viper.GetInt(option.XtermMaxBufferSizeBytes.Arg), - XtermUrlRoutePrefix: "xterm", + httpServer := &httpserver.BasicHTTPServer{ + APIUrlRoutePrefix: "api", + EnableAll: true, + EntitySearchRoutePrefix: "entity-search", + LogLevelName: viper.GetString(option.LogLevel.Arg), + ObserverOrigin: viper.GetString(option.ObserverOrigin.Arg), + Observers: observers, + OpenAPISpecificationRest: senzingrestservice.OpenAPISpecificationJSON, + ReadHeaderTimeout: 60 * time.Second, + SenzingSettings: senzingSettings, + SenzingModuleName: viper.GetString(option.EngineModuleName.Arg), + SenzingVerboseLogging: viper.GetInt64(option.EngineLogLevel.Arg), + ServerAddress: viper.GetString(option.ServerAddress.Arg), + ServerPort: viper.GetInt(option.HTTPPort.Arg), + SwaggerURLRoutePrefix: "swagger", + TtyOnly: viper.GetBool(option.TtyOnly.Arg), + XtermAllowedHostnames: viper.GetStringSlice(option.XtermAllowedHostnames.Arg), + XtermArguments: viper.GetStringSlice(option.XtermArguments.Arg), + XtermCommand: viper.GetString(option.XtermCommand.Arg), + XtermConnectionErrorLimit: viper.GetInt(option.XtermConnectionErrorLimit.Arg), + XtermKeepalivePingTimeout: viper.GetInt(option.XtermKeepalivePingTimeout.Arg), + XtermMaxBufferSizeBytes: viper.GetInt(option.XtermMaxBufferSizeBytes.Arg), + XtermURLRoutePrefix: "xterm", } // Start servers. diff --git a/httpserver/httpserver.go b/httpserver/httpserver_basic.go similarity index 69% rename from httpserver/httpserver.go rename to httpserver/httpserver_basic.go index 8646062..6d5a51d 100644 --- a/httpserver/httpserver.go +++ b/httpserver/httpserver_basic.go @@ -26,51 +26,51 @@ import ( // Types // ---------------------------------------------------------------------------- -// HttpServerImpl is the default implementation of the HttpServer interface. -type HttpServerImpl struct { - ApiUrlRoutePrefix string // FIXME: Only works with "api" - EnableAll bool - EnableEntitySearch bool - EnableSenzingRestAPI bool - EnableSwaggerUI bool - EnableXterm bool - EntitySearchRoutePrefix string // FIXME: Only works with "entity-search" - GrpcDialOptions []grpc.DialOption - GrpcTarget string - LogLevelName string - ObserverOrigin string - Observers []observer.Observer - OpenApiSpecificationRest []byte - ReadHeaderTimeout time.Duration - SenzingEngineConfigurationJson string - SenzingModuleName string - SenzingVerboseLogging int64 - ServerAddress string - ServerOptions []senzingrestapi.ServerOption - ServerPort int - SwaggerUrlRoutePrefix string // FIXME: Only works with "swagger" - TtyOnly bool - XtermAllowedHostnames []string - XtermArguments []string - XtermCommand string - XtermConnectionErrorLimit int - XtermKeepalivePingTimeout int - XtermMaxBufferSizeBytes int - XtermUrlRoutePrefix string // FIXME: Only works with "xterm" +// BasicHTTPServer is the default implementation of the HttpServer interface. +type BasicHTTPServer struct { + APIUrlRoutePrefix string // FIXME: Only works with "api" + EnableAll bool + EnableEntitySearch bool + EnableSenzingRestAPI bool + EnableSwaggerUI bool + EnableXterm bool + EntitySearchRoutePrefix string // FIXME: Only works with "entity-search" + GrpcDialOptions []grpc.DialOption + GrpcTarget string + LogLevelName string + ObserverOrigin string + Observers []observer.Observer + OpenAPISpecificationRest []byte + ReadHeaderTimeout time.Duration + SenzingModuleName string + SenzingSettings string + SenzingVerboseLogging int64 + ServerAddress string + ServerOptions []senzingrestapi.ServerOption + ServerPort int + SwaggerURLRoutePrefix string // FIXME: Only works with "swagger" + TtyOnly bool + XtermAllowedHostnames []string + XtermArguments []string + XtermCommand string + XtermConnectionErrorLimit int + XtermKeepalivePingTimeout int + XtermMaxBufferSizeBytes int + XtermURLRoutePrefix string // FIXME: Only works with "xterm" } type TemplateVariables struct { - HttpServerImpl - ApiServerStatus string - ApiServerUrl string + BasicHTTPServer + APIServerStatus string + APIServerURL string EntitySearchStatus string - EntitySearchUrl string - HtmlTitle string + EntitySearchURL string + HTMLTitle string RequestHost string SwaggerStatus string - SwaggerUrl string + SwaggerURL string XtermStatus string - XtermUrl string + XtermURL string } // ---------------------------------------------------------------------------- @@ -84,7 +84,7 @@ var static embed.FS // Internal methods // ---------------------------------------------------------------------------- -func (httpServer *HttpServerImpl) getServerStatus(up bool) string { +func (httpServer *BasicHTTPServer) getServerStatus(up bool) string { result := "red" if httpServer.EnableAll { result = "green" @@ -95,7 +95,7 @@ func (httpServer *HttpServerImpl) getServerStatus(up bool) string { return result } -func (httpServer *HttpServerImpl) getServerUrl(up bool, url string) string { +func (httpServer *BasicHTTPServer) getServerURL(up bool, url string) string { result := "" if httpServer.EnableAll { result = url @@ -106,18 +106,20 @@ func (httpServer *HttpServerImpl) getServerUrl(up bool, url string) string { return result } -func (httpServer *HttpServerImpl) openApiFunc(ctx context.Context, openApiSpecification []byte) http.HandlerFunc { +func (httpServer *BasicHTTPServer) openAPIFunc(ctx context.Context, openAPISpecification []byte) http.HandlerFunc { + _ = ctx + _ = openAPISpecification return func(w http.ResponseWriter, r *http.Request) { var bytesBuffer bytes.Buffer bufioWriter := bufio.NewWriter(&bytesBuffer) - openApiSpecificationTemplate, err := template.New("OpenApiTemplate").Parse(string(httpServer.OpenApiSpecificationRest)) + openAPISpecificationTemplate, err := template.New("OpenApiTemplate").Parse(string(httpServer.OpenAPISpecificationRest)) if err != nil { panic(err) } templateVariables := TemplateVariables{ RequestHost: r.Host, } - err = openApiSpecificationTemplate.Execute(bufioWriter, templateVariables) + err = openAPISpecificationTemplate.Execute(bufioWriter, templateVariables) if err != nil { panic(err) } @@ -127,7 +129,8 @@ func (httpServer *HttpServerImpl) openApiFunc(ctx context.Context, openApiSpecif } } } -func (httpServer *HttpServerImpl) populateStaticTemplate(responseWriter http.ResponseWriter, request *http.Request, filepath string, templateVariables TemplateVariables) { +func (httpServer *BasicHTTPServer) populateStaticTemplate(responseWriter http.ResponseWriter, request *http.Request, filepath string, templateVariables TemplateVariables) { + _ = request templateBytes, err := static.ReadFile(filepath) if err != nil { http.Error(responseWriter, http.StatusText(500), 500) @@ -179,7 +182,7 @@ func (httpServer *HttpServerImpl) populateStaticTemplate(responseWriter http.Res // --- http.ServeMux ---------------------------------------------------------- -func (httpServer *HttpServerImpl) getSenzingRestApiMux(ctx context.Context) *http.ServeMux { +func (httpServer *BasicHTTPServer) getSenzingRestAPIMux(ctx context.Context) *http.ServeMux { service := &restapiservicelegacy.RestApiServiceLegacyImpl{ JarFile: "/app/senzing-poc-server.jar", ProxyTemplate: "http://localhost:8250%s", @@ -188,7 +191,7 @@ func (httpServer *HttpServerImpl) getSenzingRestApiMux(ctx context.Context) *htt return service.Handler(ctx) } -func (httpServer *HttpServerImpl) getSenzingRestApiProxyMux(ctx context.Context) *http.ServeMux { +func (httpServer *BasicHTTPServer) getSenzingRestAPIProxyMux(ctx context.Context) *http.ServeMux { service := &restapiservicelegacy.RestApiServiceLegacyImpl{ JarFile: "/app/senzing-poc-server.jar", ProxyTemplate: "http://localhost:8250%s", @@ -197,21 +200,21 @@ func (httpServer *HttpServerImpl) getSenzingRestApiProxyMux(ctx context.Context) return service.Handler(ctx) } -func (httpServer *HttpServerImpl) getEntitySearchMux(ctx context.Context) *http.ServeMux { +func (httpServer *BasicHTTPServer) getEntitySearchMux(ctx context.Context) *http.ServeMux { service := &entitysearchservice.BasicHTTPService{} return service.Handler(ctx) } -func (httpServer *HttpServerImpl) getSwaggerUiMux(ctx context.Context) *http.ServeMux { +func (httpServer *BasicHTTPServer) getSwaggerUIMux(ctx context.Context) *http.ServeMux { swaggerMux := swaggerui.Handler([]byte{}) // OpenAPI specification handled by openApiFunc() swaggerFunc := swaggerMux.ServeHTTP submux := http.NewServeMux() submux.HandleFunc("/", swaggerFunc) - submux.HandleFunc("/swagger_spec", httpServer.openApiFunc(ctx, httpServer.OpenApiSpecificationRest)) + submux.HandleFunc("/swagger_spec", httpServer.openAPIFunc(ctx, httpServer.OpenAPISpecificationRest)) return submux } -func (httpServer *HttpServerImpl) getXtermMux(ctx context.Context) *http.ServeMux { +func (httpServer *BasicHTTPServer) getXtermMux(ctx context.Context) *http.ServeMux { xtermService := &xtermservice.XtermServiceImpl{ AllowedHostnames: httpServer.XtermAllowedHostnames, Arguments: httpServer.XtermArguments, @@ -219,25 +222,25 @@ func (httpServer *HttpServerImpl) getXtermMux(ctx context.Context) *http.ServeMu ConnectionErrorLimit: httpServer.XtermConnectionErrorLimit, KeepalivePingTimeout: httpServer.XtermKeepalivePingTimeout, MaxBufferSizeBytes: httpServer.XtermMaxBufferSizeBytes, - UrlRoutePrefix: httpServer.XtermUrlRoutePrefix, + UrlRoutePrefix: httpServer.XtermURLRoutePrefix, } return xtermService.Handler(ctx) } // --- Http Funcs ------------------------------------------------------------- -func (httpServer *HttpServerImpl) siteFunc(w http.ResponseWriter, r *http.Request) { +func (httpServer *BasicHTTPServer) siteFunc(w http.ResponseWriter, r *http.Request) { templateVariables := TemplateVariables{ - HttpServerImpl: *httpServer, - HtmlTitle: "Senzing Tools", - ApiServerStatus: httpServer.getServerStatus(httpServer.EnableSenzingRestAPI), - ApiServerUrl: httpServer.getServerUrl(httpServer.EnableSenzingRestAPI, fmt.Sprintf("http://%s/api", r.Host)), + BasicHTTPServer: *httpServer, + HTMLTitle: "Senzing Tools", + APIServerStatus: httpServer.getServerStatus(httpServer.EnableSenzingRestAPI), + APIServerURL: httpServer.getServerURL(httpServer.EnableSenzingRestAPI, fmt.Sprintf("http://%s/api", r.Host)), EntitySearchStatus: httpServer.getServerStatus(httpServer.EnableEntitySearch), - EntitySearchUrl: httpServer.getServerUrl(httpServer.EnableEntitySearch, fmt.Sprintf("http://%s/entity-search", r.Host)), + EntitySearchURL: httpServer.getServerURL(httpServer.EnableEntitySearch, fmt.Sprintf("http://%s/entity-search", r.Host)), SwaggerStatus: httpServer.getServerStatus(httpServer.EnableSwaggerUI), - SwaggerUrl: httpServer.getServerUrl(httpServer.EnableSwaggerUI, fmt.Sprintf("http://%s/swagger", r.Host)), + SwaggerURL: httpServer.getServerURL(httpServer.EnableSwaggerUI, fmt.Sprintf("http://%s/swagger", r.Host)), XtermStatus: httpServer.getServerStatus(httpServer.EnableXterm), - XtermUrl: httpServer.getServerUrl(httpServer.EnableXterm, fmt.Sprintf("http://%s/xterm", r.Host)), + XtermURL: httpServer.getServerURL(httpServer.EnableXterm, fmt.Sprintf("http://%s/xterm", r.Host)), } w.Header().Set("Content-Type", "text/html") filePath := fmt.Sprintf("static/templates%s", r.RequestURI) @@ -259,23 +262,23 @@ Output See the example output. */ -func (httpServer *HttpServerImpl) Serve(ctx context.Context) error { +func (httpServer *BasicHTTPServer) Serve(ctx context.Context) error { rootMux := http.NewServeMux() - var userMessage string = "" + var userMessage string // Enable Senzing HTTP REST API. if httpServer.EnableAll || httpServer.EnableSenzingRestAPI { - senzingApiMux := httpServer.getSenzingRestApiMux(ctx) - rootMux.Handle(fmt.Sprintf("/%s/", httpServer.ApiUrlRoutePrefix), http.StripPrefix("/api", senzingApiMux)) - userMessage = fmt.Sprintf("%sServing Senzing REST API at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.ApiUrlRoutePrefix) + senzingAPIMux := httpServer.getSenzingRestAPIMux(ctx) + rootMux.Handle(fmt.Sprintf("/%s/", httpServer.APIUrlRoutePrefix), http.StripPrefix("/api", senzingAPIMux)) + userMessage = fmt.Sprintf("%sServing Senzing REST API at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.APIUrlRoutePrefix) } // Enable Senzing HTTP REST API as reverse proxy. if httpServer.EnableAll || httpServer.EnableSenzingRestAPI || httpServer.EnableEntitySearch { - senzingApiProxyMux := httpServer.getSenzingRestApiProxyMux(ctx) - rootMux.Handle("/entity-search/api/", http.StripPrefix("/entity-search/api", senzingApiProxyMux)) + senzingAPIProxyMux := httpServer.getSenzingRestAPIProxyMux(ctx) + rootMux.Handle("/entity-search/api/", http.StripPrefix("/entity-search/api", senzingAPIProxyMux)) userMessage = fmt.Sprintf("%sServing Senzing REST API Reverse Proxy at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, "entity-search/api") } @@ -290,21 +293,21 @@ func (httpServer *HttpServerImpl) Serve(ctx context.Context) error { // Enable SwaggerUI. if httpServer.EnableAll || httpServer.EnableSwaggerUI { - swaggerUiMux := httpServer.getSwaggerUiMux(ctx) - rootMux.Handle(fmt.Sprintf("/%s/", httpServer.SwaggerUrlRoutePrefix), http.StripPrefix("/swagger", swaggerUiMux)) - userMessage = fmt.Sprintf("%sServing SwaggerUI at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.SwaggerUrlRoutePrefix) + swaggerUIMux := httpServer.getSwaggerUIMux(ctx) + rootMux.Handle(fmt.Sprintf("/%s/", httpServer.SwaggerURLRoutePrefix), http.StripPrefix("/swagger", swaggerUIMux)) + userMessage = fmt.Sprintf("%sServing SwaggerUI at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.SwaggerURLRoutePrefix) } // Enable Xterm. if httpServer.EnableAll || httpServer.EnableXterm { - err := os.Setenv("SENZING_ENGINE_CONFIGURATION_JSON", httpServer.SenzingEngineConfigurationJson) + err := os.Setenv("SENZING_ENGINE_CONFIGURATION_JSON", httpServer.SenzingSettings) if err != nil { panic(err) } xtermMux := httpServer.getXtermMux(ctx) - rootMux.Handle(fmt.Sprintf("/%s/", httpServer.XtermUrlRoutePrefix), http.StripPrefix("/xterm", xtermMux)) - userMessage = fmt.Sprintf("%sServing XTerm at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.XtermUrlRoutePrefix) + rootMux.Handle(fmt.Sprintf("/%s/", httpServer.XtermURLRoutePrefix), http.StripPrefix("/xterm", xtermMux)) + userMessage = fmt.Sprintf("%sServing XTerm at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.XtermURLRoutePrefix) } // Add route to template pages. diff --git a/httpserver/httpserver_examples_test.go b/httpserver/httpserver_examples_test.go new file mode 100644 index 0000000..7b1b3f8 --- /dev/null +++ b/httpserver/httpserver_examples_test.go @@ -0,0 +1,9 @@ +package httpserver + +// ---------------------------------------------------------------------------- +// Examples for godoc documentation +// ---------------------------------------------------------------------------- + +func ExampleBasicHTTPServer_Serve() { + +} diff --git a/httpserver/httpserver_test.go b/httpserver/httpserver_test.go index 075bb19..802284a 100644 --- a/httpserver/httpserver_test.go +++ b/httpserver/httpserver_test.go @@ -1,51 +1,14 @@ package httpserver import ( - "fmt" - "os" "testing" ) -// ---------------------------------------------------------------------------- -// Test harness -// ---------------------------------------------------------------------------- - -func TestMain(m *testing.M) { - err := setup() - if err != nil { - fmt.Print(err) - os.Exit(1) - } - code := m.Run() - err = teardown() - if err != nil { - fmt.Print(err) - } - os.Exit(code) -} - -func setup() error { - var err error = nil - return err -} - -func teardown() error { - var err error = nil - return err -} - // ---------------------------------------------------------------------------- // Test interface functions // ---------------------------------------------------------------------------- -func TestHttpServerImpl_Serve(test *testing.T) { - -} - -// ---------------------------------------------------------------------------- -// Examples for godoc documentation -// ---------------------------------------------------------------------------- - -func ExampleHttpServerImpl_Serve() { +func TestBasicHTTPServer_Serve(test *testing.T) { + _ = test } diff --git a/httpserver/main.go b/httpserver/main.go index fad90cf..6191a53 100644 --- a/httpserver/main.go +++ b/httpserver/main.go @@ -8,7 +8,7 @@ import ( // Types // ---------------------------------------------------------------------------- -// The HttpServer interface... -type HttpServer interface { +// The HTTPServer interface... +type HTTPServer interface { Serve(ctx context.Context) error } diff --git a/main_test.go b/main_test.go index 462ec78..8081925 100644 --- a/main_test.go +++ b/main_test.go @@ -1,10 +1,15 @@ package main import ( + "os" "testing" ) /* * The unit tests in this file simulate command line invocation. */ -func TestMain(testing *testing.T) {} +func TestMain(test *testing.T) { + _ = test + os.Args = []string{"command-name", "--help"} + main() +} diff --git a/makefiles/darwin.mk b/makefiles/darwin.mk index 116a4be..19a7838 100644 --- a/makefiles/darwin.mk +++ b/makefiles/darwin.mk @@ -17,13 +17,22 @@ SENZING_TOOLS_DATABASE_URL ?= sqlite3://na:na@/tmp/sqlite/G2C.db .PHONY: clean-osarch-specific clean-osarch-specific: - @docker rm --force $(DOCKER_CONTAINER_NAME) 2> /dev/null || true + @docker rm --force $(DOCKER_CONTAINER_NAME) 2> /dev/null || true @docker rmi --force $(DOCKER_IMAGE_NAME) $(DOCKER_BUILD_IMAGE_NAME) 2> /dev/null || true - @rm -rf $(TARGET_DIRECTORY) || true - @rm -f $(GOPATH)/bin/$(PROGRAM_NAME) || true + @rm -f $(GOPATH)/bin/$(PROGRAM_NAME) || true + @rm -f $(MAKEFILE_DIRECTORY)/coverage.html || true + @rm -f $(MAKEFILE_DIRECTORY)/coverage.out || true + @rm -fr $(TARGET_DIRECTORY) || true @rm -rf /tmp/sqlite || true +.PHONY: coverage-osarch-specific +coverage-osarch-specific: + @go test -v -coverprofile=coverage.out -p 1 ./... + @go tool cover -html="coverage.out" -o coverage.html + @open file://$(MAKEFILE_DIRECTORY)/coverage.html + + .PHONY: hello-world-osarch-specific hello-world-osarch-specific: @echo "Hello World, from darwin." diff --git a/makefiles/linux.mk b/makefiles/linux.mk index b30538a..47ccb6e 100644 --- a/makefiles/linux.mk +++ b/makefiles/linux.mk @@ -13,11 +13,21 @@ SENZING_TOOLS_DATABASE_URL ?= sqlite3://na:na@/tmp/sqlite/G2C.db .PHONY: clean-osarch-specific clean-osarch-specific: - @docker rm --force $(DOCKER_CONTAINER_NAME) 2> /dev/null || true + @docker rm --force $(DOCKER_CONTAINER_NAME) 2> /dev/null || true @docker rmi --force $(DOCKER_IMAGE_NAME) $(DOCKER_BUILD_IMAGE_NAME) 2> /dev/null || true - @rm -rf $(TARGET_DIRECTORY) || true - @rm -f $(GOPATH)/bin/$(PROGRAM_NAME) || true - @rm -rf /tmp/sqlite || true + @rm -f $(GOPATH)/bin/$(PROGRAM_NAME) || true + @rm -f $(MAKEFILE_DIRECTORY)/coverage.html || true + @rm -f $(MAKEFILE_DIRECTORY)/coverage.out || true + @rm -fr $(TARGET_DIRECTORY) || true + @rm -fr /tmp/sqlite || true + + +.PHONY: coverage-osarch-specific +coverage-osarch-specific: export SENZING_LOG_LEVEL=TRACE +coverage-osarch-specific: + @go test -v -coverprofile=coverage.out -p 1 ./... + @go tool cover -html="coverage.out" -o coverage.html + @xdg-open $(MAKEFILE_DIRECTORY)/coverage.html .PHONY: hello-world-osarch-specific @@ -47,7 +57,7 @@ setup-osarch-specific: .PHONY: test-osarch-specific test-osarch-specific: - @go test -v -p 1 ./... + @go test -json -v -p 1 ./... 2>&1 | tee /tmp/gotest.log | gotestfmt # ----------------------------------------------------------------------------- # Makefile targets supported only by this platform. diff --git a/makefiles/windows.mk b/makefiles/windows.mk index 268f716..83b6b3b 100644 --- a/makefiles/windows.mk +++ b/makefiles/windows.mk @@ -12,11 +12,20 @@ SENZING_TOOLS_DATABASE_URL ?= sqlite3://na:na@nowhere/C:\Temp\sqlite\G2C.db .PHONY: clean-osarch-specific clean-osarch-specific: - del /F /S /Q $(TARGET_DIRECTORY) del /F /S /Q $(GOPATH)/bin/$(PROGRAM_NAME) + del /F /S /Q $(MAKEFILE_DIRECTORY)/coverage.html + del /F /S /Q $(MAKEFILE_DIRECTORY)/coverage.out + del /F /S /Q $(TARGET_DIRECTORY) del /F /S /Q C:\Temp\sqlite +.PHONY: coverage-osarch-specific +coverage-osarch-specific: + @go test -v -coverprofile=coverage.out -p 1 ./... + @go tool cover -html="coverage.out" -o coverage.html + @xdg-open file://$(MAKEFILE_DIRECTORY)/coverage.html + + .PHONY: hello-world-osarch-specific hello-world-osarch-specific: @echo "Hello World, from windows." @@ -37,7 +46,7 @@ setup-osarch-specific: @mkdir C:\Temp\sqlite @copy testdata\sqlite\G2C.db C:\Temp\sqlite\G2C.db @mkdir $(TARGET_DIRECTORY)\ - @mkdir $(TARGET_DIRECTORY)\$(GO_OS)-$(GO_ARCH) + @mkdir $(TARGET_DIRECTORY)\$(GO_OS)-$(GO_ARCH) .PHONY: test-osarch-specific From ba47bb5254fe005e4fb8aef85d572daae0614ff2 Mon Sep 17 00:00:00 2001 From: docktermj Date: Tue, 9 Jul 2024 10:54:14 -0400 Subject: [PATCH 4/8] #58 Coverage improvements --- .gitignore | 1 + cmd/cmd_test.go | 66 ++++++++++- cmd/root.go | 12 ++ go.mod | 3 + httpserver/httpserver_basic.go | 196 +++++++++++++++++---------------- testdata/sqlite/G2C.db | Bin 245760 -> 315392 bytes 6 files changed, 181 insertions(+), 97 deletions(-) diff --git a/.gitignore b/.gitignore index e0690d9..5032336 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ go.work .history target +coverage.html diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go index a96d8c1..b02d249 100644 --- a/cmd/cmd_test.go +++ b/cmd/cmd_test.go @@ -1,12 +1,76 @@ package cmd import ( + "bytes" + "os" "testing" + + "github.com/stretchr/testify/require" ) +// ---------------------------------------------------------------------------- +// Test public functions +// ---------------------------------------------------------------------------- + /* * The unit tests in this file simulate command line invocation. */ -func TestMain(test *testing.T) { +func Test_Execute(test *testing.T) { + _ = test + os.Args = []string{"command-name", "--avoid-serving", "--tty-only"} + Execute() +} + +func Test_Execute_completion(test *testing.T) { + _ = test + os.Args = []string{"command-name", "completion"} + Execute() +} + +func Test_Execute_docs(test *testing.T) { + _ = test + os.Args = []string{"command-name", "docs"} + Execute() +} + +func Test_Execute_help(test *testing.T) { _ = test + os.Args = []string{"command-name", "--help"} + Execute() +} + +func Test_PreRun(test *testing.T) { + _ = test + args := []string{"command-name", "--help"} + PreRun(RootCmd, args) +} + +func Test_RunE(test *testing.T) { + test.Setenv("SENZING_TOOLS_AVOID_SERVING", "true") + err := RunE(RootCmd, []string{}) + require.NoError(test, err) +} + +func Test_RunE_badGrpcURL(test *testing.T) { + test.Setenv("SENZING_TOOLS_AVOID_SERVING", "true") + test.Setenv("SENZING_TOOLS_GRPC_URL", "grpc://bad") + err := RunE(RootCmd, []string{}) + require.NoError(test, err) +} + +// ---------------------------------------------------------------------------- +// Test private functions +// ---------------------------------------------------------------------------- + +func Test_completionAction(test *testing.T) { + var buffer bytes.Buffer + err := completionAction(&buffer) + require.NoError(test, err) +} + +func Test_docsAction_badDir(test *testing.T) { + var buffer bytes.Buffer + badDir := "/tmp/no/directory/exists" + err := docsAction(&buffer, badDir) + require.Error(test, err) } diff --git a/cmd/root.go b/cmd/root.go index 5fbd86f..6d9b48d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -13,6 +13,7 @@ import ( "github.com/senzing-garage/demo-quickstart/httpserver" "github.com/senzing-garage/go-cmdhelping/cmdhelper" "github.com/senzing-garage/go-cmdhelping/option" + "github.com/senzing-garage/go-cmdhelping/option/optiontype" "github.com/senzing-garage/go-cmdhelping/settings" "github.com/senzing-garage/go-observing/observer" "github.com/senzing-garage/go-rest-api-service/senzingrestservice" @@ -33,11 +34,20 @@ A server supporting the following services: ` ) +var avoidServe = option.ContextVariable{ + Arg: "avoid-serving", + Default: option.OsLookupEnvBool("SENZING_TOOLS_AVOID_SERVING", false), + Envar: "SENZING_TOOLS_AVOID_SERVING", + Help: "Avoid serving. For testing only. [%s]", + Type: optiontype.Bool, +} + // ---------------------------------------------------------------------------- // Context variables // ---------------------------------------------------------------------------- var ContextVariablesForMultiPlatform = []option.ContextVariable{ + avoidServe, option.Configuration, option.DatabaseURL, option.EngineConfigurationJSON, @@ -141,6 +151,7 @@ func RunE(_ *cobra.Command, _ []string) error { // Setup gRPC server grpcserver := &grpcserver.BasicGrpcServer{ + AvoidServing: viper.GetBool(avoidServe.Arg), EnableAll: true, LogLevelName: viper.GetString(option.LogLevel.Arg), ObserverOrigin: viper.GetString(option.ObserverOrigin.Arg), @@ -155,6 +166,7 @@ func RunE(_ *cobra.Command, _ []string) error { httpServer := &httpserver.BasicHTTPServer{ APIUrlRoutePrefix: "api", + AvoidServing: viper.GetBool(avoidServe.Arg), EnableAll: true, EntitySearchRoutePrefix: "entity-search", LogLevelName: viper.GetString(option.LogLevel.Arg), diff --git a/go.mod b/go.mod index 34bc8f0..6460523 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/senzing-garage/serve-grpc v0.7.4 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 + github.com/stretchr/testify v1.9.0 google.golang.org/grpc v1.65.0 ) @@ -24,6 +25,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/creack/pty v1.1.21 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dlclark/regexp2 v1.11.1 // indirect github.com/fatih/color v1.17.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -44,6 +46,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/ogen-go/ogen v1.2.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect diff --git a/httpserver/httpserver_basic.go b/httpserver/httpserver_basic.go index 6d5a51d..89bbd2a 100644 --- a/httpserver/httpserver_basic.go +++ b/httpserver/httpserver_basic.go @@ -29,6 +29,7 @@ import ( // BasicHTTPServer is the default implementation of the HttpServer interface. type BasicHTTPServer struct { APIUrlRoutePrefix string // FIXME: Only works with "api" + AvoidServing bool EnableAll bool EnableEntitySearch bool EnableSenzingRestAPI bool @@ -80,6 +81,105 @@ type TemplateVariables struct { //go:embed static/* var static embed.FS +// ---------------------------------------------------------------------------- +// Interface methods +// ---------------------------------------------------------------------------- + +/* +The Serve method simply prints the 'Something' value in the type-struct. + +Input + - ctx: A context to control lifecycle. + +Output + - Nothing is returned, except for an error. However, something is printed. + See the example output. +*/ + +func (httpServer *BasicHTTPServer) Serve(ctx context.Context) error { + rootMux := http.NewServeMux() + var userMessage string + + // Enable Senzing HTTP REST API. + + if httpServer.EnableAll || httpServer.EnableSenzingRestAPI { + senzingAPIMux := httpServer.getSenzingRestAPIMux(ctx) + rootMux.Handle(fmt.Sprintf("/%s/", httpServer.APIUrlRoutePrefix), http.StripPrefix("/api", senzingAPIMux)) + userMessage = fmt.Sprintf("%sServing Senzing REST API at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.APIUrlRoutePrefix) + } + + // Enable Senzing HTTP REST API as reverse proxy. + + if httpServer.EnableAll || httpServer.EnableSenzingRestAPI || httpServer.EnableEntitySearch { + senzingAPIProxyMux := httpServer.getSenzingRestAPIProxyMux(ctx) + rootMux.Handle("/entity-search/api/", http.StripPrefix("/entity-search/api", senzingAPIProxyMux)) + userMessage = fmt.Sprintf("%sServing Senzing REST API Reverse Proxy at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, "entity-search/api") + } + + // Enable Senzing Entity Search. + + if httpServer.EnableAll || httpServer.EnableEntitySearch { + entitySearchMux := httpServer.getEntitySearchMux(ctx) + rootMux.Handle(fmt.Sprintf("/%s/", httpServer.EntitySearchRoutePrefix), http.StripPrefix("/entity-search", entitySearchMux)) + userMessage = fmt.Sprintf("%sServing Entity Search at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.EntitySearchRoutePrefix) + } + + // Enable SwaggerUI. + + if httpServer.EnableAll || httpServer.EnableSwaggerUI { + swaggerUIMux := httpServer.getSwaggerUIMux(ctx) + rootMux.Handle(fmt.Sprintf("/%s/", httpServer.SwaggerURLRoutePrefix), http.StripPrefix("/swagger", swaggerUIMux)) + userMessage = fmt.Sprintf("%sServing SwaggerUI at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.SwaggerURLRoutePrefix) + } + + // Enable Xterm. + + if httpServer.EnableAll || httpServer.EnableXterm { + err := os.Setenv("SENZING_ENGINE_CONFIGURATION_JSON", httpServer.SenzingSettings) + if err != nil { + panic(err) + } + xtermMux := httpServer.getXtermMux(ctx) + rootMux.Handle(fmt.Sprintf("/%s/", httpServer.XtermURLRoutePrefix), http.StripPrefix("/xterm", xtermMux)) + userMessage = fmt.Sprintf("%sServing XTerm at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.XtermURLRoutePrefix) + } + + // Add route to template pages. + + rootMux.HandleFunc("/site/", httpServer.siteFunc) + userMessage = fmt.Sprintf("%sServing Console at http://localhost:%d\n", userMessage, httpServer.ServerPort) + + // Add route to static files. + + rootDir, err := fs.Sub(static, "static/root") + if err != nil { + panic(err) + } + rootMux.Handle("/", http.StripPrefix("/", http.FileServer(http.FS(rootDir)))) + + // Start service. + + listenOnAddress := fmt.Sprintf("%s:%v", httpServer.ServerAddress, httpServer.ServerPort) + userMessage = fmt.Sprintf("%sStarting server on interface:port '%s'...\n", userMessage, listenOnAddress) + fmt.Println(userMessage) + server := http.Server{ + ReadHeaderTimeout: httpServer.ReadHeaderTimeout, + Addr: listenOnAddress, + Handler: rootMux, + } + + // Start a web browser. Unless disabled. + + if !httpServer.TtyOnly { + _ = browser.OpenURL(fmt.Sprintf("http://localhost:%d", httpServer.ServerPort)) + } + + if !httpServer.AvoidServing { + err = server.ListenAndServe() + } + return err +} + // ---------------------------------------------------------------------------- // Internal methods // ---------------------------------------------------------------------------- @@ -246,99 +346,3 @@ func (httpServer *BasicHTTPServer) siteFunc(w http.ResponseWriter, r *http.Reque filePath := fmt.Sprintf("static/templates%s", r.RequestURI) httpServer.populateStaticTemplate(w, r, filePath, templateVariables) } - -// ---------------------------------------------------------------------------- -// Interface methods -// ---------------------------------------------------------------------------- - -/* -The Serve method simply prints the 'Something' value in the type-struct. - -Input - - ctx: A context to control lifecycle. - -Output - - Nothing is returned, except for an error. However, something is printed. - See the example output. -*/ - -func (httpServer *BasicHTTPServer) Serve(ctx context.Context) error { - rootMux := http.NewServeMux() - var userMessage string - - // Enable Senzing HTTP REST API. - - if httpServer.EnableAll || httpServer.EnableSenzingRestAPI { - senzingAPIMux := httpServer.getSenzingRestAPIMux(ctx) - rootMux.Handle(fmt.Sprintf("/%s/", httpServer.APIUrlRoutePrefix), http.StripPrefix("/api", senzingAPIMux)) - userMessage = fmt.Sprintf("%sServing Senzing REST API at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.APIUrlRoutePrefix) - } - - // Enable Senzing HTTP REST API as reverse proxy. - - if httpServer.EnableAll || httpServer.EnableSenzingRestAPI || httpServer.EnableEntitySearch { - senzingAPIProxyMux := httpServer.getSenzingRestAPIProxyMux(ctx) - rootMux.Handle("/entity-search/api/", http.StripPrefix("/entity-search/api", senzingAPIProxyMux)) - userMessage = fmt.Sprintf("%sServing Senzing REST API Reverse Proxy at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, "entity-search/api") - } - - // Enable Senzing Entity Search. - - if httpServer.EnableAll || httpServer.EnableEntitySearch { - entitySearchMux := httpServer.getEntitySearchMux(ctx) - rootMux.Handle(fmt.Sprintf("/%s/", httpServer.EntitySearchRoutePrefix), http.StripPrefix("/entity-search", entitySearchMux)) - userMessage = fmt.Sprintf("%sServing Entity Search at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.EntitySearchRoutePrefix) - } - - // Enable SwaggerUI. - - if httpServer.EnableAll || httpServer.EnableSwaggerUI { - swaggerUIMux := httpServer.getSwaggerUIMux(ctx) - rootMux.Handle(fmt.Sprintf("/%s/", httpServer.SwaggerURLRoutePrefix), http.StripPrefix("/swagger", swaggerUIMux)) - userMessage = fmt.Sprintf("%sServing SwaggerUI at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.SwaggerURLRoutePrefix) - } - - // Enable Xterm. - - if httpServer.EnableAll || httpServer.EnableXterm { - err := os.Setenv("SENZING_ENGINE_CONFIGURATION_JSON", httpServer.SenzingSettings) - if err != nil { - panic(err) - } - xtermMux := httpServer.getXtermMux(ctx) - rootMux.Handle(fmt.Sprintf("/%s/", httpServer.XtermURLRoutePrefix), http.StripPrefix("/xterm", xtermMux)) - userMessage = fmt.Sprintf("%sServing XTerm at http://localhost:%d/%s\n", userMessage, httpServer.ServerPort, httpServer.XtermURLRoutePrefix) - } - - // Add route to template pages. - - rootMux.HandleFunc("/site/", httpServer.siteFunc) - userMessage = fmt.Sprintf("%sServing Console at http://localhost:%d\n", userMessage, httpServer.ServerPort) - - // Add route to static files. - - rootDir, err := fs.Sub(static, "static/root") - if err != nil { - panic(err) - } - rootMux.Handle("/", http.StripPrefix("/", http.FileServer(http.FS(rootDir)))) - - // Start service. - - listenOnAddress := fmt.Sprintf("%s:%v", httpServer.ServerAddress, httpServer.ServerPort) - userMessage = fmt.Sprintf("%sStarting server on interface:port '%s'...\n", userMessage, listenOnAddress) - fmt.Println(userMessage) - server := http.Server{ - ReadHeaderTimeout: httpServer.ReadHeaderTimeout, - Addr: listenOnAddress, - Handler: rootMux, - } - - // Start a web browser. Unless disabled. - - if !httpServer.TtyOnly { - _ = browser.OpenURL(fmt.Sprintf("http://localhost:%d", httpServer.ServerPort)) - } - - return server.ListenAndServe() -} diff --git a/testdata/sqlite/G2C.db b/testdata/sqlite/G2C.db index 5e002b727bb64f24d9c460a38a88bcd2592228d8..ec181c1350b22270d1daa44a4580e17e8549b674 100644 GIT binary patch literal 315392 zcmeIb&5tBUmM2!pVtw(ey4ll{&E{}BSR5`ZhecLKX609L*qX=)kId+bk7Rg6k=2cz zK(Z=WOm$UeO=i{(IjuevyRi_Ui&lSu009dKyH{NVNte|^2hCzX23QC>=&}bv5U>XU zk`~%M=sh!Y`*>#V;U3{ZGHV}a*vxP@v-h)~z4z?dr^lbP4^GFGFOH5M@1Isy&;8)s z!os;ft5nXNJGTJ;cHrOSpEux-7n2|GUwl95pM`TD-e0%?sTQvOJ52i@UHx~joxJi7 zUVY=`KY!)urJFC`ywZN@+~v-dA6@+G%dcPf%Zq>i{J+1jeg5+KfBeGhFZ{EGs|)}7 z+`okXEA-Dte{^xNx3qBX;PAottCPQY1l1euKRrDXzen-CcvSB-qIfinqsFM}{{Hyc zCvRL@eDlqPZ@xa=|NPNdylw8N|NOMxk7|RcGN^60ql$W1xnA#eo2{Kuqc*6GT8+wf zYp2y6RJuL*ci3*%ODe^u{wI#G8JSMJvO_1#+k`pWY1l9fz|60%2)L1obD zMDd{3*|SpY^;?}<|6b)zbdTU!TKeFp7Z+=9W)jleQA{*<-h6g@@zUbE?=F0^p(%)? zPli#q9wCn8@1J;NByTF$lfOpYS|`$#T65~ujXoRb!UCk#>bub>Zv8Uy-`SOQL@h0C z{N&=|op-b9sxyeDPkz1eZ1cym)~lk{eNd2o)E-4ZsQvdJI<>anRIcMMXvLroh_X`O zNm(J?v8!szzfm#eL7o3FtIjsYQPuvn_)YysmlofCd*Sz=*mVXCSE=ByKM2(qZ9vo( zQG`%;T3ui-osCZIv&{GHT09s<{r<2WVfiPI_a8kvI6S>kX~m;PD+VJ1+pTQh8${Qu zOX6v*17!4=&o0n!KQ9h^wUuz8q`|t*u1sgx1+leyh_XwH1|e@ zHifMG($eZ5TwL6FJ5A*bm708@@5kRP{_xV`d+#m$?y;u63BF|nc0Ir>`p4^D1L#+k z>+ROIOc`o~?y!@PTmkYdXJNe=^?DuhwqENtTHws0QN6YYC7>ZTD#9&Qmnw~@SsS(o zmG`>uStZ8xUcc4dDUicv)2hbO($?!27d!7|(WwcLjOw31`lfzWkox<`B{eZ(krIFW zAWSO0$~I#QsqdD0+fw7};QeJMaHAqRnP$J&aU8dLKG^LK$@Avm-kziLHp#=iJ-!LkPn#Jd7X0aJll*A{SJprIb@f^GWf?qd z+0|F5UkO!ug0}VQchIUr^%X91&>Mn_gODImw>IP$HR67KRI3kKy{=IdyRwEy2o7G! z3J#K#qThgezWVI9S40(mC%X(qoBGd7P8HR|>?TFP#i}T32aF`0g4LkuwZ|qxRzUf* zo!oN55%dj1sIE{S*V)^;@xe=3bR{XP>W`PddF|4r#dqFW_}zV>5dwQZ0%zH<{=Dqa zX1&m%rB;9&m1e6CePbL&UE(=}LIj>mai~K{Z?@tFVw1Vap!^qc4}d`A8{kb#zEM#n zEG?~FzPQ+WC(XNCbstr&A6Ne3!llKZ{cPb`RnUlDSU5iY$3=%i{kU?yn13{>mzJs* zFD^zuOGBzfjH>$2OW*wQdEx$k|FVFI(em!6Bj`TsckI7kbimqgCiLi8ox|OzAEUts z%tCZ~yR~>%Yk;r%5Dmq3{k|#!o@UgJI-|R__E4F{^;L|aEQ70cd)<2-h|zVAWWBUK z4ss-5v>M=FU(E8aHXm|Ol5lw8o1ZLPT72uRh2NjoYJi0%g}>nNnmqjvgVUQYTwJWb zm8GqMexa=R*LgXl{`u8c@sA%A8enr`W`G%B2ABb6fEi#0m;q*h8DIvO0cL<1IAaXF zgm`)Uf5uvk;W7iv05iZ0Fayj0Gr$Zm1Iz$3zzi@0#TelA|6+V`YG!~LUcay|1ZWD zr)CD20cL<1U;Gr5)fh7~zzi@0 z%m6dM3@`)C05iZ0Fayj0Gf<2HUjHw~7pGMfF*5_q05iZ0Fayj0Gr$Zm1Iz$3zzi@0#TelA|6+V`YG!~LUcay|1ZWDr)CD2 z0cL<1UVF4+@;}S~Gr$Zm1Iz$3zzi@0%m6dM3@`)C05kAi zG4R6+FTQ={d_Rgu{ir=^H5UHffBEW*FTQc*d~Z9JKYw^0Q{d02JCKiFf8oV!1ezNSO14|SO4Fu|NGVdBzo;%;zVM&_SMNQ0`J;2^{^7s*xBu&JuI;Rh z>b-8WwR7$EZ?4swJEPiQ(7$&3SHHQ2f57zfwcFL@kMfdI^P`1H{ucoMavPT)yD`UG;{8=pX~M%1hg z+k?^FT6?H7wz`9;->tPFRrl!HZ*RB&R}&Z#U_Yw&`VB;%JTCAw0*m^PBg-%qx9hmcxE^2wd9%Au-ArhZAX_Nn_M>VbPQIPS6l`K zz~->so)#eH9XZG)zS`l}(=>5)nJAzD*z501ix0Av3h!2cKTx^BwD{s-zf^o{0esC? ze|msBt-DdTREX;Vh@DoW(Vp5$WbP2iY0ZQ<8li=I{ixacY}$r)izvgCHv>Gz!{)3Q zbrEG?+zMdaiLgg=ymjJ0tX?kY4h4xa|Lo{is>=xs*_}Yaji^ttA<)+LaNzlCom@gu zT{?L>Q+K?w;>QcosMj2AxB7$K+&~+>ZAj~&gup}8NAxu_VkBJ(NE_XYYWaCgftM6g zxS_H0cEg&L73ftU$onH)|6jQJ|D1#W=YN<1W`G%B2ABb6fEi#0m;q*h8DIvO0cPO2 zV&Ka83s>Ya4OHtbIq{?x5MZvN)9cPYm!eB4WwwG$GUJR&qjqoB`5sk9DG13lGa}rr z#WPPyC54oMah1%Sb;Vj*t=$^rXVT3hQK@;pdT-br^sy)#?34>fE4K*PdTY@7Wz>y# zTYI^i-OV#cuMw`lpd`Vgq}BQB#vY@8kI{c0pn_w*i5Z1 z9LT6U>}>mM4y^_pYHKxH;*GON4EY9_iJFf0e5OhL)haQc1a70(skOZ2nf%`hu`REGHQ$%dLjP{cIes5RMa}u&E>IS{(IFXF179 z;hKUEF^N*epXkA|I(17&-PmVaxf=Fl?R%* zGz}U|KOUe%ol!NUCXZxUwsz!V+3(C&X}Hzs!^VMrJZiV<5XVG?9bKajIjKUIYJaQ5 z{wU&jAe%EM(?P&V88*YSc(_$!e-v|ZGYrBm+Xh#O4N};N{SrP<*su|pvh zb-9oc2CDUMeq^ymJewtair~V^O`(_V+t!G0vqX;)e^kJ)S=lM_ zq_on!+Zyq1mTc5;WluT#KPxi@Ub?GW^Y#$p9^e|@6cXHSn;wN`qgGpY%j&)9#L1xc z*)+~XW($+7pUyTmq0=V{sWJPUN)d)?iYbj*;yo1J;^9yjaM?a%o%jp|H!<)6?jnpg zDX270u}(aN0$kWhgyEL%A2vwW-5czR^M3`MLy}D!m74oCUZyPl-5~vTBDrv&kz@=& zhQ`uQXY&pl#M%;}#Y2oFrv{ceyFSavX@i(tB6*77BFRcYm+d7sh|wi-rwJ>PycBck zo??S^&57XR0Y#FNLN47~Y!YuV=nvyTgr}Yg`U{gWfH@FLoXS6nnvoK-{y9<*w zfVeb=u}05DeHv}YEm$M{21F8cYlv&J zL&PG=fJlziYKZHzL&PG=fJjc%3W%_)%HJ<$T#S8U71PUTR)R^!va$pl;M7isoTn8C zlQl-Clee(sfS43vW1P~U>7iNyajypw+VZxFq!(2eH53Et7G%SnmQot;3%q86at2aO zA*J9X0l&Z*!_6Xclr{rSQ;3Z-SM&R;X6rQGH#p^$7qbFY7iU-pm#0P=>UxIV)*v|Q zFQ%tVt%knVa7#r4*#0u1KgD-i6YM2DQE2Ue~+op%}fv@=8G;>ZPy?C=0n) zRw<}M9hc@Pu(&=Y+okOmTCavWGQrKvXsuE_ZejdinY67i;L}#fMG?ZMsjg_o2+JzP zLpu#pGL;mO4AJ66)Ue+O>LgCz^4bV3kr>Ss?~;x4mxA zX%x}xj%xj=CWa-%86hg;KE!o{~ER$GO(V4ckQV?pHzJ8OsQ1}#;I75i1 z@`7VTI{{8f+2)Vmv4ZJgT#b?Dqh^Qjxl*RWX61SPO*$)WBO3L4{uO(6g1nGR*4|C( zS8YtAK(}hY&x;xIsG@9^(cGsvXtYUZtpy@&DS?HRX&{%r9JEP&ZUQ?s+L{`6nRd8E z?QkdRjldGyy{>mHXi9h}a`e38B&HBsDW;rB+@iLpV73NBxV4wWTZM5ZrIZ4c3}Yla z-JL{6o?&7dqtGTvF{MBy0S$_UdpPT@Sl)|V5GsuS-?k$}TAU3z*R&$_z$@Mr&pZ9z zaBl<$5phi(cPS^{-i4le$t2B=4$rPa&c5T?^`qm5OOQEZ;{$*vakvlOx=**H3RorD z^iSuS;Z9F719CUoZPnY6K8FUQEZBGy9$KXDF@RFAgptTin?Pcs-US%##brcsI%AZ-GlwYp%@M;0?8buC|TR9w;=j}zwusFEm{%{O! zVsYyE>{S}hHDNkuyVonQbIQswXQ*V@JovOVfcyNRhEC(By8@G8&OphqIldFP20tBU zl6=k}$+-EKyE|{w>F4td){3(>Fsaj zm@ibiUmD+y^zsv$B%d=#G6uTa3QRSp zt7npY&LGL?=hLVThLoR5oqnz`Z_xlseKe*}_~hns@CG8NDF+9)=tgO=gU6cgb!hM?K0ME_w%qx_hm{Se-ocgG$|9J1P#<$ul>o-g33FX!On2 z+!^iqQgt^qyHkU_ZX=h=*r1VQr?=gLiKklV^J(d7OmaDR%hco0>ei^%t?%~wBYo1x z@z9eN17v3EC}902ahI|#(l<{xyBb>GN;AbN1&3X;Kr6)cV z35thNf&L*T{P7J0R?%lseFPt6gh`*>Q(cr&?Zs7YJMf!BwAF>uST0hkE#U}i6}(1fGSaj^DEO9ZP)zTv_%?c zCBHUpk;YlcuT5K|aaO1{L4}M1#2?xL-Xegh(Da;mrID?|`DNlg&2~0k-MJhIVaUKBPYDds%J*d3H5~6rk?mi*AtHm*)nN+LN8)+;t!n@PmdSP3FH5F zI-*y_)7*A$stp-(NnNQnWaNZbwoIxG899l;P-m8rlQ=W#%QA9K=oK?^5-&(SS$fXZ z3Eg5wPU=3XBg@E26)C?C!WX^WCavbzqblx%wAI1u7}Fu+bx}^%{Hj#N(*aIis!X73 z#^msaHaWa~*2zjjkMx}DgeOWhuf9%ag;&8Cxp*CLrreCYRXp=%XD%YRibv4w%+w47PE%tCbrt6U z?ab5=s*a}-zqD#itg>T(Rs5y%-XfsAX3EIBHc2hvy)lPXNA4&P(NH<^?UY^Llbo`wh>I9Zjk)F3zRp1x3jei^^}rB5}HjCW_6-J4r0+uNI5Z zkP$nnGrQ$@4ZK6RKwigsacEc|uj8F@5L_THwx_ADt5s00-9(;NIaY)>&lZsDSi-tv zMU!}5b1Y%q(a4E;9gSSa8fdkenAcG&?0*X6b@XbZkY3@%<))4B%G?5S9lgTgh{-$2 zjMg08zlnnQV-OSb zItGC=$OU+I3<9T+O zam;Db(s0%vpP97Y#E(B7Gl{)|9d6NmW~6nTCq~H`X&ru1g-u#Yus=4*Nb71%Cc%Cj zZ_1@SAVQ;K*teOqRB`<{JtM8d1NP-6Eydu+!zQh_PUi=)R$}T-abuTNJ4fBUIY;aV zO=9%oreqJYWAEs-GtxRuhh91(t)rIMJ7%PHnhw8>kdf9=VGIs4(mG9t!C-n?KlsZ? z>jirmX`P0{;4UMr({32dWu$f54THCgv`)KWu$Gb5X$uU_Oj>G2eoSN1(hkUvVN6z+SCc^={ z3BJIEFg;kuLFE7|zLREyg*-O3a|P>IWe%`Alv$|lw+7aA(RR<|tHJj}aUBDmL~qoM z)OP$%ZBWP0U)x#%EoBouUxRZTn&W3mWf~Z9tqz@r=OQ)%fafAMiHmS!ai{B<9`Y8r z1;jSZ?Bj!SmB*y&l` z!VcH&@K8-%ZN|RMLyUo@hj@)5F6x(i)Gvb++g*5_h|%N{v>1dLEp}Ikrzd#MYV5dX zv4EyywC^ouC&qJE#J{(g(S_=1CwDdd`-&Ntt_)`A3(XMNc)v12WY1%4!4uD8;6u-2 zY^h<94v`%jbTH#8t*p-X4YOl|4rbFae)pL5Pzokb)le##M%CT7I)jHdCD(f$Je@8X zZ$vTVxfY)u9~?fc+&_B!WdHc!sm8VqOaQt~#+tFu;eo?zy8`bgl`%xD!Grx_;K;^`40#G--0*Ird5I}fdIoy9d z&V~r7x{#=3jJkJL7^BZ>KuZW^^ws|T)5_!h)B9fvpaB*|k`AUQ8Kw3K3MJmV6$Dv( z@ZflSa+1xYN>nmN?E@6XMsGU^5uRtmYwVwv-O9S}QrP5ejiFZF`w}i%$;Ky=luVxP zs1!i_pm+!#JWo?TcvUheJrGl%;M`saQ>#%y!KuEb(JmR68Ez?HaQ|7mR}X@dud)Hk zG-ZRN?pb;kc_uLkRXUglN00Xp4s-aKhDbOMZ)4(&gkO4lTM+-w@zK*KmDzct<+`n?|F9d1;mg7N5J@_G_w*fXUC@c@rFJp*O>O49At#?|KFZ`$PNgw z=WxVYOfIR=+t?Y!Ty?ID&;{5T#qw#cj1Y_28AW)RDlq znVxe}Ju`B`E88p4dS>LDP*3QBOg-_3uBVvNvxQP8nx2)O(W5>zBj<#QX5^f@qWC2e zyPj0#Gh`B1M*U|-PSVZL{xl;e>1C+*%*aVxAa$PUIqCU4uPe^TN}Q+MO=cN)Mpm$1 zyItglmt0xBgL2eh(xrM~2lWgYS-qou`BkY}B^n`*pXaKrf3}aR6X>b2a{OUgInfGg z<>^`Ju|R6&899lq($-1OiF-tBouG}Ak&`GQZ5p7#P=r4;MgBfcxP8NFnDm^%gF(4+ z(&I>!p>&zJ)Ro0hMo!{cC`0aAk@%IHqpZAiFEiDnth|$W%E~*5sm#1HaOIgg?Ka#6 zF7Ycr(V*r=kKMcziO$G7k?4%P6N%2sJBjFwyqahj|G$^qo#T=1#E4>@Ec?ob& zt26RWBs(MTM6$E;63m_l$jD2Ts|e4!p^`?T{g=BGDSqij3ZApEoNQ)Z;w-&Ja{7}T zr(A8h8F_IFrR}7tTyY*xFLCEMooC6-%nJ=TwcH7zd6wJ_2%2oUwA;?i3q0C+sZwU; zt>P8$c4n%T*_jDys+HN932YjtXJ;mQNkesahrIZu?O{^5l9iV_9;%n_ZhP@7zg(!3 z>6zTTlLDnIxfHYBPAhFfECO5R;r18s6)3&m!BZ?7FBpzVN!6DQztdCF!GlRjHPi7P z@WZ5}5ju_NOiCIx`Vmb=T9+vJm66u#7c$a1WTA65X=%-b!_{sOf2F7O?I}I2Zvq)< zJ+-yd>Sc;#yMgsGL8}&p>B0V^$^+OF z5Mp1w$1MZ+x-8zotpzdSPM1`SxP>JHBW_+P6QlMXgh%yFwsf5Pa*s$BR<%Q9R=kNf ziTiTzQUm@-PJxKO6N8Lm;XClPavg*5$tg5wKN>_`@wu^fbT`67A^q{=@#D|O$Kpf5 zx%&iKHqgr2VViyk+Z#3RNzW-&g&?bCUY9~`=zY1oNfoZK~om|vg5wVWx3rFOf$_=7}%@{b=)x}4Ob>3 zb7F=GW1j?eDrHV@re)(Dvp_%wW9sWk7WwHVk(e7>$!fN4Oqy0wOUhN2)EfVzr{Nra&Y&Iqz%`s(UM6&1m*Ctl}P z02wWfxM;lJtw3qI@r9bvvLwq|(~H6n z^4JYIu_wwXis;0|ZYaH|4bq63$TTZTFN)5ut@QXir(l{JG~@pjGiB?lv}UCTX^wjg8cFVvm_! z8i28}p>N1;QFMA*btkN=xP^s`6x&IcHsQ|5$)%y|)1_&eMGOQLv+GIv-vBi1&8)&S z&C`{J`*5t%G|f|%=J+-|7cCoY%F@s&XxiMHu!?(1aBz*ps5TgxdSd!kJi6QJ4~8|IZt+LA4lhoVxx$EjPbbWAyP_-9 zUBVosxmK)u1)s=L>gHIv@JA_iL+b3W<=lYr{}ME7;ig05*D4LA8vAg`gqqs|@n>;i z8S%9%trRjHzl6-Da7p^=>9o>~$sCvJR*kgWbVQ0M%`{s^yOqLZR#4~Gt{icWiMzp& zD~@#WQ#PGz;~CDfoZ6u(>b7&ca<_Knh)eJ5=O8UB7?^{&tY~2#;?U4^)4AcqJj7vl zW5i`Rl~Ob%DAjCN%gA_Z<<@zK8CYCe+Mfpg*T$T zsN0Cm6%{rpbVf2+vUZH7FRrxEZxkkRr;+={f`nD>z+yEZ!HX_*;-3ehTw7hPiY06t z3wj|3i@f8>6{*04UZtZksZ-&scyQ1UIdIesQ$akzcj~w1VdpEbE z-P+w&uYVI8`d24UA7B6Q=CCVUtn!~!KD^oOjq1Db)!}HV^7Beiy_3se6fiN(f!@i% z3B?3e$$Op?BbuDRC$wGsWr5aL8;KWb_4zn|eIV*_>(lG+ge&B~uxdp7Mv^vF0oJem z7RLX7f;&efn}S>z|GHqLN~bU!ei;U3*+%8)ShhYkTM9r}->q&?9TlH_a@xK#Y{R@$ z)ppY2vLf%f1eU2*v2uGe zAoThN;d}#a>pjoLrjQl(Z23L4SUYvv9z1dYIC+{2woB-|ee{ag=b(J3i>0b|aOb?p zu8*z5MGQ-vJ$A^IF0W~HQz7!6X98-bYHVK5DE0(6$Rt@lGVl2WWZFsR^^B`2k#N(; zqU_#!F#$}vXB67#cQQ@8sYMzgvrwaZp|qkfO%I#ai|qPDrVGr?ZkqFKraMpP)dWPd zJ5TYoMn@H;leAh{8Hx8i8{7PyC!WP{BQbQ7K5+6h7i?4-qk!{vp13E91@y~+nPRWXV< zDe;+8hfwLH;Brr`2nwnHA`>T!A`5o`_+1%S`x2p66i47#ZzkZ0rvQ}JC&?or3ae`m z&Z~)#X0-@$W0BK<%3uR67KaSuH6Bt z;G=VQp63LgYRAIY>lq9f|GzJuq&cYkvlzELCoj$Ht^?n(Gxt?y%`oW{mgdc@C~b8m zyQb#8n~Z8^WAi+_)L9pYqt5QDyb$N8(D=0|*TqpK00k)so@m_;5Dcm#!o$bo9Hp zn(u;i6yJT7j$fIOs(|{XK+9iA71X=TI;`G+=n(pwm1S?)U@h$CU7WUExNoc)ctbHv z314u!nH+wklS}b8zXU_7pcs*YbWAxqGKmw zx*;CawmmxuyveE!BGX~z+py-mBqx?Ex%k126G+Cav!tX=6b%Q=VSTpZ= z?s{Q68SNB*6^>F0D3BMTs)2H_R>60(*Q|&MieovB2?Euk|AEaX!I_}IOAE5yi^+mM zu2%LBAHc;LxHKy?6#Jc}kAntq4X$Eb^LjOLn9K!;6`NWp6AHH>;yqvIcAM^`NE-SoeHD2%)gNxIa4l3JsuHqC6S}6KB!!X(Sa?c%z!E9!Ifgm-buYN9;?`%^yTMnRMw=R zY?#Vos_)xaOzX+lZnKB$mK3DxVHc<$PGO)cvc5qB^};Qza$Opz3tBZ_f>PDc@GLWRQa#_I)419n_^v^F-^?`IETEQ?FX(Ae!_^g~@-Mt!z!tS|ct z>BTZ=THRn=kob^r@DOed>M-oQX;`Z_HUe7_v;2IJ_yn#^m{KV>eLm!NF`9STI$4S& zJVBt}5|=xBK24Z~@leE{8BI1x@_{!w(@C%T?g}^MyY33K17b2XCIi7mnM4h4noO9~ zFr}@AJ?jP-rl-aJN|CU|Q5#Dd0cH=ZHkkKSe2yt)6uQYX=$}v(Q(B6>%G#_2+Qgf&#oA;j57fgne=gOru$!D2IDL@* zWS;;ysv}gFL#G!NMk-}$*lzMLtb-F*TSTkq9KBQQn2nhe18s4!fc1OF&M%U&*P-Z zja2y@$eh9ImWLHTeC>9kA^>({5QkD2gOh>#nprYuKd>Qb3kBi4eT_u#WL2*zG1tBIPa?=Djgz^6eYFXW#1`q{h=p#()totF5 z_~e?yrE)?p5Jw}euE9+efD2HKPsndP;Sr(u$eROJ20+-CwOuF*uob(guGhp8ZiX;+ zD?b5m^~@>}mY1R^5Dnp!ns+v$y6KH^MbsZdg~CHzWj{&$+{{0^O>*jb$OmSsOvkq= zmB7Vo&>`O*w>*W%27%K|uE%n82%5o55N-lvgUV%0Iwl1U&FgGemi?(b9Iw>;;fkQe zes00?R;6p!DU{&+RA7}3*3GGdkadJbc;lcPwwyQFc+wYN^W*bo&P0r3bE43B&$F@3 ze+TZ0_(+1|B48RMfSf$dg&Q^F+gtjAEh1D+lxq4~;=jnQkgX&|R<~A`y%k2K0)gG* zfj1LSeGB{eR+hb4IDr#)hk%t?yGU&n_utwznY>y~mv}Wb;A(^K`cWP4gGlql&74|M^s~kAXS*>Tf#5>nnC_vzcE5U(4Cv3)_=OW78*wcTpk>FrpTOg(jK&ww>~!P zVtxe+p_rlB{rSgRYpR#P2RrmZEFLW3`eb^ZKb4Du>L_>jPnVZ+*V1$Bh{D7_!D@zH zPp;?YCaLG9U2&}E<|eHt$>Y~kp7BJ?JuG0&{1(*a?LbzSy$%G+v|_0s5yAI4m{_4q zxa|iOS@D=~^GswytY{l0E1>t@tS&Mk=eI#~gFFP@rm$cmGHoTaekHfgdc6!HOk%7c zK>uYXK4EnE@pwIq(8sjn)!~YFXyv_4V}- z2H3HozeN!B`$G_P`&W408~;>yX^41R{I>6{5K#{7+v>IN;zb#FgCl-Kp$*^GkeB(v zFMY`n_~TFDmcJ1hsOp#)D)Wi^65TpFaUplmf?Gvy%WtPT&_oa9K!bS$e>cR8FoR|K zkgtgzPEQNk$i*kDY~*rt14Zs{ZkQdpUuF^HF#i8ge(>8tFZx%Cp70JAE6J_Uv)6%? z42qUk2Pbs0S|Csd(Ra=uC+6E`t<^YCd5$fH=*js;tTj z08LeEpHz9zKnh|pV^$hoQCcCi;wxpg8p{LH6s?$%nz`wb*`%Z*C|8%oS1T<4D-TQC zD9y$Mv8+;xCWOl@g8Y_`+%qvf`>Z#r&8822c{3swp=6lrWQJ^Z#M0uD@@7LU7szeI za#7h{tDOz8UtSvGH0QhKX@*=1_faPnQwHLstTeQtj@m~mSHc~nIQ@$QLACv0My#Z? z8PR$jv%lh97T#nzcSgjXkFZy@XUAHO7RY67TMI>#Uwa2IYgw}wP&grvtrp!k6?k>*yH=OYe`jm#{V z04FZ$l4nnRuxcsY5Ia3iRn*iFLA225N1TOc>#)f9~)pf>|r-7o5647ywJoH z5P>$L!#}re<*x~*42V)ke>t(q#eD~xj66z-`Q42IK7rueVf=p+B9u_9X+f?mdy~F$ zH`Z+6%&x8JfqCNv*u7Gc!eKen1M@>!bkzl*g#$ui3#ud^9N?2>^LXaY_JKYw~0&0XVF&1c1DxxRL~5 zH(?0?c_jcV!N?UPYs@I}yBvyo8EC z)0&u2+>mKI6i-5}D}pFhIXdNtpx>@8N2MGQ-skG) zpi%OQ39G@&={}%M=d87kg!yQ#D*}Gm<_$kfux?kxT(s5^F(0jUM9fKRi46E@w?;Wy z3;Y|c6?d;#hGBWu=?CE8B`gVIK5VWc#MUWG0{9oAwbqlo9fng0@u3w<0yIq75+<6( ztaYf0t^HOdrg7#lq3;ec9h$1*z?3Co8ecw1Lx+ra8`SiG}I^cATAO6^uh)*p&~f0PmB=8|5ZGDG1XY#lLMA!$5hlY zdR4KUaf;8%79pDb{!v)-P=E;#j!#1BMt8MaHog+bP zy_k_E&#qkwBx;++CbA_^Z7RnkaJ6dAZS9I!Aw-qZ*sh4Vv^EhzYEepayCS}g_O9ZB zPtvhsXHibziLuSRmC6w@AEk0c%txtQ5pz*0N5q_z%8@ZIr24fYkme}IQ#m52 z-um4)Fq;HEd3!z_%^RYq-j?I3ToHt*X?iBF?{jNG^|mBG7z~}g7|c(B&miaG`CWL-k4g5Pn25mlvUsiwQxjKabRyVJHhOk;rlXo=PXTEG@EjR^*XKrx1_`82vS>=Q>vt>y^n6^#E^ zv_j`rUq{Ruaag`;S%PzmfI=;@=3?j0kVAZIcLG_3i9&;zb1iVDYu+NDMdvNTb?aa$ zw*6W9GrdE^nKV<2HEL9IVM$$X_N|q&$}9qh`G$Jy0xH8P2+L>=o7yOJ7=bdh`6vO%BRA?|L{Q=2Z`;`=k5C%V`fsgt+(7iWB_iu!QE;DyM6jsunQ*UllhoW*k*q zbHtGGKsgn00-h=!0J6s%7Bw^22ay5lZ_AiVJpi~Z!|%zhn&obEQV$Xx`h%xwWH?hJ zQz_O&rE)~fL#c3Mh4EE$nJUJO74sGWiaBo)P8T~LqMZJ3J|dicV?H7rmp&g6j<21M z2*-iUM}%YCa}j|zOU>CX@Px*^ML5aYf9hMO+zkYLWT(9h;7b zIrSZznU1{_uj`7Kk5)Ogn3GmHGUlXJj%Tmp77x3hEvGpge^sTYljkCXgm0z93wVR3 z@rm=P2bD3GdI0059&7WM0mb`pj0kVHUOCM{WRQCJk&mTld1pXrJ;;dGk9_jUFqZ+| zg}wXmktB0P8PsAZE(2B{NZKC8t!@9JQJaOf7e*8{%WqgtZ@*QE+2kkA#vy`z&;z_$P3!SVP+-F9bc zic=*{P4{+tT_4!qmq&*l5)1{Lyipsz>=-qWeEmwHh#rmapN=0?;FY)x!63jM%qgW6 z$HQ~HZ%(Z}&0Fu4^JB3KNN{^JjD0>^ho|G?LqPHLWL!BqeDt+f9(pdPym+rxk4A%*xa3v6Qi$Rw z`}fBmoF4d!EOy#E#fWdFwR+unx3%Y0tv`OWe|m6qc=F}J6aAq!;iRQ)K?BRnxzIqw z4`o^6yP1i3i5Ci56INa-hiGCjJ5n3e#D_M)H=Udw9~?fEwbrGgt=OgZ%!l#h^P~li zAMPI>{FQ*3yKuA{yKw76e@@}?Q)rlcc+q(5B6r|=)vow(IWjBWD8xGle|LPC8>)`6 z6}z2QqXFN?3-Q}Ic<|uSICsf9T(msmXs;hNTc1(L=oc$bj>lgde3hr|bdYG591ojm zC7(R~B4^1uG_*^GkN*S#KO7&9kA-670c}p@sj}RO zQ_ZaRhTVbhf9gk14^Q)Xo)xN}@t{BI4m-4g;?v{t__T8P^zrBUJP_VdL|BD_NHb8_ZwEzv&vy1pX#IOkQix5m* zyev8T%Xn1$A>2nT;|aS16!h_|-IXQZIe1BZY>&tFYgA>3* zG$+XOa*Z1fT-*V74v?wKHM0l8@5A`?HXgQcin>gFVc(ng8 zSG!RItJm7?QQX?`?4iC7Be;`;hq>$)51=@JL(Nss+1=ctwzb#m`_AR)_%v6AsZq6~ z?#^JB(%2p!K0N(0SAo=|wxgQYZEcVDbD0r-_tW8R(Cc<GY`=0fY;sR@3fvcfzF}9X`xoEH#;An!}EO1~|Xr`g$}O zGworjPR#};Jw|sTFG91YJ1V~(=Ze;FF5GD;EIZ^joWk?^4&0pPl-};`w7O~<%O<0J z^zh&i=dfHtg3~Hy$F%DFWTA~-r`Gb!T^9V{=<)tRE{n(W)(&FfN5f?&p0q&e)W~Wb z3^}RQ)*fTuLbwPju-S&IxR6l`_JyPBGA&m|F4!lEcN512W(Tfc`dWJ7_-b<5)bt=n zGztwgv2Us59c`{t(-XyZdR^Z)igG(ghxz>DIyFL3aHHl~p(wVokJbm{|Mkg4Pzw}8 z2K+Q*CmPiB{IzW@o$)Em(ZdvWMMe8KLz0VhYL7V3%OeK|f0f))sFuqhaug55M7muQ z7zQ3b*gt-7@K<6Yyg)c*_Kzyv6z#EFi@iQjG|2A$Nv>`X?*(=2U$@32^j1?;bOYsS z6uc(X5h)sFk~q;K#pF;8RwHTOlI0Q$#x<4eUmP5toL1H<4-TOJJ6XzAA*#_kQ4eQj z>#fiLrFDpOjgRTTC+P3YUO(09*t4dWjeYFrM_*O;j>q>80%M@C3>v3lDB1O5p&G=I zUmP7*a1gF~=7IYmJ>ZEa>j2|pjJ(U4F`JB3tBbn$qO7_UDV?gTsE9uipexc7%S|V8xhZ#hP~8%B@TFLFm`aY>exSGl zKZy2C4aDgpm&XZFL)nTklV5P^e3#?2OSoXnB z3putTG@zMVmBpfFUPaiVA%su_Uznu`#mcAZEY{EUZUsAd5bNi1mx9~o4{$cZ9X@W+ zxE^NATKy*ZNT{IO{40$NR_Q{oIqTRd2z)*4b|D412?PBsY`E4Lf#)nsOUd z1y?-%36EevTJ_f7jhI2pU)QcZ{`}zK)1#*+mBE3xx|AY;c8HzMy?dk3Xi5y2D-hU; zA$cY5xJrC~%TfAHr_q=o0Y=dU1W-FRB*jCqIs&_}K-+M$8dYM$Sp4*fSTBL$D5&1? z{_)q9q{Y11sT3;B=m*CC8?deq`-2RY(A=64k6HoXY_F9fh1xrOF}dz_IeU*_Clx6# z>_6~!Wv6-6T4>Nz)PiUw@65OOW}s90pm!(gwtfjM;t#9_N53A!b|`3pyfKNmfYT`- zHmQY|M~5fl)7;~^;%bb_#K?3{T=ul*ZKk#0)QyG*6nrgb->X;5kl5oEE$Hax1qy}cYB|X zU^${w8`O8j6poZ50tsCT_KbGr8@+ApKJ2=S8OEb8DxV)5i^*h*1f4tC#4hHMMCSBO z?0CUgeiCHrIkSM#x66W<%MG#c03sZmYkdw`z!1Y`!R#xviO~BBEe14yi5}d|qX4P$6-28-H)?Z$-Ije?L-_+W#B=pP^Ovw7W?V#R-?>8oY#|Q( z%ljG~%JEz8FoomDj}0tMaorf)ow#YmafFUHe$hW7>6(kM84%gp=|8r^mQ% zq#{_zD7WsT7U^OVGQ0ygvNlqdI)Nh}<+X=zg$^8K+H^Gf?N%Mz-6o`Q4EyC_%Kg#7 zeb_UG0r{*<6mksT3K3!`Y%{S3N0^cwE;bo^`zI$)V3$jIYVoa+kvnD(19qE?LG3fO z>%pdCu>X~e7-v<7Z_hCDQ=lUsHId(i{W`s_KE!16&=qSD;4q752tk zn~P-A)pS9{nJ^BVBDamh+F{^?6=K;_PJdYXU^-&uBIYperYa$S=Nx&bcnN44ci@d* z)p2+b6J%;a$WaNoab9hC%%Z|SLSC{$%!LT?p%YsnU_VuW2IxFt#?1{bJ!NQmarT*D z0CdJt1-X_JAVIF;V=+VQ9+fs#372sf;>cybD;qiEVDEPkT54mE?jK!pz>W1B3Lqf%%xiq#|dr!aW~o>-Ia$a zY~{E+hKpg~dWN$(Oixh{-;0PZ#!xz7T5kj^lK$Wwv#^%Bx+j0iS zPvI^CabFPhF6qqx+OL_>dvwi8}crGeT`zc<_) zK}~!0mY6rE!+w_b=tueM&` zxIb$6@oF1}{No2LVjJ2MB_w!#u0ZW{x!<+dKwjNJj5wQXlhB0ypWD5jHv!UwEufzt z9g(?@=Y#}3gQLu0@M&uR_Y_iZIrz(iQ#fMi`pD;m0v#VH3gSEJel6P_#J`psi!ER9 zoK&9%p1C7=t5tuBn3cKY%L4_gshhj1zrcF#VaG-#bx zw(#k0Z4lS?#Lb{K3!i?ue|l1T@?_4s0OSAL-@*h}pmU({B;JHm^A^}+xCRII_c|ro|gqz8qPjk@WUeY_(x;s5=Zrc_H`-cz3UDsw-;`z`4@ewmo zQ&s)Dt!+OvxO?DjH+oL05An2Y=)@UDb#RBY`9B@k!5Kb}K0sXMVYffrK+)@)yXR~p z=#TFo9X}9<@?0u(bd|Wn@+TR}A4&)37{sUQY&yjGno+Mg+HUpb?Kn0g;%rR?=IFNl zLk&4dnQ;hJJ|})BDZYPZ6Vi`%;Jis+%(v)+;Wj7z@xuc+J}2f|DtPF_)fGJ$Npz*7 zjqOaG^$?e=q!MFYlA6kmxiQrma6BhkLqjV)RhQgrX0zf=(|P-SbswE5&6%8%5f|Io zD$^KtW4t#r(BtAObA70#Aez~P3U6XYPA`2oGc&no{lz!eY%aQctrRNY&GXEJ_(+(| zL_11j0^U5=Oz4mv*=cX0gCvBnXN7IQ$6q{n85OK=jihT z*ojb^yreq!J)a_02`(MN`2V9BPM&VkL9Ey%AKK3(cgpA3_2_xj8RInRkj;F*{2e62 zCn9CSA0W9?-J80PRK|mQ{c7F%uKdJ-P#Lv-N$>XCKfM2?_}GEfzvyCA{{m-&BO0O2 z$cM;o=ny{*8zpV`6JJcT4F&nw>xs=>x;~VUCr1bPksdc!ZOgoY&p$wP8~de1~lZ zhJhk-#q;{x(QfT-3(Sg~@y88Juq_f#-M8Rw61WJUwg(6N;ZY1jYP_C6Joo@D8a}l$ z8uUi}sL@mB_R*Tt#8~^$!$M$Y+mV64i;6H-o>K-^tgw(++ur=7n886iLr9z7$XgHMl~#;#bB73N-RHOCfv%@GSJ#52${rJj+#uAV$E+& zU6o06-ThYh0x5GL32cl>4%px2vmbO zh#KJ}3dBtEX>x2$-5FhJ9X`ZkDC%BE6F!2=a*B~B;8Kf`$KdqGKl@^lQy`OnioN*| zwyIwWTQY*v&lS4H7;o};0Mc6VsL_h+?H=4nCGVEPzS}AjaQ0#Re@?EdCgtiZUdab1 z_a7a>ArrrB(Pb-Q#aL3p*U<)|cSnP9uYDI_CC~Lx@Z{)`L~r55s2{GxyaNF{d~p~r z$r2UOrDHwp(&4hsxV7EBH;UyYVDhCB0ataN9DM%h>&l7zAVC2+FpU+KBgSujZL}zH z8Jpm(fHc@OWYqZXjIVcZWYj7upq$E2oA=n{Rxu#f6oWs+1*U#6 z@G7eqJu`_pAvR4b2Il>*Wm&}_0Ik)y)R0mPh|4NQPvjyRoIgn^ z2GV5}qt`mH7z}u(EJsffigGgAY62cT6NKfMs~GVYQ60dVRWVT)&9gX4H626d4joao z3~ioJHSwKUjYu3|ni7$t(D);zoC$VeZa=}AiDl?13vzWDbs?poNfg0*%Q&W2YjKUN z=31=(Oo_-*Y_T*jWkHT+qb?hcRzOH>oFcq)G<$iO`bD%;T|1{JVkATZ*1VE1vndH( zTuSw-pl1%M-|8L!yt(QCEWa-6qv8#5rFL>#t$dU8)Od?_a#^jqW)wcqgEM~*SKyoS zCu4P?Cj@dkL;Q5x?L+wX`HgG8sNIG8v*80%u)K>AfOsrD)M11RLZnE?>;MG%90 zH3bA9)PVqZhQckMBY9a}0E2u%F*J{kq1Tu1rT_s(<$#c_0XCmJciKW9sy%`C6p3gN zk#h}*3OL&693@R|Q4BPW_|#PzDal2PQvdm5=7!c`B}O%EF!X2`tBS`K%b4U`lRT<;WXK5NQ7JGA>9`qLRy?BHtB5=6}{wuElzkRKb zb7c6t9o>a*&)>#$ji^~0w#_C{3{arclS@X`Q60Wj2+^wbM3jrV+J!GAtEDB8WLfl6 zaIpe>Bx<`BM#rQ zbNvB)L1zE+edrIW-pgX;3_>gw&)TOY11Z>+$L;#<`ZmT%o&UN%W8)mu8r z)~h%H@B{oG{)ZW02ABb6fEi#0m;q*h8DIvO0cL<1UvOODqpSbZtL@iLUik;FzVY&(zjE}_ z&6jUpX}@&ta_7pAF8=l9*Dw6##lL_4-(T21fBF1Be&O{O{@KFSg@1kSU&8+t`sbrR zy13X|S~z!b_+b3i$zMEzFUF1bpPs_GZ}>gJO(3|FC?1JZ$5r{ekN`*wSpUDGG7^~| zL+1Z}@y$0EzWEw9S3DXE1kD}wpP$xYqx&GL3~Jl$sG=TLuB#0ju=k?|JJ&1QtsOY# zUg`GW-(kCbqhh_Uz-f$a{}t>7>A-c-apf+4Dyi1LzOuZ$WF-@#gzQmcP#Lt~)Zn1j z*|SpY^;?}<|6ToM z)U8K|Bl-I$9vR7-%Jt+gv7bp-YR##W*o>1T43Ji<@4^;0*yrZIvn!jFAVe)KZT#fo z;+=Q1>Z&t{3MaqbxcvJ0|54O>Rn!_zn!st3_9y~E?Z5xfskQy4avgs`D+YByl$H8U z$_nX@T~$;5jfyD`>imaUb+$2%s`jtN%dfxi&llf*d*Sz=*mVXCSE=ByKM2(qZ9vo( zQG`%;;EVMJt>1th_|$CHd)T@=7)Aa5upMFfCy)0Z!KblKZ&d6fO_l9?gXns7Nj%lp zuA8T@nO1&wOc>pD*b=r3Y4y`lBO1U5J!A9MdM~z{8FK{9y-}e}AuGSMwE71Z7kA!H zQ#nJWCLieg@#WVShKujLxA42in))XA7TD8S8()| z4P&R4v#{RaraSW1xj_L+KtpU)gj=dERn+dg%6r}StP-tLy*YE(Y+BV=TH1R3;$r8$ zEIKs-l2QHhN8i-1UP4lTAGxF^Ml4d|j~|3d#aG#8Y$5fvy0|&OduKwF| zALVEOB+F_5{Q1LY^;a(mC)&~tfDW+-?-FVF_iG;gNvg{Agv5|WCuM}*X}dP|3^wcg z5Q|Tn86y__>1&hxX#!W)Klyd_S@q>hB6!%ctFKVM5~}nBZR^$V;Ke1O`U)30=ncWe zfo92=<37^UlKW?hB0&*yR8kwA2c4qta~kp>K?%s7pMDP>8^D zb)zg4p@T~|5Sz?R2IaqqdjJF?-vDn~@{NirVQFdY^2Np0J89nCs{5#F{kZZM7cMRS z>}Lzls)9!J!ouc^Gq#r&g5y|h%lcyTfMSsGF;VpP?CUi#*b&kOhW`KxQ|@sL@FZg001?`jS3RUe|ExUSze8QG`WF|sFP*>eHx~vk{+}=YXD|NI z`TyqpN05#GVFtc?22TG3;{K(DXYY!6q}FGn2)xz^<}AQ-ffF{rI?6>1yDfNIX>}XX zXB8)X1%f6w&vmPVR6QBS+e?+NmM$&c)KW2%HF*^amv0`lLz2BbiFA_>W^)>mI1Ysq zN$@9l(8~DwrNs~4TX=R})E9#^VcjAmkMB6Y?xHU|^&~~mZ~s{Gwjl&zBPU%L z6k-3|3028XphVh_u8XF|?i_+abv*k<#q`9`Z0|tK`PRa-_k{SQAB3WkKbs-3$x9_N z`8iqKv!A~Wye`@Eg~s3zx%t&lg3Sb~c~`mKiNix3K{)EZj!#yc5iTlLc5n|R2jWvH zZ)xeHYm+9W4N4i2nBUQ}*M0_C`}V@KhdSoNIhuAY&anwA2`GU@1b}($dYpl@$&p)sqxJuDAw$ zm{C8Jg&2IF@yebvwW4*KH7!B* zDuovbo_+F$oa%Uv)=8#bJ9u_`QBHfE$rY1nR}Y?T{#e%f?5&tgHD&)z{YS#n^J*6nS`e7@%;Y_SO3wutN#c55C6jqFayj0 zGr$Zm1Iz$3zzi@0%m6dM3@`)VIRhWPaN&*j-~LGMCs!LW<&RclWpne^+WOi`HGI)u zb@j&!7v6m1N9WW&kr;NRbZT(5A)fz#;p*Rbj$!Vzzi@0%m6dM3@`)C z05iZ0FaylM*=2yo|7W-D7&$Y*3@`)C05iZ0Fayj0Gr$Zm1Iz$3ke2}-|L0|j(=h|g z05iZ0Fayj0Gr$Zm1Iz$3zzi@0XO{sU|DWBqW8};LGr$Zm1Iz$3zzi@0%m6dM3@`)C IKwbv^e|l3AHUIzs delta 5782 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 Rl_TuEw4Eq!uv3gW{{<90WnBOO From 41f797b73242b104704dde6aa6751751a4d18f18 Mon Sep 17 00:00:00 2001 From: docktermj Date: Tue, 9 Jul 2024 11:26:43 -0400 Subject: [PATCH 5/8] #58 Improve test coverage --- cmd/root.go | 2 +- go.mod | 2 +- httpserver/httpserver_basic.go | 2 +- httpserver/httpserver_test.go | 101 +++++++++++++++++++++++++++++++++ main_test.go | 2 +- 5 files changed, 105 insertions(+), 4 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 6d9b48d..ed792c0 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -175,7 +175,7 @@ func RunE(_ *cobra.Command, _ []string) error { OpenAPISpecificationRest: senzingrestservice.OpenAPISpecificationJSON, ReadHeaderTimeout: 60 * time.Second, SenzingSettings: senzingSettings, - SenzingModuleName: viper.GetString(option.EngineModuleName.Arg), + SenzingInstanceName: viper.GetString(option.EngineModuleName.Arg), SenzingVerboseLogging: viper.GetInt64(option.EngineLogLevel.Arg), ServerAddress: viper.GetString(option.ServerAddress.Arg), ServerPort: viper.GetInt(option.HTTPPort.Arg), diff --git a/go.mod b/go.mod index 6460523..b90aaf2 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/senzing-garage/demo-entity-search v0.1.2 github.com/senzing-garage/go-cmdhelping v0.2.2 + github.com/senzing-garage/go-helpers v0.5.2 github.com/senzing-garage/go-observing v0.3.2 github.com/senzing-garage/go-rest-api-service v0.9.4 github.com/senzing-garage/go-rest-api-service-legacy v0.1.1 @@ -55,7 +56,6 @@ require ( github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/segmentio/asm v1.2.0 // indirect - github.com/senzing-garage/go-helpers v0.5.2 // indirect github.com/senzing-garage/go-logging v1.5.0 // indirect github.com/senzing-garage/go-messaging v1.5.1 // indirect github.com/senzing-garage/go-sdk-abstract-factory v0.8.1 // indirect diff --git a/httpserver/httpserver_basic.go b/httpserver/httpserver_basic.go index 89bbd2a..b52177d 100644 --- a/httpserver/httpserver_basic.go +++ b/httpserver/httpserver_basic.go @@ -43,7 +43,7 @@ type BasicHTTPServer struct { Observers []observer.Observer OpenAPISpecificationRest []byte ReadHeaderTimeout time.Duration - SenzingModuleName string + SenzingInstanceName string SenzingSettings string SenzingVerboseLogging int64 ServerAddress string diff --git a/httpserver/httpserver_test.go b/httpserver/httpserver_test.go index 802284a..95bfcda 100644 --- a/httpserver/httpserver_test.go +++ b/httpserver/httpserver_test.go @@ -1,7 +1,18 @@ package httpserver import ( + "context" + "net/http" + "net/http/httptest" + "os" "testing" + "time" + + "github.com/senzing-garage/go-helpers/settings" + "github.com/senzing-garage/go-observing/observer" + "github.com/senzing-garage/go-rest-api-service/senzingrestservice" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // ---------------------------------------------------------------------------- @@ -10,5 +21,95 @@ import ( func TestBasicHTTPServer_Serve(test *testing.T) { _ = test + ctx := context.TODO() + httpServer := getTestObject(ctx, test) + err := httpServer.Serve(ctx) + require.NoError(test, err) +} + +// ---------------------------------------------------------------------------- +// Test private functions +// ---------------------------------------------------------------------------- + +func TestBasicHTTPServer_getServerStatus(test *testing.T) { + _ = test + ctx := context.TODO() + httpServer := getTestObject(ctx, test) + actual := httpServer.getServerStatus(true) + assert.Equal(test, "green", actual) +} + +func TestBasicHTTPServer_getServerURL(test *testing.T) { + _ = test + ctx := context.TODO() + expected := "http://expected" + httpServer := getTestObject(ctx, test) + actual := httpServer.getServerURL(true, expected) + assert.Equal(test, expected, actual) +} + +func TestBasicHTTPServer_openAPIFunc(test *testing.T) { + _ = test + ctx := context.TODO() + httpServer := getTestObject(ctx, test) + openAPIFunction := httpServer.openAPIFunc(ctx, httpServer.OpenAPISpecificationRest) + request := httptest.NewRequest(http.MethodGet, "/", nil) + response := httptest.NewRecorder() + openAPIFunction(response, request) +} + +func TestBasicHTTPServer_populateStaticTemplate(test *testing.T) { + _ = test + ctx := context.TODO() + request := httptest.NewRequest(http.MethodGet, "/", nil) + response := httptest.NewRecorder() + httpServer := getTestObject(ctx, test) + httpServer.populateStaticTemplate(response, request, "/", TemplateVariables{}) +} + +func TestBasicHTTPServer_siteFunc(test *testing.T) { + _ = test + ctx := context.TODO() + request := httptest.NewRequest(http.MethodGet, "/", nil) + response := httptest.NewRecorder() + httpServer := getTestObject(ctx, test) + httpServer.siteFunc(response, request) +} + +// ---------------------------------------------------------------------------- +// Internal functions +// ---------------------------------------------------------------------------- + +func getTestObject(ctx context.Context, test *testing.T) *BasicHTTPServer { + _ = ctx + + observer1 := &observer.NullObserver{ + ID: "Observer 1", + } + + logLevelName := "INFO" + osenvLogLevel := os.Getenv("SENZING_LOG_LEVEL") + if len(osenvLogLevel) > 0 { + logLevelName = osenvLogLevel + } + + senzingSettings, err := settings.BuildSimpleSettingsUsingEnvVars() + require.NoError(test, err) + result := &BasicHTTPServer{ + APIUrlRoutePrefix: "api", + AvoidServing: true, + EnableAll: true, + LogLevelName: logLevelName, + ObserverOrigin: "Test Observer origin", + Observers: []observer.Observer{observer1}, + OpenAPISpecificationRest: senzingrestservice.OpenAPISpecificationJSON, + ReadHeaderTimeout: 10 * time.Second, + SenzingInstanceName: "Test HTTP Server", + SenzingSettings: senzingSettings, + SwaggerURLRoutePrefix: "swagger", + TtyOnly: true, + XtermURLRoutePrefix: "xterm", + } + return result } diff --git a/main_test.go b/main_test.go index 8081925..dd3b348 100644 --- a/main_test.go +++ b/main_test.go @@ -10,6 +10,6 @@ import ( */ func TestMain(test *testing.T) { _ = test - os.Args = []string{"command-name", "--help"} + os.Args = []string{"command-name", "--avoid-serving"} main() } From f23ce40cea4f5268d857dbba462d6240f6dc0ff7 Mon Sep 17 00:00:00 2001 From: docktermj Date: Tue, 9 Jul 2024 11:34:09 -0400 Subject: [PATCH 6/8] #58 Prepare for versioned release --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 467331d..54e722b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.1.1] - 2024-07-09 + +### Changed in 0.1.1 + +- Update dependencies + ## [0.1.0] - 2024-05-10 ### Changed in 0.1.0 From 255e43cad3dca1bea7d1ee0c8d244b571ec7f0f5 Mon Sep 17 00:00:00 2001 From: docktermj Date: Tue, 9 Jul 2024 11:41:22 -0400 Subject: [PATCH 7/8] #58 Prepare for versioned release --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index a2977c1..5cfbe98 100755 --- a/Dockerfile +++ b/Dockerfile @@ -65,6 +65,8 @@ COPY --from=go_builder "/output/linux/demo-quickstart" "/app/demo-quickstart" # Install packages via apt-get. +USER root + RUN export STAT_TMP=$(stat --format=%a /tmp) \ && chmod 777 /tmp \ && apt-get update \ From fba8e81e49e2729c562c46ffb40b0954a3ae353d Mon Sep 17 00:00:00 2001 From: docktermj Date: Tue, 9 Jul 2024 14:04:08 -0400 Subject: [PATCH 8/8] #58 Prepare for versioned release --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b90aaf2..d408218 100644 --- a/go.mod +++ b/go.mod @@ -80,7 +80,7 @@ require ( golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 5eb3687..72d01d8 100644 --- a/go.sum +++ b/go.sum @@ -171,8 +171,8 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b h1:04+jVzTs2XBnOZcPsLnmrTGqltqJbZQ1Ey26hjYdQQ0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240708141625-4ad9e859172b/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 h1:SbSDUWW1PAO24TNpLdeheoYPd7kllICcLU52x6eD4kQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=