Example #1
0
func (s *ServiceDiscovery) ParseObject(contents string, jsonParsed *gabs.Container) error {
	log.Debug("Parsing raw data: ", contents)
	jp, pErr := gabs.ParseJSON([]byte(contents))
	if pErr != nil {
		log.Error(pErr)
	}
	*jsonParsed = *jp
	log.Debug("Got:", jsonParsed)
	return pErr
}
Example #2
0
func GetURLFromService(spec *APISpec) (interface{}, error) {
	log.Debug("[PROXY] [SERVICE DISCOVERY] [CACHE] Checking:", spec.APIID)
	serviceURL, found := ServiceCache.Get(spec.APIID)
	if found {
		log.Debug("[PROXY] [SERVICE DISCOVERY] [CACHE] Cached value returned")
		return serviceURL, nil
	}

	// Not found? Query the service
	resp, err := http.Get(spec.Proxy.ServiceDiscovery.QueryEndpoint)
	if err != nil {
		return nil, err
	}

	defer resp.Body.Close()
	contents, readErr := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, readErr
	}

	jsonParsed, pErr := gabs.ParseJSON(contents)
	if pErr != nil {
		return nil, pErr
	}

	if spec.Proxy.ServiceDiscovery.UseNestedQuery {
		// If this is a nested query, we need to extract the nested JSON string first
		log.Debug("[PROXY] [SERVICE DISCOVERY] Data: ", string(contents))
		log.Debug("[PROXY] [SERVICE DISCOVERY] Nested parent path: ", string(spec.Proxy.ServiceDiscovery.ParentDataPath))
		nestedValueObject, nestedOk := jsonParsed.Path(spec.Proxy.ServiceDiscovery.ParentDataPath).Data().(string)
		if !nestedOk {
			return nil, errors.New("Nested path traversal failed")
		}
		var secondNestedErr error
		jsonParsed, secondNestedErr = gabs.ParseJSON([]byte(nestedValueObject))
		if secondNestedErr != nil {
			log.Debug("[PROXY] [SERVICE DISCOVERY] Nested object parsing error, data was: ", nestedValueObject)
			return nil, secondNestedErr
		}
	}

	var value interface{}
	// Check if we are getting a target list or just a single value
	if spec.Proxy.ServiceDiscovery.UseTargetList {
		var valErr error
		value, valErr = jsonParsed.Path(spec.Proxy.ServiceDiscovery.DataPath).Children()
		if valErr != nil {
			log.Debug("Failed to get children!")
			return nil, valErr
		}
		// Some servcies separate out port numbers, lets take this into account
		if spec.Proxy.ServiceDiscovery.PortDataPath != "" {
			newHostArray := make([]string, len(value.([]*gabs.Container)))
			portsData, portsErr := jsonParsed.Path(spec.Proxy.ServiceDiscovery.PortDataPath).Children()
			if portsErr != nil {
				return nil, portsErr
			}

			// Zip them up
			for i, v := range value.([]*gabs.Container) {
				asString := v.Data().(string) + ":" + portsData[i].Data().(string)
				newHostArray[i] = asString
			}
			value = newHostArray

		}
	} else {
		var ok bool
		value, ok = jsonParsed.Path(spec.Proxy.ServiceDiscovery.DataPath).Data().(string)
		if !ok {
			return nil, errors.New("Failed to traverse data path")
		}

		if spec.Proxy.ServiceDiscovery.PortDataPath != "" {
			portsData, pOk := jsonParsed.Path(spec.Proxy.ServiceDiscovery.PortDataPath).Data().(string)
			if !pOk {
				return nil, errors.New("Failed to traverse port data path")
			}
			newHost := value.(string) + ":" + portsData
			value = newHost
		}
	}

	if ServiceCache != nil {
		// Set the cached value for this API
		log.Debug("SETTING SERVICE CACHE TIMEOUT TO: ", spec.Proxy.ServiceDiscovery.CacheTimeout)
		ServiceCache.Set(spec.APIID, value, time.Duration(spec.Proxy.ServiceDiscovery.CacheTimeout)*time.Second)
	}

	return value, nil
}