Skip to content

Commit 32f65d2

Browse files
FEAT[DXTA-323]: Add onboarding endpoints to trigger workflows (#707)
* feat: Add endpoints and handlers to trigger onbaording workflows * refactor: Remove unused func and rename type
1 parent 0a28bbe commit 32f65d2

5 files changed

Lines changed: 172 additions & 32 deletions

File tree

cmd/internal-api/main.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,6 @@ func main() {
129129

130130
defer temporalClient.Close()
131131

132-
usersHandler := handler.NewUsers(temporalClient, *cfg)
133-
134132
r.Route("/tenant", func(r chi.Router) {
135133
if os.Getenv("ENABLE_JWT_AUTH") == "true" {
136134
pubKey, _ := util.GetRawPublicKey()
@@ -139,16 +137,37 @@ func main() {
139137

140138
r.Use(jwtauth.Verifier(tokenAuth))
141139
r.Use(util.Authenticator())
140+
} else {
141+
// TO-DO Handle different type of auth or no auth at all
142+
// right now just exit with error
143+
log.Fatalln("Enable jwt auth")
142144
}
143145

144-
// TO-DO Add middleware if we don't authenticate with JWT
145-
// https://app.plane.so/crocoder/browse/DXTA-307/
146-
147146
r.Post("/teams", handler.CreateTeam)
148147
r.Post("/teams/{team_id}/members/{member_id}", handler.AddMemberToTeam)
149148
r.Post("/members", handler.CreateMember)
150149
})
151150

151+
temporalHandler := handler.NewTemporalHandler(temporalClient, *cfg)
152+
153+
r.Route("/onboarding", func(r chi.Router) {
154+
if os.Getenv("ENABLE_JWT_AUTH") == "true" {
155+
pubKey, _ := util.GetRawPublicKey()
156+
157+
tokenAuth := util.CreateAuthVerifier(pubKey)
158+
159+
r.Use(jwtauth.Verifier(tokenAuth))
160+
r.Use(util.Authenticator())
161+
} else {
162+
// TO-DO Handle different type of auth or no auth at all
163+
// right now just exit with error
164+
log.Fatalln("Enable jwt auth")
165+
}
166+
167+
r.Post("/databases", temporalHandler.CreateTenantDB)
168+
r.Post("/github-installation", temporalHandler.GithubInstallation)
169+
})
170+
152171
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
153172
w.Write([]byte(`OK`))
154173
})
@@ -157,7 +176,7 @@ func main() {
157176
w.Write([]byte(`OK`))
158177
})
159178

160-
r.Get("/users-count", usersHandler.UsersCount)
179+
r.Get("/users-count", temporalHandler.UsersCount)
161180

162181
go func() {
163182
log.Printf("Listening on %s\n", srv.Addr)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package handler
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
8+
"github.com/dxta-dev/app/internal/onboarding"
9+
"github.com/dxta-dev/app/internal/onboarding/workflow"
10+
"github.com/dxta-dev/app/internal/util"
11+
"go.temporal.io/sdk/client"
12+
)
13+
14+
type CreateDatabaseRequestBody struct {
15+
DBName string `json:"dbName"`
16+
OrganizationName string `json:"organizationName"`
17+
}
18+
19+
type TemporalHandler struct {
20+
temporalClient client.Client
21+
config onboarding.Config
22+
}
23+
24+
func NewTemporalHandler(temporalClient client.Client, config onboarding.Config) *TemporalHandler {
25+
return &TemporalHandler{
26+
temporalClient,
27+
config,
28+
}
29+
}
30+
31+
func (th *TemporalHandler) CreateTenantDB(w http.ResponseWriter, r *http.Request) {
32+
ctx := r.Context()
33+
34+
body := &CreateDatabaseRequestBody{}
35+
36+
if err := json.NewDecoder(r.Body).Decode(body); err != nil {
37+
fmt.Printf("Issue while parsing body. Error: %s", err.Error())
38+
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
39+
return
40+
}
41+
42+
if body.DBName == "" || body.OrganizationName == "" {
43+
fmt.Printf("Bad request body: %v", body)
44+
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
45+
return
46+
}
47+
48+
authId := ctx.Value(util.AuthIdCtxKey).(string)
49+
50+
_, err := workflow.ExecuteCreateTenantDBWorkflow(ctx, th.temporalClient, workflow.ExecuteCreateTenantDBWorkflowParams{
51+
TemporalOnboardingQueueName: th.config.TemporalOnboardingQueueName,
52+
AuthID: authId,
53+
DBName: body.DBName,
54+
OrganizationName: body.OrganizationName,
55+
})
56+
57+
if err != nil {
58+
fmt.Printf("Failed to execute CreateTenantDBWorkflow with error: %s", err.Error())
59+
util.JSONError(
60+
w,
61+
util.ErrorParam{Error: "Failed to execute CreateTenantDBWorkflow"},
62+
http.StatusInternalServerError,
63+
)
64+
}
65+
66+
w.Header().Set("Content-Type", "application/json")
67+
w.WriteHeader(http.StatusOK)
68+
69+
if err := json.NewEncoder(w).Encode(struct{ Message string }{Message: "OK"}); err != nil {
70+
fmt.Printf("Issue while formatting response. Error: %s", err.Error())
71+
util.JSONError(
72+
w,
73+
util.ErrorParam{Error: "Internal Server Error"},
74+
http.StatusInternalServerError,
75+
)
76+
return
77+
}
78+
79+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package handler
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
8+
"github.com/dxta-dev/app/internal/onboarding/workflow"
9+
"github.com/dxta-dev/app/internal/util"
10+
)
11+
12+
type GithubInstallationRequestBody struct {
13+
InstallationID int64 `json:"installationId"`
14+
DBURL string `json:"dbUrl"`
15+
DBDomainName string `json:"dbDomainName"`
16+
}
17+
18+
func (th *TemporalHandler) GithubInstallation(w http.ResponseWriter, r *http.Request) {
19+
ctx := r.Context()
20+
21+
body := &GithubInstallationRequestBody{}
22+
23+
if err := json.NewDecoder(r.Body).Decode(body); err != nil {
24+
fmt.Printf("Issue while parsing body. Error: %s", err.Error())
25+
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
26+
return
27+
}
28+
29+
if body.InstallationID == 0 || body.DBURL == "" || body.DBDomainName == "" {
30+
fmt.Printf("Bad request body %v", body)
31+
util.JSONError(w, util.ErrorParam{Error: "Bad Request"}, http.StatusBadRequest)
32+
}
33+
34+
authId := ctx.Value(util.AuthIdCtxKey).(string)
35+
36+
_, err := workflow.ExecuteAfterGithubInstallationWorkflow(ctx, th.temporalClient, workflow.ExecuteAfterGithubInstallationParams{
37+
TemporalOnboardingQueueName: th.config.TemporalOnboardingQueueName,
38+
AuthID: authId,
39+
InstallationID: body.InstallationID,
40+
DBURL: body.DBURL,
41+
DBDomainName: body.DBDomainName,
42+
})
43+
44+
if err != nil {
45+
fmt.Printf("Failed to execute AfterGithubInstallationWorkflow with error: %s", err.Error())
46+
util.JSONError(
47+
w,
48+
util.ErrorParam{Error: "Failed to execute AfterGithubInstallationWorkflow"},
49+
http.StatusInternalServerError,
50+
)
51+
}
52+
53+
w.Header().Set("Content-Type", "application/json")
54+
w.WriteHeader(http.StatusOK)
55+
56+
if err := json.NewEncoder(w).Encode(struct{ Message string }{Message: "OK"}); err != nil {
57+
fmt.Printf("Issue while formatting response. Error: %s", err.Error())
58+
util.JSONError(
59+
w,
60+
util.ErrorParam{Error: "Internal Server Error"},
61+
http.StatusInternalServerError,
62+
)
63+
return
64+
}
65+
66+
}

internal/internal-api/handler/users_count.go

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,16 @@ import (
77
"log"
88
"net/http"
99

10-
"github.com/dxta-dev/app/internal/onboarding"
1110
"github.com/dxta-dev/app/internal/onboarding/workflow"
1211
"github.com/dxta-dev/app/internal/util"
13-
"go.temporal.io/sdk/client"
1412
)
1513

1614
type UsersCountResponse struct {
1715
Count int `json:"count"`
1816
}
1917

20-
type Users struct {
21-
temporalClient client.Client
22-
config onboarding.Config
23-
}
24-
25-
func NewUsers(temporalClient client.Client, config onboarding.Config) *Users {
26-
return &Users{
27-
temporalClient: temporalClient,
28-
config: config,
29-
}
30-
}
31-
32-
func (u *Users) UsersCount(w http.ResponseWriter, r *http.Request) {
33-
out, err := workflow.ExecuteCountUsersWorkflow(r.Context(), u.temporalClient, u.config)
18+
func (th *TemporalHandler) UsersCount(w http.ResponseWriter, r *http.Request) {
19+
out, err := workflow.ExecuteCountUsersWorkflow(r.Context(), th.temporalClient, th.config)
3420
if err != nil {
3521
log.Fatal(errors.Unwrap(err))
3622
}

internal/onboarding/tenant.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,3 @@ func GetCachedTenantDB(DBURL string, ctx context.Context) (*sql.DB, error) {
104104

105105
return db.DB, nil
106106
}
107-
108-
func GetDB(ctx context.Context, DBURL string) (*sql.DB, error) {
109-
db, err := NewDB(DBURL, ctx)
110-
111-
if err != nil {
112-
return nil, errors.New("failed to create db connection: " + err.Error())
113-
}
114-
115-
return db.DB, nil
116-
}

0 commit comments

Comments
 (0)