github.com/dbernstein1/tyk@v2.9.0-beta9-dl-apic+incompatible/apidef/importer/blueprint.go (about) 1 package importer 2 3 import ( 4 "encoding/json" 5 "errors" 6 "io" 7 "strconv" 8 "strings" 9 10 uuid "github.com/satori/go.uuid" 11 12 "github.com/TykTechnologies/tyk/apidef" 13 ) 14 15 const ApiaryBluePrint APIImporterSource = "blueprint" 16 17 type BluePrintAST struct { 18 Version string `json:"_version"` 19 Description string `json:"description"` 20 Metadata []struct { 21 Name string `json:"name"` 22 Value string `json:"value"` 23 } `json:"metadata"` 24 Name string `json:"name"` 25 ResourceGroups []struct { 26 Description string `json:"description"` 27 Name string `json:"name"` 28 Resources []struct { 29 Actions []struct { 30 Description string `json:"description"` 31 Examples []struct { 32 Description string `json:"description"` 33 Name string `json:"name"` 34 Requests []struct { 35 Body string `json:"body"` 36 Description string `json:"description"` 37 Headers []struct { 38 Name string `json:"name"` 39 Value string `json:"value"` 40 } `json:"headers"` 41 Name string `json:"name"` 42 Schema string `json:"schema"` 43 } `json:"requests"` 44 Responses []struct { 45 Body string `json:"body"` 46 Description string `json:"description"` 47 Headers []struct { 48 Name string `json:"name"` 49 Value string `json:"value"` 50 } `json:"headers"` 51 Name string `json:"name"` 52 Schema string `json:"schema"` 53 } `json:"responses"` 54 } `json:"examples"` 55 Method string `json:"method"` 56 Name string `json:"name"` 57 Parameters []struct { 58 Default string `json:"default"` 59 Description string `json:"description"` 60 Example string `json:"example"` 61 Name string `json:"name"` 62 Required bool `json:"required"` 63 Type string `json:"type"` 64 Values []struct { 65 Value string `json:"value"` 66 } `json:"values"` 67 } `json:"parameters"` 68 } `json:"actions"` 69 Description string `json:"description"` 70 Model struct { 71 Body string `json:"body"` 72 Description string `json:"description"` 73 Headers []struct { 74 Name string `json:"name"` 75 Value string `json:"value"` 76 } `json:"headers"` 77 Name string `json:"name"` 78 Schema string `json:"schema"` 79 } `json:"model"` 80 Name string `json:"name"` 81 Parameters []struct { 82 Default string `json:"default"` 83 Description string `json:"description"` 84 Example string `json:"example"` 85 Name string `json:"name"` 86 Required bool `json:"required"` 87 Type string `json:"type"` 88 Values []struct { 89 Value string `json:"value"` 90 } `json:"values"` 91 } `json:"parameters"` 92 UriTemplate string `json:"uriTemplate"` 93 } `json:"resources"` 94 } `json:"resourceGroups"` 95 } 96 97 func (b *BluePrintAST) LoadFrom(r io.Reader) error { 98 return json.NewDecoder(r).Decode(&b) 99 } 100 101 func (b *BluePrintAST) ConvertIntoApiVersion(asMock bool) (apidef.VersionInfo, error) { 102 versionInfo := apidef.VersionInfo{} 103 versionInfo.UseExtendedPaths = true 104 versionInfo.Name = b.Name 105 106 if len(b.ResourceGroups) < 1 { 107 return versionInfo, errors.New("There are no resource groups defined in this blueprint, are you sure it is correctly formatted?") 108 } 109 110 for _, resourceGroup := range b.ResourceGroups { 111 if len(resourceGroup.Resources) < 1 { 112 return versionInfo, errors.New("no resources defined in the resource group") 113 } 114 115 for _, resource := range resourceGroup.Resources { 116 newMetaData := apidef.EndPointMeta{} 117 newMetaData.Path = resource.UriTemplate 118 newMetaData.MethodActions = make(map[string]apidef.EndpointMethodMeta) 119 120 for _, action := range resource.Actions { 121 if len(action.Examples) == 0 || len(action.Examples[0].Responses) == 0 { 122 continue 123 } 124 endPointMethodMeta := apidef.EndpointMethodMeta{} 125 code, err := strconv.Atoi(action.Examples[0].Responses[0].Name) 126 if err != nil { 127 log.Warning("Could not generate response code from Name field, using 200") 128 code = 200 129 } 130 endPointMethodMeta.Code = code 131 132 if asMock { 133 endPointMethodMeta.Action = apidef.Reply 134 } else { 135 endPointMethodMeta.Action = apidef.NoAction 136 } 137 138 for _, h := range action.Examples[0].Responses[0].Headers { 139 endPointMethodMeta.Headers = make(map[string]string) 140 endPointMethodMeta.Headers[h.Name] = h.Value 141 } 142 endPointMethodMeta.Data = action.Examples[0].Responses[0].Body 143 newMetaData.MethodActions[action.Method] = endPointMethodMeta 144 } 145 146 // Add it to the version 147 versionInfo.ExtendedPaths.WhiteList = make([]apidef.EndPointMeta, 0) 148 versionInfo.ExtendedPaths.WhiteList = append(versionInfo.ExtendedPaths.WhiteList, newMetaData) 149 } 150 151 } 152 153 return versionInfo, nil 154 } 155 156 func (b *BluePrintAST) InsertIntoAPIDefinitionAsVersion(version apidef.VersionInfo, def *apidef.APIDefinition, versionName string) error { 157 def.VersionData.NotVersioned = false 158 def.VersionData.Versions[versionName] = version 159 return nil 160 } 161 162 func (b *BluePrintAST) ToAPIDefinition(orgID, upstreamURL string, asMock bool) (*apidef.APIDefinition, error) { 163 ad := apidef.APIDefinition{ 164 Name: b.Name, 165 Active: true, 166 UseKeylessAccess: true, 167 APIID: uuid.NewV4().String(), 168 OrgID: orgID, 169 } 170 ad.VersionDefinition.Key = "version" 171 ad.VersionDefinition.Location = "header" 172 ad.VersionData.Versions = make(map[string]apidef.VersionInfo) 173 ad.Proxy.ListenPath = "/" + ad.APIID + "/" 174 ad.Proxy.StripListenPath = true 175 ad.Proxy.TargetURL = upstreamURL 176 177 versionData, err := b.ConvertIntoApiVersion(asMock) 178 if err != nil { 179 return nil, err 180 } 181 182 err = b.InsertIntoAPIDefinitionAsVersion(versionData, &ad, strings.Trim(b.Name, " ")) 183 return &ad, err 184 }