func (e *SwaggerResourceExpander) Expand(ctx context.Context, currentItem *TreeNode) ExpanderResult {

	span, ctx := tracing.StartSpanFromContext(ctx, "expand(swagger):"+currentItem.ItemType+":"+currentItem.Name+":"+currentItem.ID, tracing.SetTag("item", currentItem))
	defer span.Finish()

	resourceType := currentItem.SwaggerResourceType
	if resourceType == nil {
		panic(fmt.Errorf("SwaggerResourceType not set"))
	}

	method := resourceType.Verb
	data, err := armclient.DoRequest(ctx, method, currentItem.ExpandURL)
	if err != nil {
		return ExpanderResult{
			Nodes:    nil,
			Response: string(data),
			Err:      fmt.Errorf("Failed" + err.Error() + currentItem.ExpandURL),
		}
	}

	newItems := []*TreeNode{}
	matchResult := resourceType.Endpoint.Match(currentItem.ExpandURL) // TODO - return the matches from getHandledTypeForURL to avoid re-calculating!
	templateValues := matchResult.Values

	if len(resourceType.SubResources) > 0 {
		// We have defined subResources - Unmarshal the ARM response and add these to newItems
		var resourceResponse armclient.ResourceResponse
		err = json.Unmarshal([]byte(data), &resourceResponse)
		if err != nil {
			err = fmt.Errorf("Error unmarshalling response: %s\nURL:%s", err, currentItem.ExpandURL)
			panic(err)
		}
		for _, resource := range resourceResponse.Resources {
			subResourceType := getResourceTypeForURL(ctx, resource.ID, resourceType.SubResources)
			if subResourceType == nil {
				panic(fmt.Errorf("SubResource type not found! %s", resource.ID))
			}
			subResourceTemplateValues := subResourceType.Endpoint.Match(resource.ID).Values
			name := substituteValues(subResourceType.Display, subResourceTemplateValues)
			deleteURL := ""
			if subResourceType.DeleteEndpoint != nil {
				deleteURL, err = subResourceType.DeleteEndpoint.BuildURL(subResourceTemplateValues)
				if err != nil {
					panic(fmt.Errorf("Error building subresource delete url '%s': %s", subResourceType.DeleteEndpoint.TemplateURL, err))
				}
			}
			newItems = append(newItems, &TreeNode{
				Parentid:            currentItem.ID,
				Namespace:           "swagger",
				Name:                name,
				Display:             name,
				ExpandURL:           resource.ID + "?api-version=" + subResourceType.Endpoint.APIVersion,
				ItemType:            SubResourceType,
				DeleteURL:           deleteURL,
				SwaggerResourceType: subResourceType,
			})
		}
	}
	// Add any children to newItems
	for _, child := range resourceType.Children {
		loopChild := child
		url, err := child.Endpoint.BuildURL(templateValues)
		if err != nil {
			err = fmt.Errorf("Error building URL: %s\nURL:%s", child.Display, err)
			panic(err)
		}
		display := substituteValues(child.Display, templateValues)
		deleteURL := ""
		if child.DeleteEndpoint != nil {
			deleteURL, err = child.DeleteEndpoint.BuildURL(templateValues)
			if err != nil {
				panic(fmt.Errorf("Error building child delete url '%s': %s", child.DeleteEndpoint.TemplateURL, err))
			}
		}
		newItems = append(newItems, &TreeNode{
			Parentid:            currentItem.ID,
			Namespace:           "swagger",
			Name:                display,
			Display:             display,
			ExpandURL:           url,
			ItemType:            SubResourceType,
			DeleteURL:           deleteURL,
			SwaggerResourceType: &loopChild,
		})
	}

	return ExpanderResult{
		Nodes:             newItems,
		Response:          string(data),
		IsPrimaryResponse: true, // only returning items that we are the primary response for
	}
}
// Expand returns Resources in the RG
Expand returns Resources in the RG
// Expand returns Resources in the RG
func (e *SwaggerResourceExpander) Expand(ctx context.Context, currentItem *TreeNode) ExpanderResult {
	span, ctx := tracing.StartSpanFromContext(ctx, "expand(swagger):"+currentItem.ItemType+":"+currentItem.Name+":"+currentItem.ID, tracing.SetTag("item", currentItem))
	defer span.Finish()
	resourceType := currentItem.SwaggerResourceType
	if resourceType == nil {
		panic(fmt.Errorf("SwaggerResourceType not set"))
	}
	method := resourceType.Verb
	data, err := armclient.DoRequest(ctx, method, currentItem.ExpandURL)
	if err != nil {
		return ExpanderResult{
			Nodes:    nil,
			Response: string(data),
			Err:      fmt.Errorf("Failed" + err.Error() + currentItem.ExpandURL),
		}
	}
	newItems := []*TreeNode{}
	matchResult := resourceType.Endpoint.Match(currentItem.ExpandURL) 
	templateValues := matchResult.Values
	if len(resourceType.SubResources) > 0 {
		var resourceResponse armclient.ResourceResponse
		err = json.Unmarshal([]byte(data), &resourceResponse)
		if err != nil {
			err = fmt.Errorf("Error unmarshalling response: %s\nURL:%s", err, currentItem.ExpandURL)
			panic(err)
		}
		for _, resource := range resourceResponse.Resources {
			subResourceType := getResourceTypeForURL(ctx, resource.ID, resourceType.SubResources)
			if subResourceType == nil {
				panic(fmt.Errorf("SubResource type not found! %s", resource.ID))
			}
			subResourceTemplateValues := subResourceType.Endpoint.Match(resource.ID).Values
			name := substituteValues(subResourceType.Display, subResourceTemplateValues)
			deleteURL := ""
			if subResourceType.DeleteEndpoint != nil {
				deleteURL, err = subResourceType.DeleteEndpoint.BuildURL(subResourceTemplateValues)
				if err != nil {
					panic(fmt.Errorf("Error building subresource delete url '%s': %s", subResourceType.DeleteEndpoint.TemplateURL, err))
				}
			}
			newItems = append(newItems, &TreeNode{
				Parentid:            currentItem.ID,
				Namespace:           "swagger",
				Name:                name,
				Display:             name,
				ExpandURL:           resource.ID + "?api-version=" + subResourceType.Endpoint.APIVersion,
				ItemType:            SubResourceType,
				DeleteURL:           deleteURL,
				SwaggerResourceType: subResourceType,
			})
		}
	}
	for _, child := range resourceType.Children {
		loopChild := child
		url, err := child.Endpoint.BuildURL(templateValues)
		if err != nil {
			err = fmt.Errorf("Error building URL: %s\nURL:%s", child.Display, err)
			panic(err)
		}
		display := substituteValues(child.Display, templateValues)
		deleteURL := ""
		if child.DeleteEndpoint != nil {
			deleteURL, err = child.DeleteEndpoint.BuildURL(templateValues)
			if err != nil {
				panic(fmt.Errorf("Error building child delete url '%s': %s", child.DeleteEndpoint.TemplateURL, err))
			}
		}
		newItems = append(newItems, &TreeNode{
			Parentid:            currentItem.ID,
			Namespace:           "swagger",
			Name:                display,
			Display:             display,
			ExpandURL:           url,
			ItemType:            SubResourceType,
			DeleteURL:           deleteURL,
			SwaggerResourceType: &loopChild,
		})
	}
	return ExpanderResult{
		Nodes:             newItems,
		Response:          string(data),
		IsPrimaryResponse: true, 
	}
}
func ( e * SwaggerResourceExpander ) Expand ( ctx context . Context , currentItem * TreeNode ) ExpanderResult { span , ctx := tracing . StartSpanFromContext ( ctx , " " + currentItem . ItemType + " " + currentItem . Name + " " + currentItem . ID , tracing . SetTag ( " " , currentItem ) ) defer span . Finish ( ) resourceType := currentItem . SwaggerResourceType if resourceType == nil { panic ( fmt . Errorf ( " " ) ) } method := resourceType . Verb data , err := armclient . DoRequest ( ctx , method , currentItem . ExpandURL ) if err != nil { return ExpanderResult { Nodes : nil , Response : string ( data ) , Err : fmt . Errorf ( " " + err . Error ( ) + currentItem . ExpandURL ) , } } newItems := [ ] * TreeNode { } matchResult := resourceType . Endpoint . Match ( currentItem . ExpandURL ) templateValues := matchResult . Values if len ( resourceType . SubResources ) > 0 { var resourceResponse armclient . ResourceResponse err = json . Unmarshal ( [ ] byte ( data ) , & resourceResponse ) if err != nil { err = fmt . Errorf ( " \n " , err , currentItem . ExpandURL ) panic ( err ) } for _ , resource := range resourceResponse . Resources { subResourceType := getResourceTypeForURL ( ctx , resource . ID , resourceType . SubResources ) if subResourceType == nil { panic ( fmt . Errorf ( " " , resource . ID ) ) } subResourceTemplateValues := subResourceType . Endpoint . Match ( resource . ID ) . Values name := substituteValues ( subResourceType . Display , subResourceTemplateValues ) deleteURL := " " if subResourceType . DeleteEndpoint != nil { deleteURL , err = subResourceType . DeleteEndpoint . BuildURL ( subResourceTemplateValues ) if err != nil { panic ( fmt . Errorf ( " " , subResourceType . DeleteEndpoint . TemplateURL , err ) ) } } newItems = append ( newItems , & TreeNode { Parentid : currentItem . ID , Namespace : " " , Name : name , Display : name , ExpandURL : resource . ID + " " + subResourceType . Endpoint . APIVersion , ItemType : SubResourceType , DeleteURL : deleteURL , SwaggerResourceType : subResourceType , } ) } } for _ , child := range resourceType . Children { loopChild := child url , err := child . Endpoint . BuildURL ( templateValues ) if err != nil { err = fmt . Errorf ( " \n " , child . Display , err ) panic ( err ) } display := substituteValues ( child . Display , templateValues ) deleteURL := " " if child . DeleteEndpoint != nil { deleteURL , err = child . DeleteEndpoint . BuildURL ( templateValues ) if err != nil { panic ( fmt . Errorf ( " " , child . DeleteEndpoint . TemplateURL , err ) ) } } newItems = append ( newItems , & TreeNode { Parentid : currentItem . ID , Namespace : " " , Name : display , Display : display , ExpandURL : url , ItemType : SubResourceType , DeleteURL : deleteURL , SwaggerResourceType : & loopChild , } ) } return ExpanderResult { Nodes : newItems , Response : string ( data ) , IsPrimaryResponse : true , } }
Expand returns Resources in the RG
Expand returns Resources in the RG
// TODO - return the matches from getHandledTypeForURL to avoid re-calculating! // We have defined subResources - Unmarshal the ARM response and add these to newItems // Add any children to newItems // only returning items that we are the primary response for