github.com/Axway/agent-sdk@v1.1.101/pkg/apic/specramlprocessor.go (about) 1 package apic 2 3 import ( 4 "fmt" 5 "net" 6 "net/url" 7 "strconv" 8 "strings" 9 ) 10 11 type ramlProcessor struct { 12 ramlDef map[string]interface{} 13 spec []byte 14 } 15 16 func newRamlProcessor(ramlDef map[string]interface{}, spec []byte) *ramlProcessor { 17 return &ramlProcessor{ramlDef: ramlDef, spec: spec} 18 } 19 20 func (p *ramlProcessor) GetResourceType() string { 21 return Raml 22 } 23 24 func (p *ramlProcessor) GetVersion() string { 25 if version := p.ramlDef["version"]; version != nil { 26 switch v := version.(type) { 27 // yaml Unmarshalling converts the underlying interface values which can be floats like 2.0 to 2 28 case float64: 29 if float64(int(v)) == v { 30 return fmt.Sprintf("%v.0", v) 31 } 32 return fmt.Sprintf("%v", v) 33 default: 34 return fmt.Sprintf("%v", v) 35 } 36 } 37 return "" 38 } 39 40 func (p *ramlProcessor) GetDescription() string { 41 if description := p.ramlDef["description"]; description != nil { 42 return fmt.Sprintf("%v", description) 43 } 44 return "" 45 } 46 47 func (p *ramlProcessor) GetEndpoints() ([]EndpointDefinition, error) { 48 baseUri := p.ramlDef["baseUri"] 49 if baseUri == nil { 50 return nil, fmt.Errorf("no baseUri provided") 51 } 52 53 if params := p.ramlDef["baseUriParameters"]; params != nil { 54 return nil, fmt.Errorf("not implemented error") 55 } 56 57 return p.uriToEndpoints(baseUri.(string), p.getProtocols()) 58 } 59 60 func (p *ramlProcessor) GetSpecBytes() []byte { 61 return p.spec 62 } 63 64 func (p *ramlProcessor) getProtocols() []string { 65 if protocols := p.ramlDef["protocols"]; protocols != nil { 66 // in case [HTTP, HTTPS] is provided 67 if ramlProtocols, ok := protocols.([]interface{}); ok { 68 return validateRamlProtocols(ramlProtocols) 69 } 70 // in case just HTTP is provided 71 if ramlProtocols, ok := protocols.(string); ok { 72 return validateRamlProtocols([]interface{}{ramlProtocols}) 73 } 74 } 75 return nil 76 } 77 78 func (p *ramlProcessor) uriToEndpoints(uri string, protocols []string) ([]EndpointDefinition, error) { 79 parseURL, err := url.Parse(uri) 80 if err != nil { 81 return nil, err 82 } 83 if !strings.HasPrefix(strings.ToLower(parseURL.Scheme), "http") { 84 return p.uriToEndpoints("https://"+uri, protocols) 85 } 86 endpoints := []EndpointDefinition{} 87 ep := EndpointDefinition{} 88 // currently accepting only version as a dynamic value to the endpoints 89 if version := p.ramlDef["version"]; version != nil { 90 parseURL.Path = strings.Replace(parseURL.Path, "{version}", fmt.Sprintf("%v", version), 1) 91 } 92 93 ep.Host = parseURL.Hostname() 94 ep.BasePath = parseURL.Path 95 ep.Protocol = parseURL.Scheme 96 97 port, _ := strconv.Atoi(parseURL.Port()) 98 if port == 0 { 99 port, _ = net.LookupPort("tcp", ep.Protocol) 100 } 101 ep.Port = int32(port) 102 103 if len(protocols) == 0 { 104 return append(endpoints, ep), err 105 // Overrides the protocol from the URI, but does not override the port. 106 } else if len(protocols) == 1 { 107 ep.Protocol = strings.ToLower(protocols[0]) 108 if port == 0 { 109 port, _ = net.LookupPort("tcp", ep.Protocol) 110 } 111 ep.Port = int32(port) 112 return append(endpoints, ep), err 113 } 114 // With multiple protocols provided, ignores the port from the url. 115 for i := range protocols { 116 epCpy := endpointCopy(ep) 117 port, _ = net.LookupPort("tcp", protocols[i]) 118 epCpy.Port = int32(port) 119 epCpy.Protocol = strings.ToLower(protocols[i]) 120 endpoints = append(endpoints, epCpy) 121 } 122 123 return endpoints, err 124 } 125 126 func endpointCopy(e EndpointDefinition) EndpointDefinition { 127 ed := &e 128 return *ed 129 } 130 131 func validateRamlProtocols(protocols []interface{}) []string { 132 stringProtocols := []string{} 133 for i := range protocols { 134 p, ok := protocols[i].(string) 135 if !ok { 136 return []string{} 137 } 138 if strings.ToUpper(p) != "HTTPS" && strings.ToUpper(p) != "HTTP" { 139 return []string{} 140 } 141 stringProtocols = append(stringProtocols, p) 142 } 143 return stringProtocols 144 }