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  }