github.com/sacloud/iaas-api-go@v1.12.0/internal/tools/gen-api-op/main.go (about) 1 // Copyright 2022-2023 The sacloud/iaas-api-go Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "log" 19 "path/filepath" 20 21 "github.com/sacloud/iaas-api-go/internal/define" 22 "github.com/sacloud/iaas-api-go/internal/tools" 23 ) 24 25 const destination = "zz_api_ops.go" 26 27 func init() { 28 log.SetFlags(0) 29 log.SetPrefix("gen-api-op: ") 30 } 31 32 func main() { 33 outputPath := destination 34 tools.WriteFileWithTemplate(&tools.TemplateConfig{ 35 OutputPath: filepath.Join(tools.ProjectRootPath(), outputPath), 36 Template: tmpl, 37 Parameter: define.APIs, 38 }) 39 log.Printf("generated: %s\n", outputPath) 40 } 41 42 const tmpl = `// generated by 'github.com/sacloud/iaas-api-go/internal/tools/gen-api-op'; DO NOT EDIT 43 44 package iaas 45 46 import ( 47 "context" 48 "github.com/sacloud/packages-go/mutexkv" 49 "github.com/sacloud/iaas-api-go/types" 50 ) 51 52 var apiLocker = mutexkv.NewMutexKV() 53 54 func init() { 55 {{ range . }} 56 SetClientFactoryFunc("{{.TypeName}}", func(caller APICaller) interface{} { 57 return &{{ .TypeName }}Op { 58 Client: caller, 59 PathSuffix: "{{.GetPathSuffix}}", 60 PathName: "{{.GetPathName}}", 61 } 62 }) 63 {{ end -}} 64 } 65 66 {{ range . }}{{ $typeName := .TypeName }}{{$resource := .}} 67 68 /************************************************* 69 * {{$typeName}}Op 70 *************************************************/ 71 72 // {{ .TypeName }}Op implements {{ .TypeName }}API interface 73 type {{ .TypeName }}Op struct{ 74 // Client APICaller 75 Client APICaller 76 // PathSuffix is used when building URL 77 PathSuffix string 78 // PathName is used when building URL 79 PathName string 80 } 81 82 // New{{ $typeName}}Op creates new {{ $typeName}}Op instance 83 func New{{ $typeName}}Op(caller APICaller) {{ $typeName}}API { 84 return GetClientFactoryFunc("{{$typeName}}")(caller).({{$typeName}}API) 85 } 86 87 {{ range .Operations }}{{$returnErrStatement := .ReturnErrorStatement}}{{ $operationName := .MethodName }} 88 // {{ .MethodName }} is API call 89 func (o *{{ $typeName }}Op) {{ .MethodName }}(ctx context.Context{{if not $resource.IsGlobal}}, zone string{{end}}{{ range .Arguments }}, {{ .ArgName }} {{ .TypeName }}{{ end }}) {{.ResultsStatement}} { 90 // build request URL 91 pathBuildParameter := map[string]interface{}{ 92 "rootURL": SakuraCloudAPIRoot, 93 "pathSuffix": o.PathSuffix, 94 "pathName": o.PathName, 95 {{- if $resource.IsGlobal }} 96 "zone": APIDefaultZone, 97 {{- else }} 98 "zone": zone, 99 {{- end }} 100 {{- range .Arguments }} 101 "{{.PathFormatName}}": {{.Name}}, 102 {{- end }} 103 } 104 105 url, err := buildURL("{{.GetPathFormat}}", pathBuildParameter) 106 if err != nil { 107 return {{ $returnErrStatement }} 108 } 109 {{ if .LockKeyFormat -}} 110 lockKey, err := buildURL("{{.LockKeyFormat}}", pathBuildParameter) 111 if err != nil { 112 return {{ $returnErrStatement }} 113 } 114 apiLocker.Lock(lockKey) 115 defer apiLocker.Unlock(lockKey) 116 {{ end -}} 117 118 // build request body 119 var body interface{} 120 {{ if .HasRequestEnvelope -}} 121 v, err := o.transform{{.MethodName}}Args({{ range .Arguments }}{{ .ArgName }},{{ end }}) 122 if err != nil { 123 return {{ $returnErrStatement }} 124 } 125 body = v 126 {{ end }} 127 128 // do request 129 {{ if .HasResponseEnvelope -}} 130 data, err := o.Client.Do(ctx, "{{.Method}}", url, body) 131 {{ else -}} 132 _, err = o.Client.Do(ctx, "{{.Method}}", url, body) 133 {{ end -}} 134 if err != nil { 135 return {{ $returnErrStatement }} 136 } 137 138 // build results 139 {{ if .HasResponseEnvelope -}} 140 results, err := o.transform{{.MethodName}}Results(data) 141 if err != nil { 142 return {{ $returnErrStatement }} 143 } 144 return {{ .ReturnStatement }} 145 {{ else }} 146 return nil 147 {{ end -}} 148 } 149 {{ end -}} 150 {{ end -}} 151 `