github.com/dbernstein1/tyk@v2.9.0-beta9-dl-apic+incompatible/apidef/importer/swagger.go (about) 1 package importer 2 3 import ( 4 "encoding/json" 5 "errors" 6 "io" 7 "strings" 8 9 uuid "github.com/satori/go.uuid" 10 11 "github.com/TykTechnologies/tyk/apidef" 12 ) 13 14 const SwaggerSource APIImporterSource = "swagger" 15 16 type DefinitionObjectFormatAST struct { 17 Format string `json:"format"` 18 Type string `json:"type"` 19 } 20 21 type DefinitionObjectAST struct { 22 Type string `json:"type"` 23 Required []string `json:"required"` 24 Properties map[string]DefinitionObjectFormatAST `json:"properties"` 25 } 26 27 type ResponseCodeObjectAST struct { 28 Description string `json:"description"` 29 Schema struct { 30 Items map[string]interface{} `json:"items"` 31 Type string `json:"type"` 32 } `json:"schema"` 33 } 34 35 type PathMethodObject struct { 36 Description string `json:"description"` 37 OperationID string `json:"operationId"` 38 Responses map[string]ResponseCodeObjectAST `json:"responses"` 39 } 40 41 type PathItemObject struct { 42 Get PathMethodObject `json:"get"` 43 Put PathMethodObject `json:"put"` 44 Post PathMethodObject `json:"post"` 45 Patch PathMethodObject `json:"patch"` 46 Options PathMethodObject `json:"options"` 47 Delete PathMethodObject `json:"delete"` 48 Head PathMethodObject `json:"head"` 49 } 50 51 type SwaggerAST struct { 52 BasePath string `json:"basePath"` 53 Consumes []string `json:"consumes"` 54 Definitions map[string]DefinitionObjectAST `json:"definitions"` 55 Host string `json:"host"` 56 Info struct { 57 Contact struct { 58 Email string `json:"email"` 59 Name string `json:"name"` 60 URL string `json:"url"` 61 } `json:"contact"` 62 Description string `json:"description"` 63 License struct { 64 Name string `json:"name"` 65 URL string `json:"url"` 66 } `json:"license"` 67 TermsOfService string `json:"termsOfService"` 68 Title string `json:"title"` 69 Version string `json:"version"` 70 } `json:"info"` 71 Paths map[string]PathItemObject `json:"paths"` 72 Produces []string `json:"produces"` 73 Schemes []string `json:"schemes"` 74 Swagger string `json:"swagger"` 75 } 76 77 func (s *SwaggerAST) LoadFrom(r io.Reader) error { 78 return json.NewDecoder(r).Decode(&s) 79 } 80 81 func (s *SwaggerAST) ConvertIntoApiVersion(asMock bool) (apidef.VersionInfo, error) { 82 versionInfo := apidef.VersionInfo{} 83 84 if asMock { 85 return versionInfo, errors.New("Swagger mocks not supported") 86 } 87 88 versionInfo.UseExtendedPaths = true 89 versionInfo.Name = s.Info.Version 90 versionInfo.ExtendedPaths.TrackEndpoints = make([]apidef.TrackEndpointMeta, 0) 91 92 if len(s.Paths) == 0 { 93 return versionInfo, errors.New("no paths defined in swagger file") 94 } 95 for pathName, pathSpec := range s.Paths { 96 newEndpointMeta := apidef.TrackEndpointMeta{} 97 newEndpointMeta.Path = pathName 98 99 // We just want the paths here, no mocks 100 methods := map[string]PathMethodObject{ 101 "GET": pathSpec.Get, 102 "PUT": pathSpec.Put, 103 "POST": pathSpec.Post, 104 "HEAD": pathSpec.Head, 105 "PATCH": pathSpec.Patch, 106 "OPTIONS": pathSpec.Options, 107 "DELETE": pathSpec.Delete, 108 } 109 for methodName, m := range methods { 110 // skip methods that are not defined 111 if len(m.Responses) == 0 && m.Description == "" && m.OperationID == "" { 112 continue 113 } 114 115 newEndpointMeta.Method = methodName 116 versionInfo.ExtendedPaths.TrackEndpoints = append(versionInfo.ExtendedPaths.TrackEndpoints, newEndpointMeta) 117 } 118 } 119 120 return versionInfo, nil 121 } 122 123 func (s *SwaggerAST) InsertIntoAPIDefinitionAsVersion(version apidef.VersionInfo, def *apidef.APIDefinition, versionName string) error { 124 def.VersionData.NotVersioned = false 125 def.VersionData.Versions[versionName] = version 126 return nil 127 } 128 129 func (s *SwaggerAST) ToAPIDefinition(orgId, upstreamURL string, as_mock bool) (*apidef.APIDefinition, error) { 130 ad := apidef.APIDefinition{ 131 Name: s.Info.Title, 132 Active: true, 133 UseKeylessAccess: true, 134 APIID: uuid.NewV4().String(), 135 OrgID: orgId, 136 } 137 ad.VersionDefinition.Key = "version" 138 ad.VersionDefinition.Location = "header" 139 ad.VersionData.Versions = make(map[string]apidef.VersionInfo) 140 ad.Proxy.ListenPath = "/" + ad.APIID + "/" 141 ad.Proxy.StripListenPath = true 142 ad.Proxy.TargetURL = upstreamURL 143 144 if as_mock { 145 log.Warning("Mocks not supported for Swagger definitions, ignoring option") 146 } 147 versionData, err := s.ConvertIntoApiVersion(false) 148 if err != nil { 149 return nil, err 150 } 151 152 s.InsertIntoAPIDefinitionAsVersion(versionData, &ad, strings.Trim(s.Info.Version, " ")) 153 154 return &ad, nil 155 }