Skip to content

Compilation error: LRO (sometimes?) doesn't clone the members required for setting header params #919

@antkmsft

Description

@antkmsft

This affects specification/containerservice/resource-manager/Microsoft.ContainerService/fleet

It goes like this (see comments starting with <--)

pub fn create(
        &self,
        resource_group_name: &str,
        fleet_name: &str,
        fleet_member_name: &str,
        resource: RequestContent<FleetMember>,
        options: Option<ContainerServiceFleetMembersClientCreateOptions<'_>>,
    ) -> Result<Poller<ContainerServiceFleetMembersClientCreateOperationStatus>> {
        let options = options.unwrap_or_default().into_owned();
        let pipeline = self.pipeline.clone();
        let mut url = self.endpoint.clone();
        let mut path = String::from("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerService/fleets/{fleetName}/members/{fleetMemberName}");
        path = path.replace("{fleetMemberName}", fleet_member_name);
        path = path.replace("{fleetName}", fleet_name);
        path = path.replace("{resourceGroupName}", resource_group_name);
        path = path.replace("{subscriptionId}", &self.subscription_id);
        url.append_path(&path);
        let mut query_builder = url.query_builder();
        query_builder.set_pair("api-version", &self.api_version);
        query_builder.build();
        let api_version = self.api_version.clone();
        Ok(Poller::new(
            move |poller_state: PollerState, poller_options| {
                let (mut request, continuation) = match poller_state {
                    PollerState::More(continuation) => {
                        let (mut next_link, final_link) = match continuation {
                            PollerContinuation::Links {
                                next_link,
                                final_link,
                            } => (next_link, final_link),
                            _ => {
                                unreachable!()
                            }
                        };
                        let mut query_builder = next_link.query_builder();
                        query_builder.set_pair("api-version", &api_version);
                        query_builder.build();
                        let mut request = Request::new(next_link.clone(), Method::Get);
                        request.insert_header("accept", "application/json");
                        request.insert_header("content-type", "application/json");
                        if let Some(if_match) = options.if_match.as_ref() { // <-- ok here
                            request.insert_header("if-match", if_match);
                        }
                        if let Some(if_none_match) = options.if_none_match.as_ref() {
                            request.insert_header("if-none-match", if_none_match);
                        }
                        (
                            request,
                            PollerContinuation::Links {
                                next_link,
                                final_link,
                            },
                        )
                    }
                    PollerState::Initial => {
                        let mut request = Request::new(url.clone(), Method::Put);
                        request.insert_header("accept", "application/json");
                        request.insert_header("content-type", "application/json");
                        if let Some(if_match) = options.if_match.as_ref() {
                            request.insert_header("if-match", if_match);
                        }
                        if let Some(if_none_match) = options.if_none_match.as_ref() {
                            request.insert_header("if-none-match", if_none_match);
                        }
                        request.set_body(resource.clone());
                        (
                            request,
                            PollerContinuation::Links {
                                next_link: url.clone(),
                                final_link: None,
                            },
                        )
                    }
                };
                let ctx = poller_options.context.clone();
                let pipeline = pipeline.clone();
                let url = url.clone();
                // <-- doesn't clone if_match here
                Box::pin(async move {
                    let rsp = pipeline
                        .send(
                            &ctx,
                            &mut request,
                            Some(PipelineSendOptions {
                                check_success: CheckSuccessOptions {
                                    success_codes: &[200, 201],
                                },
                                ..Default::default()
                            }),
                        )
                        .await?;
                    let (status, headers, body) = rsp.deconstruct();
                    let continuation = if let Some(final_link) = headers
                        .get_optional_string(&HeaderName::from_static("azure-asyncoperation"))
                    {
                        let final_link = Url::parse(&final_link)?;
                        match continuation {
                            PollerContinuation::Links { next_link, .. } => {
                                PollerContinuation::Links {
                                    next_link,
                                    final_link: Some(final_link),
                                }
                            }
                            _ => {
                                unreachable!()
                            }
                        }
                    } else {
                        continuation
                    };
                    let final_link = match &continuation {
                        PollerContinuation::Links { final_link, .. } => {
                            final_link.clone().unwrap_or_else(|| url.clone())
                        }
                        _ => {
                            unreachable!()
                        }
                    };
                    let retry_after = get_retry_after(
                        &headers,
                        &[X_MS_RETRY_AFTER_MS, RETRY_AFTER_MS, RETRY_AFTER],
                        &poller_options,
                    );
                    let res: ContainerServiceFleetMembersClientCreateOperationStatus =
                        json::from_json(&body)?;
                    let rsp = RawResponse::from_bytes(status, headers, body).into();
                    Ok(match res.status() {
                        PollerStatus::InProgress => PollerResult::InProgress {
                            response: rsp,
                            retry_after,
                            continuation,
                        },
                        PollerStatus::Succeeded => PollerResult::Succeeded {
                            response: rsp,
                            target: Box::new(move || {
                                Box::pin(async move {
                                    let mut request = Request::new(final_link, Method::Get);
                                    request.insert_header("accept", "application/json");
                                    request.insert_header("content-type", "application/json");
                                    if let Some(if_match) = if_match.as_ref() { // <-- fails here
                                        request.insert_header("if-match", if_match);
                                    }
                                    if let Some(if_none_match) = if_none_match.as_ref() {
                                        request.insert_header("if-none-match", if_none_match);
                                    }
                                    Ok(pipeline.send(&ctx, &mut request, None).await?.into())
                                })
                            }),
                        },
                        _ => PollerResult::Done { response: rsp },
                    })
                })
            },
            Some(options.method_options),
        ))
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    Untriaged

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions