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

Bring back domain subdomain as it is required for domain registration and other steps #448

Merged
merged 6 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions golem-worker-service-base/src/api_definition/api_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use poem_openapi::NewType;
use serde::{Deserialize, Serialize};

use crate::worker_binding::GolemWorkerBinding;
use poem_openapi::Object;

// Common to API definitions regardless of different protocols
#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Encode, Decode, NewType)]
Expand Down Expand Up @@ -48,28 +49,35 @@ pub struct ApiDeployment<Namespace> {
pub site: ApiSite,
}

#[derive(
Eq,
Hash,
PartialEq,
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
bincode::Encode,
bincode::Decode,
NewType,
)]
pub struct ApiSite(pub String);
#[derive(Debug, Eq, Clone, Hash, PartialEq, Serialize, Deserialize, Encode, Decode, Object)]
pub struct ApiSite {
pub host: String,
pub subdomain: String,
}

impl Display for ApiSite {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
// Need to see how to remove the need of subdomain for localhost , as subdomains are not allowed for localhost
let host = &self.host;
if host.contains("localhost") || host.contains("127.0.0.1") {
write!(f, "{}", self.host)
} else {
write!(f, "{}.{}", self.subdomain, self.host)
}
}
}

#[derive(PartialEq, Eq, Clone, Debug, Hash, Serialize, Deserialize, Encode, Decode, NewType)]
pub struct ApiSiteString(pub String);

impl From<&ApiSite> for ApiSiteString {
fn from(value: &ApiSite) -> Self {
ApiSiteString(value.to_string())
}
}

impl From<&str> for ApiSite {
fn from(site: &str) -> Self {
ApiSite(site.to_string())
impl Display for ApiSiteString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
2 changes: 1 addition & 1 deletion golem-worker-service-base/src/api_definition/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub use api_common::{ApiDefinitionId, ApiDeployment, ApiSite, ApiVersion};
pub use api_common::{ApiDefinitionId, ApiDeployment, ApiSite, ApiSiteString, ApiVersion};
pub(crate) use api_common::{HasApiDefinitionId, HasGolemWorkerBindings, HasVersion};
mod api_common;
pub mod http;
6 changes: 3 additions & 3 deletions golem-worker-service-base/src/http/http_request.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashMap;

use crate::api_definition::ApiSite;
use crate::api_definition::ApiSiteString;
use golem_wasm_ast::analysis::AnalysedType;
use golem_wasm_rpc::TypeAnnotatedValue;
use hyper::http::{HeaderMap, Method};
Expand All @@ -24,11 +24,11 @@ pub struct InputHttpRequest {
}

impl InputHttpRequest {
pub fn get_host(&self) -> Option<ApiSite> {
pub fn get_host(&self) -> Option<ApiSiteString> {
self.headers
.get("host")
.and_then(|host| host.to_str().ok())
.map(ApiSite::from)
.map(|host_str| ApiSiteString(host_str.to_string()))
}

// Converts all request details to type-annotated-value
Expand Down
51 changes: 30 additions & 21 deletions golem-worker-service-base/src/repo/api_deployment_repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::error::Error;
use std::sync::Mutex;

use crate::api_definition::{ApiDefinitionId, ApiDeployment, ApiSite};
use crate::api_definition::{ApiDefinitionId, ApiDeployment, ApiSiteString};
use async_trait::async_trait;
use bytes::Bytes;
use golem_common::config::RedisConfig;
Expand All @@ -18,10 +18,12 @@ const API_DEFINITION_REDIS_NAMESPACE: &str = "apidefinition";
pub trait ApiDeploymentRepo<Namespace: ApiNamespace> {
async fn deploy(&self, deployment: &ApiDeployment<Namespace>) -> Result<(), Box<dyn Error>>;

async fn get(&self, host: &ApiSite)
-> Result<Option<ApiDeployment<Namespace>>, Box<dyn Error>>;
async fn get(
&self,
host: &ApiSiteString,
) -> Result<Option<ApiDeployment<Namespace>>, Box<dyn Error>>;

async fn delete(&self, host: &ApiSite) -> Result<bool, Box<dyn Error>>;
async fn delete(&self, host: &ApiSiteString) -> Result<bool, Box<dyn Error>>;

async fn get_by_id(
&self,
Expand All @@ -31,7 +33,7 @@ pub trait ApiDeploymentRepo<Namespace: ApiNamespace> {
}

pub struct InMemoryDeployment<Namespace> {
deployments: Mutex<HashMap<ApiSite, ApiDeployment<Namespace>>>,
deployments: Mutex<HashMap<ApiSiteString, ApiDeployment<Namespace>>>,
}

impl<Namespace> Default for InMemoryDeployment<Namespace> {
Expand All @@ -54,14 +56,14 @@ impl<Namespace: ApiNamespace> ApiDeploymentRepo<Namespace> for InMemoryDeploymen

let mut deployments = self.deployments.lock().unwrap();

deployments.insert(key, deployment.clone());
deployments.insert(ApiSiteString::from(&key), deployment.clone());

Ok(())
}

async fn get(
&self,
host: &ApiSite,
host: &ApiSiteString,
) -> Result<Option<ApiDeployment<Namespace>>, Box<dyn Error>> {
debug!("Get API site: {}", host);
let deployments = self.deployments.lock().unwrap();
Expand All @@ -71,7 +73,7 @@ impl<Namespace: ApiNamespace> ApiDeploymentRepo<Namespace> for InMemoryDeploymen
Ok(deployment)
}

async fn delete(&self, host: &ApiSite) -> Result<bool, Box<dyn Error>> {
async fn delete(&self, host: &ApiSiteString) -> Result<bool, Box<dyn Error>> {
debug!("Delete API site: {}", host);
let mut deployments = self.deployments.lock().unwrap();

Expand Down Expand Up @@ -115,10 +117,10 @@ impl<Namespace: ApiNamespace> ApiDeploymentRepo<Namespace> for RedisApiDeploy {
async fn deploy(&self, deployment: &ApiDeployment<Namespace>) -> Result<(), Box<dyn Error>> {
debug!(
"Deploy API site: {}, id: {}",
deployment.site, deployment.api_definition_id
&deployment.site, &deployment.api_definition_id
);

let key = redis_keys::api_deployment_redis_key(&deployment.site);
let key = redis_keys::api_deployment_redis_key(&ApiSiteString::from(&deployment.site));

let value = self.pool.serialize(deployment).map_err(|e| e.to_string())?;

Expand Down Expand Up @@ -148,7 +150,7 @@ impl<Namespace: ApiNamespace> ApiDeploymentRepo<Namespace> for RedisApiDeploy {

async fn get(
&self,
host: &ApiSite,
host: &ApiSiteString,
) -> Result<Option<ApiDeployment<Namespace>>, Box<dyn Error>> {
info!("Get host id: {}", host);

Expand All @@ -173,7 +175,7 @@ impl<Namespace: ApiNamespace> ApiDeploymentRepo<Namespace> for RedisApiDeploy {
}
}

async fn delete(&self, host: &ApiSite) -> Result<bool, Box<dyn Error>> {
async fn delete(&self, host: &ApiSiteString) -> Result<bool, Box<dyn Error>> {
debug!("Delete API site: {}", host);
let key = redis_keys::api_deployment_redis_key(host);
let value: Option<Bytes> = self
Expand Down Expand Up @@ -245,7 +247,7 @@ impl<Namespace: ApiNamespace> ApiDeploymentRepo<Namespace> for RedisApiDeploy {
let mut deployments = Vec::new();

for site in sites {
let key = redis_keys::api_deployment_redis_key(&ApiSite(site));
let key = redis_keys::api_deployment_redis_key(&ApiSiteString(site));

let value: Option<Bytes> = self
.pool
Expand All @@ -268,11 +270,11 @@ impl<Namespace: ApiNamespace> ApiDeploymentRepo<Namespace> for RedisApiDeploy {
}

mod redis_keys {
use crate::api_definition::{ApiDefinitionId, ApiSite};
use crate::api_definition::{ApiDefinitionId, ApiSiteString};
use crate::repo::api_deployment_repo::API_DEFINITION_REDIS_NAMESPACE;
use crate::repo::api_namespace::ApiNamespace;

pub(crate) fn api_deployment_redis_key(api_site: &ApiSite) -> String {
pub(crate) fn api_deployment_redis_key(api_site: &ApiSiteString) -> String {
format!("{}:deployment:{}", API_DEFINITION_REDIS_NAMESPACE, api_site)
}

Expand All @@ -289,7 +291,9 @@ mod redis_keys {

#[cfg(test)]
mod tests {
use crate::api_definition::{ApiDefinitionId, ApiDeployment, ApiSite, ApiVersion};
use crate::api_definition::{
ApiDefinitionId, ApiDeployment, ApiSite, ApiSiteString, ApiVersion,
};

use crate::auth::CommonNamespace;
use crate::repo::api_deployment_repo::redis_keys::{
Expand All @@ -304,7 +308,12 @@ mod tests {

let namespace = CommonNamespace::default();

let site = ApiSite::from("test.dev-api.golem.cloud");
let site = ApiSite {
host: "dev-api.golem.cloud".to_string(),
subdomain: "test".to_string(),
};

let site_str = ApiSiteString::from(&site);

let api_definition_id = ApiDefinitionId("api1".to_string());
let version = ApiVersion("0.0.1".to_string());
Expand All @@ -320,7 +329,7 @@ mod tests {

let _ = registry.deploy(&deployment).await;

let result = registry.get(&site).await.unwrap_or(None);
let result = registry.get(&site_str).await.unwrap_or(None);

let result1 = registry
.get_by_id(
Expand All @@ -330,9 +339,9 @@ mod tests {
.await
.unwrap_or(vec![]);

let delete = registry.delete(&site).await.unwrap_or(false);
let delete = registry.delete(&site_str).await.unwrap_or(false);

let result2 = registry.get(&site).await.unwrap_or(None);
let result2 = registry.get(&site_str).await.unwrap_or(None);

assert!(result.is_some());
assert_eq!(result.unwrap(), deployment);
Expand All @@ -345,7 +354,7 @@ mod tests {
#[test]
pub fn test_get_api_deployment_redis_key() {
assert_eq!(
api_deployment_redis_key(&ApiSite::from("foo.dev-api.golem.cloud")),
api_deployment_redis_key(&ApiSiteString("foo.dev-api.golem.cloud".to_string())),
"apidefinition:deployment:foo.dev-api.golem.cloud"
);
}
Expand Down
41 changes: 20 additions & 21 deletions golem-worker-service-base/src/service/api_deployment.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::api_definition::{ApiDefinitionId, ApiDeployment, ApiSite, ApiVersion};
use crate::api_definition::{ApiDefinitionId, ApiDeployment, ApiSiteString, ApiVersion};
use crate::repo::api_definition_repo::ApiDefinitionRepo;
use crate::repo::api_deployment_repo::ApiDeploymentRepo;
use crate::repo::api_namespace::ApiNamespace;
Expand All @@ -25,7 +25,7 @@ pub trait ApiDeploymentService<Namespace> {

async fn get_by_host(
&self,
host: &ApiSite,
host: &ApiSiteString,
) -> Result<Option<ApiDeployment<Namespace>>, ApiDeploymentError<Namespace>>;

// Example: A version of API definition can only be utmost 1 deployment
Expand All @@ -39,15 +39,15 @@ pub trait ApiDeploymentService<Namespace> {
async fn delete(
&self,
namespace: &Namespace,
host: &ApiSite,
host: &ApiSiteString,
) -> Result<bool, ApiDeploymentError<Namespace>>;
}

pub enum ApiDeploymentError<Namespace> {
ApiDefinitionNotFound(Namespace, ApiDefinitionId),
ApiDeploymentNotFound(Namespace, ApiSite),
ApiDeploymentNotFound(Namespace, ApiSiteString),
InternalError(String),
DeploymentConflict(ApiSite),
DeploymentConflict(ApiSiteString),
}

pub struct ApiDeploymentServiceDefault<Namespace, ApiDefinition> {
Expand Down Expand Up @@ -94,16 +94,13 @@ impl<Namespace: ApiNamespace, ApiDefinition> ApiDeploymentService<Namespace>
));
}

let existing_deployment =
self.deployment_repo
.get(&deployment.site)
.await
.map_err(|err| {
ApiDeploymentError::InternalError(format!(
"Error getting api deployment: {}",
err
))
})?;
let existing_deployment = self
.deployment_repo
.get(&ApiSiteString::from(&deployment.site))
.await
.map_err(|err| {
ApiDeploymentError::InternalError(format!("Error getting api deployment: {}", err))
})?;

match existing_deployment {
Some(existing_deployment)
Expand All @@ -115,9 +112,9 @@ impl<Namespace: ApiNamespace, ApiDefinition> ApiDeploymentService<Namespace>
&deployment.api_definition_id.namespace,
&deployment.site,
);
Err(ApiDeploymentError::DeploymentConflict(
existing_deployment.site,
))
Err(ApiDeploymentError::DeploymentConflict(ApiSiteString::from(
&existing_deployment.site,
)))
}
_ => self
.deployment_repo
Expand Down Expand Up @@ -150,7 +147,7 @@ impl<Namespace: ApiNamespace, ApiDefinition> ApiDeploymentService<Namespace>

async fn get_by_host(
&self,
host: &ApiSite,
host: &ApiSiteString,
) -> Result<Option<ApiDeployment<Namespace>>, ApiDeploymentError<Namespace>> {
self.deployment_repo.get(host).await.map_err(|err| {
ApiDeploymentError::InternalError(format!("Error getting api deployment: {}", err))
Expand Down Expand Up @@ -184,7 +181,7 @@ impl<Namespace: ApiNamespace, ApiDefinition> ApiDeploymentService<Namespace>
async fn delete(
&self,
namespace: &Namespace,
host: &ApiSite,
host: &ApiSiteString,
) -> Result<bool, ApiDeploymentError<Namespace>> {
let deployment = self.deployment_repo.get(host).await.map_err(|err| {
ApiDeploymentError::InternalError(format!("Error getting api deployment: {}", err))
Expand All @@ -197,7 +194,9 @@ impl<Namespace: ApiNamespace, ApiDefinition> ApiDeploymentService<Namespace>
namespace,
&host,
);
Err(ApiDeploymentError::DeploymentConflict(deployment.site))
Err(ApiDeploymentError::DeploymentConflict(ApiSiteString::from(
&deployment.site,
)))
}
Some(_) => self.deployment_repo.delete(host).await.map_err(|err| {
ApiDeploymentError::InternalError(format!("Error deleting api deployment: {}", err))
Expand Down
9 changes: 6 additions & 3 deletions golem-worker-service/src/api/deploy_api_definition.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::sync::Arc;

use golem_worker_service_base::api::ApiEndpointError;
use golem_worker_service_base::api_definition::{ApiDefinitionId, ApiSite};
use golem_worker_service_base::api_definition::{ApiDefinitionId, ApiSiteString};
use poem_openapi::param::Query;
use poem_openapi::payload::Json;
use poem_openapi::*;
Expand Down Expand Up @@ -48,7 +48,10 @@ impl ApiDeploymentApi {

self.deployment_service.deploy(&api_deployment).await?;

let data = self.deployment_service.get_by_host(&payload.site).await?;
let data = self
.deployment_service
.get_by_host(&ApiSiteString::from(&payload.site))
.await?;

let deployment = data.ok_or(ApiEndpointError::internal(
"Failed to verify the deployment",
Expand Down Expand Up @@ -82,7 +85,7 @@ impl ApiDeploymentApi {
let site = site_query.0;

self.deployment_service
.delete(&CommonNamespace::default(), &ApiSite(site))
.delete(&CommonNamespace::default(), &ApiSiteString(site))
.await?;

Ok(Json("API deployment deleted".to_string()))
Expand Down
Loading
Loading