in xds/client/resource/unmarshal.go [63:162]
func processAllResources(opts *UnmarshalOptions, ret interface{}) (UpdateMetadata, error) {
timestamp := time.Now()
md := UpdateMetadata{
Version: opts.Version,
Timestamp: timestamp,
}
var topLevelErrors []error
perResourceErrors := make(map[string]error)
for _, r := range opts.Resources {
switch ret2 := ret.(type) {
case map[string]ListenerUpdateErrTuple:
name, update, err := unmarshalListenerResource(r, opts.UpdateValidator, opts.Logger)
name = ParseName(name).String()
if err == nil {
ret2[name] = ListenerUpdateErrTuple{Update: update}
continue
}
if name == "" {
topLevelErrors = append(topLevelErrors, err)
continue
}
perResourceErrors[name] = err
// Add place holder in the map so we know this resource name was in
// the response.
ret2[name] = ListenerUpdateErrTuple{Err: err}
case map[string]RouteConfigUpdateErrTuple:
name, update, err := unmarshalRouteConfigResource(r, opts.Logger)
name = ParseName(name).String()
if err == nil {
ret2[name] = RouteConfigUpdateErrTuple{Update: update}
continue
}
if name == "" {
topLevelErrors = append(topLevelErrors, err)
continue
}
perResourceErrors[name] = err
// Add place holder in the map so we know this resource name was in
// the response.
ret2[name] = RouteConfigUpdateErrTuple{Err: err}
case map[string]ClusterUpdateErrTuple:
name, update, err := unmarshalClusterResource(r, opts.UpdateValidator, opts.Logger)
name = ParseName(name).String()
if err == nil {
ret2[name] = ClusterUpdateErrTuple{Update: update}
continue
}
if name == "" {
topLevelErrors = append(topLevelErrors, err)
continue
}
perResourceErrors[name] = err
// Add place holder in the map so we know this resource name was in
// the response.
ret2[name] = ClusterUpdateErrTuple{Err: err}
case map[string]EndpointsUpdateErrTuple:
name, update, err := unmarshalEndpointsResource(r, opts.Logger)
name = ParseName(name).String()
if err == nil {
ret2[name] = EndpointsUpdateErrTuple{Update: update}
continue
}
if name == "" {
topLevelErrors = append(topLevelErrors, err)
continue
}
perResourceErrors[name] = err
// Add place holder in the map so we know this resource name was in
// the response.
ret2[name] = EndpointsUpdateErrTuple{Err: err}
}
}
if len(topLevelErrors) == 0 && len(perResourceErrors) == 0 {
md.Status = ServiceStatusACKed
return md, nil
}
var typeStr string
switch ret.(type) {
case map[string]ListenerUpdate:
typeStr = "LDS"
case map[string]RouteConfigUpdate:
typeStr = "RDS"
case map[string]ClusterUpdate:
typeStr = "CDS"
case map[string]EndpointsUpdate:
typeStr = "EDS"
}
md.Status = ServiceStatusNACKed
errRet := combineErrors(typeStr, topLevelErrors, perResourceErrors)
md.ErrState = &UpdateErrorMetadata{
Version: opts.Version,
Err: errRet,
Timestamp: timestamp,
}
return md, errRet
}