Skip to content

Commit

Permalink
feat: Create RPCs are idempotent
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinmichaelchen committed Jan 5, 2024
1 parent 01d77fe commit ed1c770
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 45 deletions.
31 changes: 22 additions & 9 deletions cmd/saga/start/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
package service

import (

Check failure on line 4 in cmd/saga/start/service/service.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with -s standard -s default -s prefix(github.com/kevinmichaelchen/temporal-saga-grpc) -s blank -s dot --custom-order (gci)
"context"
"fmt"

temporalConnect "buf.build/gen/go/kevinmichaelchen/temporalapis/connectrpc/go/temporal/v1beta1/temporalv1beta1connect"
temporalPB "buf.build/gen/go/kevinmichaelchen/temporalapis/protocolbuffers/go/temporal/v1beta1"
"connectrpc.com/connect"
"context"

Check failure on line 8 in cmd/saga/start/service/service.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with -s standard -s default -s prefix(github.com/kevinmichaelchen/temporal-saga-grpc) -s blank -s dot --custom-order (gci)
"fmt"
"github.com/bufbuild/protovalidate-go"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
"go.temporal.io/sdk/client"

Expand Down Expand Up @@ -53,10 +53,24 @@ func (s *Service) CreateOnboardingWorkflow(
TaskQueue: saga.CreateLicenseTaskQueue,
}

orgID := uuid.New().String()
profileID := uuid.New().String()

args := saga.CreateLicenseInputArgs{
OrgName: req.Msg.GetOrg().GetName(),
ProfileName: req.Msg.GetProfile().GetName(),
LicenseName: "New License",
Org: saga.Org{
ID: orgID,
Name: req.Msg.GetOrg().GetName(),
},
Profile: saga.Profile{
ID: profileID,
FullName: req.Msg.GetProfile().GetFullName(),
},
License: saga.License{
ID: uuid.New().String(),
Start: req.Msg.GetLicense().GetStart().AsTime(),
End: req.Msg.GetLicense().GetEnd().AsTime(),
UserID: profileID,
},
}

workflow, err := temporalClient.ExecuteWorkflow(
Expand All @@ -83,9 +97,8 @@ func (s *Service) CreateOnboardingWorkflow(

func printResults(args saga.CreateLicenseInputArgs, workflowID, runID string) {
logrus.WithFields(logrus.Fields{
"org_name": args.OrgName,
"profile_name": args.ProfileName,
"license_name": args.LicenseName,
"org_name": args.Org.Name,
"profile_name": args.Profile.FullName,
"temporal.workflow_id": workflowID,
"temporal.run_id": runID,
}).Info("Successfully completed Workflow")
Expand Down
2 changes: 1 addition & 1 deletion cmd/saga/start/service/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestValidate(t *testing.T) {
Name: "Name",
},
Profile: &temporalPB.Profile{
Name: "Name",
FullName: "Name",
},
}
}
Expand Down
7 changes: 6 additions & 1 deletion cmd/svc/license/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ func (s *Service) CreateLicense(

res := &licensev1beta1.CreateLicenseResponse{}

logrus.WithField("name", req.Msg.GetName()).Info("Creating License")
logrus.
WithField("id", req.Msg.GetId()).
WithField("user_id", req.Msg.GetUserId()).
WithField("start", req.Msg.GetStart()).
WithField("end", req.Msg.GetEnd()).
Info("Creating License")

out := connect.NewResponse(res)
out.Header().Set("API-Version", "v1beta1")
Expand Down
5 changes: 4 additions & 1 deletion cmd/svc/org/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ func (s *Service) CreateOrg(

res := &orgPB.CreateOrgResponse{}

logrus.WithField("name", req.Msg.GetName()).Info("Creating Org")
logrus.
WithField("id", req.Msg.GetId()).
WithField("name", req.Msg.GetName()).
Info("Creating Org")

out := connect.NewResponse(res)
out.Header().Set("API-Version", "v1beta1")
Expand Down
6 changes: 5 additions & 1 deletion cmd/svc/profile/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ func (s *Service) CreateProfile(

res := &profilePB.CreateProfileResponse{}

logrus.WithField("name", req.Msg.GetName()).Info("Creating Profile")
logrus.
WithField("id", req.Msg.GetId()).
WithField("org_id", req.Msg.GetOrgId()).
WithField("name", req.Msg.GetFullName()).
Info("Creating Profile")

out := connect.NewResponse(res)
out.Header().Set("API-Version", "v1beta1")
Expand Down
18 changes: 9 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ module github.com/kevinmichaelchen/temporal-saga-grpc
go 1.21.5

require (
buf.build/gen/go/kevinmichaelchen/licenseapis/connectrpc/go v1.14.0-20231230182852-a5b0c8441680.1
buf.build/gen/go/kevinmichaelchen/licenseapis/protocolbuffers/go v1.32.0-20231230182852-a5b0c8441680.1
buf.build/gen/go/kevinmichaelchen/orgapis/connectrpc/go v1.14.0-20231230143300-f1e12ab42c62.1
buf.build/gen/go/kevinmichaelchen/orgapis/protocolbuffers/go v1.32.0-20231230143300-f1e12ab42c62.1
buf.build/gen/go/kevinmichaelchen/profileapis/connectrpc/go v1.14.0-20231230143301-839882cce539.1
buf.build/gen/go/kevinmichaelchen/profileapis/protocolbuffers/go v1.32.0-20231230143301-839882cce539.1
buf.build/gen/go/kevinmichaelchen/temporalapis/connectrpc/go v1.14.0-20231230182854-8d9d2e3ad33c.1
buf.build/gen/go/kevinmichaelchen/temporalapis/protocolbuffers/go v1.32.0-20231230182854-8d9d2e3ad33c.1
buf.build/gen/go/kevinmichaelchen/licenseapis/connectrpc/go v1.14.0-20240105230935-96a83ee74301.1
buf.build/gen/go/kevinmichaelchen/licenseapis/protocolbuffers/go v1.32.0-20240105230935-96a83ee74301.1
buf.build/gen/go/kevinmichaelchen/orgapis/connectrpc/go v1.14.0-20240105230936-cc69561a5883.1
buf.build/gen/go/kevinmichaelchen/orgapis/protocolbuffers/go v1.32.0-20240105230936-cc69561a5883.1
buf.build/gen/go/kevinmichaelchen/profileapis/connectrpc/go v1.14.0-20240105230937-9f5a2b967cc7.1
buf.build/gen/go/kevinmichaelchen/profileapis/protocolbuffers/go v1.32.0-20240105230937-9f5a2b967cc7.1
buf.build/gen/go/kevinmichaelchen/temporalapis/connectrpc/go v1.14.0-20240105224636-721997cf176e.1
buf.build/gen/go/kevinmichaelchen/temporalapis/protocolbuffers/go v1.32.0-20240105224636-721997cf176e.1
connectrpc.com/connect v1.14.0
connectrpc.com/grpchealth v1.3.0
connectrpc.com/grpcreflect v1.2.0
Expand All @@ -25,7 +25,7 @@ require (
github.com/stretchr/testify v1.8.4
github.com/volatiletech/null/v8 v8.1.2
github.com/volatiletech/sqlboiler/v4 v4.15.0
github.com/volatiletech/strmangle v0.0.5
github.com/volatiletech/strmangle v0.0.6
go.opentelemetry.io/otel v1.21.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0
go.opentelemetry.io/otel/sdk v1.21.0
Expand Down
35 changes: 18 additions & 17 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.32.0-20231115204500-e097f827e652.1 h1:u0olL4yf2p7Tl5jfsAK5keaFi+JFJuv1CDHrbiXkxkk=
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.32.0-20231115204500-e097f827e652.1/go.mod h1:tiTMKD8j6Pd/D2WzREoweufjzaJKHZg35f/VGcZ2v3I=
buf.build/gen/go/kevinmichaelchen/licenseapis/connectrpc/go v1.14.0-20231230182852-a5b0c8441680.1 h1:Li+ostVf9g8qR1aXY5JyQJJCsszfazjWSigIfG5F+gQ=
buf.build/gen/go/kevinmichaelchen/licenseapis/connectrpc/go v1.14.0-20231230182852-a5b0c8441680.1/go.mod h1:AnmQTTp9GU6KlMj64LOa2aj0ZLeY+7g8n3RfH+tNO4c=
buf.build/gen/go/kevinmichaelchen/licenseapis/protocolbuffers/go v1.32.0-20231230182852-a5b0c8441680.1 h1:iP5aO8HJdXvq7pL+EKLq3I6wkw37KS9BTtizhO/m8V4=
buf.build/gen/go/kevinmichaelchen/licenseapis/protocolbuffers/go v1.32.0-20231230182852-a5b0c8441680.1/go.mod h1:f0zTv4+cZ3+O0fQx7E6JKpPLhQuUJMkl+M7Ott4b4wo=
buf.build/gen/go/kevinmichaelchen/orgapis/connectrpc/go v1.14.0-20231230143300-f1e12ab42c62.1 h1:GvCPyGpxUQ1GK6dZ63fuAqnULnRGaVzTuN3xdMGpUj0=
buf.build/gen/go/kevinmichaelchen/orgapis/connectrpc/go v1.14.0-20231230143300-f1e12ab42c62.1/go.mod h1:k9MXsI946kP98De3USAMI1C+FJa23s2cbJQRgDa7ebY=
buf.build/gen/go/kevinmichaelchen/orgapis/protocolbuffers/go v1.32.0-20231230143300-f1e12ab42c62.1 h1:VLe/5LqsGoc+P2b0dW/u1/ppt6TUap0dzwU27k4hFUw=
buf.build/gen/go/kevinmichaelchen/orgapis/protocolbuffers/go v1.32.0-20231230143300-f1e12ab42c62.1/go.mod h1:01Q17lfPPU5yLwTfmXR7xxcgheeltV8MnYDOBK/76UE=
buf.build/gen/go/kevinmichaelchen/profileapis/connectrpc/go v1.14.0-20231230143301-839882cce539.1 h1:h0uNblC7l/WCFK2SoxWbaR/YHoNN4JPOQopgFMPezLQ=
buf.build/gen/go/kevinmichaelchen/profileapis/connectrpc/go v1.14.0-20231230143301-839882cce539.1/go.mod h1:feIZBXMSAhget6j1/h9kospvcT9gd71lMRYVv9S/N0A=
buf.build/gen/go/kevinmichaelchen/profileapis/protocolbuffers/go v1.32.0-20231230143301-839882cce539.1 h1:Cf1gSTF6fcrqwwZonbKV3vtiGW9NmBxq2czibB80ReA=
buf.build/gen/go/kevinmichaelchen/profileapis/protocolbuffers/go v1.32.0-20231230143301-839882cce539.1/go.mod h1:CThAb0pmoNp60CIAHgS3gRBKiFL50Frrsw1pfWGzodg=
buf.build/gen/go/kevinmichaelchen/temporalapis/connectrpc/go v1.14.0-20231230182854-8d9d2e3ad33c.1 h1:In+vy2TA5flkwluSZDfUepAMuhNFu/p43PxvcTVzD8E=
buf.build/gen/go/kevinmichaelchen/temporalapis/connectrpc/go v1.14.0-20231230182854-8d9d2e3ad33c.1/go.mod h1:4pucHCVy5j99kBB5OYo5a0IZQCcmzxUAF4/4/oYIgSg=
buf.build/gen/go/kevinmichaelchen/temporalapis/protocolbuffers/go v1.32.0-20231230182854-8d9d2e3ad33c.1 h1:M/lKXqOTBbQhYf9PpswPYpAvDHtImHtUMSg5xZiHSvo=
buf.build/gen/go/kevinmichaelchen/temporalapis/protocolbuffers/go v1.32.0-20231230182854-8d9d2e3ad33c.1/go.mod h1:2Mpji+rUNpkV7r9a5cIDXpKJMRYmp0I0XrM61EBLEDY=
buf.build/gen/go/kevinmichaelchen/licenseapis/connectrpc/go v1.14.0-20240105230935-96a83ee74301.1 h1:iz8B4/o/Tu9kCU1O61ce9LoMO4cruyKOxZg+Xn3jkIk=
buf.build/gen/go/kevinmichaelchen/licenseapis/connectrpc/go v1.14.0-20240105230935-96a83ee74301.1/go.mod h1:TWnyka2/a0+psN92AVScMT7Sq3mKdjCAWLjcfLQDMgk=
buf.build/gen/go/kevinmichaelchen/licenseapis/protocolbuffers/go v1.32.0-20240105230935-96a83ee74301.1 h1:uxRlX4/HFwA//ZcSZdryz5Nk9hzsLWRUMnmJjwQGA7s=
buf.build/gen/go/kevinmichaelchen/licenseapis/protocolbuffers/go v1.32.0-20240105230935-96a83ee74301.1/go.mod h1:f0zTv4+cZ3+O0fQx7E6JKpPLhQuUJMkl+M7Ott4b4wo=
buf.build/gen/go/kevinmichaelchen/orgapis/connectrpc/go v1.14.0-20240105230936-cc69561a5883.1 h1:w6j+cfXANJ3mFei+DLs8afQp305z35sSXJdrVTP+Kig=
buf.build/gen/go/kevinmichaelchen/orgapis/connectrpc/go v1.14.0-20240105230936-cc69561a5883.1/go.mod h1:2c3rsXGY3Zpto2kEM0hr3bTrvRqcUQzlPF5Glj/Xjno=
buf.build/gen/go/kevinmichaelchen/orgapis/protocolbuffers/go v1.32.0-20240105230936-cc69561a5883.1 h1:pHMAxU1GI79GvmdTi2mfOKDRaPWqZ7UqMSoyxBVLp9U=
buf.build/gen/go/kevinmichaelchen/orgapis/protocolbuffers/go v1.32.0-20240105230936-cc69561a5883.1/go.mod h1:VX7SaxTl48U3BUn1ZWGPaw3Z3trZei6Lijff1hWDCmM=
buf.build/gen/go/kevinmichaelchen/profileapis/connectrpc/go v1.14.0-20240105230937-9f5a2b967cc7.1 h1:+pGDboLYUQSzr+YieYCoY1AP9RtL69rLKhBx5tNzwT4=
buf.build/gen/go/kevinmichaelchen/profileapis/connectrpc/go v1.14.0-20240105230937-9f5a2b967cc7.1/go.mod h1:yZWWCij9/6ffN2PJwEYWgs7DjkWa5cXl2AR8Xvnc+Ng=
buf.build/gen/go/kevinmichaelchen/profileapis/protocolbuffers/go v1.32.0-20240105230937-9f5a2b967cc7.1 h1:YaUHKKR7AZRrnCiZ+QOQuw2wQB0DlOe8KBdN7bDymhs=
buf.build/gen/go/kevinmichaelchen/profileapis/protocolbuffers/go v1.32.0-20240105230937-9f5a2b967cc7.1/go.mod h1:mdFxPRDe6P7qFVw9urFLZ3SkG+ZdPW5q5QXFGjGr8DE=
buf.build/gen/go/kevinmichaelchen/temporalapis/connectrpc/go v1.14.0-20240105224636-721997cf176e.1 h1:JRUSsAPd9V5UQFPYs1dckEwRS0R/bAQtCRlRRQ+n9Pw=
buf.build/gen/go/kevinmichaelchen/temporalapis/connectrpc/go v1.14.0-20240105224636-721997cf176e.1/go.mod h1:2PeRAbDFPMunT2xjMRMjvkzCGgilVlNWYwgYRatp3/4=
buf.build/gen/go/kevinmichaelchen/temporalapis/protocolbuffers/go v1.32.0-20240105224636-721997cf176e.1 h1:3dN5NHBYnXnHPa2qG22eeVYNG/ZwAni9potlZz6XcNA=
buf.build/gen/go/kevinmichaelchen/temporalapis/protocolbuffers/go v1.32.0-20240105224636-721997cf176e.1/go.mod h1:2Mpji+rUNpkV7r9a5cIDXpKJMRYmp0I0XrM61EBLEDY=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
Expand Down Expand Up @@ -1317,8 +1317,9 @@ github.com/volatiletech/randomize v0.0.1/go.mod h1:GN3U0QYqfZ9FOJ67bzax1cqZ5q2xu
github.com/volatiletech/sqlboiler/v4 v4.15.0 h1:+twm3mA34SaUF6wB9U6QkXxkK8AKkV5EfgMSvcKWeY4=
github.com/volatiletech/sqlboiler/v4 v4.15.0/go.mod h1:s643wqYyCQ7Ak2hMVxH7kTS0+lFPNlj+gHKUIukJ0YA=
github.com/volatiletech/strmangle v0.0.1/go.mod h1:F6RA6IkB5vq0yTG4GQ0UsbbRcl3ni9P76i+JrTBKFFg=
github.com/volatiletech/strmangle v0.0.5 h1:CompJPy+lAi9h+YU/IzBR4X2RDRuAuEIP+kjFdyZXcU=
github.com/volatiletech/strmangle v0.0.5/go.mod h1:ycDvbDkjDvhC0NUU8w3fWwl5JEMTV56vTKXzR3GeR+0=
github.com/volatiletech/strmangle v0.0.6 h1:AdOYE3B2ygRDq4rXDij/MMwq6KVK/pWAYxpC7CLrkKQ=
github.com/volatiletech/strmangle v0.0.6/go.mod h1:ycDvbDkjDvhC0NUU8w3fWwl5JEMTV56vTKXzR3GeR+0=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
13 changes: 10 additions & 3 deletions pkg/saga/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package saga
import (
"context"
"fmt"

Check failure on line 5 in pkg/saga/activity.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
"google.golang.org/protobuf/types/known/timestamppb"

Check failure on line 6 in pkg/saga/activity.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with -s standard -s default -s prefix(github.com/kevinmichaelchen/temporal-saga-grpc) -s blank -s dot --custom-order (gci)

license "buf.build/gen/go/kevinmichaelchen/licenseapis/protocolbuffers/go/license/v1beta1"
org "buf.build/gen/go/kevinmichaelchen/orgapis/protocolbuffers/go/org/v1beta1"
Expand All @@ -14,7 +15,8 @@ import (
func (c *Controller) CreateOrg(ctx context.Context, args CreateLicenseInputArgs) error {
_, err := c.orgClient.CreateOrg(ctx, connect.NewRequest(
&org.CreateOrgRequest{
Name: args.OrgName,
Id: args.Org.ID,
Name: args.Org.Name,
},
))
if err != nil {
Expand All @@ -28,7 +30,9 @@ func (c *Controller) CreateOrg(ctx context.Context, args CreateLicenseInputArgs)
func (c *Controller) CreateProfile(ctx context.Context, args CreateLicenseInputArgs) error {
_, err := c.profileClient.CreateProfile(ctx, connect.NewRequest(
&profile.CreateProfileRequest{
Name: args.ProfileName,
Id: args.Profile.ID,
OrgId: args.Profile.OrgID,
FullName: args.Profile.FullName,
},
))
if err != nil {
Expand All @@ -42,7 +46,10 @@ func (c *Controller) CreateProfile(ctx context.Context, args CreateLicenseInputA
func (c *Controller) CreateLicense(ctx context.Context, args CreateLicenseInputArgs) error {
_, err := c.licenseClient.CreateLicense(ctx, connect.NewRequest(
&license.CreateLicenseRequest{
Name: args.LicenseName,
Id: args.License.ID,
Start: timestamppb.New(args.License.Start),
End: timestamppb.New(args.License.End),
UserId: args.License.UserID,
},
))
if err != nil {
Expand Down
26 changes: 23 additions & 3 deletions pkg/saga/shared.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
package saga

import "time"

// CreateLicenseTaskQueue - Queue name for workflow tasks.
const CreateLicenseTaskQueue = "CREATE_LICENSE_TASK_QUEUE"

// CreateLicenseInputArgs - Arguments to kick off the Temporal workflow.
type CreateLicenseInputArgs struct {
OrgName string
ProfileName string
LicenseName string
Org Org
Profile Profile
License License
}

type Org struct {

Check failure on line 15 in pkg/saga/shared.go

View workflow job for this annotation

GitHub Actions / lint

exported: exported type Org should have comment or be unexported (revive)
ID string
Name string
}

type Profile struct {

Check failure on line 20 in pkg/saga/shared.go

View workflow job for this annotation

GitHub Actions / lint

exported: exported type Profile should have comment or be unexported (revive)
ID string
FullName string
OrgID string
}

type License struct {

Check failure on line 26 in pkg/saga/shared.go

View workflow job for this annotation

GitHub Actions / lint

exported: exported type License should have comment or be unexported (revive)
ID string
Start time.Time
End time.Time
UserID string
}

0 comments on commit ed1c770

Please sign in to comment.