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

Fixing API Gateway remaining tickets and bug fixes #543

Merged
merged 18 commits into from
Jun 6, 2024
Merged
5 changes: 2 additions & 3 deletions golem-cli/src/clients/api_deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::model::{ApiDefinitionId, ApiDefinitionVersion, ApiDeployment, GolemError};
use crate::model::{ApiDefinitionId, ApiDefinitionIdWithVersion, ApiDeployment, GolemError};
use async_trait::async_trait;

#[async_trait]
Expand All @@ -21,8 +21,7 @@ pub trait ApiDeploymentClient {

async fn deploy(
&self,
api_definition_id: &ApiDefinitionId,
version: &ApiDefinitionVersion,
api_definitions: Vec<ApiDefinitionIdWithVersion>,
host: &str,
subdomain: Option<String>,
project: &Self::ProjectContext,
Expand Down
36 changes: 22 additions & 14 deletions golem-cli/src/cloud/clients/api_deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use golem_cloud_client::model::ApiSite;
use itertools::Itertools;
use tracing::info;

use crate::model::{ApiDefinitionId, ApiDefinitionVersion, ApiDeployment, GolemError};
use crate::model::{ApiDefinitionId, ApiDefinitionIdWithVersion, ApiDeployment, GolemError};

#[derive(Clone)]
pub struct ApiDeploymentClientLive<C: golem_cloud_client::api::ApiDeploymentClient + Sync + Send> {
Expand All @@ -35,30 +35,38 @@ impl<C: golem_cloud_client::api::ApiDeploymentClient + Sync + Send> ApiDeploymen

async fn deploy(
&self,
api_definition_id: &ApiDefinitionId,
version: &ApiDefinitionVersion,
api_definitions: Vec<ApiDefinitionIdWithVersion>,
host: &str,
subdomain: Option<String>,
project: &Self::ProjectContext,
) -> Result<ApiDeployment, GolemError> {
info!(
"Deploying definition {api_definition_id}/{version}, host {host} {}",
"Deploying definitions to host {host} {}",
subdomain
.clone()
.map_or("".to_string(), |s| format!("subdomain {}", s))
);

let deployment = golem_cloud_client::model::ApiDeployment {
api_definition_id: api_definition_id.0.to_string(),
version: version.0.to_string(),
project_id: project.0,
site: ApiSite {
host: host.to_string(),
subdomain: subdomain.expect("Subdomain is mandatory"), // TODO: unify OSS and cloud
},
};
if api_definitions.len() > 1 {
Err(GolemError(
"Multiple API definitions in a deployment is not supported in Golem Cloud yet"
.to_string(),
))
} else {
let api_definition_id = api_definitions[0].id.0.clone();
let version = api_definitions[0].version.0.clone();
let deployment = golem_cloud_client::model::ApiDeployment {
api_definition_id,
version,
project_id: project.0,
site: ApiSite {
host: host.to_string(),
subdomain: subdomain.expect("Subdomain is mandatory"), // TODO: unify OSS and cloud
},
};

Ok(self.client.deploy(&deployment).await?.into())
Ok(self.client.deploy(&deployment).await?.into())
}
}

async fn list(
Expand Down
17 changes: 6 additions & 11 deletions golem-cli/src/command/api_deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::model::{ApiDefinitionId, ApiDefinitionVersion, GolemError, GolemResult};
use crate::model::{ApiDefinitionId, ApiDefinitionIdWithVersion, GolemError, GolemResult};
use crate::service::api_deployment::ApiDeploymentService;
use crate::service::project::ProjectResolver;
use clap::Subcommand;
Expand All @@ -27,13 +27,9 @@ pub enum ApiDeploymentSubcommand<ProjectRef: clap::Args> {
#[command(flatten)]
project_ref: ProjectRef,

/// Api definition id
#[arg(short, long)]
id: ApiDefinitionId,

/// Api definition version
#[arg(short = 'V', long)]
version: ApiDefinitionVersion,
/// Api definition id with version
#[arg(short = 'd', long = "definition")]
definitions: Vec<ApiDefinitionIdWithVersion>,

#[arg(short = 'H', long)]
host: String,
Expand Down Expand Up @@ -80,14 +76,13 @@ impl<ProjectRef: clap::Args + Send + Sync + 'static> ApiDeploymentSubcommand<Pro
match self {
ApiDeploymentSubcommand::Deploy {
project_ref,
id,
version,
definitions,
host,
subdomain,
} => {
let project_id = projects.resolve_id_or_default(project_ref).await?;
service
.deploy(id, version, host, subdomain, &project_id)
.deploy(definitions, host, subdomain, &project_id)
.await
}
ApiDeploymentSubcommand::Get { site } => service.get(site).await,
Expand Down
56 changes: 41 additions & 15 deletions golem-cli/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use clap::builder::{StringValueParser, TypedValueParser};
use clap::error::{ContextKind, ContextValue, ErrorKind};
use clap::{Arg, ArgMatches, Command, Error, FromArgMatches};
use derive_more::{Display, FromStr};
use golem_client::model::{ApiSite, ScanCursor};
use golem_client::model::{ApiDefinitionInfo, ApiSite, ScanCursor};
use golem_examples::model::{Example, ExampleName, GuestLanguage, GuestLanguageTier};
use serde::{Deserialize, Serialize};
use strum::IntoEnumIterator;
Expand Down Expand Up @@ -293,6 +293,36 @@ impl IdempotencyKey {
}
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct ApiDefinitionIdWithVersion {
pub id: ApiDefinitionId,
pub version: ApiDefinitionVersion,
}

impl Display for ApiDefinitionIdWithVersion {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}/{}", self.id, self.version)
}
}

impl FromStr for ApiDefinitionIdWithVersion {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = s.split('/').collect();
if parts.len() != 2 {
return Err(format!(
"Invalid api definition id with version: {s}. Expected format: <id>/<version>"
));
}

let id = ApiDefinitionId(parts[0].to_string());
let version = ApiDefinitionVersion(parts[1].to_string());

Ok(ApiDefinitionIdWithVersion { id, version })
}
}

#[derive(Clone, PartialEq, Eq, Debug, Display, FromStr)]
pub struct ApiDefinitionId(pub String); // TODO: Validate

Expand Down Expand Up @@ -586,9 +616,8 @@ impl From<golem_cloud_client::model::WorkersMetadataResponse> for WorkersMetadat

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ApiDeployment {
#[serde(rename = "apiDefinitionId")]
pub api_definition_id: String,
pub version: String,
#[serde(rename = "apiDefinitions")]
pub api_definitions: Vec<ApiDefinitionInfo>,
#[serde(rename = "projectId")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
Expand All @@ -598,17 +627,10 @@ pub struct ApiDeployment {

impl From<golem_client::model::ApiDeployment> for ApiDeployment {
fn from(value: golem_client::model::ApiDeployment) -> Self {
let golem_client::model::ApiDeployment {
api_definition_id,
version,
site,
} = value;

ApiDeployment {
api_definition_id,
version,
api_definitions: value.api_definitions,
project_id: None,
site,
site: value.site,
}
}
}
Expand All @@ -622,9 +644,13 @@ impl From<golem_cloud_client::model::ApiDeployment> for ApiDeployment {
site: golem_cloud_client::model::ApiSite { host, subdomain },
} = value;

ApiDeployment {
api_definition_id,
let api_definitions = vec![ApiDefinitionInfo {
id: api_definition_id,
version,
}];

ApiDeployment {
api_definitions,
project_id: Some(project_id),
site: ApiSite {
host,
Expand Down
53 changes: 28 additions & 25 deletions golem-cli/src/model/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,17 +407,19 @@ impl TextFormat for ScanCursor {

impl TextFormat for ApiDeployment {
fn print(&self) {
printdoc!(
"
API deployment on {} with definition {}/{}
",
match &self.site.subdomain {
Some(subdomain) => format!("{}.{}", subdomain, self.site.host),
None => self.site.host.to_string(),
},
self.api_definition_id,
self.version,
);
for api_defs in &self.api_definitions {
printdoc!(
"
API deployment on {} with definition {}/{}
",
match &self.site.subdomain {
Some(subdomain) => format!("{}.{}", subdomain, self.site.host),
None => self.site.host.to_string(),
},
api_defs.id,
api_defs.version,
);
}
}
}

Expand All @@ -431,24 +433,25 @@ struct ApiDeploymentView {
pub version: String,
}

impl From<&ApiDeployment> for ApiDeploymentView {
fn from(value: &ApiDeployment) -> Self {
ApiDeploymentView {
site: match &value.site.subdomain {
Some(subdomain) => format!("{}.{}", subdomain, value.site.host),
None => value.site.host.to_string(),
},
id: value.api_definition_id.to_string(),
version: value.version.to_string(),
}
}
}

impl TextFormat for Vec<ApiDeployment> {
fn print(&self) {
print_stdout(
self.iter()
.map(ApiDeploymentView::from)
.flat_map(|deployment| {
deployment
.api_definitions
.iter()
.map(|def| ApiDeploymentView {
site: match &deployment.site.subdomain {
Some(subdomain) => {
format!("{}.{}", subdomain, deployment.site.host)
}
None => deployment.site.host.to_string(),
},
id: def.id.to_string(),
version: def.version.to_string(),
})
})
.collect::<Vec<_>>()
.with_title(),
)
Expand Down
20 changes: 13 additions & 7 deletions golem-cli/src/oss/clients/api_deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ use async_trait::async_trait;
use itertools::Itertools;

use crate::clients::api_deployment::ApiDeploymentClient;
use golem_client::model::ApiSite;
use golem_client::model::{ApiDefinitionInfo, ApiSite};
use tracing::info;

use crate::model::{ApiDefinitionId, ApiDefinitionVersion, ApiDeployment, GolemError};
use crate::model::{ApiDefinitionId, ApiDefinitionIdWithVersion, ApiDeployment, GolemError};
use crate::oss::model::OssContext;

#[derive(Clone)]
Expand All @@ -35,22 +35,28 @@ impl<C: golem_client::api::ApiDeploymentClient + Sync + Send> ApiDeploymentClien

async fn deploy(
&self,
api_definition_id: &ApiDefinitionId,
version: &ApiDefinitionVersion,
definitions: Vec<ApiDefinitionIdWithVersion>,
host: &str,
subdomain: Option<String>,
_project: &Self::ProjectContext,
) -> Result<ApiDeployment, GolemError> {
info!(
"Deploying definition {api_definition_id}/{version}, host {host} {}",
"Deploying definitions to host {host} {}",
subdomain
.clone()
.map_or("".to_string(), |s| format!("subdomain {}", s))
);

let api_definition_infos = definitions
.iter()
.map(|d| ApiDefinitionInfo {
id: d.id.0.clone(),
version: d.version.0.clone(),
})
.collect::<Vec<_>>();

let deployment = golem_client::model::ApiDeployment {
api_definition_id: api_definition_id.0.to_string(),
version: version.0.to_string(),
api_definitions: api_definition_infos,
site: ApiSite {
host: host.to_string(),
subdomain,
Expand Down
10 changes: 4 additions & 6 deletions golem-cli/src/service/api_deployment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

use crate::clients::api_deployment::ApiDeploymentClient;
use crate::model::{ApiDefinitionId, ApiDefinitionVersion, GolemError, GolemResult};
use crate::model::{ApiDefinitionId, ApiDefinitionIdWithVersion, GolemError, GolemResult};
use async_trait::async_trait;

#[async_trait]
Expand All @@ -22,8 +22,7 @@ pub trait ApiDeploymentService {

async fn deploy(
&self,
id: ApiDefinitionId,
version: ApiDefinitionVersion,
definitions: Vec<ApiDefinitionIdWithVersion>,
host: String,
subdomain: Option<String>,
project: &Self::ProjectContext,
Expand All @@ -49,15 +48,14 @@ impl<ProjectContext: Send + Sync> ApiDeploymentService

async fn deploy(
&self,
id: ApiDefinitionId,
version: ApiDefinitionVersion,
definitions: Vec<ApiDefinitionIdWithVersion>,
host: String,
subdomain: Option<String>,
project: &Self::ProjectContext,
) -> Result<GolemResult, GolemError> {
let deployment = self
.client
.deploy(&id, &version, &host, subdomain, project)
.deploy(definitions, &host, subdomain, project)
.await?;

Ok(GolemResult::Ok(Box::new(deployment)))
Expand Down
Loading
Loading