in codegen/module_system.go [1349:1496]
func (g *EndpointGenerator) generateEndpointFile(e *EndpointSpec, instance *ModuleInstance,
out *sync.Map) (*EndpointMeta, error) {
m := e.ModuleSpec
methodName := e.ThriftMethodName
thriftServiceName := e.ThriftServiceName
if len(m.Services) == 0 {
return nil, nil
}
endpointDirectory := filepath.Join(
g.packageHelper.CodeGenTargetPath(),
instance.Directory,
)
var err error
if e.EndpointType == "http" {
structFilePath, err := filepath.Rel(endpointDirectory, e.GoStructsFileName)
if err != nil {
structFilePath = e.GoStructsFileName
}
if _, ok := out.Load(structFilePath); !ok {
meta := &StructMeta{
Instance: instance,
Spec: m,
}
structs, err := ExecuteDefaultOrCustomTemplate(
"structs.tmpl",
g.templates,
instance.CustomTemplates,
e.Config,
meta,
g.packageHelper,
)
if err != nil {
return nil, err
}
out.Store(structFilePath, structs)
}
}
method := findMethod(m, thriftServiceName, methodName)
if method == nil {
return nil, errors.Errorf(
"Could not find thriftServiceName %q + methodName %q in module",
thriftServiceName, methodName,
)
}
includedPackages := m.IncludedPackages
includedPackages = append(includedPackages, GoPackageImport{
PackageName: instance.PackageInfo.GeneratedPackagePath + "/workflow",
AliasName: "workflow",
})
if e.WorkflowType == customWorkflow {
includedPackages = append(includedPackages, GoPackageImport{
PackageName: e.WorkflowImportPath,
AliasName: "custom" + strings.Title(m.PackageName),
})
}
workflowPkg := "workflow"
if method.Downstream == nil && e.WorkflowType == "custom" {
workflowPkg = "custom" + strings.Title(m.PackageName)
}
clientID := e.ClientID
clientName := ""
clientType := "clientless"
if e.ClientSpec != nil {
clientName = e.ClientSpec.ClientName
clientType = e.ClientSpec.ClientType
}
// TODO: http client needs to support multiple thrift services
meta := &EndpointMeta{
Instance: instance,
Spec: e,
GatewayPackageName: g.packageHelper.GoGatewayPackageName(),
IncludedPackages: includedPackages,
Method: method,
ReqHeaders: e.ReqHeaders,
IsClientlessEndpoint: e.IsClientlessEndpoint,
ReqHeadersKeys: sortedHeaders(e.ReqHeaders, false),
ReqRequiredHeadersKeys: sortedHeaders(e.ReqHeaders, true),
ResHeadersKeys: sortedHeaders(e.ResHeaders, false),
ResRequiredHeadersKeys: sortedHeaders(e.ResHeaders, true),
ResHeaders: e.ResHeaders,
ClientID: clientID,
ClientName: clientName,
ClientType: clientType,
ClientMethodName: e.ClientMethod,
WorkflowPkg: workflowPkg,
TraceKey: g.packageHelper.traceKey,
DeputyReqHeader: g.packageHelper.DeputyReqHeader(),
DefaultHeaders: e.DefaultHeaders,
}
targetPath := e.TargetEndpointPath(thriftServiceName, method.Name)
if e.EndpointType == "tchannel" {
targetPath = strings.TrimSuffix(targetPath, ".go") + "_tchannel.go"
}
endpointFilePath, err := filepath.Rel(endpointDirectory, targetPath)
if err != nil {
endpointFilePath = targetPath
}
workCount := 2
runner := parallelize.NewUnboundedRunner(workCount)
f := func() (interface{}, error) {
var endpoint []byte
if e.EndpointType == "http" {
endpoint, err = ExecuteDefaultOrCustomTemplate("endpoint.tmpl", g.templates,
instance.CustomTemplates, e.Config, meta, g.packageHelper)
} else if e.EndpointType == "tchannel" {
endpoint, err = g.templates.ExecTemplate("tchannel_endpoint.tmpl", meta, g.packageHelper)
} else {
err = errors.Errorf("Endpoint type '%s' is not supported", e.EndpointType)
}
if err != nil {
return nil, errors.Wrap(err, "Error executing endpoint template")
}
out.Store(endpointFilePath, endpoint)
return nil, nil
}
runner.SubmitWork(parallelize.StatelessFunc(f))
f = func() (interface{}, error) {
var tmpl string
if e.IsClientlessEndpoint {
tmpl = "clientless-workflow.tmpl"
} else {
tmpl = "workflow.tmpl"
}
workflow, err := ExecuteDefaultOrCustomTemplate(tmpl, g.templates, instance.CustomTemplates, e.Config, meta, g.packageHelper)
if err != nil {
return nil, errors.Wrap(err, "Error executing workflow template")
}
out.Store("workflow/"+endpointFilePath, workflow)
return nil, nil
}
runner.SubmitWork(parallelize.StatelessFunc(f))
if _, err := runner.GetResult(); err != nil {
return nil, err
}
return meta, nil
}