Skip to content

Commit 6b3847c

Browse files
committed
fix(workflows): pass pre-built request types to provider child workflows
The merge from main reintroduced the pattern where the authorize/revoke child workflows expect a WorkflowRoleRequest and resolve it to an AuthorizeRoleRequest inside the workflow via a local activity. The branch design instead pre-builds the AuthorizeRoleRequest at execution-planning time and stores it on ExecutionPlanEntry, and the thand task caller already invokes the child workflow with the pre-built type. That mismatch caused integration failures with: unable to decode the workflow function input payload: cannot unmarshal object into Go struct field WorkflowRoleRequest.identity of type string Restore the branch's signatures so the workflows accept the materialized request types directly. The BuildAuthorizeRoleRequest activity remains registered for callers that still build via WorkflowRoleRequest, but the provider child workflows themselves no longer depend on it.
1 parent ac299ac commit 6b3847c

1 file changed

Lines changed: 16 additions & 71 deletions

File tree

internal/models/provider_workflows.go

Lines changed: 16 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -332,49 +332,23 @@ func (r *WorkflowRoleRequest) GetDuration() *time.Duration {
332332
return r.Duration
333333
}
334334

335-
// CreateProviderAuthorizeRoleWorkflow returns a workflow function that captures the
336-
// live provider instance via closure. The child workflow receives the Temporal
337-
// workflow.Context, dispatches a local activity to resolve the AuthorizeRoleRequest
338-
// (config/identity/tenant lookups and composite-role construction), and then
339-
// delegates to provider.AuthorizeRole — allowing the provider to dispatch activities,
340-
// use workflow.Go, and manage state just as it does in the primary workflow.
341-
func CreateProviderAuthorizeRoleWorkflow(provider Provider) func(workflow.Context, WorkflowRoleRequest) (*AuthorizeRoleResponse, error) {
342-
return func(ctx workflow.Context, req WorkflowRoleRequest) (*AuthorizeRoleResponse, error) {
335+
// CreateProviderAuthorizeRoleWorkflow returns a workflow function that captures
336+
// the live provider instance via closure. The child workflow receives a fully
337+
// materialized AuthorizeRoleRequest (built at execution-planning time) so it
338+
// can delegate directly to provider.AuthorizeRole without any workflow-side
339+
// config lookups.
340+
func CreateProviderAuthorizeRoleWorkflow(provider Provider) func(workflow.Context, AuthorizeRoleRequest) (*AuthorizeRoleResponse, error) {
341+
return func(ctx workflow.Context, req AuthorizeRoleRequest) (*AuthorizeRoleResponse, error) {
343342

344343
log := workflow.GetLogger(ctx)
345344
log.Info("Starting authorize role workflow", "provider", provider.GetIdentifier())
346345

347-
// Resolve config/provider state via a registered local activity rather than
348-
// workflow.SideEffect. This keeps mutable config reads outside workflow code,
349-
// records the resolved request in history with a stable activity type name,
350-
// and enables retry on transient failure.
351-
activityName := CreateTemporalProviderWorkflowName(
352-
provider.GetIdentifier(),
353-
TemporalBuildAuthorizeRoleRequestActivityName,
354-
)
355-
lao := workflow.LocalActivityOptions{
356-
StartToCloseTimeout: 30 * time.Second,
357-
RetryPolicy: &temporal.RetryPolicy{
358-
InitialInterval: 1 * time.Second,
359-
BackoffCoefficient: 2.0,
360-
MaximumInterval: 30 * time.Second,
361-
MaximumAttempts: 5,
362-
},
363-
}
364-
lctx := workflow.WithLocalActivityOptions(ctx, lao)
365-
366-
var authReq AuthorizeRoleRequest
367-
if err := workflow.ExecuteLocalActivity(lctx, activityName, &req).Get(ctx, &authReq); err != nil {
368-
log.Error("Failed to build authorize role request", "error", err)
369-
return nil, err
370-
}
371-
372-
log.Debug("Constructed authorize role request, invoking provider",
346+
log.Debug("Invoking provider authorize role",
373347
"provider", provider.GetIdentifier(),
374-
"authorizeReq", authReq,
348+
"authorizeReq", req,
375349
)
376350

377-
return provider.AuthorizeRole(ctx, &authReq)
351+
return provider.AuthorizeRole(ctx, &req)
378352
}
379353
}
380354

@@ -384,51 +358,22 @@ type WorkflowRevokeRoleRequest struct {
384358
}
385359

386360
// CreateProviderRevokeRoleWorkflow returns a workflow function that captures the
387-
// live provider instance via closure for revocation operations.
361+
// live provider instance via closure for revocation operations. The child
362+
// workflow receives a fully materialized RevokeRoleRequest (built at
363+
// execution-planning / hydration time) so it can delegate directly to
364+
// provider.RevokeRole without any workflow-side config lookups.
388365
func CreateProviderRevokeRoleWorkflow(provider Provider) func(workflow.Context, WorkflowRevokeRoleRequest) (*RevokeRoleResponse, error) {
389366
return func(ctx workflow.Context, req WorkflowRevokeRoleRequest) (*RevokeRoleResponse, error) {
390367

391368
log := workflow.GetLogger(ctx)
392369
log.Info("Starting revoke role workflow", "provider", provider.GetIdentifier())
393370

394-
var authReq *AuthorizeRoleRequest
395-
if req.RevokeRoleRequest != nil {
396-
// Resolve config/provider state via a registered local activity. See
397-
// CreateProviderAuthorizeRoleWorkflow for the full rationale.
398-
activityName := CreateTemporalProviderWorkflowName(
399-
provider.GetIdentifier(),
400-
TemporalBuildAuthorizeRoleRequestActivityName,
401-
)
402-
lao := workflow.LocalActivityOptions{
403-
StartToCloseTimeout: 30 * time.Second,
404-
RetryPolicy: &temporal.RetryPolicy{
405-
InitialInterval: 1 * time.Second,
406-
BackoffCoefficient: 2.0,
407-
MaximumInterval: 30 * time.Second,
408-
MaximumAttempts: 5,
409-
},
410-
}
411-
lctx := workflow.WithLocalActivityOptions(ctx, lao)
412-
413-
var result AuthorizeRoleRequest
414-
if err := workflow.ExecuteLocalActivity(lctx, activityName, req.RevokeRoleRequest).Get(ctx, &result); err != nil {
415-
log.Error("Failed to build authorize role request for revocation", "error", err)
416-
return nil, err
417-
}
418-
authReq = &result
419-
}
420-
421-
revokeReq := &RevokeRoleRequest{
422-
AuthorizeRoleRequest: authReq,
423-
AuthorizeRoleResponse: req.AuthorizeRoleResponse,
424-
}
425-
426-
log.Debug("Constructed revoke role request, invoking provider",
371+
log.Debug("Invoking provider revoke role",
427372
"provider", provider.GetIdentifier(),
428373
"revokeReq", req.RevokeRoleRequest,
429374
)
430375

431-
return provider.RevokeRole(ctx, revokeReq)
376+
return provider.RevokeRole(ctx, req.RevokeRoleRequest)
432377
}
433378
}
434379

0 commit comments

Comments
 (0)