Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tools/generator-go-sdk: unmarshaling a list of discriminated types is broken #3639

Closed
tombuildsstuff opened this issue Jan 17, 2024 · 0 comments · Fixed by #3640
Closed

tools/generator-go-sdk: unmarshaling a list of discriminated types is broken #3639

tombuildsstuff opened this issue Jan 17, 2024 · 0 comments · Fixed by #3640
Assignees
Labels
area/discriminators Discriminators are interface/implementations bug Something isn't working tool/generator-go-sdk Issues with the Go SDK Generator

Comments

@tombuildsstuff
Copy link
Contributor

When switching DataShare over to the new base layer, the ListByShare operation is broken, returning map[string]interface{} as the type of SynchronizationSetting, rather than the correctly unmarshalled object.

This is accounted for/works fine when using the old base layer - as such this is scoped to the new base layer.

Working (old base layer): hashicorp/go-azure-sdk@a476e69#diff-b7ab6a17ff3638f8b2855cc7cbce18daea707f6b7b7b68f523a1767abc94e0b1L117-L126

// responderForListByShare handles the response to the ListByShare request. The method always
// closes the http.Response Body.
func (c SynchronizationSettingClient) responderForListByShare(resp *http.Response) (result ListByShareOperationResponse, err error) {
	type page struct {
		Values   []json.RawMessage `json:"value"`
		NextLink *string           `json:"nextLink"`
	}
	var respObj page
	err = autorest.Respond(
		resp,
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&respObj),
		autorest.ByClosing())
	result.HttpResponse = resp
	temp := make([]SynchronizationSetting, 0)
	for i, v := range respObj.Values {
		val, err := unmarshalSynchronizationSettingImplementation(v)
		if err != nil {
			err = fmt.Errorf("unmarshalling item %d for SynchronizationSetting (%q): %+v", i, v, err)
			return result, err
		}
		temp = append(temp, val)
	}
	result.Model = &temp
	result.nextLink = respObj.NextLink
	if respObj.NextLink != nil {
		result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListByShareOperationResponse, err error) {
			req, err := c.preparerForListByShareWithNextLink(ctx, nextLink)
			if err != nil {
				err = autorest.NewErrorWithError(err, "synchronizationsetting.SynchronizationSettingClient", "ListByShare", nil, "Failure preparing request")
				return
			}

			result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client))
			if err != nil {
				err = autorest.NewErrorWithError(err, "synchronizationsetting.SynchronizationSettingClient", "ListByShare", result.HttpResponse, "Failure sending request")
				return
			}

			result, err = c.responderForListByShare(result.HttpResponse)
			if err != nil {
				err = autorest.NewErrorWithError(err, "synchronizationsetting.SynchronizationSettingClient", "ListByShare", result.HttpResponse, "Failure responding to request")
				return
			}

			return
		}
	}
	return
}

Broken (new base layer):

/ ListByShare ...
func (c SynchronizationSettingClient) ListByShare(ctx context.Context, id ShareId) (result ListByShareOperationResponse, err error) {
	opts := client.RequestOptions{
		ContentType: "application/json; charset=utf-8",
		ExpectedStatusCodes: []int{
			http.StatusOK,
		},
		HttpMethod: http.MethodGet,
		Path:       fmt.Sprintf("%s/synchronizationSettings", id.ID()),
	}

	req, err := c.Client.NewRequest(ctx, opts)
	if err != nil {
		return
	}

	var resp *client.Response
	resp, err = req.ExecutePaged(ctx)
	if resp != nil {
		result.OData = resp.OData
		result.HttpResponse = resp.Response
	}
	if err != nil {
		return
	}

	var values struct {
		Values *[]SynchronizationSetting `json:"value"`
	}
	if err = resp.Unmarshal(&values); err != nil {
		return
	}

	result.Model = values.Values

	return
}

As such we’ll need to update generator-go-sdk to conditionally unmarshal the object when a list of a discriminated reference is returned.

Blocks hashicorp/terraform-provider-azurerm#24481

@tombuildsstuff tombuildsstuff added bug Something isn't working tool/generator-go-sdk Issues with the Go SDK Generator area/discriminators Discriminators are interface/implementations labels Jan 17, 2024
@tombuildsstuff tombuildsstuff self-assigned this Jan 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/discriminators Discriminators are interface/implementations bug Something isn't working tool/generator-go-sdk Issues with the Go SDK Generator
Projects
None yet
1 participant