Skip to main content

mz_testdrive/action/
webhook.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use anyhow::bail;
11
12use crate::action::{ControlFlow, State};
13use crate::parser::BuiltinCommand;
14
15pub async fn run_append(
16    mut cmd: BuiltinCommand,
17    state: &State,
18) -> Result<ControlFlow, anyhow::Error> {
19    let database = cmd
20        .args
21        .opt_string("database")
22        .unwrap_or_else(|| "materialize".to_string());
23    let schema = cmd
24        .args
25        .opt_string("schema")
26        .unwrap_or_else(|| "public".to_string());
27    let name = cmd.args.string("name")?;
28
29    let status_code = cmd.args.opt_parse::<u16>("status")?;
30    // Interpret the remaining arguments as headers.
31    let headers: Vec<(String, String)> = cmd.args.into_iter().collect();
32
33    let body = cmd.input.join("\n");
34
35    println!("$ webhook-append {database}.{schema}.{name}\n{body}\n{headers:?}");
36
37    let url = format!(
38        "{}/api/webhook/{database}/{schema}/{name}",
39        state.materialize.http_url()
40    );
41    let mut builder = state.materialize.http_client().post(url).body(body);
42
43    // Append all of our headers.
44    for (name, value) in headers {
45        builder = builder.header(name, value);
46    }
47
48    let response = builder.send().await?;
49    let status = response.status();
50
51    println!("{}\n{}", status, response.text().await?);
52
53    let expected_status = status_code.unwrap_or(200);
54    if status.as_u16() == expected_status {
55        Ok(ControlFlow::Continue)
56    } else {
57        bail!("webhook append returned unexpected status: {}", status);
58    }
59}