Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-generated Pull Request for feat/content-loader #352

Merged
merged 17 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
74f6109
refactor(logger.go): replace ioutil.TempFile with os.CreateTemp for c…
cybersiddhu Feb 2, 2024
f2ee56a
feat(keys.go): add ContentClientKey and ContentClient constants
cybersiddhu Feb 2, 2024
6fc5bb2
feat(stockcenter.go): add content API client to stockcenter registry
cybersiddhu Feb 2, 2024
12f0cb7
feat(client.go): add SetContentAPIClient function to establish grpc c…
cybersiddhu Feb 2, 2024
53fe3a7
feat(client.go): add NewCliS3Client function to support urfave/cli co…
cybersiddhu Feb 2, 2024
e88045e
feat(client.go): add SetS3Client function to initialize S3 client
cybersiddhu Feb 2, 2024
8a128a0
refactor(main.go, logger.go): move setupCliLogger function from main.…
cybersiddhu Feb 2, 2024
8779261
feat(client.go): add new client.go file with SetS3Client and SetConte…
cybersiddhu Feb 2, 2024
2367e79
feat(cli/flag.go): add ContentLoaderFlags function to handle CLI flags
cybersiddhu Feb 2, 2024
878c0c8
feat(action.go): add LoadContent function to handle S3 objects
cybersiddhu Feb 2, 2024
b2b740f
feat(client.go): add CliSetup function to initialize S3 and ContentAP…
cybersiddhu Feb 2, 2024
cf9a445
feat(main.go): add new loader command line application
cybersiddhu Feb 2, 2024
8976a48
chore(go.mod): update dependencies for better functionality and security
cybersiddhu Feb 5, 2024
2c23c16
feat(action.go): add comprehensive content processing from S3 bucket
cybersiddhu Feb 5, 2024
010e4f2
refactor(plasmid.go): replace ioutil with os and fs for directory rea…
cybersiddhu Feb 5, 2024
58bc5e2
chore(lint.yml): update Go version from 1.20 to 1.21 and linter versi…
cybersiddhu Feb 5, 2024
fdf63d0
refactor(action.go): remove unused variable sct in storeOrUpdateConte…
cybersiddhu Feb 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions cmd/loader/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"fmt"
"os"

contentcli "github.com/dictyBase/modware-import/internal/content/cli"
"github.com/dictyBase/modware-import/internal/content/client"
"github.com/dictyBase/modware-import/internal/logger"
"github.com/urfave/cli/v2"
)

func main() {
app := &cli.App{
Name: "loader",
Usage: "A command line application for loading data",
Before: logger.SetupCliLogger,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "log-level",
Usage: "Logging level, should be one of debug,warn,info or error",
Value: "error",
},
&cli.StringFlag{
Name: "log-format",
Usage: "Format of log, either of json or text",
Value: "json",
},
&cli.StringFlag{
Name: "log-file",
Usage: "log file for output in addition to stderr",
},
},
Commands: []*cli.Command{
{
Name: "content-data",
Usage: "load content data from s3 storage",
Action: contentcli.LoadContent,
Flags: contentcli.ContentLoaderFlags(),
Before: client.CliSetup,
},
},
}

err := app.Run(os.Args)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
11 changes: 1 addition & 10 deletions cmd/logto/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func main() {
app := &cli.App{
Name: "logto",
Usage: "A command line application for logto instance management",
Before: setupCliLogger,
Before: logger.SetupCliLogger,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "endpoint",
Expand Down Expand Up @@ -96,12 +96,3 @@ func setupTTLCache(cltx *cli.Context) error {
registry.SetReader("USER_INPUT", reader)
return nil
}

func setupCliLogger(cltx *cli.Context) error {
l, err := logger.NewCliLogger(cltx)
if err != nil {
return fmt.Errorf("error in getting a new logger %s", err)
}
registry.SetLogger(l)
return nil
}
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/dictyBase/aphgrpc v1.4.2
github.com/dictyBase/arangomanager v0.4.0
github.com/dictyBase/go-genproto v0.0.0-20211001224012-6cf691015622
github.com/dictyBase/go-genproto v0.0.0-20231030202356-522cb6f9976a
github.com/dictyBase/go-obograph v1.6.0
github.com/dictybase-playground/gobio v0.0.0-20190320200520-c29a8b327c1f
github.com/emirpasic/gods v1.18.1
Expand Down Expand Up @@ -48,11 +48,12 @@ require (
)

require (
github.com/IBM/fp-go v1.0.110
github.com/jedib0t/go-pretty/v6 v6.5.4
github.com/jellydator/ttlcache/v3 v3.1.0
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.8.4
github.com/urfave/cli/v2 v2.25.7
github.com/urfave/cli/v2 v2.27.1
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
)

Expand Down Expand Up @@ -120,7 +121,7 @@ require (
github.com/subosito/gotenv v1.6.0 // indirect
github.com/urfave/cli v1.22.14 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/mod v0.14.0 // indirect
Expand Down
14 changes: 8 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4 h1:vdT7QwBhJJEVNFMBNhRSFDRCB6O16T28VhvqRgqFyn8=
github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4/go.mod h1:SvXOG8ElV28oAiG9zv91SDe5+9PfIr7PPccpr8YyXNs=
github.com/IBM/fp-go v1.0.110 h1:aGYVOMwqEdRR73aOGkf400lv5mCWNJo04zcvNqgRbQs=
github.com/IBM/fp-go v1.0.110/go.mod h1:qqstC2fZZZajHWYAIj6GGxqiKnnWiBjfJzGRcB3mqGs=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
Expand Down Expand Up @@ -53,8 +55,8 @@ github.com/dictyBase/aphgrpc v1.4.2 h1:jkNyIpUBATNVNTM99TfAHln8UEpzyvNNNuM2+UY6t
github.com/dictyBase/aphgrpc v1.4.2/go.mod h1:rzi2U95QntAuS6XpqespgZmQ8Ujo2Sq2R5FyhW5adA8=
github.com/dictyBase/arangomanager v0.4.0 h1:+HgmadUY0qXFMLfZocktynbERkX/FgWzC3vd/MMebnU=
github.com/dictyBase/arangomanager v0.4.0/go.mod h1:SmElsQJN3EbTjfYCkjS7/uyUkNVwaO2qJB9Mqrs0ND8=
github.com/dictyBase/go-genproto v0.0.0-20211001224012-6cf691015622 h1:UqICH4tshsyfhtwFv/0i48bddx9cJXcPsYEbZFVyULE=
github.com/dictyBase/go-genproto v0.0.0-20211001224012-6cf691015622/go.mod h1:KY6iUqXl1lLq81WTW9u5DfZE58xM61PsGLSLwwtePlk=
github.com/dictyBase/go-genproto v0.0.0-20231030202356-522cb6f9976a h1:V0xN+gehQLCJrqFPI1nNd8wCIi6Z0ZQgmoZ6dmkPlV0=
github.com/dictyBase/go-genproto v0.0.0-20231030202356-522cb6f9976a/go.mod h1:KY6iUqXl1lLq81WTW9u5DfZE58xM61PsGLSLwwtePlk=
github.com/dictyBase/go-obograph v1.6.0 h1:otuiEadRCJ25o6X/5tWhDjiiAbK0R8LBLQpBxVREotc=
github.com/dictyBase/go-obograph v1.6.0/go.mod h1:osNZ7PRqai1OTnrLy8SoDavKIMaDp7Sw8CFh52ddBkY=
github.com/dictybase-playground/gobio v0.0.0-20190320200520-c29a8b327c1f h1:4iSwwwVRNLZDA1mc+RuuIU1lFHoUp/7MVDbsLC8tNiY=
Expand Down Expand Up @@ -336,12 +338,12 @@ github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKk
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI=
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
Expand Down
216 changes: 216 additions & 0 deletions internal/content/cli/action.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package cli

import (
"context"
"fmt"
"io"
"regexp"
"strings"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

A "github.com/IBM/fp-go/array"
Fn "github.com/IBM/fp-go/function"
O "github.com/IBM/fp-go/option"
"github.com/dictyBase/go-genproto/dictybaseapis/content"
"github.com/dictyBase/modware-import/internal/registry"
regsc "github.com/dictyBase/modware-import/internal/registry/stockcenter"
"github.com/minio/minio-go/v6"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)

var noncharReg = regexp.MustCompile("[^a-z0-9]+")

func Slugify(name string) string {
return strings.Trim(
noncharReg.ReplaceAllString(strings.ToLower(name), "-"),
"-",
)
}

func LoadContent(cltx *cli.Context) error {
logger := registry.GetLogger()
s3Client := registry.GetS3Client()
client := regsc.GetContentAPIClient()

doneCh := make(chan struct{})
defer close(doneCh)
s3Objects := listS3Objects(cltx, s3Client, doneCh)

for cinfo := range s3Objects {
err := processS3Object(cltx, logger, s3Client, client, cinfo)
if err != nil {
return cli.Exit(err.Error(), 2)
}
}

return nil
}

func listS3Objects(
cltx *cli.Context,
s3Client *minio.Client,
doneCh chan struct{},
) <-chan minio.ObjectInfo {
return s3Client.ListObjects(
cltx.String("s3-bucket"),
cltx.String("s3-bucket-path"),
true,
doneCh,
)
}

func processS3Object(
cltx *cli.Context,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function processS3Object has 5 arguments (exceeds 4 allowed). Consider refactoring.

logger *logrus.Entry,
s3Client *minio.Client,
client content.ContentServiceClient,
cinfo minio.ObjectInfo,
) error {
sinfo, err := s3Client.StatObject(
cltx.String("s3-bucket"), cinfo.Key, minio.StatObjectOptions{},
)
if err != nil {
return fmt.Errorf(
"error in getting information for object %s %s",
sinfo.Key,
err,
)
}
logger.Infof("read content file %s", sinfo.Key)

jsonContent, err := getContent(cltx, s3Client, sinfo)
if err != nil {
return err
}

name, namespace := nameAndNamespace(sinfo.Key)
slug := Slugify(fmt.Sprintf("%s %s", name, namespace))

err = storeOrUpdateContent(
client,
slug,
name,
namespace,
jsonContent,
logger,
sinfo,
)
if err != nil {
return err
}

return nil
}

func getContent(
cltx *cli.Context,
s3Client *minio.Client,
sinfo minio.ObjectInfo,
) ([]byte, error) {
obj, err := s3Client.GetObject(
cltx.String("s3-bucket"), sinfo.Key, minio.GetObjectOptions{},
)
if err != nil {
return nil, fmt.Errorf("error in getting object %s", err)
}
jsonContent, err := io.ReadAll(obj)
if err != nil {
return nil, fmt.Errorf(
"error in reading content for file %s %s",
sinfo.Key,
err,
)
}

return jsonContent, nil
}

func storeOrUpdateContent(
client content.ContentServiceClient,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function storeOrUpdateContent has 5 arguments (exceeds 4 allowed). Consider refactoring.

slug, name, namespace string,
jsonContent []byte,
logger *logrus.Entry,
sinfo minio.ObjectInfo,
) error {
sct, err := client.GetContentBySlug(
context.Background(),
&content.ContentRequest{
Slug: slug,
},
)
if err != nil {
if status.Code(err) == codes.NotFound {
return createStoreContent(
client,
name,
namespace,
string(jsonContent),
slug,
logger,
sinfo,
)
}
return fmt.Errorf(
"error in fetching content %s %s %s",
sinfo.Key,
sct.Data.Attributes.Name,
sct.Data.Attributes.Namespace,
)
}
logger.Infof("found existing content %s %s %s", sinfo.Key, name, namespace)

return nil
}

func createStoreContent(
client content.ContentServiceClient,
name, namespace, jsonContent, slug string,
logger *logrus.Entry,
sinfo minio.ObjectInfo,
) error {
nct, err := client.StoreContent(
context.Background(),
&content.StoreContentRequest{
Data: &content.StoreContentRequest_Data{
Attributes: &content.NewContentAttributes{
Name: name,
Namespace: namespace,
CreatedBy: "[email protected]",
Content: jsonContent,
Slug: slug,
},
},
},
)
if err != nil {
return fmt.Errorf(
"error in creating content %s %s %s",
sinfo.Key,
name,
namespace,
)
}
logger.Infof(
"created content %s %s %s",
sinfo.Key,
nct.Data.Attributes.Name,
nct.Data.Attributes.Namespace,
)

return nil
}

func nameAndNamespace(input string) (string, string) {
output := Fn.Pipe4(
strings.Split(input, "/"),
A.Last,
O.Map(func(val string) []string { return strings.Split(val, ".") }),
O.Map(func(val []string) string { return val[0] }),
O.Map(func(val string) []string { return strings.Split(val, "-") }),
)
data, _ := O.Unwrap(output)
return data[1], data[0]
}
Loading
Loading